diff --git a/mypy/stubtest.py b/mypy/stubtest.py index ac0378cc5468..a3292178f0f4 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -700,6 +700,10 @@ def verify_typeinfo( to_check.discard("__init__") if is_runtime_typeddict: to_check.discard("__new__") + # PEP 695 generic syntax (class Foo[T]: ...) implicitly provides __class_getitem__ + # at runtime, so don't require an explicit stub definition. + if stub.defn.type_args is not None: + to_check.discard("__class_getitem__") for entry in sorted(to_check): mangled_entry = entry diff --git a/mypy/test/teststubtest.py b/mypy/test/teststubtest.py index ada69fc6e47c..b467079a2378 100644 --- a/mypy/test/teststubtest.py +++ b/mypy/test/teststubtest.py @@ -1825,6 +1825,19 @@ def test_dunders(self) -> Iterator[Case]: runtime="class D:\n def __class_getitem__(cls, type): ...", error=None, ) + if sys.version_info >= (3, 12): + # PEP 695 generic syntax implicitly provides __class_getitem__ at runtime + yield Case( + stub="class D2[T]: ...", + runtime="class D2:\n def __class_getitem__(cls, _): return cls", + error=None, + ) + # Non-generic stub still reports missing __class_getitem__ + yield Case( + stub="class D3: ...", + runtime="class D3:\n def __class_getitem__(cls, _): return cls", + error="D3.__class_getitem__", + ) yield Case( stub="class E:\n def __getitem__(self, item: object) -> object: ...", runtime="class E:\n def __getitem__(self, item: object, /) -> object: ...",