MCPcopy Index your code
hub / github.com/python/mypy / lookup_fully_qualified

Function lookup_fully_qualified

mypy/lookup.py:13–68  ·  view source on GitHub ↗

Find a symbol using it fully qualified name. The algorithm has two steps: first we try splitting the name on '.' to find the module, then iteratively look for each next chunk after a '.' (e.g. for nested classes). This function should *not* be used to find a module. Those should be

(
    name: str, modules: dict[str, MypyFile], *, raise_on_missing: bool = False
)

Source from the content-addressed store, hash-verified

11
12
13def lookup_fully_qualified(
14 name: str, modules: dict[str, MypyFile], *, raise_on_missing: bool = False
15) -> SymbolTableNode | None:
16 """Find a symbol using it fully qualified name.
17
18 The algorithm has two steps: first we try splitting the name on '.' to find
19 the module, then iteratively look for each next chunk after a '.' (e.g. for
20 nested classes).
21
22 This function should *not* be used to find a module. Those should be looked
23 in the modules dictionary.
24 """
25 # 1. Exclude the names of ad hoc instance intersections from step 2.
26 i = name.find("<subclass ")
27 head = name if i == -1 else name[:i]
28 rest = []
29 # 2. Find a module tree in modules dictionary.
30 while True:
31 if "." not in head:
32 if raise_on_missing:
33 assert "." in head, f"Cannot find module for {name}"
34 return None
35 # TODO: this logic is not correct as it confuses a submodule and a local symbol.
36 # A potential solution may be to use format like pkg.mod:Cls.method for fullname,
37 # but this is a relatively big change.
38 head, tail = head.rsplit(".", maxsplit=1)
39 rest.append(tail)
40 mod = modules.get(head)
41 if mod is not None:
42 break
43 names = mod.names
44 # 3. Find the symbol in the module tree.
45 if not rest:
46 # Looks like a module, don't use this to avoid confusions.
47 if raise_on_missing:
48 assert rest, f"Cannot find {name}, got a module symbol"
49 return None
50 if i != -1:
51 rest[0] += name[i:]
52 while True:
53 key = rest.pop()
54 if key not in names:
55 if raise_on_missing:
56 assert key in names, f"Cannot find component {key!r} for {name!r}"
57 return None
58 stnode = names[key]
59 if not rest:
60 return stnode
61 node = stnode.node
62 # In fine-grained mode, could be a cross-reference to a deleted module
63 # or a Var made up for a missing module.
64 if not isinstance(node, TypeInfo):
65 if raise_on_missing:
66 assert node, f"Cannot find {name}"
67 return None
68 names = node.names
69
70

Callers 6

resolve_cross_refMethod · 0.90
visit_typeddict_typeMethod · 0.90

Calls 6

isinstanceFunction · 0.85
findMethod · 0.80
rsplitMethod · 0.80
appendMethod · 0.80
getMethod · 0.45
popMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…