Les modifications apportées au langage se concentrent sur la facilité d'utilisation : les f-strings ont été débarrassées de nombreuses limitations et les suggestions "Did you mean ..." continuent de s'améliorer. La nouvelle syntaxe des paramètres de type et la déclaration de type améliorent l'ergonomie de l'utilisation des types génériques et des alias de type avec les vérificateurs de types statiques.
PEP 695 : Syntaxe des paramètres de type
Les classes et fonctions génériques de la PEP 484 étaient déclarées à l'aide d'une syntaxe verbeuse qui ne permettait pas de déterminer clairement la portée des paramètres de type et nécessitait des déclarations explicites de variance.
La PEP 695 introduit une nouvelle méthode, plus compacte et plus explicite, pour créer des classes et des fonctions génériques :
La nouvelle syntaxe permet de déclarer des paramètres TypeVarTuple et ParamSpec, ainsi que des paramètres TypeVar avec des limites ou des contraintes :
La valeur des alias de type et les contraintes des variables de type créées à l'aide de cette syntaxe ne sont évaluées qu'à la demande. Cela signifie que les alias de type peuvent faire référence à d'autres types définis plus loin dans le fichier.
Les paramètres de type déclarés au moyen d'une liste de paramètres de type sont visibles dans la portée de la déclaration et dans toute portée imbriquée, mais pas dans la portée extérieure. Par exemple, ils peuvent être utilisés dans les annotations de type pour les méthodes d'une classe générique ou dans le corps de la classe. Toutefois, ils ne peuvent pas être utilisés dans la portée du module après la définition de la classe.
Afin de prendre en charge cette sémantique de portée, un nouveau type de portée est introduit, la portée d'annotation. Les portées d'annotation se comportent pour la plupart comme les portées de fonction, mais interagissent différemment avec les portées de classe qui les entourent. Dans Python 3.13, les annotations seront également évaluées dans les portées d'annotation.
PEP 701 : Formalisation syntaxique des f-strings
La PEP 701 lève certaines restrictions sur l'utilisation des f-strings. Les composants d'expression à l'intérieur des f-strings peuvent maintenant être n'importe quelle expression Python valide, y compris les chaînes réutilisant le même guillemet que le f-strings contenant, les expressions multi-lignes, les commentaires, les antislashs, et les séquences d'échappement unicode. Voyons cela en détail :
- Réutilisation des guillemets : dans Python 3.11, la réutilisation des mêmes guillemets que la f-string contenante soulève une SyntaxError, obligeant l'utilisateur à utiliser d'autres guillemets disponibles (comme des guillemets doubles ou triples si la chaîne f utilise des guillemets simples). Dans Python 3.12, vous pouvez maintenant faire des choses comme ceci :
- Expressions et commentaires sur plusieurs lignes : Dans Python 3.11, les expressions f-string doivent être définies sur une seule ligne, même si l'expression à l'intérieur de la f-string pourrait normalement s'étendre sur plusieurs lignes (comme les listes littérales définies sur plusieurs lignes), ce qui les rend plus difficiles à lire. Dans Python 3.12, vous pouvez désormais définir des chaînes f s'étendant sur plusieurs lignes et ajouter des commentaires en ligne :
- Barres obliques inversées et caractères unicode : avant Python 3.12, les expressions f-string ne pouvaient contenir aucun caractère \. Cela affectait également les séquences d'échappement unicode (telles que \N{snowman}) car elles contiennent la partie \N qui, auparavant, ne pouvait pas faire partie des composants d'expression des chaînes f. Désormais, vous pouvez définir des expressions comme celles-ci:
Un effet secondaire positif de la façon dont cette fonctionnalité a été implémentée (en analysant les chaînes f avec l'analyseur PEG) est que les messages d'erreur pour les chaînes f sont maintenant plus précis et incluent l'emplacement exact de l'erreur. Dans Python 3.12, comme les f-strings sont analysées avec l'analyseur PEG, les messages d'erreur peuvent être plus précis et afficher la ligne entière :
PEP 684 : Une GIL par interprète
La PEP 684 introduit une GIL par interprète, de sorte que les sous-interprètes peuvent désormais être créés avec une GIL unique par interprète. Cela permet aux programmes Python de tirer pleinement parti de plusieurs cœurs de processeur.Ceci n'est actuellement disponible qu'à travers l'API C, bien qu'une API Python soit prévue pour la version 3.13.
Utilisez la nouvelle fonction Py_NewInterpreterFromConfig() pour créer un interpréteur avec sa propre GIL :
PEP 669 : Surveillance à faible impact pour CPython
Le PEP 669 définit une nouvelle API pour les profileurs, les débogueurs et d'autres outils pour surveiller les événements dans CPython. Elle couvre une large gamme d'événements, y compris les appels, les retours, les lignes, les exceptions, les sauts, et plus encore. Cela signifie que vous ne payez que pour ce que vous utilisez, fournissant un support pour les débogueurs et les outils de couverture avec un surcoût proche de zéro.
PEP 688 :Rendre le protocole de tampon accessible en Python
La PEP 688 introduit un moyen d'utiliser le protocole de tampon à partir du code Python. Les classes qui implémentent la méthode __buffer__() sont désormais utilisables en tant que types de tampons.
Le nouvel ABC collections.abc.Buffer fournit un moyen standard de représenter les objets tampons, par exemple dans les annotations de type. Le nouvel enum inspect.BufferFlags représente les drapeaux qui peuvent être utilisés pour personnaliser la création de tampons.
PEP 709 : Inlining de la compréhension
Les compréhensions de dictionnaires, de listes et d'ensembles sont désormais intégrées, plutôt que de créer un nouvel objet fonction à usage unique pour chaque exécution de la compréhension. Cela permet d'accélérer l'exécution d'une compréhension jusqu'à deux fois.
Les variables d'itération de la compréhension restent isolées et n'écrasent pas une variable du même nom dans la portée extérieure, et ne sont pas visibles après la compréhension. L'incrustation entraîne quelques changements de comportement visibles :
- Il n'y a plus de cadre séparé pour la compréhension dans les tracesbacks, et le traçage/profilage ne montre plus la compréhension comme un appel de fonction.
- Le module symtable ne produira plus de tables de symboles enfants pour chaque compréhension ; à la place, les locales de la compréhension seront incluses dans la table de symboles de la fonction parente.
- L'appel à locals() à l'intérieur d'une compréhension inclut désormais des variables extérieures à la compréhension et n'inclut plus la variable synthétique .0 pour l'"argument" de la compréhension.
- Une compréhension itérant directement sur locals() (par exemple [k for k in locals()]) peut voir "RuntimeError : dictionary changed size during iteration" lorsqu'elle est exécutée sous traçage (par exemple, mesure de la couverture du code). Il s'agit du même comportement que celui observé dans for k in locals() :. Pour éviter l'erreur, il faut d'abord créer une liste de clés sur lesquelles itérer : keys = list(locals()) ; [k for k in keys].
Amélioration des messages d'erreur
- Les modules de la bibliothèque standard sont maintenant potentiellement suggérés dans les messages d'erreur affichés par l'interpréteur lorsqu'une NameError est remontée au niveau supérieur.
- Amélioration de la suggestion d'erreur pour les exceptions NameError pour les instances. Maintenant, si une NameError est levée dans une méthode et que l'instance a un attribut qui est exactement égal au nom dans l'exception, la suggestion inclura self.<NAME> au lieu de la correspondance la plus proche dans la portée de la méthode.
- Améliorer le message d'erreur SyntaxError lorsque l'utilisateur tape import x from y au lieu de from y import x.
- Les exceptions ImportError soulevées par l'échec de from <module> import <nom> incluent maintenant des suggestions pour la valeur de <nom> basées sur les noms disponibles dans <module>.
PEP 692 : Utilisation de TypedDict pour un typage plus précis des **kwargs
Le typage des **kwargs dans la signature d'une fonction, tel qu'introduit par la PEP 484, ne permettait des annotations valides que dans les cas où tous les **kwargs étaient du même type.
La PEP 692 spécifie une manière plus précise de typer les **kwargs en s'appuyant sur les dictionnaires typés :
PEP 698 : Décorateur de surcharge pour le typage statique
Un nouveau décorateur typing.override() a été ajouté au module de typage.Il indique aux vérificateurs de type que la méthode est destinée à remplacer une méthode d'une superclasse.Cela permet aux vérificateurs de type de détecter les erreurs lorsqu'une méthode destinée à remplacer une méthode d'une classe de base ne le fait pas.
Cet article ne prétend pas fournir une spécification complète de toutes les nouvelles fonctionnalités, mais donne plutôt une vue d'ensemble pratique. Pour plus de détails, vous pouvez voir dans la source.
Source : Python
Et vous ?
Quel est votre avis sur le sujet ?
Voir aussi :
Une nouvelle version alpha de Python 3.12, plus rapide et plus légère, est désormais disponible et apporte plusieurs améliorations au niveau du multitraitement et de la gestion des erreurs
Python 3.12.0b1, la première des quatre versions bêta de la 3.12, a été publiée et apporte de nouvelles fonctionnalités ainsi que des corrections de bogues
Le plan de travail pour la future version 3.13 de Python a été dévoilé et vise la réduction d'au moins 50 % du temps passé dans l'interpréteur ainsi qu'une meilleure gestion de la mémoire