# 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`

When printing `AttributeError`, `PyErr_Display()` will offer suggestions of similar attribute names in the object that the exception was raised from:

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

Notice this won't work if `PyErr_Display()` is not called to display the error which can happen if some other custom error display function is used. This is a common scenario in some REPLs like IPython.

#### `NameError`

When printing `NameError` raised by the interpreter, `PyErr_Display()` will offer suggestions of similar variable names in the function that the exception was raised from:

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

Notice this won't work if `PyErr_Display()` is not called to display the error, which can happen if some other custom error display function is used. This is a common scenario in some REPLs like 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

If you are using classes to structure your data, you can use as a pattern the class name followed by an argument list resembling a constructor. This pattern has the ability to capture instance attributes into variables:

    class Point:
        def __init__(self, x, y):
            self.x = x
            self.y = y

    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

      color = Color.GREEN
      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

The default encoding of `TextIOWrapper` and `open()` is platform and locale dependent. Since UTF-8 is used on most Unix platforms, omitting `encoding` option when opening UTF-8 files (e.g. JSON, YAML, TOML, Markdown) is a very common bug. For example:

    # 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

A new type union operator was introduced which enables the syntax `X | Y`. This provides a cleaner way of expressing 'either type X or type Y' instead of using `typing.Union`, especially in type hints.

In previous versions of Python, to apply a type hint for functions accepting arguments of multiple types, `typing.Union` was used:

    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

Now the `typing` module has a special value `TypeAlias` which lets you declare type aliases more explicitly:

    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` has been added to the `typing` module to annotate type guard functions and improve information provided to static type checkers during type narrowing. For more information, please see `TypeGuard`'s documentation, and 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).

- Static methods (`@staticmethod`) and class methods (`@classmethod`) now inherit the method attributes (`__module__`, `__name__`, `__qualname__`, `__doc__`, `__annotations__`) and have a new `__wrapped__` attribute. Moreover, static methods are now callable as regular functions. (Contributed by Victor Stinner in 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`

Add missing `connect_accepted_socket()` method. (Contributed by Alex Grönholm in 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`

Add `clearBreakpoints()` to reset all set breakpoints. (Contributed by Irit Katriel in 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).

Add `AsyncContextDecorator`, for supporting usage of async context managers as decorators.

### `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()` now returns `TextIOWrapper` object when mode is "r" and file is compressed, like uncompressed files. (Contributed by Inada Naoki in 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.

Applique la coloration syntaxique aux fichiers `.pyi` (contribution d'Alex Waygood et de Terry Jan Reedy dans 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).

importlib.metadata entry points now provide a nicer experience for selecting entry points by group and name through a new importlib.metadata.EntryPoints class. See the Compatibility Note in the docs for more info on the deprecation and usage.

Added importlib.metadata.packages_distributions() for resolving top-level Python modules and packages to their importlib.metadata.Distribution.

### `inspect`

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

Add `inspect.get_annotations()`, which safely computes the annotations defined on an object. It works around the quirks of accessing the annotations on various types of objects, and makes very few assumptions about the object it examines. `inspect.get_annotations()` can also correctly un-stringize stringized annotations. `inspect.get_annotations()` is now considered best practice for accessing the annotations dict defined on any Python object; for more information on best practices for working with annotations, please see Bonnes pratiques concernant les annotations. Relatedly, `inspect.signature()`, `inspect.Signature.from_callable()`, and `inspect.Signature.from_function()` now call `inspect.get_annotations()` to retrieve annotations. This means `inspect.signature()` and `inspect.Signature.from_callable()` can also now un-stringize stringized annotations. (Contributed by Larry Hastings in 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`

Add `os.cpu_count()` support for VxWorks RTOS. (Contributed by Peixing Xin in 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).

Add `os.splice()` that allows to move data between two file descriptors without copying between kernel address space and user address space, where one of the file descriptors must refer to a pipe. (Contributed by Pablo Galindo in 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.)

Add `Path.hardlink_to` method that supersedes `link_to()`. The new method has the same argument order as `symlink_to()`. (Contributed by Barney Gale in 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`

Add audit events for `connect()`, `enable_load_extension()`, and `load_extension()`. (Contributed by Erlend E. Aasland in 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`

Python versions earlier than Python 3.10 allowed using both `;` and `&` as query parameter separators in `urllib.parse.parse_qs()` and `urllib.parse.parse_qsl()`. Due to security concerns, and to conform with newer W3C recommendations, this has been changed to allow only a single separator key, with `&` as the default. This change also affects `cgi.parse()` and `cgi.parse_multipart()` as they use the affected functions internally. For more details, please see their respective documentation. (Contributed by Adam Goldschmidt, Senthil Kumaran and Ken Jin in 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.)

- Starting in this release, there will be a concerted effort to begin cleaning up old import semantics that were kept for Python 2.7 compatibility. Specifically, `find_loader()`/`find_module()` (superseded by `find_spec()`), `load_module()` (superseded by `exec_module()`), `module_repr()` (which the import system takes care of for you), the `__package__` attribute (superseded by `__spec__.parent`), the `__loader__` attribute (superseded by `__spec__.loader`), and the `__cached__` attribute (superseded by `__spec__.cached`) will slowly be removed (as well as other classes and methods in `importlib`). `ImportWarning` and/or `DeprecationWarning` will be raised as appropriate to help identify code which needs updating during this transition.

- 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()` has been deprecated in preference for `exec_module()`. (Contributed by Brett Cannon in 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).

- The use of `importlib.abc.MetaPathFinder.find_module()` and `importlib.abc.PathEntryFinder.find_module()` by the import system now trigger an `ImportWarning` as `importlib.abc.MetaPathFinder.find_spec()` and `importlib.abc.PathEntryFinder.find_spec()` are preferred, respectively. You can use `importlib.util.spec_from_loader()` to help in porting. (Contributed by Brett Cannon in bpo-42134.)

- The use of `importlib.abc.PathEntryFinder.find_loader()` by the import system now triggers an `ImportWarning` as `importlib.abc.PathEntryFinder.find_spec()` is preferred. You can use `importlib.util.spec_from_loader()` to help in porting. (Contributed by Brett Cannon in bpo-43672.)

- The various implementations of `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()`, `importlib.abc.MetaPathFinder.find_module()` ), `importlib.abc.PathEntryFinder.find_module()` ( `importlib.machinery.FileFinder.find_module()` ), and `importlib.abc.PathEntryFinder.find_loader()` ( `importlib.machinery.FileFinder.find_loader()` ) now raise `DeprecationWarning` and are slated for removal in Python 3.12 (previously they were documented as deprecated in Python 3.4). (Contributed by Brett Cannon in bpo-42135.)

- `importlib.abc.Finder` is deprecated (including its sole method, `find_module()`). Both `importlib.abc.MetaPathFinder` and `importlib.abc.PathEntryFinder` no longer inherit from the class. Users should inherit from one of these two classes as appropriate instead. (Contributed by Brett Cannon in bpo-42135.)

- The deprecations of `imp`, `importlib.find_loader()`, `importlib.util.set_package_wrapper()`, `importlib.util.set_loader_wrapper()`, `importlib.util.module_for_loader()`, `pkgutil.ImpImporter`, and `pkgutil.ImpLoader` have all been updated to list Python 3.12 as the slated version of removal (they began raising `DeprecationWarning` in previous versions of Python). (Contributed by Brett Cannon in bpo-43720.)

- The import system now uses the `__spec__` attribute on modules before falling back on `module_repr()` for a module's `__repr__()` method. Removal of the use of `module_repr()` is scheduled for Python 3.12. (Contributed by Brett Cannon in bpo-42137.)

- `importlib.abc.Loader.module_repr()`, `importlib.machinery.FrozenLoader.module_repr()`, and `importlib.machinery.BuiltinLoader.module_repr()` are deprecated and slated for removal in Python 3.12. (Contributed by Brett Cannon in 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()` is deprecated and slated for removal in Python 3.12. Use `pathlib.Path.hardlink_to()` instead. (Contributed by Barney Gale in 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`, and `OP_NO_TLSv1_3` are replaced by `minimum_version` and `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()` is replaced by `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).

- The threading debug (`PYTHONTHREADDEBUG` environment variable) is deprecated in Python 3.10 and will be removed in Python 3.12. This feature requires a debug build of Python. (Contributed by Victor Stinner in 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.)