Skip to content

Commit 4a54894

Browse files
authored
Fix crash on class-level import in protocol definition (#14926)
Fixes #14889 Fix is straightforward. PEP 544 doesn't say anything about this, but IMO ignoring the import (i.e. not counting it as a member) is the most reasonable thing to do.
1 parent e07ccde commit 4a54894

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

mypy/nodes.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3083,7 +3083,7 @@ def protocol_members(self) -> list[str]:
30833083
for base in self.mro[:-1]: # we skip "object" since everyone implements it
30843084
if base.is_protocol:
30853085
for name, node in base.names.items():
3086-
if isinstance(node.node, (TypeAlias, TypeVarExpr)):
3086+
if isinstance(node.node, (TypeAlias, TypeVarExpr, MypyFile)):
30873087
# These are auxiliary definitions (and type aliases are prohibited).
30883088
continue
30893089
members.add(name)

test-data/unit/check-protocols.test

+24
Original file line numberDiff line numberDiff line change
@@ -3998,3 +3998,27 @@ TF = TypeVar("TF", bound=Foo)
39983998
def outer(cls: Type[TF]) -> TF:
39993999
reveal_type(test(cls)) # N: Revealed type is "TF`-1"
40004000
return cls()
4001+
4002+
[case testProtocolImportNotMember]
4003+
import m
4004+
import lib
4005+
4006+
class Bad:
4007+
x: int
4008+
class Good:
4009+
x: lib.C
4010+
4011+
x: m.P = Bad() # E: Incompatible types in assignment (expression has type "Bad", variable has type "P") \
4012+
# N: Following member(s) of "Bad" have conflicts: \
4013+
# N: x: expected "C", got "int"
4014+
x = Good()
4015+
4016+
[file m.py]
4017+
from typing import Protocol
4018+
4019+
class P(Protocol):
4020+
import lib
4021+
x: lib.C
4022+
4023+
[file lib.py]
4024+
class C: ...

0 commit comments

Comments
 (0)