Comme je l'ai remarqué aujourd'hui, le module d'inspection de Python 3.10 utilise maintenant typing.get_type_hints ()
pour interpréter les types. Le commit correspondant est iciest.
Cela semble être un correctif lié à l'évaluation retardée des annotations activées par défaut à partir de Python 3.10. Puisque les informations d'annotation de type contenues dans ʻobj .__ annotations__deviennent une chaîne de caractères, on peut juger qu'il est approprié de la laisser à
typing.get_type_hints (). Avec ce changement, les informations de type de ʻinspect.signature ()
, qui se référaient simplement à ʻobj .__ annotations__`, seront commutées vers le résultat de l'analyse qui va encore plus loin.
Par exemple, dans Python 3.9, l'argument de fonction hello ()
suivant name
est traité comme un type str
.
$ python3.9
Python 3.9.0 (default, Oct 24 2020, 15:41:29)
[Clang 11.0.3 (clang-1103.0.32.59)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def hello(name: str = None):
... print("Hello ", name)
...
>>> import inspect
>>> inspect.signature(hello)
<Signature (name: str = None)>
Par contre, en Python 3.10 (en cours de développement), il est considéré comme étant de type ʻOptional [str] `. Voyant que l'argument par défaut est «Aucun», il renvoie un meilleur type.
$ python3.10
Python 3.10.0a1+ (heads/master:805ef73, Oct 24 2020, 15:07:19)
[Clang 11.0.3 (clang-1103.0.32.59)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def hello(name: str = None):
... print("Hello ", name)
...
>>> import inspect
>>> inspect.signature(hello)
<Signature (name: Optional[str] = None)>
D'ailleurs, si le nom ne peut pas être résolu à l'exécution (par exemple, si typing.TYPE_CHECKING
n'est pas importé à l'exécution), ʻobj .__ signature__` est toujours référencé, donc le résultat de l'interprétation peut changer en fonction de l'annotation.
$ python3.10
Python 3.10.0a1+ (heads/master:805ef73, Oct 24 2020, 15:07:19)
[Clang 11.0.3 (clang-1103.0.32.59)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def hello(name: Unknown, age: int = None): pass
...
>>> import inspect
>>> inspect.signature(hello)
<Signature (name: 'Unknown', age: 'int' = None)>
Dans ce cas, le type ʻUnknown ne peut pas être résolu, donc le type de l'argument ʻage
n'est pas ʻOptional [int] , mais simplement ʻint
.
Recommended Posts