# Les nouveautés de Python 3.10

Rédacteur:

  Pablo Galindo Salgado

This article explains the new features in Python 3.10, compared to 3.9. Python 3.10 was released on October 4, 2021. For full details, see the changelog.

## Résumé – Points forts de la publication

Nouvelles fonctionnalités de syntaxe :

- PEP 634, Filtrage par motifs structurels : spécification ;

- PEP 635, Filtrage par motifs structurels : motivation et justification ;

- PEP 636, Filtrage par motifs structurels : tutoriel ;

- bpo-12782, Les gestionnaires de contextes entre parenthèses sont maintenant autorisés.

Nouvelles fonctionnalités dans la bibliothèque standard :

- PEP 618, ajout de la vérification optionnelle de taille dans `zip`.

Améliorations de l'interpréteur :

- PEP 626, numéros de lignes précis pour le débogage et les autres outils.

Nouvelles fonctionnalités de typage :

- PEP 604, autorise l'écriture d'union de types sous la forme X | Y ;

- PEP 612, variables de spécification de paramètres.

- PEP 613, alias de types explicites ;

- PEP 647, User-Defined Type Guards

Obsolescences, retraits ou restrictions :

- PEP 644, mise à jour de la version minimale d'OpenSSL à 1.1.1 ;

- PEP 632, obsolescence du module `distutils` ;

- PEP 623, obsolescence et préparation du retrait du membre `wstr` de `PyUnicodeObject` ;

- PEP 624, retrait des API d'encodage `Py_UNICODE` ;

- PEP 597, ajout de l'`EncodingWarning` optionnel

## Nouvelles fonctionnalités

### Gestionnaires de contextes entre parenthèses

Il est maintenant possible de mettre les gestionnaires de contexte entre parenthèses pour les répartir sur plusieurs lignes. Ceci permet le formatage d'une longue série de gestionnaires de contexte sur plusieurs lignes comme ce qui était préalablement possible avec les instructions d'importation. Par exemple, tous ces blocs sont maintenant valides :

    with (CtxManager() as example):
        ...

    with (
        CtxManager1(),
        CtxManager2()
    ):
        ...

    with (CtxManager1() as example,
          CtxManager2()):
        ...

    with (CtxManager1(),
          CtxManager2() as example):
        ...

    with (
        CtxManager1() as example1,
        CtxManager2() as example2
    ):
        ...

il est aussi possible d'utiliser une virgule en fin de ligne à la fin du groupe entre parenthèses :

    with (
        CtxManager1() as example1,
        CtxManager2() as example2,
        CtxManager3() as example3,
    ):
        ...

Cette nouvelle syntaxe utilise la capacité non-LL(1) du nouvel analyseur syntaxique. Voir PEP 617 pour plus de détails.

(contribution de Guido van Rossum, Pablo Galindo et Lysandros Nikolaou dans bpo-12782 et bpo-40334).

### Meilleurs messages d'erreurs

#### `SyntaxError`

Pendant l'analyse syntaxique de code qui contient des parenthèses ou autres balises ouvrantes et fermantes, l'interpréteur inclut maintenant l'emplacement de la balise ou parenthèse non fermée plutôt que d'afficher SyntaxError: unexpected EOF while parsing ou d'indiquer un emplacement incorrect. Par exemple, considérez le code suivant (remarquez l'accolade `'{'` non-fermée) :

    expected = {9: 1, 18: 2, 19: 2, 27: 3, 28: 3, 29: 3, 36: 4, 37: 4,
                38: 4, 39: 4, 45: 5, 46: 5, 47: 5, 48: 5, 49: 5, 54: 6,
    some_other_code = foo()

Les versions précédentes de l’interpréteur indiquaient des emplacements qui portaient à confusion pour l'erreur de syntaxe :

    File "example.py", line 3
        some_other_code = foo()
                        ^
    SyntaxError: invalid syntax

mais dans Python 3.10, une erreur plus informative est levée :

    File "example.py", line 1
        expected = {9: 1, 18: 2, 19: 2, 27: 3, 28: 3, 29: 3, 36: 4, 37: 4,
                   ^
    SyntaxError: '{' was never closed

De façon similaire, les erreurs impliquant des chaînes littérales non-fermées (avec simples ou triples apostrophes) pointent maintenant vers le début de la chaîne plutôt de mentionner la fin de ligne ou la fin du fichier.

Ces améliorations sont inspirées par un travail préalable sur l'interpréteur PyPy

(contribution de Pablo Galindo dans bpo-42864 et Batuhan Taskaya dans bpo-40176).

Les exceptions `SyntaxError` levées par l'interpréteur soulignent maintenant toute la portée de l'expression qui constitue l'erreur de syntaxe plutôt que seulement la position où le problème a été détecté. De cette façon, plutôt que d'afficher (avant Python 3.10) :

    >>> foo(x, z for z in range(10), t, w)
      File "<stdin>", line 1
        foo(x, z for z in range(10), t, w)
               ^
    SyntaxError: Generator expression must be parenthesized

Python 3.10 affiche maintenant l'exception comme ceci :

    >>> foo(x, z for z in range(10), t, w)
      File "<stdin>", line 1
        foo(x, z for z in range(10), t, w)
               ^^^^^^^^^^^^^^^^^^^^
    SyntaxError: Generator expression must be parenthesized

Cette amélioration est une contribution de Pablo Galindo dans bpo-43914.

Un nombre considérable de nouveaux messages spécialisés pour les exceptions `SyntaxError` a été incorporé. Certains des plus notables sont :

- `:` manquant avant les blocs :

      >>> if rocket.position > event_horizon
        File "<stdin>", line 1
          if rocket.position > event_horizon
                                            ^
      SyntaxError: expected ':'

  (Contributed by Pablo Galindo in bpo-42997.)

- Les n-uplets sans parenthèses dans les cibles de compréhensions :

      >>> {x,y for x,y in zip('abcd', '1234')}
        File "<stdin>", line 1
          {x,y for x,y in zip('abcd', '1234')}
           ^
      SyntaxError: did you forget parentheses around the comprehension target?

  (Contributed by Pablo Galindo in bpo-43017.)

- virgules manquantes dans les littéraux de collections et entre les expressions ; :

      >>> items = {
      ... x: 1,
      ... y: 2
      ... z: 3,
        File "<stdin>", line 3
          y: 2
             ^
      SyntaxError: invalid syntax. Perhaps you forgot a comma?

  (Contributed by Pablo Galindo in bpo-43822.)

- types multiples d'`Exception` sans parenthèses :

      >>> try:
      ...     build_dyson_sphere()
      ... except NotEnoughScienceError, NotEnoughResourcesError:
        File "<stdin>", line 3
          except NotEnoughScienceError, NotEnoughResourcesError:
                 ^
      SyntaxError: multiple exception types must be parenthesized

  (Contributed by Pablo Galindo in bpo-43149.)

- `:` et valeurs manquantes dans les littéraux de dictionnaires :

      >>> values = {
      ... x: 1,
      ... y: 2,
      ... z:
      ... }
        File "<stdin>", line 4
          z:
           ^
      SyntaxError: expression expected after dictionary key and ':'

      >>> values = {x:1, y:2, z w:3}
        File "<stdin>", line 1
          values = {x:1, y:2, z w:3}
                              ^
      SyntaxError: ':' expected after dictionary key

  (Contributed by Pablo Galindo in bpo-43823.)

- blocs `try` sans blocs `except` ou `finally` :

      >>> try:
      ...     x = 2
      ... something = 3
        File "<stdin>", line 3
          something  = 3
          ^^^^^^^^^
      SyntaxError: expected 'except' or 'finally' block

  (Contributed by Pablo Galindo in bpo-44305.)

- utilisation de `=` au lieu de `==` dans les comparaisons :

      >>> if rocket.position = event_horizon:
        File "<stdin>", line 1
          if rocket.position = event_horizon:
                             ^
      SyntaxError: cannot assign to attribute here. Maybe you meant '==' instead of '='?

  (Contributed by Pablo Galindo in bpo-43797.)

- utilisation de `*` dans les chaînes formatées (f-strings) :

      >>> f"Black holes {*all_black_holes} and revelations"
        File "<stdin>", line 1
          (*all_black_holes)
           ^
      SyntaxError: f-string: cannot use starred expression here

  (Contributed by Pablo Galindo in bpo-41064.)

#### `IndentationError`

Plusieurs exceptions `IndentationError` ont maintenant plus de contexte concernant le genre de bloc qui attendait une indentation. Ceci inclut l'emplacement de l'instruction :

    >>> def foo():
    ...    if lel:
    ...    x = 2
      File "<stdin>", line 3
        x = 2
        ^
    IndentationError: expected an indented block after 'if' statement in line 2

#### `AttributeError`

À l'impression d'une `AttributeError`, `PyErr_Display()` offre des suggestions de noms d'attributs similaires dans l'objet pour lequel l'exception a été levée :

    >>> collections.namedtoplo
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: module 'collections' has no attribute 'namedtoplo'. Did you mean: namedtuple?

(contribution de Pablo Galindo dans bpo-38530).

Avertissement

notez que ceci ne fonctionne pas si `PyErr_Display()` n'est pas appelée pour afficher l'erreur, ce qui est le cas si une fonction d'affichage d'erreur personnalisée est utilisée. C'est un scénario typique avec certains interpréteurs interactifs comme IPython.

#### `NameError`

Quand elle affiche une `NameError` levée par l'interpréteur, `PyErr_Display()` offre des suggestions de variables qui ont un nom similaire dans la fonction de laquelle l’exception a été levée :

    >>> schwarzschild_black_hole = None
    >>> schwarschild_black_hole
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'schwarschild_black_hole' is not defined. Did you mean: schwarzschild_black_hole?

(contribution de Pablo Galindo dans bpo-38530).

Avertissement

notez que ceci ne fonctionne pas si `PyErr_Display()` n'est pas appelée pour afficher l'erreur, ce qui est le cas si une fonction d'affichage d'erreur personnalisée est utilisée. C'est un scénario typique avec certains interpréteurs interactifs comme IPython.

### PEP 626 : numéros de lignes précis pour le débogage et les autres outils

La PEP 626 apporte des numéros de lignes plus précis pour le débogage, le profilage et les outils de mesure de couverture. Les événements de traçage, avec les numéros de ligne corrects, sont générés pour toutes les lignes de code exécutées et seulement pour celles-ci.

The `f_lineno` attribute of frame objects will always contain the expected line number.

The `co_lnotab` attribute of code objects is deprecated and will be removed in 3.12. Code that needs to convert from offset to line number should use the new `co_lines()` method instead.

### PEP 634 : filtrage par motifs structurels

Le filtrage par motifs a été ajouté sous la forme d'une instruction match et d'instructions case pour les motifs avec des actions associées. Les motifs filtrent des séquences, des dictionnaires, des types de données et des instances de classes. Le filtrage par motifs permet aux programmes d'extraire de l'information de types de données complexes, faire du branchement selon la structure des données et réaliser des actions spécifiques en fonction des différentes formes des données.

#### Syntaxe et opérations

La syntaxe générique du filtrage par motifs est :

    match subject:
        case <pattern_1>:
            <action_1>
        case <pattern_2>:
            <action_2>
        case <pattern_3>:
            <action_3>
        case _:
            <action_wildcard>

Une instruction match prend une expression et compare successivement sa valeur à différents filtres qui sont donnés comme un ou plusieurs blocs case. Plus précisément, le filtrage par motifs s'effectue par :

1. l'utilisation de données qui ont un type et une forme (ici `subject`) ;

2. l'évaluation de `subject` dans une instruction `match` ;

3. l'application de chaque filtre sur `subject` dans des instructions `case` de haut en bas jusqu'à ce qu'un appariement soit confirmé ;

4. l’exécution de l'action associée au filtre s'il y a appariement ;

5. s'il n'y a aucun appariement et que le dernier `case` est un filtre attrape-tout `_`, l'action correspondante est exécutée. S'il n'y a aucun appariement ni filtre attrape-tout, le bloc `match` n'effectue aucune opération.

#### Approche déclarative

Le filtrage par motifs est peut-être connu des lecteurs par l'intermédiaire des langages C, Java ou JavaScript (et plusieurs autres langages), avec l'appariement simple d'un sujet (objet de données) à un littéral (filtre) avec l'instruction `switch`. Souvent, l'instruction `switch` est utilisée pour comparer des objets ou expressions à des instructions `case` qui contiennent des littéraux.

Des exemples plus puissants de filtrage par motifs sont présents dans des langages tels que Scala et Elixir. Avec le filtrage par motifs structurels, l'approche est « déclarative » et énonce les conditions (les motifs) pour apparier les données.

Bien qu'une série d'instructions « impératives » utilisant des instructions « if » imbriquées puisse être utilisée pour accomplir quelque chose de similaire au filtrage par motifs structurels, ceci est moins clair que l'approche « déclarative ». Cette dernière énonce les conditions à remplir pour réaliser un appariement grâce à ses filtres sur des motifs explicites. Bien que le filtrage par motifs structurels puisse être utilisé dans sa forme la plus simple pour comparer une variable à un littéral dans une instruction `case`, son intérêt réel en Python réside dans son traitement du sujet selon son type et sa forme.

#### Filtre simple : apparier à un littéral

Regardons cet exemple en tant que filtrage par motif dans sa forme la plus simple : une valeur, le sujet, est comparée à (ou « filtrée par ») plusieurs littéraux, les motifs. Dans l'exemple ci-dessous, `status` est le sujet de l'instruction `match`. Les filtres sont chacune des instructions `case`, où les littéraux représentent les codes de status des requêtes. Les actions associées au `case` sont exécutés suite à un appariement :

    def http_error(status):
        match status:
            case 400:
                return "Bad request"
            case 404:
                return "Not found"
            case 418:
                return "I'm a teapot"
            case _:
                return "Something's wrong with the internet"

Si on passe 418 à `status` dans la fonction ci-haut, elle renvoie `"I'm a teapot"`. Avec 500, l'instruction `case` qui contient `_` apparie comme attrape-tout et la fonction renvoie `"Something's wrong with the internet"`. Prenez note que dans le dernier bloc, le nom de variable, `_` agit comme un attrape-tout et garantit que le sujet sera toujours apparié. L'utilisation de `_` est optionnelle.

Vous pouvez combiner plusieurs littéraux dans un seul filtre en utilisant `|` (qui se lit « ou ») :

    case 401 | 403 | 404:
        return "Not allowed"

##### Comportement sans l'attrape-tout

Modifions l'exemple ci-haut en enlevant le dernier bloc `case`. Il devient :

    def http_error(status):
        match status:
            case 400:
                return "Bad request"
            case 404:
                return "Not found"
            case 418:
                return "I'm a teapot"

Sans l'utilisation de `_` dans une instruction `case`, il est possible de ne pas avoir d'appariement. Dans ce cas, il ne se passe rien. Par exemple, si 500 est passé à `status`, aucune opération n'est effectuée.

#### Filtres avec un littéral et une variable

Les motifs des filtres peuvent prendre une forme similaire aux affectations multiples et un filtre peut être utilisé pour lier plus d'une variable. Dans cet exemple, un point peut être dissocié entre son abscisse et son ordonnée :

    # point is an (x, y) tuple
    match point:
        case (0, 0):
            print("Origin")
        case (0, y):
            print(f"Y={y}")
        case (x, 0):
            print(f"X={x}")
        case (x, y):
            print(f"X={x}, Y={y}")
        case _:
            raise ValueError("Not a point")

Le motif du premier filtre comporte deux littéraux, `(0, 0)`, et peut être vu comme une extension du filtre sur un littéral montré plus haut. Les motifs des deux filtres suivants regroupent un littéral et une variable. De plus, la variable est liée à la valeur provenant du sujet (`point`). Le motif du quatrième filtre capture deux valeurs, ce qui le rend conceptuellement similaire à l'affectation multiple : `(x, y) = point`.

#### Filtres et classes

Si vous utilisez des classes pour structurer vos données, vous pouvez utiliser le nom de la classe suivie d'une liste d'arguments comme motif de filtre. Ceci ressemble à un appel du constructeur. Ce filtre peut capturer les attributs de la classe dans des variables :

    class Point:
        x: int
        y: int

    def location(point):
        match point:
            case Point(x=0, y=0):
                print("Origin is the point's location.")
            case Point(x=0, y=y):
                print(f"Y={y} and the point is on the y-axis.")
            case Point(x=x, y=0):
                print(f"X={x} and the point is on the x-axis.")
            case Point():
                print("The point is located somewhere else on the plane.")
            case _:
                print("Not a point")

##### Filtres avec arguments positionnels

Vous pouvez utiliser les arguments positionnels avec un certain nombre de classes natives qui définissent l'ordre de leurs attributs, notamment les classes de données (dataclasses). Vous pouvez aussi spécifier la position des attributs quand ils sont utilisés dans les filtres en définissant l'attribut spécial `__match_args__` dans vos classes. Par exemple, le mettre à `("x", "y")` rend tous les filtres ci-dessous équivalents (en particulier, tous provoquent la liaison de l'attribut `y` à la variable `var`) :

    Point(1, var)
    Point(1, y=var)
    Point(x=1, y=var)
    Point(y=var, x=1)

#### Filtres imbriqués

Les filtres peuvent être imbriqués de façon arbitraire. Par exemple, si nous avons une courte liste de points, elle peut être appariée comme ceci :

    match points:
        case []:
            print("No points in the list.")
        case [Point(0, 0)]:
            print("The origin is the only point in the list.")
        case [Point(x, y)]:
            print(f"A single point {x}, {y} is in the list.")
        case [Point(0, y1), Point(0, y2)]:
            print(f"Two points on the Y axis at {y1}, {y2} are in the list.")
        case _:
            print("Something else is found in the list.")

#### Filtres complexes et attrape-tout

Jusqu'à maintenant, les exemples ont utilisé `_` seul dans la dernière instruction `case`. Un attrape-tout peut être utilisé dans un filtre plus complexe tel que `('error', code, _)`. Par exemple :

    match test_variable:
        case ('warning', code, 40):
            print("A warning has been received.")
        case ('error', code, _):
            print(f"An error {code} occurred.")

Dans l'exemple précédent, `test_variable` s'apparie à `('error', code, 100)` et à `('error', code, 800)`.

#### Garde

On peut ajouter une clause `if` à un filtre, ce qu'on appelle une « garde ». Si la garde s'évalue à faux, `match` poursuit avec la tentative d'appariement du prochain bloc `case`. Notez que la capture de valeur se produit avant l'évaluation de la garde :

    match point:
        case Point(x, y) if x == y:
            print(f"The point is located on the diagonal Y=X at {x}.")
        case Point(x, y):
            print(f"Point is not on the diagonal.")

#### Autres fonctionnalités importantes

Plusieurs autres fonctionnalités importantes :

- Comme dans les affectations multiples, les motifs de filtres qui sont des n-uplets ou des listes sont totalement équivalents et autorisent tous les types de séquences. Techniquement, le sujet doit être une séquence. Ainsi, exception importante, les filtres n'autorisent pas les itérateurs. Aussi, pour prémunir d'une erreur commune, les filtres de séquences n'autorisent pas les chaînes ;

- les filtres de séquence peuvent faire intervenir l'affectation étoilée : `[x, y, *reste]` ou `(x, y, *reste)` ont le même sens que dans une affectation avec `=`. Le nom de variable après l'étoile peut aussi être l'attrape-tout `_`. Ainsi, `(x, y, *_)` est un motif de filtre qui reconnaît les séquences à deux éléments ou plus, en capturant les deux premiers et en ignorant le reste ;

- il existe les filtres d'association, qui ressemblent syntaxiquement aux dictionnaires. Par exemple, le filtre `{"bande_passante": b, "latence": l}` extrait les valeurs des clés `"bande_passante"` et `"latence"` dans un dictionnaire. Contrairement aux filtres de séquence, les clés absentes du filtre sont ignorées et le filtre réussit tout de même. L'affectation double-étoilée (`**reste`) fonctionne aussi (cependant, `**_` serait redondant et n'est donc pas permis) ;

- on peut capturer la valeur d'une partie du motif d'un filtre avec le mot-clé `as`, par exemple :

      case (Point(x1, y1), Point(x2, y2) as p2): ...

  Ceci lie `x1`, `y1`, `x2`, `y2` comme attendu sans la clause `as`, et lie `p2` à l’entièreté du second élément du sujet ;

- la plupart des littéraux sont comparés par égalité. Néanmoins, les singletons `True`, `False` et `None` sont comparés par identité ;

- les filtres peuvent contenir des noms qui se réfèrent à des constantes. Ces noms doivent impérativement être qualifiés (contenir au moins un point) pour ne pas être interprétés comme des variables de capture :

      from enum import Enum
      class Color(Enum):
          RED = 0
          GREEN = 1
          BLUE = 2

      match color:
          case Color.RED:
              print("I see red!")
          case Color.GREEN:
              print("Grass is green")
          case Color.BLUE:
              print("I'm feeling the blues :(")

Pour la spécification complète, voir la PEP 634. La motivation et la justification des choix sont dans la PEP 635, et un tutoriel plus élaboré se trouve dans la PEP 636.

### `EncodingWarning` et option `encoding="locale"` optionnels

L'encodage par défaut de `TextIOWrapper` et de `open()` dépend de la plateforme et des paramètres régionaux. Comme UTF-8 est utilisé sur la plupart des plateformes Unix, ne pas spécifier l'option `encoding` pour ouvrir des fichiers UTF-8 est une erreur courante. Par exemple :

    # BUG: "rb" mode or encoding="utf-8" should be used.
    with open("data.json") as f:
        data = json.load(f)

Pour trouver ce type de bogue, un `EncodingWarning` optionnel a été ajouté. Il est levé quand `sys.flags.warn_default_encoding` est `True` et quand l'encodage utilisé est celui défini par les paramètres régionaux.

L'option `-X warn_default_encoding` et la variable d’environnement `PYTHONWARNDEFAULTENCODING` ont été ajoutées pour activer cet avertissement.

Voir Encodage de texte pour plus d'informations.

## Nouvelles fonctionnalités reliées aux indications de types

Cette section couvre les changements majeurs touchant le module `typing` et les indications de types de style PEP 484.

### PEP 604 : nouvel opérateur d'union de types

Un nouvel opérateur d'union de types a été ajouté. Il permet la syntaxe `X | Y`. Ceci offre une façon plus propre d'exprimer « soit le type X, soit le type Y » plutôt que d'utiliser `typing.Union`, en particulier pour les indications de types.

Dans les versions précédentes de Python, pour appliquer une indication de type à des fonctions qui acceptent des arguments de plusieurs types, `typing.Union` était utilisée :

    def square(number: Union[int, float]) -> Union[int, float]:
        return number ** 2

Les indications de type peuvent maintenant être écrites de façon plus courte :

    def square(number: int | float) -> int | float:
        return number ** 2

Cette nouvelle syntaxe est aussi acceptée comme le second argument de `isinstance()` et de `issubclass()` :

    >>> isinstance(1, int | str)
    True

Voir Type Union et la PEP 604 pour plus de détails

(contribution de Maggie Moss et Philippe Prados dans bpo-41428, avec ajouts par Yurii Karabas et Serhiy Storchaka dans bpo-44490).

### PEP 612 : variables de spécification de paramètres

Deux nouvelles options ont été ajoutées au module `typing` pour améliorer l'information donnée aux vérificateurs de types statiques pour les `Callable` définis dans la PEP 484.

La première est la variable de spécification de paramètre. Elles sont utilisées pour transférer le type d'un appelable à un autre – un patron de conception souvent utilisé dans les fonctions d'ordre supérieur et dans les décorateurs. Des exemples d'utilisation se trouvent dans `typing.ParamSpec`. Préalablement, il n'y avait pas de façon facile pour annoter les dépendances de types des paramètres de manière aussi précise.

La seconde option est le nouvel opérateur `Concatenate`. Il est utilisé en conjonction avec les variables de spécification de paramètres pour annoter les types d'un appelable d'ordre supérieur qui ajoute ou retire des paramètres à un autre appelable. Des exemples d'utilisation se trouvent dans `typing.Concatenate`.

Voir `typing.Callable`, `typing.ParamSpec`, `typing.Concatenate`, `typing.ParamSpecArgs`, `typing.ParamSpecKwargs` et la PEP 612 pour plus de détails

(contribution de Ken Jin dans bpo-41559, avec améliorations mineures par Jelle Zijlstra dans bpo-43783 ; PEP écrite par Mark Mendoza).

### PEP 613 : `TypeAlias`

La PEP 484 a ajouté le concept d'alias de types, en exigeant seulement qu'ils soient des assignations non-annotées au niveau du module. Cette simplicité rendait parfois difficile pour les vérificateurs de types de distinguer entre un alias de type et une affectation ordinaire, en particulier quand des références postérieures ou des types invalides étaient impliqués. Comparez :

    StrCache = 'Cache[str]'  # a type alias
    LOG_PREFIX = 'LOG[DEBUG]'  # a module constant

Maintenant le module `typing` possède une valeur spéciale `TypeAlias` qui permet de déclarer des alias de types de façon plus explicite :

    StrCache: TypeAlias = 'Cache[str]'  # a type alias
    LOG_PREFIX = 'LOG[DEBUG]'  # a module constant

Voir la PEP 613 pour plus de détails.

(contribution de Mikhail Golubev dans bpo-41923).

### PEP 647 : gardes de type définies par l'utilisateur

`TypeGuard` a été ajouté au module `typing` pour annoter les fonctions de garde de type et améliorer l'information fournie aux vérificateurs de types statiques pendant le raffinage de types. Pour plus d'information, consultez la documentation de `TypeGuard` et la PEP 647.

(contribution de Ken Jin et Guido van Rossum dans bpo-43766. PEP écrit par Eric Traut).

## Autres changements au langage

- Le type `int` a une nouvelle méthode `int.bit_count()`, qui renvoie le nombre de chiffres uns dans l’expansion binaire d'un entier donné, aussi connue sous le nom de chiffre de population (population count) (contribution de Niklas Fiekas dans bpo-29882).

- Les vues renvoyées par `dict.keys()`, `dict.values()` et `dict.items()` ont maintenant toutes un attribut `mapping` qui donne un objet `types.MappingProxyType` encapsulant le dictionnaire original (contribution de Dennis Sweeney dans bpo-40890).

- PEP 618 : la fonction `zip()` a maintenant un argument optionnel `strict`, utilisé pour demander que tous les itérables soient de même longueur.

- Les fonctions d'extensions et les fonctions natives qui prennent des arguments entiers n'acceptent plus les `Decimal`, `Fraction` et autres objets qui ne peuvent pas être convertis en entiers sans perte de précision (par exemple ceux qui ont une méthode `__int__()` mais pas une méthode `__index__()`) (contribution de Serhiy Storchaka dans bpo-37999).

- If `object.__ipow__()` returns `NotImplemented`, the operator will correctly fall back to `object.__pow__()` and `object.__rpow__()` as expected. (Contributed by Alex Shkop in bpo-38302.)

- Les expressions d'affectations peuvent maintenant être utilisées dans les littéraux d'ensembles, dans les compréhensions d'ensembles et dans les indices de séquences (mais pas dans les tranches).

- Les fonctions ont un nouvel attribut `__builtins__` qui est utilisé pour repérer les symboles natifs quand la fonction est exécutée, plutôt que de regarder dans `__globals__['__builtins__']`. L'attribut est initialisé à partir de `__globals__["__builtins__"]` s'il existe, ou des symboles natifs en cours autrement (contribution de Mark Shannon dans bpo-42990).

- Deux nouvelles fonctions natives – `aiter()` et `anext()` – ont été ajoutées pour fournir les équivalents asynchrones de `iter()` et de `next()`, respectivement (contribution de Joshua Bronson, Daniel Pope et Justin Wang dans bpo-31861).

- Les méthodes statiques (`@staticmethod`) et les méthodes de classes (`@classmethod`) héritent maintenant des attributs de méthodes (`__module__`, `__name__`, `__qualname__`, `__doc__`, `__annotations__`) et ont un nouvel attribut `__wrapped__`. De plus, les méthodes statiques sont maintenant appelables en tant que fonctions classiques (contribution de Victor Stinner dans bpo-43682).

- Les annotations des cibles complexes (toutes cibles autre que `simple name` telles que définies dans la PEP 526) n'ont plus d'effet à l'exécution avec `from __future__ import annotations` (contribution de Batuhan Taskaya dans bpo-42737).

- Les objets `class` et `module` créent maintenant paresseusement un dictionnaire d'annotations vide sur demande. Les dictionnaires d'annotations sont stockés dans le `__dict__` de l'objet pour garder la retro-compatibilité. Cela renforce les bonnes pratiques relatives à `__annotations__` ; pour plus d'information, voir Bonnes pratiques concernant les annotations (contribution de Larry Hastings dans bpo-43901).

- Les annotations qui contiennent `yield`, `yield from`, `await` ou une expression nommée ne sont plus permises sous `from __future__ import annotations` à cause de leurs effets secondaires (contribution de Batuhan Taskaya dans bpo-42725).

- L'utilisation de variables non liées, de `super()` et d'autres expressions qui peuvent changer le traitement de la table des symboles en tant qu'annotation n'ont plus d'effet sous `from __future__ import annotations` (contribution de Batuhan Taskaya dans bpo-42725).

- Le hachage des valeurs NaN des types `float` et `decimal.Decimal` dépend maintenant de l'identité de l'objet. Préalablement, cette valeur de hachage était toujours `0` alors que les valeurs NaN ne sont pas égales entre elles. Cela pouvait potentiellement entrainer un temps d'exécution quadratique en raison des collisions excessives des valeurs de hachage lors de la création de dictionnaires et d'ensembles qui contiennent plusieurs NaN (contribution de Raymond Hettinger dans bpo-43475).

- A `SyntaxError` (instead of a `NameError`) will be raised when deleting the `__debug__` constant. (Contributed by Donghee Na in bpo-45000.)

- Les exceptions `SyntaxError` ont maintenant des attributs `end_lineno` et `end_offset`. La valeur est `None` quand ils ne peuvent pas être déterminés (contribution de Pablo Galindo dans bpo-43914).

## Nouveaux modules

- None.

## Modules améliorés

### `asyncio`

Ajout de la méthode `connect_accepted_socket()` manquante (contribution d'Alex Grönholm dans bpo-41332).

### `argparse`

L'expression `"optional arguments"` qui portait à confusion a été remplacée par `"options"` dans le message d'aide d'`argparse`. Certains tests devront être adaptés s'ils dépendent d'une comparaison exacte dans la sortie d'aide (contribution de Raymond Hettinger dans bpo-9694).

### `array`

La méthode `index()` de la classe `array.array` a maintenant les paramètres optionnels start et stop (contribution d'Anders Lorentsen et de Zackery Spytz dans bpo-31956).

### `asynchat`, `asyncore`, `smtpd`

Ces modules ont étés déclarés obsolètes dans leur documentation de modules depuis Python 3.6. Un `DeprecationWarning` au moment de l'importation est maintenant ajouté pour ces trois modules.

### `base64`

Ajout de `base64.b32hexencode()` et de `base64.b32hexdecode()` pour prendre en charge l'encodage Base32 avec l'alphabet hexadécimal étendu.

### `bdb`

Ajout de `clearBreakpoints()` pour supprimer tous les points d'arrêt (contribution d'Irit Katriel dans bpo-24160).

### `bisect`

Ajout de la possibilité de fournir une fonction `key` aux API dans le module `bisect` (contribution de Raymond Hettinger dans bpo-4356).

### `codecs`

Ajout d'une fonction `codecs.unregister()` pour désinscrire une fonction de recherche de codecs (contribution de Hai Shi dans bpo-41842).

### `collections.abc`

L'attribut `__args__` des génériques paramétrables de `collections.abc.Callable` est maintenant cohérent avec `typing.Callable`. Les génériques de `collections.abc.Callable` aplatissent maintenant les types des paramètres à l'instar de `typing.Callable`. Ceci veut dire que `collections.abc.Callable[[int, str], str]` aura un attribut `__args__` de valeur `(int, str, str)` ; auparavant, il aurait été `([int, str], str)`. Pour permettre ce changement, `types.GenericAlias` peut être dérivée, et une sous-classe sera renvoyée lors de la surcharge du type `collections.abc.Callable`. Prenez note que `TypeError` sera levée pour des formes invalides de paramétrisation de `collections.abc.Callable`, ce qui aurait pu passer silencieusement dans Python 3.9 (contribution de Ken Jin dans bpo-42195).

### `contextlib`

Ajout d'un gestionnaire de contexte `contextlib.aclosing()` pour fermer de façon sécurisée les générateurs asynchrones et les objets représentants des ressources libérées de façon asynchrone (contribution de Joongi Kim et John Belmonte dans bpo-41229).

Ajout d'un gestionnaire de contexte pour prendre en charge `contextlib.nullcontext()` (contribution de Tom Gringauz dans bpo-41543).

Ajout de `AsyncContextDecorator` pour prendre en charge les gestionnaires de contexte asynchrones en tant que décorateurs.

### `curses`

Les fonctions de couleurs étendues ajoutées dans ncurses 6.1 sont utilisées de façon transparente par `curses.color_content()`, `curses.init_color()`, `curses.init_pair()` et `curses.pair_content()`. Une nouvelle fonction, `curses.has_extended_color_support()`, indique si la prise en charge des couleurs étendues est fournie par la bibliothèque ncurses sous-jacente (contribution de Jeffrey Kintscher et de Hans Petter Jansson dans bpo-36982).

Les constantes `BUTTON5_*` sont maintenant exposées dans le module `curses` si elles sont fournies par la bibliothèque curses sous-jacente (contribution de Zackery Spytz dans bpo-39273).

### `dataclasses`

#### `__slots__`

Ajout du paramètre `slots` dans le décorateur `dataclasses.dataclass()` (contribution de Yurii Karabas dans bpo-42269).

#### Champs obligatoirement nommés

Les classes de données (`dataclass`) prennent maintenant en charge les champs obligatoirement nommés dans la méthode `__init__` générée. Il y a plusieurs façons de spécifier les champs obligatoirement nommés.

Vous pouvez indiquer que tous les champs sont obligatoirement nommés :

    from dataclasses import dataclass

    @dataclass(kw_only=True)
    class Birthday:
        name: str
        birthday: datetime.date

Les paramètres `name` et `birthday` sont tous deux obligatoirement nommés dans la méthode `__init__` générée.

Pour chaque champ, vous pouvez indiquer s'il est obligatoirement nommé :

    from dataclasses import dataclass, field

    @dataclass
    class Birthday:
        name: str
        birthday: datetime.date = field(kw_only=True)

Ici, seulement `birthday` est obligatoirement nommé. Si vous assignez `kw_only` sur un champ particulier, notez qu'il y a des règles concernant l'ordre des champs puisque les champs obligatoirement nommés doivent suivre les champs optionnellement nommés. Voir la documentation de `dataclass` pour plus de détails.

Vous pouvez aussi indiquer que tous les champs qui suivent un marqueur `KW_ONLY` sont obligatoirement nommés. Ceci sera probablement l'utilisation la plus commune :

    from dataclasses import dataclass, KW_ONLY

    @dataclass
    class Point:
        x: float
        y: float
        _: KW_ONLY
        z: float = 0.0
        t: float = 0.0

Here, `z` and `t` are keyword-only parameters, while `x` and `y` are not. (Contributed by Eric V. Smith in bpo-43532.)

### `distutils`

Le paquet `distutil` est entièrement obsolète et sera retiré dans Python 3.12. Ses fonctionnalités pour spécifier la construction de paquets sont déjà complètement remplacées par les paquets tierce-parties `setuptools` et `packaging`. Les autres API régulièrement utilisées sont disponibles ailleurs dans la bibliothèque standard (tel que dans `platform`, `shutil`, `subprocess` ou `sysconfig`). Il n'est pas prévu de migrer d'autres fonctionnalités de `distutils`, aussi les applications qui utilisent d'autres fonctions du module doivent faire des copies privées du code. Voir la discussion dans la PEP 632.

La commande `bdist_wininst` qui est obsolète depuis Python 3.8 a été retirée. La commande `bdist_wheel` est maintenant recommandée pour distribuer des paquets binaires sous Windows (contribution de Victor Stinner dans bpo-42802).

### `doctest`

Quand un module ne définit pas `__loader__`, `__spec__.loader` est utilisé (contribution de Brett Cannon dans bpo-42133).

### `encodings`

La fonction `encodings.normalize_encoding()` ignore maintenant les caractères non ASCII (contribution de Hai Shi dans bpo-39337).

### enum

`Enum` `__repr__()` now returns `enum_name.member_name` and `__str__()` now returns `member_name`. Stdlib enums available as module constants have a `repr()` of `module_name.member_name`. (Contributed by Ethan Furman in bpo-40066.)

Add `enum.StrEnum` for enums where all members are strings. (Contributed by Ethan Furman in bpo-41816.)

### `fileinput`

Ajout des paramètres `encoding` et `errors` dans `fileinput.input()` et dans `fileinput.FileInput` (contribution d'Inada Naoki dans bpo-43712).

`fileinput.hook_compressed()` renvoie maintenant un objet `TextIOWrapper` quand `mode` est `"r"` et que le fichier est compressé, comme pour les fichiers non compressés (contribution d'Inada Naoki dans bpo-5758).

### `faulthandler`

Le module `faulthandler` détecte maintenant si une erreur fatale s'est produite pendant un passage du ramasse-miettes (contribution de Victor Stinner dans bpo-44466).

### `gc`

Ajout de fonctions de rappels d'audit pour `gc.get_objects()`, `gc.get_referrers()` et `gc.get_referents()` (contribution de Pablo Galindo dans bpo-43439).

### `glob`

Ajout des paramètres `root_dir` et `dir_fd` dans `glob()` et dans `iglob()` pour permettre la spécification du répertoire racine utilisé pour la recherche (contribution de Serhiy Storchaka dans bpo-38144).

### `hashlib`

La version minimale d'OpenSSL pour le module `hashlib` est maintenant 1.1.1 (contribution de Christian Heimes dans PEP 644 et dans bpo-43669).

Le module hashlib offre une prise en charge préliminaire pour OpenSSL 3.0.0 (contribution de Christian Heimes dans bpo-38820 et autres tickets).

Le repli vers la version en pur Python de `pbkdf2_hmac()` est obsolète. Dorénavant, `PBKDF2-HMAC` n'est disponible que si Python a été compilé avec la prise en charge d'OpenSSL (contribution de Christian Heimes dans bpo-43880).

### `hmac`

L'implémentation interne du module `hmac` utilise maintenant HMAC d'OpenSSL (contribution de Christian Heimes dans bpo-40645).

### IDLE et `idlelib`

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).

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.)

Les changements ci-dessus ont été rétro-portés dans le cadre de la maintenance de 3.9.

Ajout d'une barre de côté à la console. Déplacement de l'invite de commande principale (`>>>`) vers cette barre. Ajout des invites secondaires (`...`) à la barre de côté. Le clic de gauche et le glisser optionnel sélectionnent une ou plusieurs lignes de texte, tout comme dans la barre de numéros de ligne de la fenêtre d'édition. Le clic droit après la sélection de lignes de texte affiche un menu contextuel pour copier avec invites ('copy with prompts'). Ceci combine les invites de la barre de côté avec le texte sélectionné. Cette option apparait aussi dans le menu contextuel pour le texte (contribution de Tal Einat dans bpo-37903).

Utilisation d'espaces plutôt que des tabulations pour indenter le code interactif. Ceci donne au code interactif la « bonne apparence ». Cette fonctionnalité est fortement corrélée à l'ajout de la barre de côté de la console (contribution de Terry Jan Reedy dans bpo-37892).

Coloration des nouveaux mots clés ad-hoc `match`, `case` et `_` dans les instructions de filtrage par motifs (pattern matching). Par contre, cette coloration n'est pas parfaite et elle sera incorrecte dans quelques rares cas, y-compris certains `_` dans des instructions `case` (contribution de Tal Einat dans bpo-44010).

Nouveau dans les versions de maintenance 3.10.

Apply syntax highlighting to `.pyi` files. (Contributed by Alex Waygood and Terry Jan Reedy in bpo-45447.)

Include prompts when saving Shell with inputs and outputs. (Contributed by Terry Jan Reedy in gh-95191.)

### `importlib.metadata`

Équivalence de fonctionnalités avec `importlib_metadata` 4.6 (historique).

Les points d'entrée de importlib.metadata offrent maintenant une interface plus agréable pour choisir les points d'entrée par groupe et par nom par l'intermédiaire d'une nouvelle classe `importlib.metadata.EntryPoints`. Voir la rubrique Note sur la Compatibilité (Compatibility Note) dans la documentation du module `importlib.metadata` pour plus d'information sur son utilisation et ce qui devient obsolète.

Ajout de `importlib.metadata.packages_distributions()` pour résoudre les modules et paquets Python du niveau racine vers leur `importlib.metadata.Distribution`.

### `inspect`

Quand un module ne définit pas `__loader__`, `__spec__.loader` est utilisé (contribution de Brett Cannon dans bpo-42133).

Ajout de `inspect.get_annotations()` qui calcule les annotations définies sur un objet de façon sécuritaire. Elle contourne les difficultés d’accéder aux annotations de différents types d'objets et présume très peu de l'objet examiné. `inspect.get_annotations()` peut également convertir pour vous les annotations contenues dans des chaînes de caractères en objets. `inspect.get_annotations()` est maintenant considérée comme la meilleure pratique pour accéder au dictionnaire d'annotations de tout objet qui prend en charge les annotations ; pour d'autre information sur les meilleures pratiques relatives aux annotations, voir Bonnes pratiques concernant les annotations. Dans le même esprit, `inspect.signature()`, `inspect.Signature.from_callable()` et `inspect.Signature.from_function()` appellent maintenant `inspect.get_annotations()` pour récupérer les annotations. Ceci veut dire que `inspect.signature()` et `inspect.Signature.from_callable()` peuvent maintenant convertir pour vous les annotations contenues dans des chaînes de caractères en objets (contribution de Larry Hastings dans bpo-43817).

### itertools

Add `itertools.pairwise()`. (Contributed by Raymond Hettinger in bpo-38200.)

### `linecache`

Quand un module ne définit pas `__loader__`, `__spec__.loader` est utilisé (contribution de Brett Cannon dans bpo-42133).

### `os`

Ajout de la prise en charge de VxWorks RTOS dans `os.cpu_count()` (contribution de Peixing Xin dans bpo-41440).

Ajout d'une nouvelle fonction `os.eventfd()` et des fonctions utilitaires associées pour encapsuler l'appel système `eventfd2` sur Linux (contribution de Christian Heimes dans bpo-41001).

Ajout de `os.splice()` qui permet de déplacer des données entre deux descripteurs de fichiers sans copie entre les espaces noyau et utilisateur. Un des descripteurs de fichiers doit référencer un tube (pipe) (contribution de Pablo Galindo dans bpo-41625).

Add `O_EVTONLY`, `O_FSYNC`, `O_SYMLINK` and `O_NOFOLLOW_ANY` for macOS. (Contributed by Donghee Na in bpo-43106.)

### `os.path`

`os.path.realpath()` accepte maintenant l'argument nommé strict. Lorsqu'il est `True`, une `OSError` est levée si le chemin n'existe pas ou si une boucle de liens symboliques est rencontrée (contribution de Barney Gale dans bpo-43757).

### `pathlib`

Add slice support to `PurePath.parents`. (Contributed by Joshua Cannon in bpo-35498.)

Add negative indexing support to `PurePath.parents`. (Contributed by Yaroslav Pankovych in bpo-21041.)

Ajout de la méthode `Path.hardlink_to` qui remplace `link_to()`. L'ordre des arguments de la nouvelle méthode est le même que `symlink_to()` (contribution de Barney Gale dans bpo-39950).

`pathlib.Path.stat()` et `chmod()` acceptent maintenant l'argument nommé follow_symlinks pour rester cohérent avec les fonctions correspondantes dans le module `os` (contribution de Barney Gale dans bpo-39906).

### `platform`

Add `platform.freedesktop_os_release()` to retrieve operation system identification from freedesktop.org os-release standard file. (Contributed by Christian Heimes in bpo-28468.)

### `pprint`

`pprint.pprint()` accepte maintenant le nouvel argument nommé `underscore_numbers` (contribution de sblondon dans bpo-42914).

`pprint` peut maintenant afficher élégamment les instances de `dataclasses.dataclass` (contribution de Lewis Gaul dans bpo-43080).

### `py_compile`

Ajout de l'option de ligne de commande `--quiet` à l'interface de `py_compile` (contribution de Gregory Schevchenko dans bpo-38731).

### `pyclbr`

Add an `end_lineno` attribute to the `Function` and `Class` objects in the tree returned by `pyclbr.readmodule()` and `pyclbr.readmodule_ex()`. It matches the existing (start) `lineno`. (Contributed by Aviral Srivastava in bpo-38307.)

### `shelve`

The `shelve` module now uses `pickle.DEFAULT_PROTOCOL` by default instead of `pickle` protocol `3` when creating shelves. (Contributed by Zackery Spytz in bpo-34204.)

### `statistics`

Ajout des fonctions `covariance()`, `correlation()` (corrélation de Pearson) et `linear_regression()` (régression linéaire simple) (contribution de Tymoteusz Wołodźko dans bpo-38490).

### `site`

Quand un module ne définit pas `__loader__`, `__spec__.loader` est utilisé (contribution de Brett Cannon dans bpo-42133).

### `socket`

L'exception `socket.timeout` est maintenant un alias de `TimeoutError` (contribution de Christian Heimes dans bpo-42413).

Ajout d'une option pour créer des connecteurs (socket) MPTCP avec `IPPROTO_MPTCP` (contribution de Rui Cunha dans bpo-43571).

Ajout de l'option `IP_RECVTOS` pour récupérer la valeur des champs type of service (ToS) ou differentiated services code point (DSCP/ECN) (contribution de Georg Sauthoff dans bpo-44077).

### `ssl`

La version minimale d'OpenSSL pour le module `ssl` est maintenant 1.1.1 (contribution de Christian Heimes dans PEP 644 et dans bpo-43669).

The ssl module has preliminary support for OpenSSL 3.0.0 and new option `OP_IGNORE_UNEXPECTED_EOF`. (Contributed by Christian Heimes in bpo-38820, bpo-43794, bpo-43788, bpo-43791, bpo-43799, bpo-43920, bpo-43789, and bpo-43811.)

Les fonctions obsolètes et l'accès aux constantes obsolètes lèvent maintenant un `DeprecationWarning`. `ssl.SSLContext.options` a options `OP_NO_SSLv2` et `OP_NO_SSLv3` définies par défaut ; par conséquent, il ne peut pas avertir si l'option est définie de nouveau. La section obsolescence contient la liste des fonctionnalités obsolètes (contribution de Christian Heimes dans bpo-43880).

La configuration du module `ssl` est plus sécuritaire par défaut. Les algorithmes de chiffrement sans confidentialité persistante (forward secrecy) et le code d'authentification de message (MAC) SHA-1 sont désactivés par défaut. Le niveau 2 de sécurité ne permet pas les clés faibles de moins de 112 bits pour RSA, DH et ECC. La version minimale du protocole TLS pour `SSLContext` est 1.2. La configuration est basée sur la recherche de Hynek Schlawack (contribution de Christian Heimes dans bpo-43998).

Les protocoles obsolètes SSL 3.0, TLS 1.0 et TLS 1.1 ne sont plus officiellement pris en charge. Python ne les bloque pas activement, mais les options de compilation d'OpenSSL, les configurations du système d'exploitation, les rustines des fabricants et les suites d'algorithmes de chiffrement peuvent empêcher l’établissement d'une connexion.

Ajout d'un paramètre timeout à la fonction `ssl.get_server_certificate()` (contribution de Zackery Spytz dans bpo-31870).

Le module `ssl` utilise les types du tas et l'initialisation multi-phase (contribution de Christian Heimes dans bpo-42333).

A new verify flag `VERIFY_X509_PARTIAL_CHAIN` has been added. (Contributed by l0x in bpo-40849.)

### `sqlite3`

Ajout d'événements d'audit pour `connect/handle()`, `enable_load_extension()` et `load_extension()` (contribution d'Erlend E. Aasland dans bpo-43762).

### `sys`

Ajout de l'attribut `sys.orig_argv` : la liste des arguments de ligne de commande originalement passée à l'exécutable Python (contribution de Victor Stinner dans bpo-23427).

Ajout de `sys.stdlib_module_names` qui contient la liste des noms des modules de la bibliothèque standard (contribution de Victor Stinner dans bpo-42955).

### `_thread`

`_thread.interrupt_main()` now takes an optional signal number to simulate (the default is still `signal.SIGINT`). (Contributed by Antoine Pitrou in bpo-43356.)

### `threading`

Ajout des fonctions `threading.gettrace()` et `threading.getprofile()` pour récupérer les fonctions assignées par `threading.settrace()` et `threading.setprofile()` respectivement (contribution de Mario Corchero dans bpo-42251).

Ajout de `threading.__excepthook__` pour permettre la récupération de `threading.excepthook()` au cas où elle serait affectée à une valeur incorrecte ou différente (contribution de Mario Corchero dans bpo-42308).

### `traceback`

Les fonctions `format_exception()`, `format_exception_only()` et `print_exception()` peuvent maintenant prendre un objet exception en argument positionnel (contribution de Zackery Spytz et Matthias Bussonnier dans bpo-26389).

### `types`

Les classes `types.EllipsisType`, `types.NoneType` et `types.NotImplementedType` sont ajoutées de nouveau. Elles fournissent un nouvel ensemble de types facilement interprétable par les vérificateurs de types (contribution de Bas van Beek dans bpo-41810).

### `typing`

Pour les changements majeurs, voir Nouvelles fonctionnalités reliées aux indications de types.

Le comportement de `typing.Literal` a été changé pour être conforme avec la PEP 586 et pour correspondre au comportement des vérificateurs de types statiques défini dans la PEP.

1. `Literal` dé-duplique maintenant les paramètres.

2. La comparaison d'égalité entre objets `Literal` ne tient plus compte de l'ordre.

3. Les comparaisons de `Literal` respectent maintenant les types. Par exemple, `Literal[0] == Literal[False]` était préalablement évaluée à `True`. Elle est maintenant `False`. Pour prendre en charge ce changement, le cache des types de l'implémentation interne peut maintenant différencier entre les types.

4. Les objets `Literal` lèvent maintenant une exception `TypeError` pendant la comparaison d'égalité si au moins un de leurs paramètres n'est pas hachable. Notez que déclarer un `Literal` avec des paramètres non hachables ne lève pas d'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).

Add new function `typing.is_typeddict()` to introspect if an annotation is a `typing.TypedDict`. (Contributed by Patrick Reader in bpo-41792.)

Subclasses of `typing.Protocol` which only have data variables declared will now raise a `TypeError` when checked with `isinstance` unless they are decorated with `runtime_checkable()`. Previously, these checks passed silently. Users should decorate their subclasses with the `runtime_checkable()` decorator if they want runtime protocols. (Contributed by Yurii Karabas in bpo-38908.)

Importing from the `typing.io` and `typing.re` submodules will now emit `DeprecationWarning`. These submodules have been deprecated since Python 3.8 and will be removed in a future version of Python. Anything belonging to those submodules should be imported directly from `typing` instead. (Contributed by Sebastian Rittau in bpo-38291.)

### `unittest`

Ajout d'une nouvelle méthode `assertNoLogs()` pour complémenter la méthode existante `assertLogs()` (contribution de Kit Yan Choi dans bpo-39385).

### `urllib.parse`

Les versions préalables à Python 3.10 acceptaient les deux caractères `;` et `&` comme séparateurs de paramètres de requêtes dans `urllib.parse.parse_qs()` et `urllib.parse.parse_qsl()`. Pour prévenir des failles de sécurité potentielles et pour respecter les dernières 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 l'implémentation interne de `cgi.parse()` et de `cgi.parse_multipart()` puisqu'elles utilisent les fonctions affectées. Pour plus de détails, voir la documentation respective de ces fonctions (contribution d'Adam Goldschmidt, de Senthil Kumaran et de Ken Jin dans bpo-42967).

The presence of newline or tab characters in parts of a URL allows for some forms of attacks. Following the WHATWG specification that updates RFC 3986, ASCII newline `\n`, `\r` and tab `\t` characters are stripped from the URL by the parser in `urllib.parse` preventing such attacks. The removal characters are controlled by a new module level variable `urllib.parse._UNSAFE_URL_BYTES_TO_REMOVE`. (See gh-88048)

### `xml`

Ajout d'une classe `LexicalHandler` au module `xml.sax.handler` (contribution de Jonathan Gossage de Zackery Spytz dans bpo-35018).

### `zipimport`

Ajout des méthodes relatives à la PEP 451 : `find_spec()`, `zipimport.zipimporter.create_module()` et `zipimport.zipimporter.exec_module()` (contribution de Brett Cannon dans bpo-42131).

Ajout de la méthode `invalidate_caches()` (contribution de Desmond Cheong dans bpo-14678).

## Optimisations

- Les constructeurs de `str()`, `bytes()` et `bytearray()` sont maintenant plus rapides (environ 30—40 % pour les petits objets) (contribution de Serhiy Storchaka dans bpo-41334).

- Le module `runpy` importe maintenant moins de modules. Le temps de démarrage de la commande `python3 -m module-name` est en moyenne 1,4 fois plus rapide. Sur Linux `python3 -I -m module-name` importe 69 modules dans Python 3.9, alors qu'elle n'en importe que 51 (18 de moins) dans Python 3.10 (contribution de Victor Stinner dans bpo-41006 et dans bpo-41718).

- L'instruction `LOAD_ATTR` utilise maintenant le mécanisme de cache par code d'opération. Elle est environ 36 % plus rapide pour les attributs ordinaires et 44 % plus rapide pour les slots (contribution de Pablo Galindo et de Yury Selivanov dans bpo-42093 et Guido van Rossum dans bpo-42927, basée sur des idées originalement mises en œuvre dans PyPy et dans MicroPython).

- Lors de la construction de Python avec `--enable-optimizations`, `-fno-semantic-interposition` est maintenant ajouté aux lignes de commande de compilation et d'édition des liens. Ceci accélère les binaires de l'interpréteur Python créés avec `--enable-shared` et `gcc` jusqu'à 30 %. Voir cet article (en anglais) pour plus de détails (contribution de Victor Stinner et Pablo Galindo dans bpo-38980).

- Ré-usinage du code assurant la gestion du tampon de sortie pour les modules `bz2`, `lzma` et `zlib`. Ajout de la fonction `.readall()` à la classe `_compression.DecompressReader`. La décompression bz2 est 1,09 à 1,17 fois plus rapide, la décompression lzma est 1,20 à 1,32 fois plus rapide, `GzipFile.read(-1)` est 1,11 à 1,18 fois plus rapide (contribution de Ma Lin, révision par Gregory P. Smith dans bpo-41486).

- When using stringized annotations, annotations dicts for functions are no longer created when the function is created. Instead, they are stored as a tuple of strings, and the function object lazily converts this into the annotations dict on demand. This optimization cuts the CPU time needed to define an annotated function by half. (Contributed by Yurii Karabas and Inada Naoki in bpo-42202.)

- Les fonctions de recherche de sous-chaînes telles que `str1 in str2` et `str2.find(str1)` peuvent utiliser maintenant l'algorithme « bidirectionnel » de recherche de chaînes Crochemore et Perrin pour éviter le comportement quadratique sur les longues chaînes (contribution de Dennis Sweeney dans bpo-41972).

- Add micro-optimizations to `_PyType_Lookup()` to improve type attribute cache lookup performance in the common case of cache hits. This makes the interpreter 1.04 times faster on average. (Contributed by Dino Viehland in bpo-43452.)

- The following built-in functions now support the faster PEP 590 vectorcall calling convention: `map()`, `filter()`, `reversed()`, `bool()` and `float()`. (Contributed by Donghee Na and Jeroen Demeyer in bpo-43575, bpo-43287, bpo-41922, bpo-41873 and bpo-41870.)

- `BZ2File` performance is improved by removing internal `RLock`. This makes `BZ2File` thread unsafe in the face of multiple simultaneous readers or writers, just like its equivalent classes in `gzip` and `lzma` have always been. (Contributed by Inada Naoki in bpo-43785.)

## Obsolescence

- Currently Python accepts numeric literals immediately followed by keywords, for example `0in x`, `1or x`, `0if 1else 2`. It allows confusing and ambiguous expressions like `[0x1for x in y]` (which can be interpreted as `[0x1 for x in y]` or `[0x1f or x in y]`). Starting in this release, a deprecation warning is raised if the numeric literal is immediately followed by one of keywords `and`, `else`, `for`, `if`, `in`, `is` and `or`. In future releases it will be changed to syntax warning, and finally to syntax error. (Contributed by Serhiy Storchaka in bpo-43833.)

- À partir de la version présente, il y aura un effort coordonné pour commencer le nettoyage des anciennes sémantiques d'importation qui étaient gardées pour la compatibilité avec Python 2.7. Plus spécifiquement, `find_loader()`/`find_module()` (remplacées par `find_spec()`), `load_module()` (remplacée par `exec_module()`), `module_repr()` (qui est géré par le système d'importation pour vous), l'attribut `__package__` (remplacé par `__spec__.parent`), l'attribut `__loader__` (remplacé par `__spec__.loader`) et l'attribut `__cached__` (remplacé par `__spec__.cached`) seront progressivement retirés (de même que d'autres classes et méthodes dans `importlib`). Des `ImportWarning` ou `DeprecationWarning` seront levés le cas échéant pendant cette transition pour aider à identifier le code qui doit être mis à jour.

- L'espace de noms `distutils` est complètement obsolète et sera retiré dans Python 3.12. Voir la section sur les changements aux modules pour plus d'information.

- Les arguments non entiers de `random.randrange()` sont obsolètes. La levée de `ValueError` dans ce cas est obsolète et est remplacée par `TypeError` (contribution de Serhiy Storchaka et Raymond Hettinger dans bpo-37319).

- Les multiples méthodes `load_module()` de `importlib` étaient documentées comme obsolètes depuis Python 3.6, mais elles vont maintenant aussi lever un `DeprecationWarning`. Utilisez plutôt `exec_module()` (contribution de Brett Cannon dans bpo-26131).

- `zimport.zipimporter.load_module()` est obsolète. Utilisez plutôt `exec_module()` (contribution de Brett Cannon dans bpo-26131).

- L'utilisation de `load_module()` par le système d'importation lève maintenant un `ImportWarning` car `exec_module()` est recommandée (contribution de (Brett Cannon dans bpo-26131).

- L'utilisation de `importlib.abc.MetaPathFinder.find_module()` et de `importlib.abc.PathEntryFinder.find_module()` par le système d'importation lève maintenant un `ImportWarning` car `importlib.abc.MetaPathFinder.find_spec()` et `importlib.abc.PathEntryFinder.find_spec()` sont recommandées, respectivement. Vous pouvez utiliser `importlib.util.spec_from_loader()` pour faciliter le portage (contribution de Brett Cannon dans bpo-42134).

- L'utilisation de `importlib.abc.PathEntryFinder.find_loader()` par le système d'importation lève maintenant un `ImportWarning`. Son remplacement par `importlib.abc.PathEntryFinder.find_spec()` est recommandé. Vous pouvez utiliser `importlib.util.spec_from_loader()` pour faciliter le portage (contribution de Brett Cannon dans bpo-43672).

- Plusieurs implémentations de `importlib.abc.MetaPathFinder.find_module()` (`importlib.machinery.BuiltinImporter.find_module()`, `importlib.machinery.FrozenImporter.find_module()`, `importlib.machinery.WindowsRegistryFinder.find_module()`, `importlib.machinery.PathFinder.find_module()` et `importlib.abc.MetaPathFinder.find_module()`), `importlib.abc.PathEntryFinder.find_module()` (`importlib.machinery.FileFinder.find_module()`) et `importlib.abc.PathEntryFinder.find_loader()` (`importlib.machinery.FileFinder.find_loader()`) lèvent maintenant `DeprecationWarning` et seront retirées dans Python 3.12 (elles étaient documentées comme obsolètes depuis Python 3.4) (contribution de Brett Cannon dans bpo-42135).

- `importlib.abc.Finder` est obsolète (incluant sa seule méthode, `find_module()`). Les deux classes `importlib.abc.MetaPathFinder` et `importlib.abc.PathEntryFinder` n'héritent plus de `Finder`. Les utilisateurs doivent hériter d'une de ces deux classes le cas échéant (contribution de Brett Cannon dans bpo-42135).

- Les déclarations d'obsolescence de `imp`, `importlib.find_loader()`, `importlib.util.set_package_wrapper()`, `importlib.util.set_loader_wrapper()`, `importlib.util.module_for_loader()`, `pkgutil.ImpImporter` et `pkgutil.ImpLoader` ont étés mises à jour pour indiquer Python 3.12 comme la version où elles seront retirées (elles lèvent un `DeprecationWarning` depuis les précédentes versions de Python) (contribution de Brett Cannon dans bpo-43720).

- Le système d'importation utilise maintenant l'attribut `__spec__` des modules avant de se rabattre sur `module_repr()` pour la méthode `__repr__()` des modules. Le retrait de l'utilisation de `module_repr()` est planifié pour Python 3.12 (contribution de Brett Cannon dans bpo-42137).

- `importlib.abc.Loader.module_repr()`, `importlib.machinery.FrozenLoader.module_repr()` et `importlib.machinery.BuiltinLoader.module_repr()` sont obsolètes et seront retirées dans Python 3.12 (contribution de Brett Cannon dans bpo-42136).

- `sqlite3.OptimizedUnicode` est non-documenté et désuète depuis Python 3.3, quand elle devenue un alias de `str`. Elle est maintenant déclarée obsolète et sera retiré dans Python 3.12 (contribution de Erlend E. Aasland dans bpo-42264).

- La fonction native non-documentée `sqlite3.enable_shared_cache` est maintenant obsolète et sera retirée dans Python 3.12. Son utilisation est fortement déconseillée dans la documentation de SQLite3. Voir la documentation de SQLite3 (en anglais) pour plus de détails. Si un cache partagé est nécessaire, ouvrez la base de données en mode URI en utilisant le paramètre de requête `cache=shared` (contribution de Erlend E. Aasland dans bpo-24464).

- Les méthodes suivantes du module `threading` sont maintenant obsolètes :

  - `threading.currentThread` => `threading.current_thread()` ;

  - `threading.activeCount` => `threading.active_count()` ;

  - `threading.Condition.notifyAll` => `threading.Condition.notify_all()` ;

  - `threading.Event.isSet` => `threading.Event.is_set()` ;

  - `threading.Thread.setName` => `threading.Thread.name` ;

  - `threading.thread.getName` => `threading.Thread.name` ;

  - `threading.Thread.isDaemon` => `threading.Thread.daemon` ;

  - `threading.Thread.setDaemon` => `threading.Thread.daemon`.

  (Contributed by Jelle Zijlstra in gh-87889.)

- `pathlib.Path.link_to()` est obsolète et sera retirée dans Python 3.12. Utilisez plutôt `pathlib.Path.hardlink_to()` (contribution de Barney Gale dans bpo-39950).

- `cgi.log()` est obsolète et sera retirée dans Python 3.12 (contribution de Inada Naoki dans bpo-41139).

- Les fonctionnalités suivantes de `ssl` sont obsolètes depuis Python 3.6, Python 3.7 ou OpenSSL 1.1.0 et seront retirées dans 3.11 :

  - `OP_NO_SSLv2`, `OP_NO_SSLv3`, `OP_NO_TLSv1`, `OP_NO_TLSv1_1`, `OP_NO_TLSv1_2` et `OP_NO_TLSv1_3` sont remplacés par `sslSSLContext.minimum_version` et `sslSSLContext.maximum_version` ;

  - `PROTOCOL_SSLv2`, `PROTOCOL_SSLv3`, `PROTOCOL_SSLv23`, `PROTOCOL_TLSv1`, `PROTOCOL_TLSv1_1`, `PROTOCOL_TLSv1_2`, and `PROTOCOL_TLS` are deprecated in favor of `PROTOCOL_TLS_CLIENT` and `PROTOCOL_TLS_SERVER`

  - `wrap_socket()` est remplacée par `ssl.SSLContext.wrap_socket()` ;

  - `match_hostname()` ;

  - `RAND_pseudo_bytes()`, `RAND_egd()` ;

  - Les fonctionnalités NPN (Next Protocol Negotiation) telles que `ssl.SSLSocket.selected_npn_protocol()` et `ssl.SSLContext.set_npn_protocols()` sont remplacées par ALPN (Application Layer Protocol Negotiation).

- Le débogage des fils d'exécution (variable d'environnement `PYTHONTHREADDEBUG`) est obsolète dans Python 3.10 et sera retiré dans Python 3.12. Cette fonctionnalité nécessite un interpréteur compilé avec les paramètres de débogage (contribution de Victor Stinner dans bpo-44584).

- Importing from the `typing.io` and `typing.re` submodules will now emit `DeprecationWarning`. These submodules will be removed in a future version of Python. Anything belonging to these submodules should be imported directly from `typing` instead. (Contributed by Sebastian Rittau in bpo-38291.)

## Retrait

- Les méthodes spéciales `__int__`, `__float__`, `__floordiv__`, `__mod__`, `__divmod__`, `__rfloordiv__`, `__rmod__` et `__rdivmod__` sont retirées de la classe `complex`. Elles levaient toujours une `TypeError` (contribution de Serhiy Storchaka dans bpo-41974).

- La méthode `ParserBase.error()` du module privé et non-documenté `_markupbase` a été retirée. `html.parser.HTMLParser` est la seule sous-classe de `ParserBase` et son implémentation de la méthode `error()` a été retirée dans Python 3.5 (contribution de Berker Peksag dans bpo-31844).

- Retrait de l'attribut `unicodedata.ucnhash_CAPI` qui était un objet `PyCapsule` interne. La structure privée associée `_PyUnicode_Name_CAPI` a été déplacée vers l'API C interne (contribution de Victor Stinner dans bpo-42157).

- Retrait du module `parser` qui était obsolète depuis 3.9 étant donné la transition vers le nouvel analyseur syntaxique PEG. Retrait aussi des fichiers source et en-tête C qui n'étaient utilisés que par l'ancien analyseur, ceci comprend `node.h`, `parser.h`, `graminit.h` et `grammar.h`.

- Retrait des fonctions `PyParser_SimpleParseStringFlags`, `PyParser_SimpleParseStringFlagsFilename`, `PyParser_SimpleParseFileFlags` et `PyNode_Compile` de l'API C publique. Elles étaient obsolètes depuis 3.9 étant donné la transition vers l'analyseur syntaxique PEG.

- Removed the `formatter` module, which was deprecated in Python 3.4. It is somewhat obsolete, little used, and not tested. It was originally scheduled to be removed in Python 3.6, but such removals were delayed until after Python 2.7 EOL. Existing users should copy whatever classes they use into their code. (Contributed by Donghee Na and Terry J. Reedy in bpo-42299.)

- Removed the `PyModule_GetWarningsModule()` function that was useless now due to the `_warnings` module was converted to a builtin module in 2.6. (Contributed by Hai Shi in bpo-42599.)

- Retrait des alias obsolètes Classes de base abstraites de collections du module `collections` (contribution de Victor Stinner dans bpo-37324).

- Le paramètre `loop` a été retiré de la majorité de l'API haut-niveau d'`asyncio`. Il était obsolète depuis Python 3.8. La motivation pour ce changement avait plusieurs facettes :

  1. ceci simplifie l'API haut-niveau ;

  2. les fonctions dans l'API haut niveau reçoivent implicitement la boucle d'évènements qui tourne dans le présent fil d'exécution depuis Python 3.7. Il n'y a aucun besoin de passer la boucle d'évènements à l'API dans la majorité de son utilisation normale ;

  3. le passage de la boucle d'évènements cause facilement des erreurs quand plusieurs boucles qui tournent dans plusieurs fils d'exécution sont impliquées.

  Prenez note que l'API bas-niveau accepte toujours le paramètre `loop`. Voir Changements dans l'API Python pour plus d'exemples sur comment remplacer le code existant

  (contribution de Yurii Karabas, Andrew Svetlov, Yury Selivanov et Kyle Stanley dans bpo-42392).

## Portage vers Python 3.10

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

### Changements à la syntaxe de Python

- Deprecation warning is now emitted when compiling previously valid syntax if the numeric literal is immediately followed by a keyword (like in `0in x`). In future releases it will be changed to syntax warning, and finally to a syntax error. To get rid of the warning and make the code compatible with future releases just add a space between the numeric literal and the following keyword. (Contributed by Serhiy Storchaka in bpo-43833.)

### Changements dans l'API Python

- Les paramètres etype des fonctions `format_exception()`, `format_exception_only()` et `print_exception()` du module `traceback` ont étés renommés exc (contribution de Zackery Spytz et Matthias Bussonnier dans bpo-26389).

- `atexit` : à la fin de l'exécution de Python, si une fonction de rappel qui a été enregistrée avec `atexit.register()` échoue, son exception est maintenant journalisée. Préalablement, seulement certaines exceptions étaient journalisées et la dernière exception était toujours ignorée de façon silencieuse (contribution de Victor Stinner dans bpo-42639).

- Les génériques de `collections.abc.Callable` aplatissent maintenant les paramètres de types tel qu'il est fait par `typing.Callable`. Ceci veut dire que `collections.abc.Callable[[int, str], str]` aura un attribut `__args__` de valeur `(int, str, str)` ; préalablement, il aurait été `([int, str], str)`. Les codes qui accèdent aux arguments par `typing.get_args()` ou `__args__` doivent tenir compte de ce changement. De plus, `TypeError` sera levée pour des formes invalides de paramétrisation de `collections.abc.Callable`, ce qui aurait pu passer silencieusement dans Python 3.9 (contribution de Ken Jin dans bpo-42195).

- `socket.htons()` et `socket.ntohs()` lèvent maintenant `OverflowError` plutôt que `DeprecationWarning` si le paramètre passé est trop grand pour être stocké dans un entier 16-bit non-signé (contribution de Erlend E. Aasland dans bpo-42393).

- Le paramètre `loop` a été retiré de la majorité de l'API haut-niveau d'`asyncio` suite à la déclaration de son obsolescence dans Python 3.8.

  Une coroutine qui ressemble actuellement à ceci :

      async def foo(loop):
          await asyncio.sleep(1, loop=loop)

  Doit être remplacée par ceci :

      async def foo():
          await asyncio.sleep(1)

  Si `foo()` a été spécifiquement conçue pour ne pas s'exécuter dans le fil d'exécution courant, (par exemple pour tourner dans la boucle d'exécution d'un autre fil), l'utilisation de `asyncio.run_coroutine_threadsafe()` est probablement plus appropriée.

  (contribution de Yurii Karabas, Andrew Svetlov, Yury Selivanov et Kyle Stanley dans bpo-42392).

- Le constructeur de `types.FunctionType` hérite maintenant des définitions natives si le dictionnaire globals n'a pas de clé `"__builtins__"`, plutôt que d'utiliser `{"None": None}` pour les définitions natives : même comportement que celui des fonctions `eval()` et `exec()`. Définir une fonction avec `def function(...): ...` en Python n'est pas affecté, les globales ne peuvent pas être changées avec cette syntaxe : elles héritent aussi des définitions natives courantes (contribution de Victor Stinner dans bpo-42990).

### Changements dans l'API C

- Les fonctions de l'API C `PyParser_SimpleParseStringFlags`, `PyParser_SimpleParseStringFlagsFilename`, `PyParser_SimpleParseFileFlags` et `PyNode_Compile` ainsi que `struct _node`, le type utilisé par ces fonctions, ont été retirés suite à la transition vers le nouvel analyseur syntaxique PEG.

  Le code source doit maintenant être compilé directement en un objet code, en utilisant par exemple `Py_CompileString()`. L'objet code ainsi produit peut ensuite être évalué, en utilisant par exemple `PyEval_EvalCode()`.

  Spécifiquement :

  - Un appel à `PyParser_SimpleParseStringFlags` suivi de `PyNode_Compile` peut être remplacé par `Py_CompileString()` ;

  - Il n'y a pas de remplacement immédiat pour `PyParser_SimpleParseFileFlags`. Pour compiler du code à partir d'un argument `FILE *`, vous devez lire le fichier en C et passer le tampon résultant à `Py_CompileString()`.

  - Pour compiler un fichier à partir du `char *` de son nom, ouvrez le fichier de façon explicite, lisez son contenu et compilez le résultat. Une façon de faire est d'utiliser le module `io` en conjonction avec `PyImport_ImportModule()`, `PyObject_CallMethod()`, `PyBytes_AsString()` et `Py_CompileString()`, comme dans l'esquisse qui suit (les déclarations et la gestion d'erreurs ne sont pas incluses)

        io_module = Import_ImportModule("io");
        fileobject = PyObject_CallMethod(io_module, "open", "ss", filename, "rb");
        source_bytes_object = PyObject_CallMethod(fileobject, "read", "");
        result = PyObject_CallMethod(fileobject, "close", "");
        source_buf = PyBytes_AsString(source_bytes_object);
        code = Py_CompileString(source_buf, filename, Py_file_input);

  - For `FrameObject` objects, the `f_lasti` member now represents a wordcode offset instead of a simple offset into the bytecode string. This means that this number needs to be multiplied by 2 to be used with APIs that expect a byte offset instead (like `PyCode_Addr2Line()` for example). Notice as well that the `f_lasti` member of `FrameObject` objects is not considered stable: please use `PyFrame_GetLineNumber()` instead.

## Changements au code intermédiaire CPython

- The `MAKE_FUNCTION` instruction now accepts either a dict or a tuple of strings as the function's annotations. (Contributed by Yurii Karabas and Inada Naoki in bpo-42202.)

## Changements à la compilation

- PEP 644 : la version minimale d'OpenSSL pour Python est maintenant 1.1.1. OpenSSL 1.0.2 n'est plus prise en charge (contribution de Christian Heimes dans bpo-43669).

- Les fonctions de C99 `snprintf()` et `vsnprintf()` sont maintenant nécessaires à la compilation de Python (contribution de Victor Stinner dans bpo-36020).

- La version minimale de SQLite pour le module `sqlite3` est maintenant 3.7.15 (contribution de Sergey Fedoseev et Erlend E. Aasland dans bpo-40744 et bpo-40810).

- Le module `atexit` doit maintenant toujours être compilé en tant que module natif (contribution de Victor Stinner dans bpo-42639).

- Ajout de l'option `--disable-test-modules` au script `configure` : ne pas compiler ni installer les modules de tests (contribution de Xavier de Gaye, Thomas Petazzoni et Peixing Xin dans bpo-27640).

- Ajout de l'option `--with-wheel-pkg-dir=PATH` au script `./configure`. Si elle est passée, le module `ensurepip` recherche les paquets wheel de `setuptools` et de `pip` dans ce répertoire : si les deux sont présents, ces paquets wheel sont utilisés plutôt que ceux inclus avec ensurepip.

  La politique de paquets de certaines distributions Linux déconseille l'inclusion des dépendances. Par exemple, Fedora installe les paquets wheel dans le répertoire `/usr/share/python-wheels/` et n'installe pas le paquet `ensurepip._bundled`

  (contribution de Victor Stinner dans bpo-42856).

- Ajout d'une nouvelle option `--without-static-libpython` au script `configure` pour ne pas compiler la bibliothèque statique `libpythonMAJOR.MINOR.a` et ne pas installer le fichier objet `python.o`

  (contribution de Victor Stinner dans bpo-43103).

- The `configure` script now uses the `pkg-config` utility, if available, to detect the location of Tcl/Tk headers and libraries. As before, those locations can be explicitly specified with the `--with-tcltk-includes` and `--with-tcltk-libs` configuration options. (Contributed by Manolis Stamatogiannakis in bpo-42603.)

- Ajout de l'option `--with-openssl-rpath` au script `configure`. Cette option simplifie la compilation de Python avec une installation personnalisée d'OpenSSL, par exemple : `./configure --with-openssl=/path/to/openssl --with-openssl-rpath=auto` (contribution de Christian Heimes dans bpo-43466).

## Changements à l'API C

### PEP 652 : maintenance d'une ABI stable

L'interface binaire-programme (Application Binary Interface, ABI en anglais) stable pour les modules d'extension ou pour l'intégration de Python est maintenant définie de façon explicite. Le document Stabilité de l’API C décrit les garanties de stabilité pour l'API C et pour l'interface binaire-programme ainsi que les bonnes pratiques pour travailler avec l'interface binaire-programme stable

(contribution de Petr Viktorin dans PEP 652 et dans bpo-43795).

### Nouvelles fonctionnalités

- Le résultat de `PyNumber_Index()` est maintenant exactement de type `int`. Auparavant, le résultat pouvait être une instance d'une classe dérivée de `int` (contribution de Serhiy Storchaka dans bpo-40792).

- Ajout d'un nouveau champ `orig_argv` à la structure `PyConfig` : la liste des arguments de ligne de commande originalement passée à l'exécutable Python (contribution de Victor Stinner dans bpo-23427).

- Les macros `PyDateTime_DATE_GET_TZINFO()` et `PyDateTime_TIME_GET_TZINFO()` ont été ajoutées pour récupérer l'attribut `tzinfo` des objets `datetime.datetime` et `datetime.time` (contribution de Zackery Spytz dans bpo-30155).

- Ajout d'une fonction `PyCodec_Unregister()` pour désinscrire une fonction de recherche de codecs (contribution de Hai Shi dans bpo-41842).

- Ajout de la fonction `PyIter_Send()` pour acheminer une valeur dans un itérateur sans lever une exception `StopIteration` (contribution de Vladimir Matveev dans bpo-41756).

- Ajout de `PyUnicode_AsUTF8AndSize()` à l'API C limitée (contribution d'Alex Gaynor dans bpo-41784).

- Ajout de la fonction `PyModule_AddObjectRef()` : comparable à `PyModule_AddObject()` mais ne s’accapare pas une référence à la valeur s'il y a réussite (contribution de Victor Stinner dans bpo-1635741).

- Ajout des fonctions `Py_NewRef()` et `Py_XNewRef()` pour incrémenter le compteur des références d'un objet et renvoyer l'objet (contribution de Victor Stinner dans bpo-42262).

- Les fonctions `PyType_FromSpecWithBases()` et `PyType_FromModuleAndSpec()` n'acceptent maintenant qu'une seule classe pour l'argument bases (contribution Serhiy Storchaka dans bpo-42423).

- La fonction `PyType_FromModuleAndSpec()` accepte maintenant `NULL` dans l'emplacement `tp_doc` (contribution de Hai Shi dans bpo-41832).

- La fonction `PyType_GetSlot()` peut maintenant accepter des types statiques (contribution de Hai Shi et Petr Viktorin dans bpo-41073).

- Ajout d'une nouvelle fonction `PySet_CheckExact()` à l'API C pour vérifier si un objet est une instance de `set` mais pas une instance d'un sous-type (contribution de Pablo Galindo dans bpo-43277).

- Ajout de `PyErr_SetInterruptEx()` qui accepte le numéro d'un signal à simuler (contribution d'Antoine Pitrou dans bpo-43356).

- L'API C limitée est maintenant prise en charge si Python est compilé en mode débogage (si la macro `Py_DEBUG` est définie). Dans l'API C limitée, les fonctions `Py_INCREF()` et `Py_DECREF()` sont maintenant implémentées en appel de fonctions opaques, plutôt que d'accéder directement au champ `PyObject.ob_refcnt`. C'est le cas si Python est compilé en mode débogage et que la macro `Py_LIMITED_API` vise Python 3.10 ou plus récent. Il est possible de prendre en charge l'API C limitée en mode débogage, car la structure `PyObject` est la même dans les versions standard et dans les versions débogage depuis Python 3.8 (voir bpo-36465).

  L'API C limitée n'est toujours pas prise en charge dans les compilations spéciales avec l'option `--with-trace-refs` (macro `Py_TRACE_REFS`) (Contribution de Victor Stinner dans bpo-43688).

- Ajout de la fonction `Py_Is(x, y)` pour vérifier si l'objet x est l'objet y, tout comme `x is y` en Python. Ajout aussi des fonctions `Py_IsNone()`, `Py_IsTrue()` et `Py_IsFalse()` pour vérifier si l'objet est le singleton `None`, le singleton `True` ou le singleton `False`, respectivement (contribution de Victor Stinner dans bpo-43753).

- Ajout de fonctions pour contrôler le ramasse-miettes en C : `PyGC_Enable()`, `PyGC_Disable()` et `PyGC_IsEnabled()`. Ces fonctions permettent d'activer, de désactiver et d'interroger l'état du ramasse-miettes dans du code C sans avoir à importer le module `gc`.

- Add a new `Py_TPFLAGS_DISALLOW_INSTANTIATION` type flag to disallow creating type instances. (Contributed by Victor Stinner in bpo-43916.)

- Add a new `Py_TPFLAGS_IMMUTABLETYPE` type flag for creating immutable type objects: type attributes cannot be set nor deleted. (Contributed by Victor Stinner and Erlend E. Aasland in bpo-43908.)

### Portage vers Python 3.10

- The `PY_SSIZE_T_CLEAN` macro must now be defined to use `PyArg_ParseTuple()` and `Py_BuildValue()` formats which use `#`: `es#`, `et#`, `s#`, `u#`, `y#`, `z#`, `U#` and `Z#`. See Analyse des arguments et construction des valeurs and PEP 353. (Contributed by Victor Stinner in bpo-40943.)

- Étant donné la conversion de `Py_REFCNT()` en fonction statique en-ligne, `Py_REFCNT(obj) = new_refcnt` doit être remplacé par `Py_SET_REFCNT(obj, new_refcnt)` : voir `Py_SET_REFCNT()` (disponible depuis Python 3.9). Pour la rétro-compatibilité, cette macro peut être utilisée :

      #if PY_VERSION_HEX < 0x030900A4
      #  define Py_SET_REFCNT(obj, refcnt) ((Py_REFCNT(obj) = (refcnt)), (void)0)
      #endif

  (contribution de Victor Stinner dans bpo-39573).

- Appeler `PyDict_GetItem()` sans avoir obtenu le GIL était autorisé pour des raisons historiques. Ceci n'est plus permis (contribution de Victor Stinner dans bpo-40839).

- `PyUnicode_FromUnicode(NULL, size)` et `PyUnicode_FromStringAndSize(NULL, size)` lèvent maintenant un `DeprecationWarning`. Vous devez utiliser `PyUnicode_New()` pour allouer un objet Unicode sans donnée initiale (contribution de Inada Naoki dans bpo-36346).

- La structure privée `_PyUnicode_Name_CAPI` de l'API PyCapsule `unicodedata.ucnhash_CAPI` a été déplacée dans l'API C interne. (Contribution par Victor Stinner dans bpo-42157.)

- `Py_GetPath()`, `Py_GetPrefix()`, `Py_GetExecPrefix()`, `Py_GetProgramFullPath()`, `Py_GetPythonHome()` and `Py_GetProgramName()` functions now return `NULL` if called before `Py_Initialize()` (before Python is initialized). Use the new Python Initialization Configuration API to get the Python Path Configuration. (Contributed by Victor Stinner in bpo-42260.)

- `PyList_SET_ITEM()`, `PyTuple_SET_ITEM()` and `PyCell_SET()` macros can no longer be used as l-value or r-value. For example, `x = PyList_SET_ITEM(a, b, c)` and `PyList_SET_ITEM(a, b, c) = x` now fail with a compiler error. It prevents bugs like `if (PyList_SET_ITEM (a, b, c) < 0) ...` test. (Contributed by Zackery Spytz and Victor Stinner in bpo-30459.)

- The non-limited API files `odictobject.h`, `parser_interface.h`, `picklebufobject.h`, `pyarena.h`, `pyctype.h`, `pydebug.h`, `pyfpe.h`, and `pytime.h` have been moved to the `Include/cpython` directory. These files must not be included directly, as they are already included in `Python.h`; see Include Files. If they have been included directly, consider including `Python.h` instead. (Contributed by Nicholas Sim in bpo-35134.)

- Use the `Py_TPFLAGS_IMMUTABLETYPE` type flag to create immutable type objects. Do not rely on `Py_TPFLAGS_HEAPTYPE` to decide if a type object is mutable or not; check if `Py_TPFLAGS_IMMUTABLETYPE` is set instead. (Contributed by Victor Stinner and Erlend E. Aasland in bpo-43908.)

- The undocumented function `Py_FrozenMain` has been removed from the limited API. The function is mainly useful for custom builds of Python. (Contributed by Petr Viktorin in bpo-26241.)

### Obsolescence

- La fonction `PyUnicode_InternImmortal()` est maintenant obsolète et sera retirée dans Python 3.12 : utilisez plutôt `PyUnicode_InternInPlace()` (contribution de Victor Stinner dans bpo-41692).

### Retrait

- Retrait des fonctions `Py_UNICODE_str*` manipulant des chaînes `Py_UNICODE*` (contribution de Inada Naoki dans bpo-41123) :

  - `Py_UNICODE_strlen` : utilisez `PyUnicode_GetLength()` ou `PyUnicode_GET_LENGTH` ;

  - `Py_UNICODE_strcat` : utilisez `PyUnicode_CopyCharacters()` ou `PyUnicode_FromFormat()` ;

  - `Py_UNICODE_strcpy`, `Py_UNICODE_strncpy` : utilisez `PyUnicode_CopyCharacters()` ou `PyUnicode_Substring()` ;

  - `Py_UNICODE_strcmp` : utilisez `PyUnicode_Compare()` ;

  - `Py_UNICODE_strncmp` : utilisez `PyUnicode_Tailmatch()` ;

  - `Py_UNICODE_strchr`, `Py_UNICODE_strrchr` : utilisez `PyUnicode_FindChar()`.

- Retrait de `PyUnicode_GetMax()`. Vous devez migrer vers les nouvelles API de la PEP 393 (contribution de Inada Naoki dans bpo-41103).

- Retrait de `PyLong_FromUnicode()`. Vous devez migrer vers `PyLong_FromUnicodeObject()` (contribution de Inada Naoki dans bpo-41103).

- Retrait de `PyUnicode_AsUnicodeCopy()`. Vous devez utiliser `PyUnicode_AsUCS4Copy()` ou `PyUnicode_AsWideCharString()` (contribution de Inada Naoki dans bpo-41103).

- Retrait de la variable `_Py_CheckRecursionLimit` : elle a été remplacée par le champ `ceval.recursion_limit` de la structure `PyInterpreterState` (contribution de Victor Stinner dans bpo-41834).

- Retrait des macros non-documentées `Py_ALLOW_RECURSION` et `Py_END_ALLOW_RECURSION` et du champ `recursion_critical` de la structure `PyInterpreterState` (contribution de Serhiy Storchaka dans bpo-41936).

- Retrait de la fonction non-documentée `PyOS_InitInterrupts()`. L'initialisation de Python installe déjà les gestionnaires de signaux de façon implicite : voir `PyConfig.install_signal_handlers` (contribution de Victor Stinner dans bpo-41713).

- Retrait de la fonction `PyAST_Validate()`. Il n'est plus possible de construire un objet AST (type `mod_ty`) avec l'API C publique. La fonction était déjà retirée de l'API C limitée (PEP 384) (contribution de Victor Stinner dans bpo-43244).

- Retrait du fichier d'en-tête `symtable.h` et des fonctions non-documentées :

  - `PyST_GetScope()` ;

  - `PySymtable_Build()` ;

  - `PySymtable_BuildObject()` ;

  - `PySymtable_Free()` ;

  - `Py_SymtableString()` ;

  - `Py_SymtableStringObject()`.

  Par erreur, la fonction `Py_SymtableString()` faisait partie de l'ABI stable, mais elle ne pouvait pas être utilisée, car le fichier d'en-tête `symtable.h` était exclu de l'API C limitée.

  Utilisez plutôt le module Python `symtable` (contribution de Victor Stinner dans bpo-43244).

- Retrait de `PyOS_ReadlineFunctionPointer()` des fichiers d'en-tête de l'API C limitée et de `python3.dll`, la bibliothèque qui fournit l'ABI stable sur Windows. Étant donné que la fonction prend un `FILE*` en argument, la stabilité de son interface binaire-programme ne peut pas être garantie (contribution de Petr Viktorin dans bpo-43868).

- Retrait des fichiers d'en-tête `ast.h`, `asdl.h` et `Python-ast.h`. Ces fonctions étaient non-documentées et exclues de l'API C limitée. La majorité des noms définis dans ces fichiers d'en-tête n'avaient pas le préfixe `Py` et pouvaient ainsi causer des conflits de noms. Par exemple, `Python-ast.h` définit une macro `Yield` qui était en conflit avec le nom `Yield` utilisé dans le fichier d'en-tête `<winbase.h>` de Windows. Utilisez plutôt le module Python `ast` (contribution de Victor Stinner dans bpo-43244).

- Retrait des fonctions d'analyse syntaxique et de compilation qui utilisent le type `struct _mod` car l'API C publique pour manipuler les AST a été retirée :

  - `PyAST_Compile()` ;

  - `PyAST_CompileEx()` ;

  - `PyAST_CompileObject()` ;

  - `PyFuture_FromAST()` ;

  - `PyFuture_FromASTObject()` ;

  - `PyParser_ASTFromFile()` ;

  - `PyParser_ASTFromFileObject()` ;

  - `PyParser_ASTFromFilename()` ;

  - `PyParser_ASTFromString()` ;

  - `PyParser_ASTFromStringObject()`.

  Ces fonctions étaient non-documentées et exclues de l'API C limitée (contribution de Victor Stinner dans bpo-43244).

- Retrait du fichier d'en-tête `pyarena.h` et des fonctions :

  - `PyArena_New()` ;

  - `PyArena_Free()` ;

  - `PyArena_Malloc()` ;

  - `PyArena_AddPyObject()`.

  Ces fonctions étaient non-documentées et exclues de l'API C limitée ; elles n'étaient utilisées que par le compilateur dans l'implémentation interne (contribution de Victor Stinner dans bpo-43244).

- Retrait du champ `PyThreadState.use_tracing` pour optimiser Python (contribution de Mark Shannon dans bpo-43760).

## Notable security feature in 3.10.7

Converting between `int` and `str` in bases other than 2 (binary), 4, 8 (octal), 16 (hexadecimal), or 32 such as base 10 (decimal) now raises a `ValueError` if the number of digits in string form is above a limit to avoid potential denial of service attacks due to the algorithmic complexity. This is a mitigation for CVE-2020-10735. This limit can be configured or disabled by environment variable, command line flag, or `sys` APIs. See the integer string conversion length limitation documentation. The default limit is 4300 digits in string form.

## Notable security feature in 3.10.8

The deprecated `mailcap` module now refuses to inject unsafe text (filenames, MIME types, parameters) into shell commands. Instead of using such text, it will warn and act as if a match was not found (or for test commands, as if the test failed). (Contributed by Petr Viktorin in gh-98966.)

## Notable changes in 3.10.12

### tarfile

- The extraction methods in `tarfile`, and `shutil.unpack_archive()`, have a new a filter argument that allows limiting tar features than may be surprising or dangerous, such as creating files outside the destination directory. See Extraction filters for details. In Python 3.12, use without the filter argument will show a `DeprecationWarning`. In Python 3.14, the default will switch to `'data'`. (Contributed by Petr Viktorin in PEP 706.)