1313
1414from pydantic import BaseModel , Field
1515
16+ from designer_plugin .d3sdk .builtin_modules import SUPPORTED_MODULES
17+
1618
1719###############################################################################
1820# Package info models
@@ -22,7 +24,9 @@ class ImportAlias(BaseModel):
2224 Mirrors the structure of ast.alias for Pydantic compatibility.
2325 """
2426
25- name : str = Field (description = "The imported name (e.g., 'Path' in 'from pathlib import Path')" )
27+ name : str = Field (
28+ description = "The imported name (e.g., 'Path' in 'from pathlib import Path')"
29+ )
2630 asname : str | None = Field (
2731 default = None ,
2832 description = "The alias (e.g., 'np' in 'import numpy as np')" ,
@@ -54,15 +58,11 @@ def to_import_statement(self) -> str:
5458 if self .methods :
5559 node = ast .ImportFrom (
5660 module = self .package ,
57- names = [
58- ast .alias (name = m .name , asname = m .asname ) for m in self .methods
59- ],
61+ names = [ast .alias (name = m .name , asname = m .asname ) for m in self .methods ],
6062 level = 0 ,
6163 )
6264 else :
63- node = ast .Import (
64- names = [ast .alias (name = self .package , asname = self .alias )]
65- )
65+ node = ast .Import (names = [ast .alias (name = self .package , asname = self .alias )])
6666 return ast .unparse (node )
6767
6868
@@ -453,21 +453,17 @@ def _collect_used_names(func_node: ast.FunctionDef | ast.AsyncFunctionDef) -> se
453453 return names
454454
455455
456- # Shared exclusion constants
457- _EXCLUDED_PACKAGES : set [str ] = {"d3blobgen" , "typing" }
458-
459-
460456def _is_type_checking_block (node : ast .If ) -> bool :
461457 """Check if an if statement is ``if TYPE_CHECKING:``."""
462458 return isinstance (node .test , ast .Name ) and node .test .id == "TYPE_CHECKING"
463459
464460
465- def _is_excluded_package (module_name : str ) -> bool :
466- """Check if a module name matches any excluded package."""
467- return any ( excluded in module_name for excluded in _EXCLUDED_PACKAGES )
461+ def _is_builtin_package (module_name : str ) -> bool :
462+ """Check if a module name matches python builtin package."""
463+ return module_name in SUPPORTED_MODULES
468464
469465
470- @functools .lru_cache ( maxsize = None )
466+ @functools .cache
471467def _get_module_ast (module : types .ModuleType ) -> ast .Module | None :
472468 """Return the parsed AST for *module*, cached by module identity."""
473469 try :
@@ -526,8 +522,9 @@ def find_imports_for_function(func: Callable[..., Any]) -> list[PackageInfo]:
526522
527523 if isinstance (node , ast .Import ):
528524 for alias in node .names :
529- if _is_excluded_package (alias .name ):
525+ if not _is_builtin_package (alias .name ):
530526 continue
527+
531528 # The name used in code is the alias if present, otherwise the module name
532529 effective_name = alias .asname if alias .asname else alias .name
533530 if effective_name in used_names :
@@ -541,7 +538,7 @@ def find_imports_for_function(func: Callable[..., Any]) -> list[PackageInfo]:
541538 elif isinstance (node , ast .ImportFrom ):
542539 if not node .module :
543540 continue
544- if _is_excluded_package (node .module ):
541+ if not _is_builtin_package (node .module ):
545542 continue
546543
547544 # Filter to only methods actually used by the function
0 commit comments