@@ -150,11 +150,13 @@ def __init__(self, function_names_to_find: set[str]) -> None:
150150 self .imported_modules : set [str ] = set ()
151151 self .has_dynamic_imports : bool = False
152152 self .wildcard_modules : set [str ] = set ()
153+ # Track aliases: alias_name -> original_name
154+ self .alias_mapping : dict [str , str ] = {}
153155
154156 # Precompute function_names for prefix search
155157 # For prefix match, store mapping from prefix-root to candidates for O(1) matching
156158 self ._exact_names = function_names_to_find
157- self ._prefix_roots = {}
159+ self ._prefix_roots : dict [ str , list [ str ]] = {}
158160 for name in function_names_to_find :
159161 if "." in name :
160162 root = name .split ("." , 1 )[0 ]
@@ -206,6 +208,9 @@ def visit_ImportFrom(self, node: ast.ImportFrom) -> None:
206208 imported_name = alias .asname if alias .asname else aname
207209 self .imported_modules .add (imported_name )
208210
211+ if alias .asname :
212+ self .alias_mapping [imported_name ] = aname
213+
209214 # Fast check for dynamic import
210215 if mod == "importlib" and aname == "import_module" :
211216 self .has_dynamic_imports = True
@@ -222,7 +227,6 @@ def visit_ImportFrom(self, node: ast.ImportFrom) -> None:
222227 self .found_qualified_name = qname
223228 return
224229
225- # Fast prefix match: only for relevant roots
226230 prefix = qname + "."
227231 # Only bother if one of the targets startswith the prefix-root
228232 candidates = proots .get (qname , ())
@@ -247,6 +251,18 @@ def visit_Attribute(self, node: ast.Attribute) -> None:
247251 self .found_qualified_name = node .attr
248252 return
249253
254+ if isinstance (node .value , ast .Name ) and node .value .id in self .imported_modules :
255+ for target_func in self .function_names_to_find :
256+ if "." in target_func :
257+ class_name , method_name = target_func .rsplit ("." , 1 )
258+ if node .attr == method_name :
259+ imported_name = node .value .id
260+ original_name = self .alias_mapping .get (imported_name , imported_name )
261+ if original_name == class_name :
262+ self .found_any_target_function = True
263+ self .found_qualified_name = target_func
264+ return
265+
250266 # Check if this is accessing a target function through a dynamically imported module
251267 # Only if we've detected dynamic imports are being used
252268 if self .has_dynamic_imports and node .attr in self .function_names_to_find :
0 commit comments