Skip to content

Commit 2d3a1bf

Browse files
xhochymsullivan
authored andcommitted
Fix module alias as instance attribute (#8259)
Fixes #4291
1 parent 4f3c9cd commit 2d3a1bf

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

mypy/semanal.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -3120,21 +3120,30 @@ def process_module_assignment(self, lvals: List[Lvalue], rval: Expression,
31203120
rnode = self.lookup_type_node(rval)
31213121
if rnode and isinstance(rnode.node, MypyFile):
31223122
for lval in lvals:
3123-
if not isinstance(lval, NameExpr):
3123+
if not isinstance(lval, RefExpr):
31243124
continue
31253125
# respect explicitly annotated type
31263126
if (isinstance(lval.node, Var) and lval.node.type is not None):
31273127
continue
3128-
lnode = self.current_symbol_table().get(lval.name)
3128+
3129+
# We can handle these assignments to locals and to self
3130+
if isinstance(lval, NameExpr):
3131+
lnode = self.current_symbol_table().get(lval.name)
3132+
elif isinstance(lval, MemberExpr) and self.is_self_member_ref(lval):
3133+
assert self.type is not None
3134+
lnode = self.type.names.get(lval.name)
3135+
else:
3136+
continue
3137+
31293138
if lnode:
31303139
if isinstance(lnode.node, MypyFile) and lnode.node is not rnode.node:
3140+
assert isinstance(lval, (NameExpr, MemberExpr))
31313141
self.fail(
31323142
"Cannot assign multiple modules to name '{}' "
31333143
"without explicit 'types.ModuleType' annotation".format(lval.name),
31343144
ctx)
31353145
# never create module alias except on initial var definition
31363146
elif lval.is_inferred_def:
3137-
lnode.kind = self.current_symbol_kind()
31383147
assert rnode.node is not None
31393148
lnode.node = rnode.node
31403149

test-data/unit/check-basic.test

+26
Original file line numberDiff line numberDiff line change
@@ -474,3 +474,29 @@ from typing import Any
474474
def f() -> object:
475475
x: Any = 1
476476
return x
477+
478+
[case testImportModuleAsClassMember]
479+
import test
480+
481+
class A:
482+
def __init__(self) -> None:
483+
self.test = test
484+
485+
def __call__(self) -> None:
486+
self.test.foo("Message")
487+
488+
[file test.py]
489+
def foo(s: str) -> None: ...
490+
491+
[case testLocalImportModuleAsClassMember]
492+
class A:
493+
def __init__(self) -> None:
494+
import test
495+
496+
self.test = test
497+
498+
def __call__(self) -> None:
499+
self.test.foo("Message")
500+
501+
[file test.py]
502+
def foo(s: str) -> None: ...

0 commit comments

Comments
 (0)