From 696a0e384d7a7e2902087b5c4400810b2fd169c6 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Mon, 18 Jul 2022 22:17:56 +0100 Subject: [PATCH 1/2] stubtest: fix false-positive error for Protocol `__init__`s --- mypy/stubtest.py | 3 +++ mypy/test/teststubtest.py | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mypy/stubtest.py b/mypy/stubtest.py index 044412299023..a40cb2cc712f 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -344,6 +344,9 @@ class SubClass(runtime): # type: ignore for m in cast(Any, vars)(runtime) if not is_probably_private(m) and m not in IGNORABLE_CLASS_DUNDERS ) + # Special-case the __init__ method for Protocols + if stub.is_protocol: + to_check.discard("__init__") for entry in sorted(to_check): mangled_entry = entry diff --git a/mypy/test/teststubtest.py b/mypy/test/teststubtest.py index 72944f44414c..40cce0dac076 100644 --- a/mypy/test/teststubtest.py +++ b/mypy/test/teststubtest.py @@ -1041,8 +1041,7 @@ def foo(self, x: int, y: bytes = ...) -> str: ... class X(Protocol): def foo(self, x: int, y: bytes = ...) -> str: ... """, - # TODO: this should not be an error, #12820 - error="X.__init__" + error=None ) @collect_cases From 337d7e3ac912f695b35c0adcc7155f50015da66e Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Tue, 19 Jul 2022 22:50:15 +0100 Subject: [PATCH 2/2] Add TODO, fix `__annotations__` bug --- mypy/stubtest.py | 6 ++++++ mypy/test/teststubtest.py | 2 ++ 2 files changed, 8 insertions(+) diff --git a/mypy/stubtest.py b/mypy/stubtest.py index a40cb2cc712f..b4447d798cdd 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -345,6 +345,11 @@ class SubClass(runtime): # type: ignore if not is_probably_private(m) and m not in IGNORABLE_CLASS_DUNDERS ) # Special-case the __init__ method for Protocols + # + # TODO: On Python <3.11, __init__ methods on Protocol classes + # are silently discarded and replaced. + # However, this is not the case on Python 3.11+. + # Ideally, we'd figure out a good way of validating Protocol __init__ methods on 3.11+. if stub.is_protocol: to_check.discard("__init__") @@ -1093,6 +1098,7 @@ def verify_typealias( { # Special attributes "__dict__", + "__annotations__", "__text_signature__", "__weakref__", "__del__", # Only ever called when an object is being deleted, who cares? diff --git a/mypy/test/teststubtest.py b/mypy/test/teststubtest.py index 40cce0dac076..197669714ad3 100644 --- a/mypy/test/teststubtest.py +++ b/mypy/test/teststubtest.py @@ -1033,12 +1033,14 @@ def test_protocol(self) -> Iterator[Case]: from typing_extensions import Protocol class X(Protocol): + bar: int def foo(self, x: int, y: bytes = ...) -> str: ... """, runtime=""" from typing_extensions import Protocol class X(Protocol): + bar: int def foo(self, x: int, y: bytes = ...) -> str: ... """, error=None