Skip to content

Commit

Permalink
Fix crash on class-level import in protocol definition (#14926)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ilevkivskyi authored Mar 20, 2023
1 parent e07ccde commit 4a54894
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
2 changes: 1 addition & 1 deletion mypy/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3083,7 +3083,7 @@ def protocol_members(self) -> list[str]:
for base in self.mro[:-1]: # we skip "object" since everyone implements it
if base.is_protocol:
for name, node in base.names.items():
if isinstance(node.node, (TypeAlias, TypeVarExpr)):
if isinstance(node.node, (TypeAlias, TypeVarExpr, MypyFile)):
# These are auxiliary definitions (and type aliases are prohibited).
continue
members.add(name)
Expand Down
24 changes: 24 additions & 0 deletions test-data/unit/check-protocols.test
Original file line number Diff line number Diff line change
Expand Up @@ -3998,3 +3998,27 @@ TF = TypeVar("TF", bound=Foo)
def outer(cls: Type[TF]) -> TF:
reveal_type(test(cls)) # N: Revealed type is "TF`-1"
return cls()

[case testProtocolImportNotMember]
import m
import lib

class Bad:
x: int
class Good:
x: lib.C

x: m.P = Bad() # E: Incompatible types in assignment (expression has type "Bad", variable has type "P") \
# N: Following member(s) of "Bad" have conflicts: \
# N: x: expected "C", got "int"
x = Good()

[file m.py]
from typing import Protocol

class P(Protocol):
import lib
x: lib.C

[file lib.py]
class C: ...

0 comments on commit 4a54894

Please sign in to comment.