Les nouveautés de Python 3.9

Éditeur

Łukasz Langa

This article explains the new features in Python 3.9, compared to 3.8. Python 3.9 was released on October 5, 2020.

Pour plus de détails, voir le changelog.

Voir aussi

PEP 596 – Calendrier de sortie de Python 3.9

Résumé – Points marquants de cette version

Nouvelles fonctionnalités de syntaxe :

  • PEP 584, ajout de l'opérateur d'union à dict ;

  • PEP 585, indications des types paramétrables dans les collections natives ;

  • PEP 614, restrictions grammaticales assouplies pour les décorateurs.

Nouvelles fonctionnalités natives :

  • PEP 616, méthodes sur les chaînes pour enlever des préfixes et des suffixes.

Nouvelles fonctionnalités dans la bibliothèque standard :

  • PEP 593, annotations flexibles pour les fonctions et les variables ;

  • ajout de os.pidfd_open() qui permet la gestion de processus sans concurrence critique et sans signaux.

Améliorations de l'interpréteur :

  • PEP 573, accès rapide à l'état des modules à partir des méthodes des types dans les extensions C ;

  • PEP 617, CPython utilise maintenant un analyseur lexical PEG (Parsing Expression Grammar) ;

  • certains types Python natifs (range, tuple, set, frozenset, list, dict) sont maintenant plus rapides grâce aux appels vectorcall (PEP 590) ;

  • le ramasse-miettes ne bloque pas sur les objets ressuscités ;

  • certains modules Python (_abc, audioop, _bz2, _codecs, _contextvars, _crypt, _functools, _json, _locale, math, operator, resource, time, _weakref) utilisent maintenant l'initialisation multi-phase telle que définie dans PEP 489 ;

  • certains modules de la bibliothèque standard (audioop, ast, grp, _hashlib, pwd, _posixsubprocess, random, select, struct, termios, zlib) utilisent maintenant l'ABI (Application Binary Interface) stable définie dans PEP 384.

Nouveaux modules de la bibliothèque :

  • PEP 615, la base de données des fuseaux horaires de l'IANA est maintenant incluse dans le module zoneinfo de la bibliothèque standard ;

  • une implémentation du tri topologique d'un graphe est maintenant disponible dans le nouveau module graphlib.

Changements aux procédures de publication :

  • PEP 602, CPython adopte un cycle annuel de publications.

Vous devez vérifier la présence de DeprecationWarning dans votre code

Quand Python 2.7 était encore pris en charge, plusieurs fonctionnalités dans Python 3 étaient gardées pour la rétro-compatibilité avec Python 2.7. Avec la fin de la prise en charge de Python 2, ces couches de rétro-compatibilité ont été retirées ou le seront bientôt. La plupart d'entre elles émettaient un avertissement DeprecationWarning depuis plusieurs années. Par exemple, utiliser collections.Mapping plutôt que collections.abc.Mapping émettait un DeprecationWarning depuis Python 3.3, publié en 2012.

Testez votre application avec l'option de ligne de commande -W default pour voir les DeprecationWarning et les PendingDeprecationWarning, ou même avec -W error pour les traiter comme des erreurs. Le filtre des avertissements peut être utilisé pour ignorer les avertissements provenant de code de tierces parties.

Python 3.9 est la dernière version qui fournit ces couches de rétro compatibilité avec Python 2, afin de donner plus de temps aux mainteneurs de projets Python pour organiser l'arrêt de la prise en charge de Python 2 et pour assurer celle de Python 3.9.

Les alias vers Abstract Base Classes dans le module collections, comme l'alias collections.Mapping vers collections.abc.Mapping, sont conservés pour une dernière version au titre de la rétrocompatibilité. Ils seront supprimés de Python 3.10.

Plus généralement, essayez d'exécuter vos tests dans le Python Development Mode qui aide à préparer votre code pour le rendre compatible avec la prochaine version de Python.

Note : certaines déclarations d’obsolescence pré-existantes ont été retirées de cette version de Python. Voir la section Retraits.

Nouvelles fonctionnalités

Opérateurs de fusion et de mise à jour de dictionnaires

Ajout des opérateurs de fusion (|) et de mise-à-jour (|=) à la classe native dict. Ils viennent compléter les méthodes existantes dict.update et {**d1, **d2} pour fusionner des dictionnaires.

Exemple :

>>> x = {"key1": "value1 from x", "key2": "value2 from x"}
>>> y = {"key2": "value2 from y", "key3": "value3 from y"}
>>> x | y
{'key1': 'value1 from x', 'key2': 'value2 from y', 'key3': 'value3 from y'}
>>> y | x
{'key2': 'value2 from x', 'key3': 'value3 from y', 'key1': 'value1 from x'}

Voir PEP 584 pour une description complète (contribution de Brandt Bucher dans bpo-36144).

Nouvelles méthodes sur les chaînes pour retirer des préfixes et des suffixes

str.removeprefix(préfixe) et str.removesuffix(suffixe) ont été ajoutées pour supprimer facilement un préfixe ou un suffixe inutile d'une chaîne. Les méthodes correspondantes de bytes, bytearray et collections.UserString ont également été ajoutées. Voir PEP 616 pour une description complète (contribution de Dennis Sweeney dans bpo-39939).

Indication des types paramétrables dans les collections natives

Dans les annotations de type, vous pouvez maintenant utiliser les types de collection natifs tels que list et dict comme types génériques au lieu d'importer les types en majuscules correspondants (par exemple List ou Dict) à partir de typing. D'autres types de la bibliothèque standard sont maintenant génériques, par exemple queue.Queue.

Exemple :

def greet_all(names: list[str]) -> None:
    for name in names:
        print("Hello", name)

Voir PEP 585 pour plus de détails (contribution de Guido van Rossum, Ethan Smith et Batuhan Taşkaya dans bpo-39481).

Nouvel analyseur syntaxique

Python 3.9 utilise un nouvel analyseur syntaxique, basé sur PEG au lieu de LL(1). Les performances du nouvel analyseur sont à peu près comparables à celles de l'ancien, mais le formalisme PEG est plus souple que LL(1) lorsqu'il s'agit de concevoir des nouvelles fonctionnalités du langage. Nous commencerons à utiliser cette flexibilité dans Python 3.10 et les versions suivantes.

Le module ast utilise le nouvel analyseur syntaxique et produit le même AST que l'ancien analyseur.

Dans Python 3.10, l'ancien analyseur sera supprimé ainsi que toutes les fonctionnalités qui en dépendent (principalement le module parser, qui est obsolète depuis longtemps). En Python 3.9 seulement, vous pouvez revenir à l'analyseur LL(1) en utilisant une option en ligne de commande (-X oldparser) ou une variable d'environnement (PYTHONOLDPARSER=1).

Voir PEP 617 pour plus de détails (contribution de Guido van Rossum, Pablo Galindo et Lysandros Nikolaou dans bpo-40334).

Autres changements au langage

  • __import__() lève maintenant ImportError plutôt que ValueError, ce qui se produisait lorsqu’un import relatif remontait plus loin que le répertoire racine du paquet (contribution de Ngalim Siregar dans bpo-37444).

  • Python récupère maintenant le chemin absolu du nom de fichier du script spécifié sur la ligne de commande (ex. : python3 script.py) : l'attribut __file__ du module __main__ est devenu un chemin absolu, plutôt qu'un chemin relatif. Ces nouveaux chemins restent valides même après que le répertoire courant est changé par os.chdir(). En conséquence, les traces d'appels affichent le chemin absolu pour les cadres du module __main__ dans ce cas (contribution de Victor Stinner dans bpo-20443).

  • Dans le mode de développement de Python et dans les compilations en mode débogage, les arguments encoding et errors sont maintenant vérifiés pour les opérations d'encodage et de décodage de chaînes. Exemples : open(), str.encode() et bytes.decode().

    Par défaut, afin d'améliorer les performances, l'argument errors n'est consulté qu'au moment de la première erreur d'encodage-décodage et l'argument encoding est parfois ignoré pour les chaînes vides (contribution de Victor Stinner dans bpo-37388).

  • "".replace("", s, n) renvoie maintenant s plutôt qu'une chaîne vide pour toute valeur non-nulles de n. Ce comportement est maintenant cohérent avec "".replace("", s). Les instances de bytes et bytearray ont le même comportement (contribution de Serhiy Storchaka dans bpo-28029).

  • Toute expression valide peut maintenant être utilisée comme décorateur (voir decorator). Préalablement, la grammaire était beaucoup plus contraignante. Voir PEP 614 pour les détails (contributions de Brandt Bucher dans bpo-39702).

  • Aide améliorée pour le module typing. La documentation est maintenant visible pour toutes les formes spéciales et les alias générique spéciaux (comme Union et List). Utiliser help() sur un alias générique comme List[int] montre l'aide correspondant au type réel (list dans ce cas). (Contribution de Serhiy Storchaka dans bpo-40257).

  • L'exécution parallèle de aclose() / asend() / athrow() est maintenant interdite, et ag_running reflète maintenant le statut réel du générateur asynchrone. (Contribué par Yury Selivanov dans bpo-30773.)

  • Les erreurs inattendues lors d'un appel de la méthode __iter__ ne sont plus masquées par TypeError dans l'opérateur in et les fonctions contains(), indexOf() et countOf() du module operator. (Contribué par Serhiy Storchaka dans bpo-40824.)

  • Les expressions lambda sans parenthèses ne peuvent plus être la partie expression dans une clause if dans les compréhensions de liste et les expressions de générateur. Voir bpo-41848 et bpo-43755 pour plus de détails.

Nouveaux modules

zoneinfo

Le module zoneinfo ajoute la prise en charge de la base de donnée des fuseaux horaires de l'IANA dans la bibliothèque standard. Il ajoute zoneinfo.ZoneInfo, une implémentation concrète de datetime.tzinfo à partir des données de fuseaux horaires du système.

Exemple :

>>> from zoneinfo import ZoneInfo
>>> from datetime import datetime, timedelta

>>> # Daylight saving time
>>> dt = datetime(2020, 10, 31, 12, tzinfo=ZoneInfo("America/Los_Angeles"))
>>> print(dt)
2020-10-31 12:00:00-07:00
>>> dt.tzname()
'PDT'

>>> # Standard time
>>> dt += timedelta(days=7)
>>> print(dt)
2020-11-07 12:00:00-08:00
>>> print(dt.tzname())
PST

Comme option de rabat pour les plateformes qui n'incluent pas la base de donnée de l'IANA, le module quasi-natif tzdata été publié –– il est distribué sur PyPI et maintenu par l'équipe principale de CPython.

Voir aussi

PEP 615 — Prise en charge de la base de donnée des fuseaux horaires de l'IANA dans la bibliothèque standard

PEP écrit et implémenté par Paul Ganssle

graphlib

Un nouveau module, graphlib, a été ajouté. Il contient la classe graphlib.TopologicalSorter qui offre des fonctionnalités pour faire le tri topologique de graphes (contribution de Pablo Galindo, Tim Peters et Larry Hastings dans bpo-17005).

Modules améliorés

ast

Ajout de l'option indent à dump() qui permet de produire une sortie multi-ligne indentée (contribution de Serhiy Storchaka dans bpo-37995).

Ajout de la fonction ast.unparse() au module ast pour renverser l'analyse syntaxique d'un objet ast.AST et produire une chaîne de code qui produirait un ast.AST équivalent lorsqu'il est analysé (contribution de Pablo Galindo et Batuhan Taskaya dans bpo-38870).

Ajout de chaînes de documentation aux nœuds AST qui contiennent les signatures ASDL utilisées pour construire ce nœud (contribution de Batuhan Taskaya dans bpo-39638).

asyncio

En raison de problèmes de sécurité importants, le paramètre reuse_address de asyncio.loop.create_datagram_endpoint() n'est plus supporté. C'est à cause du comportement de l'option socket SO_REUSEADDR en UDP. Pour plus de détails, voir la documentation de loop.create_datagram_endpoint(). (Contribué par Kyle Stanley, Antoine Pitrou, et Yury Selivanov dans bpo-37228.)

Ajout d'une nouvelle coroutine shutdown_default_executor() qui programme une extinction de l'exécuteur par défaut qui attend que ThreadPoolExecutor se termine. Aussi, asyncio.run() à été mis à jour pour utiliser la nouvelle coroutine. (Contribué par Kyle Stanley dans bpo-34037.)

Ajout de asyncio.PidfdChildWatcher, un surveillant de processus enfants spécifique à Linux qui interroge le descripteur de ficher du processus. (bpo-38692)

Added a new coroutine asyncio.to_thread(). It is mainly used for running IO-bound functions in a separate thread to avoid blocking the event loop, and essentially works as a high-level version of run_in_executor() that can directly take keyword arguments. (Contributed by Kyle Stanley and Yury Selivanov in bpo-32309.)

When cancelling the task due to a timeout, asyncio.wait_for() will now wait until the cancellation is complete also in the case when timeout is <= 0, like it does with positive timeouts. (Contributed by Elvis Pranskevichus in bpo-32751.)

asyncio lève maintenant une TyperError lors d'un appel à des méthodes incompatibles avec un socket ssl.SSLSocket. (Contribué par Ido Michael dans bpo-37404.)

compileall

Ajout de la possibilité d'utiliser des liens physiques pour les fichiers .pyc dupliqués : paramètre hardlink_dupes et option de ligne de commande --hardlink-dupes (contribution de Lumír 'Frenzy' Balhar dans bpo-40495).

Ajout d'options pour manipuler les chemins des fichiers .pyc résultants : paramètres stripdir, prependdir, limit_sl_dest et options de la ligne de commande -s, -p, -e. Ajout de la possibilité de spécifier l'option pour un niveau d'optimisation plus d'une fois (contribution de Lumír 'Frenzy' Balhar dans bpo-38112).

concurrent.futures

Ajout du nouveau paramètre cancel_futures à concurrent.futures.Executor.shutdown() qui annule tous les futurs en attente qui n'ont pas commencé leur exécution, plutôt que d'attendre qu'ils aient complété avant d'arrêter l'exécuteur (contribution Kyle Stanley dans bpo-39349).

Removed daemon threads from ThreadPoolExecutor and ProcessPoolExecutor. This improves compatibility with subinterpreters and predictability in their shutdown processes. (Contributed by Kyle Stanley in bpo-39812.)

Workers in ProcessPoolExecutor are now spawned on demand, only when there are no available idle workers to reuse. This optimizes startup overhead and reduces the amount of lost CPU time to idle workers. (Contributed by Kyle Stanley in bpo-39207.)

curses

Ajout des fonctions curses.get_escdelay(), curses.set_escdelay(), curses.get_tabsize(), et curses.set_tabsize() (contribution d'Anthony Sottile dans bpo-38312).

datetime

La méthode isocalendar() de datetime.date et la méthode isocalendar() de datetime.datetime renvoient maintenant un namedtuple() plutôt qu'un tuple (contribution de Dong-hee Na dans bpo-24416).

distutils

La commande upload crée maintenant des condensats SHA2-256 et Blake2b-256. Elle ne produit pas MD5 sur les plateformes qui bloquent les condensats MD5 (contribution de Christian Heimes dans bpo-40698).

fcntl

Ajout des constantes F_OFD_GETLK, F_OFD_SETLK et F_OFD_SETLKW (contribution de Dong-hee Na dans bpo-38602).

ftplib

Afin d'empêcher la création de socket non-bloquant, les classes FTP et FTP_TLS lèvent maintenant ValueError quand zéro est passé à timeout dans leur constructeur (contribution de Dong-hee Na dans bpo-39259).

gc

Quand le ramasse-miettes fait un ramassage pour lequel certains objets sont ressuscités (ils sont atteignables à partir de l'extérieur des cycles isolés après que les finaliseurs soient exécutés), le ramassage des objets qui sont toujours inatteignables n'est pas suspendu (contribution de Pablo Galindo et Tim Peters dans bpo-38379).

Ajout de la fonction gc.is_finalized() pour vérifier si un objet a été finalisé par le ramasse-miettes (contribution de Pablo Galindo dans bpo-39322).

hashlib

Le module hashlib peut maintenant utiliser les algorithmes de hachage SHA3 et SHAKE XOF de OpenSSL quand ils sont disponibles (contribution de Christian Heimes dans bpo-37630).

Les modules de hachage natifs peuvent être désactivés avec ./configure --without-builtin-hashlib-hashes ou activés sélectivement avec par exemple ./configure --with-builtin-hashlib-hashes=sha3,blake2 pour forcer l'utilisation de l’implémentation OpenSSL (contribution de Christian Heimes dans bpo-40479).

http

Les codes d'état HTTP 103 EARLY_HINTS, 418 IM_A_TEAPOT et 425 TOO_EARLY ont été ajoutés à http.HTTPStatus (contribution de Dong-hee Na dans bpo-39509 et Ross Rhodes dans bpo-39507).

IDLE et idlelib

Ajout d'une option pour désactiver le clignotement du curseur (contribution de Zackery Spytz dans bpo-4603).

La fenêtre de complétion de IDLE est maintenant fermée par la touche d'échappement (contribution de Johnny Najera dans bpo-38944).

Ajout de mots clés à la liste de complétion de noms de modules (contribution de Terry J. Reedy dans bpo-37765).

New in 3.9 maintenance releases

IDLE invoque maintenant sys.excepthook() (lorsque lancé sans '-n'). Auparavant, les fonctions de rappel définies par l'utilisateur étaient ignorées (contribution par Ken Hilton dans bpo-43008).

Les changements ci-haut ont été rétro-portés dans la version de maintenance de 3.8.

Rearrange the settings dialog. Split the General tab into Windows and Shell/Ed tabs. Move help sources, which extend the Help menu, to the Extensions tab. Make space for new options and shorten the dialog. The latter makes the dialog better fit small screens. (Contributed by Terry Jan Reedy in bpo-40468.) Move the indent space setting from the Font tab to the new Windows tab. (Contributed by Mark Roseman and Terry Jan Reedy in bpo-33962.)

Applique la coloration syntaxique aux fichiers .pyi (contribution d'Alex Waygood et de Terry Jan Reedy dans bpo-45447).

imaplib

IMAP4 et IMAP4_SSL ont maintenant un paramètre optionnel timeout dans leur constructeur. De plus, la méthode open() a maintenant un paramètre optionnel timeout avec ce changement. Les méthodes surchargées de IMAP4_SSL et IMAP4_stream appliquent ce changement (contribution de Dong-hee Na dans bpo-38615).

Ajout de imaplib.IMAP4.unselect(). imaplib.IMAP4.unselect() libère les ressources du serveur associées à la boîte de courriel sélectionnée et remet le serveur à l'état autenticated. Cette commande exécute les mêmes actions que imaplib.IMAP4.close(), mais aucun message n'est retiré de façon permanente de la boîte courriel sélectionnée (contribution de Dong-hee Na dans bpo-40375).

importlib

Pour plus de cohérence avec les instructions d'import, importlib.util.resolve_name() lève maintenant ImportError plutôt que ValueError pour les tentatives d'import relatifs invalides (contribution de Ngalim Siregar dans bpo-37444).

Les chargeurs d'importation qui publient des objets modules immuables peuvent maintenant aussi publier des paquets immuables en plus des modules individuels (contribution de Dino Viehland dans bpo-39336).

Ajout de la fonction importlib.resources.files() qui prend en charge les sous-répertoires dans les données du paquet. Aussi rétro-porté pour les version précédentes de Python dans importlib_resources version 1.5 (contribution de Jason R. Coombs dans bpo-39791).

Mise à jour de importlib.metadata à partir de importlib_metadata version 1.6.1.

inspect

inspect.BoundArguments.arguments, qui était un OrderedDict, devient un dict natif régulier (contribution de Inada Naoki dans bpo-36350 et bpo-39775).

ipaddress

ipaddress prend désormais en charge les IPv6 avec une portée spécifiée (adresses IPv6 avec un suffixe %<scope_id>).

Les adresses IPv6 avec une portée spécifiée peuvent être analysées avec ipaddress.IPv6Address. S'il est présent, l'indice de la zone de la portée est disponible dans l'attribut scope_id (contribution de Oleksandr Pavliuk dans bpo-34788).

À partir de Python 3.9.5, le module ipaddress n'accepte plus aucun zéro en tête des chaînes de caractères IPv4. (Contribué par Christian Heimes dans bpo-36384).

math

Extension de la fonction math.gcd() pour gérer les arguments multiples. Préalablement, elle ne gérait que deux arguments (contribution de Serhiy Storchaka dans bpo-39648).

Ajout de math.lcm() : renvoie le plus petit commun multiple des arguments spécifiés (contribution de Mark Dickinson, Ananthakrishnan et Serhiy Storchaka dans bpo-39479 et bpo-39648).

Ajout de math.nextafter() : renvoie la prochaine valeur à point flottant après x en direction de y (contribution de Victor Stinner dans bpo-39288).

Ajout de math.ulp() : renvoie la valeur du bit le moins significatif d'un float (contribution de Victor Stinner dans bpo-39310).

multiprocessing

La classe multiprocessing.SimpleQueue a une nouvelle méthode close() pour fermer la queue de façon explicite (contribution de Victor Stinner dans bpo-30966).

nntplib

Afin d'empêcher la création d'interfaces de connexion (sockets) non-bloquantes, les classes NNTP et NNTP_SSL lèvent maintenant ValueError si la valeur passée à timeout dans leur constructeur est zéro (contribution de Dong-hee Na dans bpo-39259).

os

Ajout de CLD_KILLED et CLD_STOPPED pour si_code (contribution de Dong-hee Na dans bpo-38493).

Sur Linux, exposition de os.pidfd_open() (bpo-38692) et de os.P_PIDFD (bpo-38713) pour la gestion de processus avec des descripteurs de fichiers.

La fonction os.unsetenv() est maintenant aussi disponible sur Windows (contribution de Victor Stinner dans bpo-39413).

Les fonctions os.putenv() et os.unsetenv() sont maintenant toujours disponibles (contribution de Victor Stinner dans bpo-39395).

Ajout de la fonction os.waitstatus_to_exitcode() : convertit la valeur de retour de wait() en code de sortie (contribution de Victor Stinner dans bpo-40094).

pathlib

Ajout de pathlib.Path.readlink() qui a un comportement similaire à os.readlink() (contribution de Girts Folkmanis dans bpo-30618).

pdb

Sur Windows, Pdb gère maintenant ~/.pdbrc (contribution de Tim Hopper et Dan Lidral-Porter dans bpo-20523).

poplib

Afin de prévenir la création d'une interface de connexion (socket) non-bloquante, POP3 et POP3_SSL lèvent maintenant une ValueError si la valeur passée à timeout dans leur constructeur est zéro (contribution de Dong-hee Na dans bpo-39259).

pprint

pprint peut maintenant faire l'affichage formaté de types.SimpleNamespace (contribution de Carl Bordum Hansen dans bpo-37376).

pydoc

La chaîne de documentation est maintenant affichée non seulement pour les classes, fonctions, méthodes, etc., mais aussi pour tout objet qui a son propre attribut __doc__ (contribution de Serhiy Storchaka dans bpo-40257).

random

Ajout de la méthode random.Random.randbytes : génère des octets aléatoires (contribution de Victor Stinner dans bpo-40286).

signal

Sur Linux, exposition de signal.pidfd_send_signal() pour envoyer des signaux à un processus en utilisant un descripteur de fichier plutôt qu'un identifiant de processus (pid). (bpo-38712)

smtplib

Afin d'éviter la création d'une interface de connexion (socket) non-bloquante, SMTP et SMTP_SSL lèvent maintenant une ValueError si la valeur de timeout passée à leur constructeur est zéro (contribution de Dong-hee Na dans bpo-39259).

Le constructeur de LMTP a maintenant un paramètre timeout optionnel (contribution de Dong-hee Na dans bpo-39329).

socket

Le module socket exporte maintenant la constante CAN_RAW_JOIN_FILTERS à partir de Linux 4.1 (contribution de Stefan Tatschner et Zackery Spytz dans bpo-25780).

Le module socket prend maintenant en charge le protocole CAN_J1939 sur les plateformes où il est disponible (contribution de Karl Ding dans bpo-40291).

Le module socket possède maintenant les fonctions socket.send_fds() et socket.recv_fds() (contribution de Joannah Nanjekye, Shinya Okano et Victor Stinner dans bpo-28724).

time

Sur AIX, thread_time() est maintenant implémenté par thread_cputime() qui a une résolution à la nanoseconde près plutôt que clock_gettime(CLOCK_THREAD_CPUTIME_ID) qui a une résolution de 10 ms (contribution de Batuhan Taskaya dans bpo-40192).

sys

Ajout du nouvel attribut sys.platlibdir : répertoire des bibliothèques spécifiques à la plateforme. Il est utilisé pour construire le chemin de la bibliothèque standard et les chemins des modules d'extension installés. Il est égal à "lib" sur la plupart des plateformes. Sur Fedora et SuSE, il est égal à "lib64" sur les plateformes 64-bit (contribution de Jan Matějek, Matěj Cepl, Charalampos Stratakis et Victor Stinner dans bpo-1294959).

Préalablement, sys.stderr avait un tampon par blocs quand il n'était pas interactif. Maintenant stderr a toujours par défaut un tampon par lignes (contribution de Jendrik Seipp dans bpo-13601).

tracemalloc

Ajout de tracemalloc.reset_peak() qui affecte la taille d'apogée (la plus grande taille atteinte) du bloc mémoire tracé à la taille courante, pour mesurer la taille d'apogée de parties de code spécifiques (contribution de Huon Wilson dans bpo-40630).

typing

PEP 593 ajoute le type typing.Annotated pour décorer les types existants avec des métadonnées spécifiques au contexte et le nouveau paramètre include_extras à typing.get_type_hints() pour récupérer les métadonnées à l'exécution (contribution de Till Varoquaux et Konstantin Kashin).

unicodedata

La base de donnée Unicode a été mise à jour à la version 13.0.0. (bpo-39926).

venv

Tous les scripts d'activations fournis par venv spécifient maintenant la personnalisation de l'invite de façon cohérente en utilisant toujours la valeur spécifiée dans __VENV_PROMPT__. Précédemment certains scripts utilisaient toujours __VENV_PROMPT__, d'autres seulement quand la variable était affectée, et un utilisait plutôt __VENV_NAME__ (contribution de Brett Cannon dans bpo-37663).

xml

Les caractères d'espacement à l'intérieur des attributs sont maintenant préservés lors de la sérialisation d'xml.etree.ElementTree en fichier XML. Les fin de lignes ne sont plus normalisées par "n". Ceci est le résultat d'une discussion sur comment interpréter la section 2.11 de la spécification XML (contribution de Mefistotelis dans bpo-39011).

Optimisations

  • L'affectation d'une variable temporaire dans les compréhensions est optimisée. Maintenant for y in [expr] dans les compréhensions est aussi rapide qu'une affectation simple y = expr. Par exemple :

    sums = [s for s in [0] for x in data for s in [s + x]]

    Contrairement à l'opérateur :=, cet idiome ne laisse pas déborder une variable dans la portée externe.

    (contribution de Serhiy Storchaka dans bpo-32856).

  • Optimisation de la gestion des signaux dans les applications avec plus d'un fil d'exécution (multithreaded applications). Si un fil d'exécution autre que le fil principal reçoit un signal, la boucle d'évaluation du code intermédiaire (bytecode) n'est plus interrompue à chaque instruction intermédiaire pour vérifier s'il y a des signaux en attente qui ne peuvent être gérés. Seul le fil principal de l'interpréteur principal peut gérer les signaux.

    Précédemment, la boucle d'évaluation du code intermédiaire était interrompue à chaque instruction jusqu'à ce que le fil principal gère les signaux (contribution de Victor Stinner dans bpo-40010).

  • Optimisation du module subprocess sur FreeBSD en utilisant closefrom() (contribution de Ed Maste, Conrad Meyer, Kyle Evans, Kubilay Kocak et Victor Stinner dans bpo-38061).

  • PyLong_FromDouble() is now up to 1.87x faster for values that fit into long. (Contributed by Sergey Fedoseev in bpo-37986.)

  • Certaines fonctions et classes natives (range, tuple, set, frozenset, list, dict) sont maintenant plus rapides grâce à l'utilisation du protocole de vectorisation de PEP 590 (contribution de Dong-hee Na, Mark Shannon, Jeroen Demeyer et Petr Viktorin dans bpo-37207).

  • Optimisation de difference_update() pour le cas où l'autre set est beaucoup plus grand que celui de base. (Suggestion par Evgeny Kapun et codage contribué par Michele Orrù dans bpo-8425.)

  • L'allocateur de petits objets de Python (obmalloc.c) alloue maintenant (au plus) un aréna vide qui reste disponible pour réutilisation immédiate, sans le renvoyer au système d'exploitation. Ceci prévient l'emballement (thrashing) dans les boucles simples où un aréna pourrait être créé puis détruit à nouveau à chaque itération (contribution de Tim Peters dans bpo-37257).

  • L'opération de division entière d'un float est plus performante. De plus, le message de ZeroDivisionError pour cette opération a été mis à jour (contribution de Dong-hee Na dans bpo-39434).

  • Le décodage de courtes chaînes ASCII avec les codecs UTF-8 et ascii est maintenant 15 % plus rapide (contribution de Inada Naoki dans bpo-37348).

Voici un résumé des améliorations de performance de Python 3.4 à Python 3.9 :

Python version                       3.4     3.5     3.6     3.7     3.8    3.9
--------------                       ---     ---     ---     ---     ---    ---

Variable and attribute read access:
    read_local                       7.1     7.1     5.4     5.1     3.9    3.9
    read_nonlocal                    7.1     8.1     5.8     5.4     4.4    4.5
    read_global                     15.5    19.0    14.3    13.6     7.6    7.8
    read_builtin                    21.1    21.6    18.5    19.0     7.5    7.8
    read_classvar_from_class        25.6    26.5    20.7    19.5    18.4   17.9
    read_classvar_from_instance     22.8    23.5    18.8    17.1    16.4   16.9
    read_instancevar                32.4    33.1    28.0    26.3    25.4   25.3
    read_instancevar_slots          27.8    31.3    20.8    20.8    20.2   20.5
    read_namedtuple                 73.8    57.5    45.0    46.8    18.4   18.7
    read_boundmethod                37.6    37.9    29.6    26.9    27.7   41.1

Variable and attribute write access:
    write_local                      8.7     9.3     5.5     5.3     4.3    4.3
    write_nonlocal                  10.5    11.1     5.6     5.5     4.7    4.8
    write_global                    19.7    21.2    18.0    18.0    15.8   16.7
    write_classvar                  92.9    96.0   104.6   102.1    39.2   39.8
    write_instancevar               44.6    45.8    40.0    38.9    35.5   37.4
    write_instancevar_slots         35.6    36.1    27.3    26.6    25.7   25.8

Data structure read access:
    read_list                       24.2    24.5    20.8    20.8    19.0   19.5
    read_deque                      24.7    25.5    20.2    20.6    19.8   20.2
    read_dict                       24.3    25.7    22.3    23.0    21.0   22.4
    read_strdict                    22.6    24.3    19.5    21.2    18.9   21.5

Data structure write access:
    write_list                      27.1    28.5    22.5    21.6    20.0   20.0
    write_deque                     28.7    30.1    22.7    21.8    23.5   21.7
    write_dict                      31.4    33.3    29.3    29.2    24.7   25.4
    write_strdict                   28.4    29.9    27.5    25.2    23.1   24.5

Stack (or queue) operations:
    list_append_pop                 93.4   112.7    75.4    74.2    50.8   50.6
    deque_append_pop                43.5    57.0    49.4    49.2    42.5   44.2
    deque_append_popleft            43.7    57.3    49.7    49.7    42.8   46.4

Timing loop:
    loop_overhead                    0.5     0.6     0.4     0.3     0.3    0.3

Ces résultats ont été obtenus avec le script de test de performance des accès aux variables : Tools/scripts/var_access_benchmark.py. Le script de test de performances affiche le chronométrage en nanosecondes. Les tests ont été effectués sur un processeur Intel® Core™ i7-4960HQ roulant la compilation macOS 64-bit disponible sur python.org.

Obsolescence

  • La commande de distutils bdist_msi est maintenant obsolète, utilisez plutôt bdist_wheel (paquet wheel) (contribution de Hugo van Kemenade dans bpo-39586).

  • Présentement, math.factorial() accepte des instances de float qui sont des entiers non-négatifs (comme 5.0). Elle lève une ValueError pour les floats non-entiers et négatifs. Ceci est maintenant obsolète. Les versions futures de Python vont lever une TypeError pour tous les floats (contribution de Serhiy Storchaka dans bpo-37315).

  • Les modules parser et symbol sont obsolètes et seront retirés des versions futures de Python. Pour la majorité des cas d'utilisation, les utilisateurs peuvent tirer profit des stades de génération et de compilation d'un arbre de syntaxe abstraite, en utilisant le module ast.

  • Les fonctions PyParser_SimpleParseStringFlags(), PyParser_SimpleParseStringFlagsFilename(), PyParser_SimpleParseFileFlags() et PyNode_Compile() de l'API C Publique sont obsolètes et seront retirées de Python 3.10 en même temps que l'ancien analyseur.

  • L'utilisation de NotImplemented dans un contexte booléen est devenu obsolète, puisque c'est presque toujours le résultat d'une implémentation incorrecte des opérateurs de comparaison avancés. Ceci va devenir une TypeError dans les versions futures de Python (contribution de Josh Rosenberg dans bpo-35712).

  • Le module random accepte présentement n'importe quel hachable comme valeur d'ensemencement. Malheureusement, certains de ces types ne garantissent pas une valeur de hachage déterministe. Après Python 3.9, le module va restreindre l'ensemencement à None, int, float, str, bytes et bytearray.

  • Ouvrir un fichier GzipFile en écriture sans spécifier l'argument mode est obsolète. Dans les futures versions de Python, il sera toujours ouvert en lecture par défaut. Spécifiez l'argument mode pour l'ouvrir en écriture et supprimer l'avertissement (contribution de Serhiy Storchaka dans bpo-28286).

  • La méthode split() de _tkinter.TkappType est obsolète. La méthode splitlist() est plus favorable, car elle a un comportement plus cohérent et prévisible (contribution de Serhiy Storchaka dans bpo-38371).

  • Le passage explicite d'objets coroutine à asyncio.wait() est devenu obsolète et sera retiré dans la version 3.11. (Contribution de Yury Selivanov et Kyle Stanley dans bpo-34790.)

  • Les standards binhex4 et hexbin4 sont maintenant obsolètes. Le module binhex et les fonctions suivantes du module binascii sont maintenant obsolètes :

    (contribution de Victor Stinner dans bpo-39353).

  • Les classes slice, Index et ExtSlice du module ast sont considérées obsolètes et seront retirées des versions futures de Python. value doit être utilisé à la place de Index(value). Tuple(slices, Load()) doit être utilisé plutôt que ExtSlice(slices) (contribution de Serhiy Storchaka dans bpo-34822).

  • Les classes Suite, Param, AugLoad et AugStore du module ast sont considérées obsolètes et seront retirées des versions futures de Python. Elles n'étaient pas produites par l'analyseur et n'étaient pas acceptées par le générateur de code dans Python 3 (contribution de Batuhan Taskaya dans bpo-39639 et bpo-39969 et Serhiy Storchaka dans bpo-39988).

  • Les fonctions PyEval_InitThreads() et PyEval_ThreadsInitialized() sont maintenant obsolètes et seront retirées de Python 3.11. Maintenant, l'appel de PyEval_InitThreads() ne fait rien du tout. Le GIL est initialisé par Py_Initialize() depuis Python 3.7 (contribution de Victor Stinner dans bpo-39877).

  • Passer None comme premier argument à la fonction shlex.split() a été rendu obsolète (contribution de Zackery Spytz dans bpo-33262).

  • smtpd.MailmanProxy() est maintenant obsolète puisqu'elle n'est pas utilisable sans le module externe mailman (contribution de Samuel Colvin dans bpo-35800).

  • Le module lib2to3 émet maintenant un PendingDeprecationWarning. Python 3.9 est passé à un analyseur PEG (voir PEP 617), et Python 3.10 peut inclure des changements à la syntaxe qui ne sont pas analysables par l'analyseur LL(1) de lib2to3. Le module lib2to3 peut être retiré de la bibliothèque standard dans une version future de Python. Considérez une alternative tierce telle que LibCST ou parso (contribution de Carl Meyer dans bpo-40360).

  • Le paramètre random de random.shuffle() est maintenant obsolète (contribution de Raymond Hettinger dans bpo-40465).

Retraits

  • La version erronée dans unittest.mock.__version__ a été retirée.

  • Les méthodes de nntplib.NNTP : xpath() et xgtitle() ont été retirées. Ces méthodes sont obsolètes depuis Python 3.3. En général, ces extensions ne sont pas prises en charge ou ne sont pas activées par les administrateurs de serveurs NNTP. Pour xgtitle() veuillez plutôt utiliser nntplib.NNTP.descriptions() ou nntplib.NNTP.description() (contribution de Dong-hee Na dans bpo-39366).

  • Les méthodes de array.array : tostring() et fromstring() ont été retirées. Elles étaient des alias de tobytes() et frombytes(), obsolètes depuis Python 3.2 (contribution de Victor Stinner dans bpo-38916).

  • La fonction non-documentée sys.callstats() a été retirée. Depuis Python 3.7, elle était obsolète et retournait toujours None. Elle dépendait de l'option de construction CALL_PROFILE qui avait déjà été retirée dans Python 3.7 (contribution de Victor Stinner dans bpo-37414).

  • Les fonctions sys.getcheckinterval() et sys.setcheckinterval() ont été retirées. Elle étaient obsolètes depuis Python 3.2. Utilisez plutôt sys.getswitchinterval() et sys.setswitchinterval() (contribution de Victor Stinner dans bpo-37392).

  • La fonction C PyImport_Cleanup() a été retirée. Elle était documentée comme "Vide la table des modules. Pour usage interne seulement." (contribution de Victor Stinner dans bpo-36710).

  • Les modules _dummy_thread et dummy_threading ont été retirés. Ces modules étaient obsolètes depuis Python 3.7 qui a besoin de la gestion de fils d'exécution multiples (contribution de Victor Stinner dans bpo-37312).

  • L'alias aifc.openfp() de aifc.open(), l'alias sunau.openfp() de sunau.open() et l'alias wave.openfp() de wave.open() ont été retirés. Ils étaient obsolètes depuis Python 3.7 (contribution de Victor Stinner dans bpo-37320).

  • La méthode isAlive() de la classe threading.Thread a été retirée. Elle était obsolète depuis Python 3.8. Utilisez plutôt is_alive() (contribution de Dong-hee Na dans bpo-37804).

  • Les méthodes getchildren() et getiterator() des classes ElementTree et Element dans le module ElementTree ont été retirées. Elle avaient été déclarées obsolètes dans Python 3.2. Utilisez iter(x) ou list(x) plutôt que x.getchildren() et x.iter() ou list(x.iter()) plutôt que x.getiterator() (contribution de Serhiy Storchaka dans bpo-36543).

  • L'ancienne API plistlib a été retirée, elle était obsolète depuis Python 3.4. Utilisez les fonctions load(), loads(), dump() et dumps(). De plus, le paramètre use_builtin_types a été retiré, les objets bytes natifs sont toujours utilisés.

  • La fonction C PyGen_NeedsFinalizing a été retirée. Elle n'était pas documentée, testée ou utilisée où que ce soit dans CPython après l'implémentation de PEP 442 (contribution de Joannah Nanjekye dans bpo-15088).

  • base64.encodestring() et base64.decodestring(), des alias obsolètes depuis Python 3.1, ont été retirées : utilisez plutôt base64.encodebytes() et base64.decodebytes() (contribution de Victor Stinner dans bpo-39351).

  • La fonction fractions.gcd() a été retirée, elle était obsolète depuis Python 3.5 (bpo-22486) : utilisez plutôt math.gcd() (contribution de Victor Stinner dans bpo-39350).

  • Le paramètre buffering de la classe bz2.BZ2File a été retiré. Depuis Python 3.0, il était ignoré et son utilisation levait un DeprecationWarning. Passez un objet fichier déjà ouvert pour déterminer comment le fichier sera ouvert (contribution de Victor Stinner dans bpo-39357).

  • Le paramètre encoding de json.loads() a été retiré. À partir de Python 3.1, il était obsolète et ignoré ; son utilisation levait un DeprecationWarning depuis Python 3.8 (contribution de Inada Naoki dans bpo-39377).

  • Les instructions with (await asyncio.lock): et with (yield from asyncio.lock): ne sont plus prises en charge, utilisez plutôt async with lock. De même pour asyncio.Condition et asyncio.Semaphore (contribution de Andrew Svetlov dans bpo-34793).

  • La fonction sys.getcounts(), l'option de ligne de commande -X showalloccount et le champ show_alloc_count de la structure C PyConfig ont été retirés. Ils dépendaient d'une compilation spéciale de Python en définissant la macro COUNT_ALLOCS (contribution de Victor Stinner dans bpo-39489).

  • L'attribut _field_types de la classe typing.NamedTuple a été retiré. Il était obsolète depuis Python 3.8. Utilisez plutôt l'attribut __annotations__ (contribution de Serhiy Storchaka dans bpo-40182).

  • La méthode symtable.SymbolTable.has_exec() a été retirée. Elle était obsolète depuis 2006 et ne renvoyait que False lorsqu'elle était appelée (contribution de Batuhan Taskaya dans bpo-40208).

  • Les méthodes asyncio.Task.current_task() et asyncio.Task.all_tasks() ont été retirées. Elles étaient obsolètes depuis Python 3.7. Utilisez plutôt asyncio.current_task() et asyncio.all_tasks() (contribution de Rémi Lapeyre dans bpo-40967).

  • La méthode unescape() de la classe html.parser.HTMLParser a été retirée (elle était obsolète depuis Python 3.4). html.unescape() doit être utilisée pour convertir les références de caractère en leurs caractères Unicode correspondants.

Portage vers Python 3.9

Cette section liste les changements mentionnés préalablement et d'autres améliorations qui peuvent demander des changements à votre code.

Changements dans l'API Python

  • __import__() et importlib.util.resolve_name() lèvent maintenant ImportError où elles levaient précédemment ValueError. Les appelants qui attrapent les types spécifiques d'exceptions et qui prennent à la fois en charge Python 3.9 et des versions précédentes doivent attraper les deux types avec except (ImportError, ValueError):.

  • Il n'y a plus de traitement spécial dans les scriptes d'activation de venv quand __VENV_PROMPT__ est mis à "".

  • La méthode select.epoll.unregister() n'ignore plus l'erreur EBADF (contribution de Victor Stinner dans bpo-39239).

  • Le paramètre compresslevel de bz2.BZ2File est devenu exclusivement nommé (keyword-only) puisque le paramètre buffering a été retiré (contribution de Victor Stinner in bpo-39357).

  • Simplification de l'AST pour les souscriptions. Les indexations simples seront représentées par leur valeur, les tranches étendues seront représentées par des n-uplets. Index(value) va renvoyer value elle-même, ExtSlice(slices) va renvoyer Tuple(slices, Load()) (contribution de Serhiy Storchaka dans bpo-34822).

  • Le module importlib ignore maintenant la variable d’environnement PYTHONCASEOK quand les options de ligne de commande -E ou -I sont utilisées.

  • Le paramètre encoding a été ajouté aux classes ftplib.FTP et ftplib.FTP_TLS en paramètre exclusivement nommé et l'encodage par défaut est passé de Latin-1 à UTF-8 en conformité à RFC 2640.

  • asyncio.loop.shutdown_default_executor() a été ajouté à AbstractEventLoop, donc les boucles d'événements alternatives qui héritent de celle-ci devraient définir cette méthode (contribution de Kyle Stanley dans bpo-34037).

  • Les valeurs constantes des drapeaux futurs du module __future__ sont mises à jour pour éviter les collisions avec les drapeaux du compilateur. Précédemment, PyCF_ALLOW_TOP_LEVEL_AWAIT était en collision avec CO_FUTURE_DIVISION (contribution de Batuhan Taskaya dans bpo-39562).

  • array('u') utilise maintenant le type C wchar_t plutôt que Py_UNICODE. Ceci ne change pas son comportement puisque Py_UNICODE est un alias de wchar_t depuis Python 3.3 (contribution de Inada Naoki dans bpo-34538).

  • L'API logging.getLogger() renvoie maintenant le journaliseur racine quand on lui passe le nom 'root', alors que préalablement il renvoyait un journaliseur non-racine appelé 'root'. Ceci peut affecter les cas où le code de l'utilisateur veut explicitement un journaliseur non-racine appelé 'root', ou instancie un journaliseur avec logging.getLogger(__name__) dans un module de niveau principal appelé 'root.py' (contribution de Vinay Sajip dans bpo-37742).

  • La gestion de la division de PurePath renvoie maintenant NotImplemented plutôt que de lever une TypeError lorsqu'on passe une valeur autre qu'une instance de str ou PurePath. Ceci permet la création de classes compatibles qui n'héritent pas de ces types (contribution de Roger Aiudi dans bpo-34775.)

  • Starting with Python 3.9.5 the ipaddress module no longer accepts any leading zeros in IPv4 address strings. Leading zeros are ambiguous and interpreted as octal notation by some libraries. For example the legacy function socket.inet_aton() treats leading zeros as octal notatation. glibc implementation of modern inet_pton() does not accept any leading zeros. (Contributed by Christian Heimes in bpo-36384).

  • codecs.lookup() now normalizes the encoding name the same way as encodings.normalize_encoding(), except that codecs.lookup() also converts the name to lower case. For example, "latex+latin1" encoding name is now normalized to "latex_latin1". (Contributed by Jordon Xu in bpo-37751.)

Changements dans l'API C

  • Les instances de types alloués sur le tas (tels que ceux créés avec PyType_FromSpec() et les APIs similaires) gardent une référence à leur objet type depuis Python 3.8. Tel qu'indiqué dans "Changements à l'API C" de Python 3.8, pour la grande majorité des cas, il ne devrait pas y avoir d'effets secondaires sauf pour les types qui ont une fonction tp_traverse personnalisée. Assurez-vous que toutes les fonctions tp_traverse personnalisées des types alloués sur le tas visitent le type de l'objet.

    Exemple :

    int
    foo_traverse(foo_struct *self, visitproc visit, void *arg) {
    // Rest of the traverse function
    #if PY_VERSION_HEX >= 0x03090000
        // This was not needed before Python 3.9 (Python issue 35810 and 40217)
        Py_VISIT(Py_TYPE(self));
    #endif
    }
    

    Si votre fonction de traversée délègue à la tp_traverse de sa classe de base (ou d'un autre type), assurez-vous que Py_TYPE(self) ne soit visité qu'une seule fois. Prenez note que seuls les types du tas doivent visiter leur type dans tp_traverse.

    Par exemple, si votre fonction tp_traverse inclut :

    base->tp_traverse(self, visit, arg)
    

    alors ajoutez :

    #if PY_VERSION_HEX >= 0x03090000
        // This was not needed before Python 3.9 (bpo-35810 and bpo-40217)
        if (base->tp_flags & Py_TPFLAGS_HEAPTYPE) {
            // a heap type's tp_traverse already visited Py_TYPE(self)
        } else {
            Py_VISIT(Py_TYPE(self));
        }
    #else
    

    (Voir bpo-35810 et bpo-40217 pour plus d'information.)

  • Les fonctions PyEval_CallObject, PyEval_CallFunction, PyEval_CallMethod et PyEval_CallObjectWithKeywords sont obsolètes. Utilisez plutôt PyObject_Call() et ses variantes. (Pour plus de détails, voir bpo-29548.)

Changements au code intermédiaire CPython

  • Le code d'opération LOAD_ASSERTION_ERROR a été ajouté pour gérer l'instruction assert. Précédemment, l'instruction assert ne fonctionnait pas correctement si l'exception AssertionError était masquée (contribution de Zackery Spytz dans bpo-34880).

  • Le code d'opération COMPARE_OP a été séparé en quatre instructions distinctes :

    • COMPARE_OP pour les comparaisons avancées ;

    • IS_OP pour les tests is et is not ;

    • CONTAINS_OP pour les tests in et not in ;

    • JUMP_IF_NOT_EXC_MATCH pour vérifier les exceptions dans les instructions try-except.

    (contribution de Mark Shannon dans bpo-39156).

Changements à la compilation

  • Ajout de l'option --with-platlibdir au script configure : nom de répertoire des bibliothèques spécifique à la plateforme, stocké dans le nouvel attribut sys.platlibdir. Voir l'attribut sys.platlibdir pour plus d'informations (contribution de Jan Matějek, Matěj Cepl, Charalampos Stratakis et Victor Stinner dans bpo-1294959).

  • La macro spéciale de compilation COUNT_ALLOCS a été retirée (contribution de Victor Stinner dans bpo-39489).

  • Sur les plateformes non-Windows, les fonctions setenv() et unsetenv() sont maintenant nécessaires à la compilation de Python (contribution de Victor Stinner dans bpo-39395).

  • Sur les plateformes non-Windows, la création d'installateurs bdist_wininst n'est maintenant officiellement plus pris en charge. (Voir bpo-10945 pour plus de détails.)

  • When building Python on macOS from source, _tkinter now links with non-system Tcl and Tk frameworks if they are installed in /Library/Frameworks, as had been the case on older releases of macOS. If a macOS SDK is explicitly configured, by using --enable-universalsdk or -isysroot, only the SDK itself is searched. The default behavior can still be overridden with --with-tcltk-includes and --with-tcltk-libs. (Contributed by Ned Deily in bpo-34956.)

  • Python peut maintenant être compilé pour Windows 10 ARM64 (contribution de Steve Dower dans bpo-33125).

  • Certains tests individuels sont maintenant ignorés lorsque --pgo est utilisé. Les tests en question augmentaient la durée de la tâche PGO de manière significative et n'optimisaient probablement pas l'exécutable final. Cela accélère la tâche par un facteur d'environ 15 fois. Le fait de lancer la suite de tests est lent. Ce changement va peut être avoir pour conséquence des exécutables compilés un peu moins optimisés car moins de branches de code seront exécutées. Si vous souhaitez attendre avec une compilation plus lente, l'ancienne manière de fonctionner peut être obtenue avec ./configure [..] PROFILE_TASK="-m test --pgo-extended". Nous ne garantissons pas quel set de tâches PGO produira une compilation plus rapide. Les utilisateurs qui s'y intéressent devraient exécuter leurs propres benchmarks, car les résultats peuvent dépendre de l'environnement, de la charge de travail et de la chaîne d'outils du compilateur. (Voir bpo-36044 et bpo-37707 pour plus de détails.)

Changements à l'API C

Nouvelles fonctionnalités

  • PEP 573 : Ajout de PyType_FromModuleAndSpec() pour associer un module à une classe ; PyType_GetModule() et PyType_GetModuleState() pour récupérer le module et son état ; et PyCMethod et METH_METHOD pour permettre à une méthode de récupérer la classe dans laquelle elle a été définie (contribution de Marcel Plch et Petr Viktorin dans bpo-38787).

  • Ajout de la fonction PyFrame_GetCode() : récupérer le code d'un cadre. Ajout de la fonction PyFrame_GetBack() : récupérer le prochain cadre englobant (contribution de Victor Stinner dans bpo-40421).

  • Ajout de PyFrame_GetLineNumber() à l'API C limité (contribution de Victor Stinner dans bpo-40421).

  • Ajout des fonctions PyThreadState_GetInterpreter() et PyInterpreterState_Get() pour récupérer l'interpréteur. Ajout de la fonction PyThreadState_GetFrame() pour récupérer le cadre de l'état d'un fil d'exécution Python. Ajout de la fonction PyThreadState_GetID() : récupérer l'identifiant unique de l'état d'un fil d'exécution Python (contribution de Victor Stinner dans bpo-39947).

  • Ajout de la nouvelle fonction publique PyObject_CallNoArgs() à l'API C, qui appelle un objet Python appelable sans aucun argument. C'est la façon la plus efficace d'appeler un objet Python appelable sans aucun argument (contribution de Victor Stinner dans bpo-37194).

  • Changements dans l'API C limité (si la macro Py_LIMITED_API est définie) :

    • Fournit Py_EnterRecursiveCall() et Py_LeaveRecursiveCall() comme fonctions régulières pour l'API limité. Précédemment, elles étaient définies en tant que macros, mais ces macros n'étaient pas compilées avec l'API C limité qui ne peut pas accéder au champ PyThreadState.recursion_depth (la structure est opaque à l'API C limité) ;

    • PyObject_INIT() et PyObject_INIT_VAR() deviennent des fonctions "opaques" régulières pour cacher les détails d'implémentation

    (contribution de Victor Stinner dans bpo-38644 et bpo-39542).

  • La fonction PyModule_AddType() est ajoutée pour faciliter l'ajout d'un type à un module (contribution de Dong-hee Na dans bpo-40024).

  • Ajout des fonctions PyObject_GC_IsTracked() et PyObject_GC_IsFinalized() à l'API publique qui déterminent respectivement si les objets Python sont présentement suivis ou ont été finalisés par le ramasse-miettes (contribution de Pablo Galindo Salgado dans bpo-40241).

  • Ajout de _PyObject_FunctionStr() pour récupérer une chaîne conviviale représentant un objet fonction-compatible. (Rustine par Jeroen Demeyer dans bpo-37645.)

  • Ajout de PyObject_CallOneArg() pour appeler un objet avec un argument positionnel. (Rustine par Jeroen Demeyer dans bpo-37483.)

Portage vers Python 3.9

  • PyInterpreterState.eval_frame (PEP 523) nécessite maintenant un nouveau paramètre obligatoire tstate (PyThreadState*) (contribution de Victor Stinner dans bpo-38500).

  • Modules d'extension : les fonctions m_traverse, m_clear et m_free de PyModuleDef ne sont plus appelées si l'état du module est demandé mais qu'il n'a pas encore été alloué. C'est le cas immédiatement après que le module a été créé et avant que le module soit exécuté (fonction Py_mod_exec). Plus précisément, ces fonctions ne sont pas appelées si m_size est plus grand que 0 et que l'état du module (tel que renvoyé par PyModule_GetState()) est NULL.

    Les modules d'extensions sans état de module (m_size <= 0) ne sont pas affectés.

  • Si Py_AddPendingCall() est appelée dans un sous-interpréteur, la fonction est planifiée pour appel dans le sous-interpréteur, plutôt que dans l'interpréteur principal. Chaque sous interpréteur a maintenant sa propre liste d'appels planifiés (contribution de Victor Stinner dans bpo-39984).

  • Le registre de Windows n'est plus utilisé pour initialiser sys.path quand l'option -E est utilisée (si PyConfig.use_environment est affecté à 0). Ceci est pertinent quand Python est embarqué sur Windows (contribution de Zackery Spytz dans bpo-8901).

  • La variable globale PyStructSequence_UnnamedField est maintenant une constante et fait référence à une chaîne constante (contribution de Serhiy Storchaka dans bpo-38650).

  • La structure PyGC_Head est maintenant opaque. Elle est définie uniquement dans l'API C interne (pycore_gc.h) (contribution de Victor Stinner dans bpo-40241).

  • Py_UNICODE_COPY, Py_UNICODE_FILL, PyUnicode_WSTR_LENGTH, PyUnicode_FromUnicode(), PyUnicode_AsUnicode(), _PyUnicode_AsUnicode, et PyUnicode_AsUnicodeAndSize() sont étiquetées comme obsolètes en C. Elles avaient été déclarées obsolètes par PEP 393 depuis Python 3.3 (contribution de Inada Naoki dans bpo-36346).

  • La fonction Py_FatalError() est remplacée par une macro qui ajoute automatiquement une entrée au journal avec le nom de la fonction courante, sauf si la macro Py_LIMITED_API est définie (contribution de Victor Stinner dans bpo-39882).

  • Le protocole vectorcall requiert maintenant que l'appelant ne passe que des chaînes pour les noms des arguments nommés. (Voir bpo-37540 pour plus d'informations.)

  • Les détails d'implémentation de certaines macros et fonctions sont maintenant cachés :

    (Voir bpo-40170 pour plus de détails.)

Retraits

  • Exclusion des macros PyFPE_START_PROTECT() et PyFPE_END_PROTECT() de l'API C limité (contribution de Victor Stinner dans bpo-38835).

  • Le champ tp_print de PyTypeObject a été retiré. Il était utilisé pour écrire des objets dans des fichiers dans Python 2.7 et dans les versions précédentes. Depuis Python 3.0, il était ignoré et inutilisé (contribution de Jeroen Demeyer dans bpo-36974).

  • Changements dans l'API C limité (si la macro Py_LIMITED_API est définie) :

    • Exclusion des fonctions suivantes de l'API C limité :

      • PyThreadState_DeleteCurrent() (contribution de Joannah Nanjekye dans bpo-37878) ;

      • _Py_CheckRecursionLimit ;

      • _Py_NewReference() ;

      • _Py_ForgetReference() ;

      • _PyTraceMalloc_NewReference() ;

      • _Py_GetRefTotal() ;

      • Le mécanisme trashcan qui n'a jamais fonctionné dans l'API C limité ;

      • PyTrash_UNWIND_LEVEL ;

      • Py_TRASHCAN_BEGIN_CONDITION ;

      • Py_TRASHCAN_BEGIN ;

      • Py_TRASHCAN_END ;

      • Py_TRASHCAN_SAFE_BEGIN ;

      • Py_TRASHCAN_SAFE_END.

    • Migration des fonctions et définitions suivantes vers l'API C interne :

      • _PyDebug_PrintTotalRefs() ;

      • _Py_PrintReferences() ;

      • _Py_PrintReferenceAddresses() ;

      • _Py_tracemalloc_config ;

      • _Py_AddToAllObjects() (spécifique aux compilations Py_TRACE_REFS).

    (contribution de Victor Stinner dans bpo-38644 et bpo-39542).

  • Retrait de la fonction de rappel _PyRuntime.getframe et de la macro _PyThreadState_GetFrame qui était un alias pour _PyRuntime.getframe. Elles étaient exposées uniquement dans l'API C interne. Retrait aussi du type PyThreadFrameGetter (contribution de Victor Stinner dans bpo-39946).

  • Retrait des fonctions suivantes de l'API C. Appelez PyGC_Collect() explicitement pour vider toutes les free lists (contribution de Inada Naoki et Victor Stinner dans bpo-37340, bpo-38896 et bpo-40428) :

    • PyAsyncGen_ClearFreeLists() ;

    • PyContext_ClearFreeList() ;

    • PyDict_ClearFreeList() ;

    • PyFloat_ClearFreeList() ;

    • PyFrame_ClearFreeList() ;

    • PyList_ClearFreeList() ;

    • PyMethod_ClearFreeList() et PyCFunction_ClearFreeList() : les free lists des objets méthode liées ont été retirées ;

    • PySet_ClearFreeList() : la free list des objets sets a été retirée dans Python 3.4 ;

    • PyTuple_ClearFreeList() ;

    • PyUnicode_ClearFreeList() : la free list des objets Unicode a été retirée dans Python 3.3.

  • Retrait de la fonction _PyUnicode_ClearStaticStrings() (contribution de Victor Stinner dans bpo-39465).

  • Retrait de Py_UNICODE_MATCH. Elle était devenue obsolète par PEP 393, non-fonctionnelle depuis Python 3.3. La fonction PyUnicode_Tailmatch() peut être utilisée à sa place (contribution de Inada Naoki dans bpo-36346).

  • Nettoyage dans les fichiers d'en-têtes d'interfaces déclarées pour lesquelles il n'y avait pas d'implémentation. Les symboles retirés de l'API publique sont : _PyBytes_InsertThousandsGroupingLocale, _PyBytes_InsertThousandsGrouping, _Py_InitializeFromArgs, _Py_InitializeFromWideArgs, _PyFloat_Repr, _PyFloat_Digits, _PyFloat_DigitsInit, PyFrame_ExtendStack, _PyAIterWrapper_Type, PyNullImporter_Type, PyCmpWrapper_Type, PySortWrapper_Type, PyNoArgsFunction (contribution de Pablo Galindo Salgado dans bpo-39372).

Changements importants dans Python 3.9.1

typing

Le comportement de typing.Literal a été changé pour être conforme avec PEP 586 et pour avoir le comportement des vérificateurs de types statique spécifiés dans le PEP :

  1. Literal de-duplique maintenant les paramètres ;

  2. Les comparaisons d'égalité entre les objets Literal sont maintenant indépendantes de l'ordre ;

  3. Les comparaisons des Literal respectent maintenant les types. Par exemple, Literal[0] == Literal[False] évaluait précédemment à True. C'est maintenant False. Pour gérer ce changement, le cache interne des types utilisés peut maintenant différentier les types ;

  4. Les objets Literal lèvent maintenant une exception TypeError lors des comparaisons d'égalités si n'importe quel de leurs paramètres n'est pas immuable. Prenez-note que déclarer un Literal avec un paramètre muable ne lève pas une erreur :

    >>> from typing import Literal
    >>> Literal[{0}]
    >>> Literal[{0}] == Literal[{False}]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unhashable type: 'set'
    

(Contribution de Yurii Karabas dans bpo-42345.)

Prise en charge de macOS 11.0 (Big Sur) et de Mac sur processeur Apple

Depuis la version 3.9.1, Python est maintenant totalement compatible (compilation et lancement) sur macOS 11.0 (Big Sur) et sur les Macs Apple Silicon (basés sur l'architecture ARM64). Un nouveau variant de build, universal2, est maintenant disponible et supporte nativement les plateformes ARM64 et Intel 64 en un seul jeu d'exécutables. Les binaires peuvent aussi être compilés sur les versions actuelles de macOS pour ensuite être déployés sur des versions antérieures (testé jusqu'à 10.9), tout en rendant de nouvelles fonctionnalités du système d'exploitation disponibles en fonction de la version du système utilisée à l'exécution ("weaklinking").

(contribution de Ronald Oussoren et Lawrence D'Anna dans bpo-41100).

Changements importants dans Python 3.9.2

collections.abc

collections.abc.Callable generic now flattens type parameters, similar to what typing.Callable currently does. This means that collections.abc.Callable[[int, str], str] will have __args__ of (int, str, str); previously this was ([int, str], str). To allow this change, types.GenericAlias can now be subclassed, and a subclass will be returned when subscripting the collections.abc.Callable type. Code which accesses the arguments via typing.get_args() or __args__ need to account for this change. A DeprecationWarning may be emitted for invalid forms of parameterizing collections.abc.Callable which may have passed silently in Python 3.9.1. This DeprecationWarning will become a TypeError in Python 3.10. (Contributed by Ken Jin in bpo-42195.)

urllib.parse

Les versions précédentes de Python acceptaient à la fois ; et & comme séparateurs des paramètres de requête dans urllib.parse.parse_qs() et urllib.parse.parse_qsl(). Pour des raisons de sécurité, et pour être conforme aux nouvelles recommandations du W3C, ceci a été changé pour ne permettre qu'une seule clé de séparation, avec & par défaut. Ce changement affecte aussi cgi.parse() et cgi.parse_multipart() puisqu'elles utilisent les fonctions affectées à l'interne. Pour plus de détails, voir leur documentation respective (contribution de Adam Goldschmidt, Senthil Kumaran et Ken Jin dans bpo-42967).