hbllmutils.meta.code.imp
Module for analyzing and extracting import statements from Python source code.
This module provides comprehensive functionality to parse Python code and extract all import statements, including both regular imports and from-imports. It uses the Abstract Syntax Tree (AST) to analyze the code structure and collect detailed import information with position tracking.
The module contains the following main components:
ImportStatement- Represents regular import statements (e.g.,import os)FromImportStatement- Represents from-import statements (e.g.,from typing import List)ImportVisitor- AST visitor for collecting import statementsanalyze_imports()- Main function for extracting imports from code text
Key Features:
Support for both absolute and relative imports
Wildcard import detection (
from module import *)Import alias tracking
Source location information (line number and column offset)
Module classification (builtin, standard library, third-party)
PyPI package popularity checking for filtering
Note
This module requires the hbutils package for reflection utilities
and depends on sibling modules for PyPI information retrieval.
Warning
The module uses dynamic import mechanisms which may have security implications when analyzing untrusted code.
Example:
>>> code = '''
... import os
... import sys as system
... from typing import List, Dict
... from collections import *
... '''
>>> imports = analyze_imports(code)
>>> len(imports)
4
>>> print(imports[0])
import os
>>> print(imports[2])
from typing import List
>>> imports[3].is_wildcard
True
>>>
>>> # Check if imports should be ignored based on popularity
>>> stmt = ImportStatement(module='requests', line=1, col_offset=0)
>>> stmt.check_ignore_or_not(min_last_month_downloads=1000000)
True
ImportStatementTyping
- hbllmutils.meta.code.imp.ImportStatementTyping
Type alias for either ImportStatement or FromImportStatement.
This type alias is used throughout the module to represent any kind of import statement, providing flexibility in function signatures and return types.
Example:
>>> def process_import(stmt: ImportStatementTyping) -> str: ... return str(stmt) >>> >>> stmt1 = ImportStatement(module='os') >>> stmt2 = FromImportStatement(module='typing', name='List', level=0) >>> process_import(stmt1) 'import os' >>> process_import(stmt2) 'from typing import List'
alias of
ImportStatement|FromImportStatement
ImportStatement
- class hbllmutils.meta.code.imp.ImportStatement(module: str, alias: str | None = None, line: int = 0, col_offset: int = 0)[source]
Data class representing a regular import statement.
This class stores information about an import statement of the form
import moduleorimport module as alias. It provides utilities for analyzing the import and determining whether it should be included in documentation or analysis based on module popularity and type.- Parameters:
module (str) – The name of the module being imported
alias (Optional[str]) – The alias name for the imported module, if any
line (int) – The line number where the import statement appears
col_offset (int) – The column offset where the import statement starts
- Variables:
module (str) – The full module path being imported
alias (Optional[str]) – Optional alias for the imported module
line (int) – Line number in source code
col_offset (int) – Column offset in source code
Example:
>>> stmt = ImportStatement(module='os', alias='operating_system', line=1, col_offset=0) >>> print(stmt) import os as operating_system >>> stmt.root_module 'os' >>> >>> # Nested module import >>> stmt = ImportStatement(module='os.path', line=2, col_offset=0) >>> stmt.root_module 'os' >>> print(stmt) import os.path
- __str__() str[source]
Return a Python-readable representation of the import statement.
Constructs a valid Python import statement string that includes the module name and optional alias.
- Returns:
A string representation of the import statement
- Return type:
str
Example:
>>> stmt = ImportStatement(module='os', alias='operating_system') >>> str(stmt) 'import os as operating_system' >>> stmt = ImportStatement(module='sys') >>> str(stmt) 'import sys'
- check_ignore_or_not(min_last_month_downloads: int = 1000000, ignore_modules: Iterable[str] | None = None, no_ignore_modules: Iterable[str] | None = None) bool[source]
Determine whether this import should be ignored in analysis or documentation.
This method checks various criteria to decide if an import statement should be excluded from analysis, such as:
Module popularity (based on PyPI download statistics)
Module type (standard library vs third-party)
Explicit inclusion in no-ignore list
- Parameters:
min_last_month_downloads (int, optional) – Minimum monthly download threshold for considering a package as “hot” and ignorable, defaults to 1000000
ignore_modules (Optional[Iterable[str]], optional) – Iterable of module names that should always be ignored
no_ignore_modules (Optional[Iterable[str]], optional) – Iterable of module names that should never be ignored regardless of other criteria
- Returns:
True if the import should be ignored, False if it should be included
- Return type:
bool
Note
The logic for ignoring imports:
Modules in
ignore_modulesare always ignoredModules in
no_ignore_modulesare never ignoredUnknown/unimportable modules are ignored
Standard library modules are ignored
Popular third-party packages (hot projects) are ignored
Less popular third-party packages are not ignored
Example:
>>> stmt = ImportStatement(module='requests', line=1, col_offset=0) >>> # Popular package, should be ignored >>> stmt.check_ignore_or_not(min_last_month_downloads=1000000) True >>> >>> # Force inclusion with no_ignore_modules >>> stmt.check_ignore_or_not(no_ignore_modules={'requests'}) False >>> >>> # Standard library module >>> stmt = ImportStatement(module='os', line=1, col_offset=0) >>> stmt.check_ignore_or_not() True
- property module_file: str
Get the source code file path of the imported module.
This property attempts to locate and return the file path where the module’s source code is defined. It uses dynamic import to resolve the module location.
- Returns:
The file path of the module’s source code
- Return type:
str
- Raises:
TypeError – If the module is a built-in module without a source file
ImportError – If the module cannot be imported
Warning
This property performs dynamic imports which may have side effects if the module executes code at import time.
Example:
>>> stmt = ImportStatement(module='os') >>> stmt.module_file '/usr/lib/python3.x/os.py'
- property root_module: str
Get the root module name from a potentially nested module path.
Extracts the top-level module name from a dotted module path. For example, for
import os.path, this returns'os'instead of'os.path'.- Returns:
The root module name
- Return type:
str
Example:
>>> stmt = ImportStatement(module='os.path.join') >>> stmt.root_module 'os' >>> stmt = ImportStatement(module='numpy') >>> stmt.root_module 'numpy'
FromImportStatement
- class hbllmutils.meta.code.imp.FromImportStatement(module: str, name: str, alias: str | None = None, level: int = 0, line: int = 0, col_offset: int = 0)[source]
Data class representing a from-import statement.
This class stores information about an import statement of the form
from module import nameorfrom module import name as alias. It supports both absolute and relative imports, as well as wildcard imports.- Parameters:
module (str) – The name of the module to import from
name (str) – The name of the object being imported (can be ‘*’ for wildcard imports)
alias (Optional[str]) – The alias name for the imported object, if any
level (int) – The level of relative import (0 for absolute, 1+ for relative)
line (int) – The line number where the import statement appears
col_offset (int) – The column offset where the import statement starts
- Variables:
module (str) – Module path to import from
name (str) – Name of the imported object or ‘*’
alias (Optional[str]) – Optional alias for the imported name
level (int) – Relative import level (0=absolute, 1+=relative)
line (int) – Line number in source code
col_offset (int) – Column offset in source code
Example:
>>> stmt = FromImportStatement(module='typing', name='List', alias=None, level=0, line=1, col_offset=0) >>> print(stmt) from typing import List >>> >>> # Wildcard import >>> stmt = FromImportStatement(module='collections', name='*', level=0) >>> print(stmt) from collections import * >>> stmt.is_wildcard True >>> >>> # Relative import >>> stmt = FromImportStatement(module='module', name='func', level=2) >>> print(stmt) from ..module import func >>> stmt.is_relative True
- __str__() str[source]
Return a Python-readable representation of the from-import statement.
This method constructs a string representation that includes relative import dots, module path, imported name, and optional alias. It correctly handles all import variations including relative imports and wildcards.
- Returns:
A string representation of the from-import statement
- Return type:
str
Example:
>>> stmt = FromImportStatement(module='typing', name='List', level=0) >>> str(stmt) 'from typing import List' >>> >>> # With alias >>> stmt = FromImportStatement(module='typing', name='Dict', alias='D', level=0) >>> str(stmt) 'from typing import Dict as D' >>> >>> # Relative import >>> stmt = FromImportStatement(module='module', name='func', level=2) >>> str(stmt) 'from ..module import func' >>> >>> # Wildcard import (no alias allowed) >>> stmt = FromImportStatement(module='collections', name='*', level=0) >>> str(stmt) 'from collections import *'
- check_ignore_or_not(min_last_month_downloads: int = 1000000, ignore_modules: Iterable[str] | None = None, no_ignore_modules: Iterable[str] | None = None) bool[source]
Determine whether this from-import should be ignored in analysis or documentation.
This method checks various criteria to decide if a from-import statement should be excluded from analysis. The logic differs from regular imports in that relative imports are never ignored since they refer to project-internal modules.
- Parameters:
min_last_month_downloads (int, optional) – Minimum monthly download threshold for considering a package as “hot” and ignorable, defaults to 1000000
ignore_modules (Optional[Iterable[str]], optional) – Iterable of module names that should always be ignored
no_ignore_modules (Optional[Iterable[str]], optional) – Iterable of module names that should never be ignored regardless of other criteria
- Returns:
True if the import should be ignored, False if it should be included
- Return type:
bool
Note
The logic for ignoring from-imports:
Relative imports are never ignored (they’re project-internal)
Modules in
ignore_modulesare always ignoredModules in
no_ignore_modulesare never ignoredUnknown/unimportable modules are ignored
Standard library modules are ignored
Popular third-party packages (hot projects) are ignored
Less popular third-party packages are not ignored
Example:
>>> # Relative import - never ignored >>> stmt = FromImportStatement(module='module', name='func', level=1) >>> stmt.check_ignore_or_not() False >>> >>> # Popular package - should be ignored >>> stmt = FromImportStatement(module='requests', name='get', level=0) >>> stmt.check_ignore_or_not(min_last_month_downloads=1000000) True >>> >>> # Force inclusion with no_ignore_modules >>> stmt.check_ignore_or_not(no_ignore_modules={'requests'}) False >>> >>> # Standard library module >>> stmt = FromImportStatement(module='os', name='path', level=0) >>> stmt.check_ignore_or_not() True
- property is_relative: bool
Check if this is a relative import statement.
A relative import is one that uses dots to indicate the current and parent packages (e.g.,
from . import moduleorfrom ..package import func), or has no module specified which implies the current package.- Returns:
True if this is a relative import, False otherwise
- Return type:
bool
Example:
>>> # Absolute import >>> stmt = FromImportStatement(module='typing', name='List', level=0) >>> stmt.is_relative False >>> >>> # Relative import with level >>> stmt = FromImportStatement(module='module', name='func', level=1) >>> stmt.is_relative True >>> >>> # Current package import >>> stmt = FromImportStatement(module='', name='func', level=1) >>> stmt.is_relative True
- property is_wildcard: bool
Check if this is a wildcard import statement.
A wildcard import is one that uses ‘*’ to import all public names from a module, such as
from module import *. This is generally discouraged in Python but is sometimes used for convenience.- Returns:
True if this is a wildcard import, False otherwise
- Return type:
bool
Warning
Wildcard imports can pollute the namespace and make code harder to understand and maintain. They should be used sparingly.
Example:
>>> # Wildcard import >>> stmt = FromImportStatement(module='collections', name='*', level=0) >>> stmt.is_wildcard True >>> >>> # Regular import >>> stmt = FromImportStatement(module='typing', name='List', level=0) >>> stmt.is_wildcard False
ImportVisitor
- class hbllmutils.meta.code.imp.ImportVisitor[source]
Custom AST visitor class for collecting import information from Python code.
This class extends
ast.NodeVisitorto traverse the Abstract Syntax Tree and collect all import statements (both regular imports and from-imports) found in the code. It handles all import variations including aliases, relative imports, and wildcard imports.- Variables:
imports (List[ImportStatementTyping]) – List of collected import statements
Note
The visitor collects imports in the order they appear in the source code, preserving line numbers and column offsets for each import.
Example:
>>> code = ''' ... import os ... import sys as system ... from typing import List, Dict ... from collections import * ... ''' >>> tree = ast.parse(code) >>> visitor = ImportVisitor() >>> visitor.visit(tree) >>> len(visitor.imports) 5 >>> print(visitor.imports[0]) import os >>> print(visitor.imports[2]) from typing import List >>> visitor.imports[4].is_wildcard True
- __init__()[source]
Initialize the ImportVisitor.
Creates an empty list to store collected import statements during AST traversal.
Example:
>>> visitor = ImportVisitor() >>> len(visitor.imports) 0
- visit_Import(node: Import) None[source]
Visit an Import node in the AST.
This method is called automatically when an import statement is encountered during AST traversal. It extracts information about each imported module and creates
ImportStatementobjects with position information.- Parameters:
node (ast.Import) – The Import AST node to visit
Note
A single import statement can import multiple modules (e.g.,
import os, sys), so this method may create multiple ImportStatement objects from a single node.Example:
>>> code = "import os, sys as system" >>> tree = ast.parse(code) >>> visitor = ImportVisitor() >>> visitor.visit(tree) >>> len(visitor.imports) 2 >>> print(visitor.imports[0]) import os >>> print(visitor.imports[1]) import sys as system
- visit_ImportFrom(node: ImportFrom) None[source]
Visit an ImportFrom node in the AST.
This method is called automatically when a from-import statement is encountered during AST traversal. It extracts information about each imported name and creates
FromImportStatementobjects. This includes support for wildcard imports (from module import *) and relative imports.- Parameters:
node (ast.ImportFrom) – The ImportFrom AST node to visit
Note
A single from-import statement can import multiple names (e.g.,
from typing import List, Dict), so this method may create multiple FromImportStatement objects from a single node.Example:
>>> code = ''' ... from typing import List, Dict as D ... from collections import * ... from ..module import func ... ''' >>> tree = ast.parse(code) >>> visitor = ImportVisitor() >>> visitor.visit(tree) >>> len(visitor.imports) 4 >>> print(visitor.imports[0]) from typing import List >>> print(visitor.imports[1]) from typing import Dict as D >>> visitor.imports[2].is_wildcard True >>> visitor.imports[3].is_relative True
analyze_imports
- hbllmutils.meta.code.imp.analyze_imports(code_text: str) List[ImportStatement | FromImportStatement][source]
Analyze Python code text and extract all import statements.
This function parses the provided Python source code using the AST module and collects all import statements (both regular imports and from-imports), including wildcard imports and relative imports. It returns a comprehensive list of all imports with their position information.
- Parameters:
code_text (str) – The Python source code to analyze
- Returns:
A list of all import statements found in the code, in order of appearance
- Return type:
List[ImportStatementTyping]
- Raises:
SyntaxError – If the code_text contains invalid Python syntax
Note
The function preserves the order of imports as they appear in the source code and includes detailed position information (line number and column offset) for each import statement.
Warning
The code_text must be syntactically valid Python code. If it contains syntax errors, a SyntaxError will be raised during parsing.
Example:
>>> code = ''' ... import os ... import sys as system ... from typing import List, Dict ... from ..module import func ... from collections import * ... ''' >>> imports = analyze_imports(code) >>> len(imports) 6 >>> >>> # Check first import >>> print(imports[0]) import os >>> imports[0].line 2 >>> >>> # Check from-import >>> print(imports[2]) from typing import List >>> >>> # Check wildcard import >>> print(imports[5]) from collections import * >>> imports[5].is_wildcard True >>> >>> # Check relative import >>> imports[4].is_relative True >>> >>> # Handle syntax error >>> try: ... analyze_imports("import os as") ... except SyntaxError as e: ... print("Syntax error detected") Syntax error detected