Python 3.15 est l’une des versions Python les plus riches en fonctionnalités depuis de nombreuses années, et la version générale vient d’arriver. Voici un aperçu des innovations, changements et correctifs les plus importants, les plus audacieux et les plus importants.

Importations paresseuses

Fonctionnalité demandée depuis longtemps, les importations paresseuses permettent de traiter les importations uniquement lorsqu’elles sont réellement utilisées par le programme. Pour les modules à importation lente qui imposent un coût important sur le temps de démarrage d’un programme, vous pouvez reporter ce coût au moment où le code de ce module sera réellement exécuté.

Vous pouvez utiliser les importations paresseuses explicitement à l’aide de la nouvelle syntaxe d’importation paresseuse, mais vous pouvez également forcer le code avec les importations conventionnelles à se comporter paresseusement, soit par programme, soit en utilisant une variable d’environnement. Cela permet de faire en sorte que le code existant profite facilement de cette fonctionnalité sans avoir à réécrire beaucoup. Mieux encore, il n’y a aucun inconvénient à rendre les importations paresseuses : elles se comportent autrement exactement comme prévu.

Le type intégré Frozendict

Python n’ajoute que rarement un nouveau type de données, mais il s’agit d’un ajout longtemps débattu et souhaité : le dictionnaire figé. Le frozendict se comporte comme un dictionnaire ordinaire, sauf qu’il est immuable (vous ne pouvez pas ajouter, supprimer ou modifier des éléments) et qu’il est hachable (vous pouvez donc l’utiliser comme clé dans un autre dictionnaire, par exemple).

Le type intégré sentinel()

Un autre nouvel ajout au langage est destiné à remplacer un modèle Python courant et problématique : la création d’un objet sentinelle unique (comme alternative à None où None pourrait être une valeur valide, par exemple) en utilisant object(). La nouvelle syntaxe ,sentinel("NAME")crée des objets uniques qui ne se comparent qu’à eux-mêmes via le is opérateur. Ces objets peuvent être vérifiés correctement et ils ont une représentation informative au lieu d’un simple descripteur d’objet aléatoire.

Tachyon, un profileur d’échantillonnage statistique

Le de longue date cProfile Le module profile le code Python de manière déterministe, c’est-à-dire qu’il suit et enregistre chaque appel. Cela rend les choses précises, mais cela signifie aussi un cProfile-le programme suivi s’exécute beaucoup plus lentement que la normale. Un nouveau module de profilage en Python 3.15, profiling.samplingutilise des méthodes d’échantillonnage statistique pour recueillir des informations utiles sur les performances avec une fraction de l’impact sur la vitesse du programme. L’existant cProfile le profileur est toujours disponible (il ne va pas disparaître) mais a un nouveau nom alternatif, profiling.tracing.

Un JIT amélioré

Le compilateur juste-à-temps (JIT) intégré de CPython a fait ses débuts dans Python 3.13. Ses objectifs à long terme sont de rendre les programmes Python plus rapides sans aucune modification du code, de la même manière que le runtime Python alternatif, PyPy, peut accélérer les choses. Et cela sans le coût du passage à un interprète totalement différent avec certaines de ses propres limites.

Les deux premières révisions du JIT n’ont pas promis, ni apporté beaucoup de vitesse supplémentaire, car elles visaient plutôt à jeter les bases d’améliorations futures. Avec Python 3.15, cependant, le JIT affiche désormais une amélioration des performances moyenne géométrique de 8 à 13 % par rapport au CPython standard, en fonction de la plate-forme et de la charge de travail. Les changements les plus importants incluent un nouveau frontal de traçage (pour permettre plus d’accélérations sur plus de types de code), l’utilisation de l’allocation de registre pour un travail plus rapide et plus économe en mémoire, un meilleur code machine généré par le JIT et des optimisations supplémentaires telles que l’élimination du nombre de références pour certaines classes d’objets.

Cela vaut la peine d’expérimenter l’activation du JIT pour les charges de travail afin de voir s’il existe une différence mesurable. Mais notez que le développement ultérieur du JIT est désormais soumis à des directives clairement définies concernant l’amélioration des performances qu’il doit apporter avant de pouvoir être considéré comme une partie entièrement prise en charge de Python, et pas seulement comme une activité secondaire expérimentale.

De meilleurs messages d’erreur

Les messages d’erreur dans Python ont été rendus plus précis, détaillés et utiles au cours des deux dernières versions, et Python 3.15 poursuit ce travail. Les points forts :

  • Suggestions de noms manquants («x n’a pas d’attribut ‘y‘. Vouliez-vous dire ‘xyz‘? ») incluent désormais les suggestions des membres d’un objet donné, et pas seulement de l’objet lui-même.
  • Les suggestions couvrent désormais également les contrôles de suppression d’attributs, et pas seulement leur accès.
  • Si l’interprète ne parvient pas à proposer une méthode basée sur une correspondance de noms floue via la distance de Levenshtein, il consulte une liste de noms couramment utilisés dans d’autres langues pour de telles méthodes. Par exemple, si vous essayez d’utiliser list.push() (une méthode JavaScript), l’interprète suggère .append()la méthode appropriée pour les listes Python.

Améliorations du système de saisie

Le TypedDict La classe, qui vous permet de créer des dictionnaires avec des clés prédéfinies et des clés et valeurs typées, ajoute la prise en charge de deux nouveaux arguments dans sa définition. Le closed L’argument vous permet de spécifier si seulement les clés spécifiées peuvent être utilisées au moment de l’exécution. Le extra_items L’argument vous permet de spécifier des clés supplémentaires au moment de l’exécution, mais uniquement des clés avec une valeur d’un type spécifié.

Le TypeForm La définition de type vous permet de représenter la valeur résultant de l’évaluation d’une expression de type. Grâce à cela, les annotations de type peuvent être utilisées là où le type lui-même est utilisé comme valeur, par exemple dans des variantes d’opérations telles que typing.cast ou même isinstanceou dans le cadre du fonctionnement d’un outil de vérification de type tiers.

Déballage dans les compréhensions

Il s’agit d’une autre fonctionnalité demandée depuis longtemps. Si vous vouliez décompresser ou « aplatir » complètement un objet imbriqué à l’aide d’une compréhension, vous aviez besoin d’une fonction comme itertools.chain() ou vous devrez écrire une compréhension imbriquée avec une syntaxe laide :

x = ((1,2,3),(4,5),(6))
y = (a for b in x for a in b)
>>> (1, 2, 3, 4, 5, 6) # y

Déballer les compréhensions à l’aide de l’opérateur étoile vous permet d’économiser une étape :

x = ((1,2,3),(4,5),(6))
y = (*a for a in x)
>>> (1, 2, 3, 4, 5, 6) # y

Déballage avec ** fonctionne également, par exemple, pour aplatir et combiner des dictionnaires :

dicts = ({'a': 1}, {'b': 2}, {'a': 3})
y = {**d for d in dicts}
>>> {'a': 3, 'b': 2}

Enfin, ce type de décompression peut également être utilisé pour former des expressions génératrices :

(*x for x in ("ab","cd","ef"))

L’expression ci-dessus crée un générateur qui donne :

('a', 'b', 'c', 'd', 'e', 'f')

Rétablir le garbage collector incrémentiel

Enfin, Python 3.15 fait un demi-tour important. Python 3.14 présentait un changement majeur dans son système de collecte des déchets : un garbage collector incrémentiel destiné à réduire le temps d’arrêt du programme nécessaire pour collecter les déchets. Malheureusement, de nombreux utilisateurs ont signalé que le nouveau garbage collector augmentait l’utilisation de la mémoire des processus, parfois de manière spectaculaire. Python 3.15 reviendra à l’ancien garbage collector générationnel utilisé dans Python 3.13 et avant. Le collecteur incrémentiel pourrait revenir dans une version future, mais pas sans un travail supplémentaire pour empêcher ce problème de refaire surface.

Autres changements

  • Un nouveau module de mathématiques, math.integervous donne des fonctions pour les mathématiques spécifiques aux entiers, telles que le plus grand diviseur commun ou la racine carrée entière.
  • L’ABI stable a été créé pour faciliter l’écriture d’extensions CPython qui n’ont pas besoin d’être recompilées pour être compatibles avec les révisions ponctuelles multiples de Python. Avec Python 3.15, les développeurs qui écrivent des extensions qui utilisent la version free-thread (alias « no-GIL ») de Python peuvent désormais utiliser Stable ABI. Cela nécessitera une réécriture des extensions qui utilisent l’ABI stable ; ce n’est pas quelque chose que vous pouvez accomplir simplement en recompilant du code avec des en-têtes différents.
  • Les versions CPython ont désormais des pointeurs de trame activés par défaut là où ils sont pris en charge. Cela facilite et accélère le déroulement de la pile, afin que CPython puisse être analysé de manière plus fiable par les outils de profilage et de débogage au niveau du système.
  • UTF-8 est désormais l’encodage par défaut pour Python dans le monde. Vous n’avez plus besoin de spécifier UTF-8 comme encodage lorsque, par exemple, vous lisez du texte à partir de fichiers. Vous pouvez désactiver ce comportement à l’aide d’un indicateur de ligne de commande ou d’une variable d’environnement.

A lire également