python / python/cpython

Calling typing.get_type_hints with a class or instance method with PEP 695 type parameters fails if PEP 563 is enabled

Ouverte
#124,089 5 commentaires 1 réaction 1 personne assignée Voir sur GitHub

@sobolevn y travaille déjà.

Depuis le 14/9/2024.

3.12 3.13 3.14 stdlib topic-typing type-bug
Langage dominant
Python
Étoiles
77.2k
Forks
35.9k
Métriques de merge des PR
Métriques de PR en attente

Description

Bug report

Bug description:
from __future__ import annotations

import typing

class Test[M]:
    def foo(self, arg: M) -> None:
        pass

print(typing.get_type_hints(Test.foo))
$ python3.12 pep_695_pep_563.py 
Traceback (most recent call last):
  File "/run/host/tmp/test/pep_695_pep_563.py", line 9, in <module>
    print(typing.get_type_hints(Test.foo))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/typing.py", line 2310, in get_type_hints
    hints[name] = _eval_type(value, globalns, localns, type_params)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/typing.py", line 415, in _eval_type
    return t._evaluate(globalns, localns, type_params, recursive_guard=recursive_guard)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/typing.py", line 947, in _evaluate
    eval(self.__forward_code__, globalns, localns),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<string>", line 1, in <module>
NameError: name 'M' is not defined

This seems very similar to #114053, but with class methods (or instance methods, the result is the same) instead of classes themselves.

Removing the from __future__ import annotations import works fine:

import typing

class Test[M]:
    def foo(self, arg: M) -> None:
        pass

print(typing.get_type_hints(Test.foo))
$ python3.12 pep_695_no_563.py 
{'arg': M, 'return': <class 'NoneType'>}

Using the pre PEP-695 syntax, with or without from __future__ import annotations, works fine as well:

from __future__ import annotations

import typing

M = typing.TypeVar("M")

class Test(typing.Generic[M]):
    def foo(self, arg: M) -> None:
        pass

print(typing.get_type_hints(Test.foo))
$ python3.12 no_695_pep_563.py 
{'arg': ~M, 'return': <class 'NoneType'>}
import typing

M = typing.TypeVar("M")

class Test(typing.Generic[M]):
    def foo(self, arg: M) -> None:
        pass

print(typing.get_type_hints(Test.foo))
$ python3.12 no_695_no_563.py 
{'arg': ~M, 'return': <class 'NoneType'>}

This happens on both 3.12.5 and 3.13.0rc2

CPython versions tested on:

3.12, 3.13

Operating systems tested on:

Linux

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.