Skip to content

Commit 00f2b29

Browse files
authored
Improve record_imported_symbol() (#19924)
This has four improvements: * Skip placeholders, they are not guaranteed to have a correct `fullname`. * Skip nodes from `builtins`/`typing`, these don't add anything. * Don't use `rsplit(".")` on variables/functions recursively, always use enclosing class. * (Most importantly) add missing `maxsplit=1`.
1 parent 354bea6 commit 00f2b29

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

mypy/semanal.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6292,22 +6292,37 @@ def record_imported_symbol(self, sym: SymbolTableNode) -> None:
62926292
if sym.kind == LDEF or sym.node is None:
62936293
return
62946294
node = sym.node
6295-
if not node.fullname:
6295+
if isinstance(node, PlaceholderNode) or not node.fullname:
6296+
# This node is not ready yet.
62966297
return
6298+
if node.fullname.startswith(("builtins.", "typing.")):
6299+
# Skip dependencies on builtins/typing.
6300+
return
6301+
# Modules, classes, and type aliases store defining module directly.
62976302
if isinstance(node, MypyFile):
62986303
fullname = node.fullname
62996304
elif isinstance(node, TypeInfo):
63006305
fullname = node.module_name
63016306
elif isinstance(node, TypeAlias):
63026307
fullname = node.module
6303-
elif isinstance(node, (Var, FuncDef, OverloadedFuncDef)) and node.info:
6304-
fullname = node.info.module_name
6308+
elif isinstance(node, (Var, FuncDef, OverloadedFuncDef, Decorator)):
6309+
# For functions/variables infer defining module from enclosing class.
6310+
info = node.var.info if isinstance(node, Decorator) else node.info
6311+
if info:
6312+
fullname = info.module_name
6313+
else:
6314+
# global function/variable
6315+
fullname = node.fullname.rsplit(".", maxsplit=1)[0]
63056316
else:
6306-
fullname = node.fullname.rsplit(".")[0]
6317+
# Some nodes (currently only TypeVarLikeExpr subclasses) don't store
6318+
# module fullname explicitly, infer it from the node fullname iteratively.
6319+
# TODO: this is not 100% robust for type variables nested within a class
6320+
# with a name that matches name of a submodule.
6321+
fullname = node.fullname.rsplit(".", maxsplit=1)[0]
63076322
if fullname == self.cur_mod_id:
63086323
return
63096324
while "." in fullname and fullname not in self.modules:
6310-
fullname = fullname.rsplit(".")[0]
6325+
fullname = fullname.rsplit(".", maxsplit=1)[0]
63116326
if fullname != self.cur_mod_id:
63126327
self.cur_mod_node.module_refs.add(fullname)
63136328

0 commit comments

Comments
 (0)