CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-import-tracker

A tool for managing dependencies in a modular python project by tracking which dependencies are needed by which sub-modules

Pending
Overview
Eval results
Files

dependency-tracking.mddocs/

Dependency Tracking

Comprehensive module dependency analysis using bytecode inspection to discover all imports and their relationships within Python projects.

Capabilities

Module Dependency Analysis

Tracks dependencies of Python modules by analyzing bytecode to discover all import statements, supporting both direct analysis and recursive submodule tracking.

def track_module(
    module_name: str,
    package_name: Optional[str] = None,
    submodules: Union[List[str], bool] = False,
    track_import_stack: bool = False,
    full_depth: bool = False,
    detect_transitive: bool = False,
    show_optional: bool = False,
) -> Union[Dict[str, List[str]], Dict[str, Dict[str, Any]]]:
    """
    Track the dependencies of a single python module
    
    Args:
        module_name: The name of the module to track (may be relative if package_name provided)
        package_name: The parent package name of the module if the module name is relative
        submodules: If True, all submodules of the given module will also be tracked. 
                   If given as a list of strings, only those submodules will be tracked.
                   If False, only the named module will be tracked.
        track_import_stack: Store the stacks of modules causing each dependency for debugging
        full_depth: Include transitive dependencies of third party dependencies
        detect_transitive: Detect whether each dependency is 'direct' or 'transitive'
        show_optional: Show whether each requirement is optional (behind a try/except) or not
        
    Returns:
        import_mapping: The mapping from fully-qualified module name to the set of imports
                       needed by the given module. If tracking import stacks or detecting
                       direct vs transitive dependencies, returns Dict[str, Dict[str, Any]]
                       with nested dicts containing "stack" and/or "type" keys.
                       Otherwise returns Dict[str, List[str]].
    """

Basic Dependency Tracking

Simple module dependency analysis returning a mapping of modules to their required dependencies:

import import_tracker

# Track a single module
deps = import_tracker.track_module('requests')
print(deps)
# {'requests': ['urllib3', 'certifi', 'charset_normalizer', 'idna']}

# Track a module with package context
deps = import_tracker.track_module('.widgets', package_name='my_package')
print(deps)
# {'my_package.widgets': ['matplotlib', 'pillow']}

Submodule Analysis

Track dependencies across all submodules within a package:

# Track all submodules
deps = import_tracker.track_module('my_package', submodules=True)
print(deps)
# {
#   'my_package': ['requests'],
#   'my_package.utils': ['numpy', 'pandas'],
#   'my_package.widgets': ['matplotlib']
# }

# Track specific submodules only
deps = import_tracker.track_module(
    'my_package', 
    submodules=['my_package.core', 'my_package.utils']
)

Advanced Dependency Analysis

Detailed analysis with transitive dependency detection and import stack tracing:

# Detect direct vs transitive dependencies
deps = import_tracker.track_module(
    'my_package',
    submodules=True,
    detect_transitive=True,
    show_optional=True
)
print(deps)
# {
#   'my_package': {
#     'requests': {'type': 'direct', 'optional': False},
#     'urllib3': {'type': 'transitive', 'optional': False}
#   }
# }

# Track import stacks for debugging
deps = import_tracker.track_module(
    'my_package',
    track_import_stack=True,
    full_depth=True
)
print(deps)
# {
#   'my_package': {
#     'requests': {'stack': [['my_package']]},
#     'urllib3': {'stack': [['my_package', 'requests']]}
#   }
# }

Optional Dependency Detection

Identifies dependencies that are wrapped in try/except blocks, indicating they are optional:

# Show which dependencies are optional
deps = import_tracker.track_module('my_package', show_optional=True)
print(deps)
# {
#   'my_package': {
#     'requests': {'optional': False},      # Required dependency
#     'matplotlib': {'optional': True}      # Optional dependency (in try/except)
#   }
# }

Command Line Interface

The dependency tracking functionality is available via command line:

# Basic tracking
python -m import_tracker --name my_package

# Track all submodules with pretty printing
python -m import_tracker --name my_package --submodules --indent 2

# Comprehensive analysis
python -m import_tracker \
    --name my_package \
    --submodules \
    --track_import_stack \
    --detect_transitive \
    --show_optional \
    --full_depth \
    --indent 2

Command Line Options

# Available CLI arguments
--name/-n           # Module name to track (required)
--package/-p        # Package for relative imports
--submodules/-s     # List of submodules to include (all if no value given)
--track_import_stack/-t    # Store import stack traces
--detect_transitive/-d     # Detect direct vs transitive dependencies  
--show_optional/-o         # Show optional vs required dependencies
--full_depth/-f           # Include transitive third-party dependencies
--indent/-i              # JSON output indentation
--log_level/-l           # Set logging level

Return Value Formats

Simple Format

When detect_transitive=False, track_import_stack=False, and show_optional=False:

{
    'module_name': ['dep1', 'dep2', 'dep3']
}

Extended Format

When any of the advanced options are enabled:

{
    'module_name': {
        'dependency_name': {
            'type': 'direct',           # When detect_transitive=True
            'stack': [['module_path']], # When track_import_stack=True  
            'optional': False           # When show_optional=True
        }
    }
}

Types

# Core function types
from typing import Any, Dict, List, Optional, Union

ModuleName = str
DependencyName = str
ImportStack = List[List[str]]

# Simple return format 
SimpleDependencyMap = Dict[ModuleName, List[DependencyName]]

# Extended return format
ExtendedDependencyInfo = Dict[str, Any]  # Contains 'type', 'stack', 'optional' keys
ExtendedDependencyMap = Dict[ModuleName, Dict[DependencyName, ExtendedDependencyInfo]]

# Function return type
TrackModuleReturn = Union[SimpleDependencyMap, ExtendedDependencyMap]

Install with Tessl CLI

npx tessl i tessl/pypi-import-tracker

docs

dependency-tracking.md

index.md

lazy-import-errors.md

setup-tools.md

tile.json