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

オープン
#124,089 コメント 5 件 リアクション 1 件 担当者 1 名 GitHub で見る

@sobolevn がすでに取り組んでいます。

2024年9月14日 から。

3.12 3.13 3.14 stdlib topic-typing type-bug
主要言語
Python
スター
77.2k
フォーク
35.9k
PR マージ指標
PR 指標を取得中

説明

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

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。