Lifeguard: A static analyzer for Python lazy imports compatibility
Lifeguard is a rapid static analysis tool designed to facilitate the transition to Lazy Imports in Python projects. In Python, every import statement is executed immediately upon module loading, which consumes unnecessary resources irrespective of the import's usage. PEP 810 introduces the concept of Lazy Imports in Python, allowing for the deferral of module loading until the imported name is first accessed.
This can lead to substantial savings in memory usage, faster startup times, and reduced import overhead, particularly in large codebases with intricate dependency structures.
However, some Python practices rely on immediate execution of imports. Converting existing codebases to utilize Lazy Imports can be a challenging endeavor, especially at scale. Lifeguard addresses this issue by identifying incompatible patterns, enabling developers to adopt Lazy Imports with confidence. It achieves this by scanning Python source files within a project in parallel, parsing each module's Abstract Syntax Tree (AST) to recognize effects and map incompatible Lazy-Imports to errors.
The analysis is conservative, marking modules as unsafe for lazy loading by default if their suitability cannot be programmatically determined. This cautious approach may lead to the marking of compatible modules as incompatible, forfeiting potential performance gains in favor of ensuring production stability.
Lifeguard is actively developed, with plans to reach general availability ahead of the Python 3.15 release. It is available on PyPI, offering precompiled packages for Linux, macOS, and Windows (x86-64 and ARM64) and requiring Python 3.12 or later, with no dependency on a Rust toolchain. The tool can be invoked via the command line (python -m lifeguard_lazy_imports) or installed as a package (lifeguard).
The Cargo version requires building and running from source, using lifeguard instead of cargo run --. PyPI releases may not be up-to-date with the main branch; running lifeguard --help reveals the capabilities of the installed version. Users can initialize the repository with submodules if they cloned without the --recurse-submodules option.
The quickest way to test Lifeguard is through the run-tree subcommand, which locates .py files beneath a specified directory and follows resolvable top-level imports. All file and directory names below the input root must be ASCII Python identifiers; other paths are disregarded. For example, using Lifeguard with a sample project:
To generate a source database (JSON file) for Lifeguard, use the gen-source-db command. This file maps Python module paths to their disk locations. It can be automatically generated with cargo run -- gen-source-db or created manually. The JSON file includes two fields: one for safely Lazy-Importable modules with their dependencies (eagerly loaded) and another for modules where all imports must be loaded eagerly. Modules absent from this dictionary are deemed unsafe for Lazy Imports.
Lifeguard can function as a standalone linter, providing a human-readable report detailing per-module incompatibilities with Lazy Imports. Running the analyzer with --verbose-output generates this report, listing flagged lines along with their respective line numbers. This capability allows Lifeguard to be integrated into CI pipelines or used locally for code review, guiding developers in safely enabling Lazy Imports.
The JSON output is intended for consumption by a lazy import loader's filter function. When Python 3.15 is released, the sys.set_lazy_imports_filter() function will install a callback to manage import deferral versus eager loading. Lifeguard's output supplies the necessary data to construct such a filter, with LAZY_ELIGIBLE identifying safe modules and LOAD_IMPORTS_EAGERLY marking modules needing immediate import resolution.
Ongoing work aims to develop tools for easier ingestion of Lifeguard's output before the Python 3.15 release.
Written by urgent.news from Lobsters's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.