Skip to main content

Automatic lazy import library - use common libraries without explicit import statements

Project description

laziest-import

PyPI version PyPI pre-release Python License Downloads GitHub stars GitHub forks GitHub issues GitHub pull requests GitHub Actions GitHub last commit GitHub repo size Type hints Code style Tests Coverage CodeFactor Maintainability Contributors First Timers Only Documentation Status Made with Love Pythonic Open Source Love Awesome PRs Welcome License MIT

中文版 English


Zero-Configuration Lazy Import Library

Import and use any installed(for the not installed, it uses pip to auto install if you permitted) module with a single line

A magical way to import Python modules - just use them!


Table of Contents


Key Features

Feature Badge Description
Lazy Loading Modules import only on first access
Background Index Symbol index builds in background thread
Auto-Correction Typo correction (numpnumpy)
Symbol Search Search symbols across all modules
Strict Mode AmbiguousSymbolError on symbol conflicts
Multi-Level Cache Three-tier caching for speed
Dependency Analysis Analyze module dependencies
Performance Benchmark Benchmark imports and functions
CLI Interface laziest-import freeze / init commands
985+ Tests Comprehensive test coverage
1000+ Aliases Predefined for common packages

Installation

# Stable version
pip install laziest-import

# Pre-release version (latest features)
pip install --pre laziest-import

# From source (latest development)
pip install git+https://github.com/ChidcGithub/Laziest-import.git

Quick Start

Method 1: Wildcard Import (Recommended)

from laziest_import import *

# Data Science
arr = np.array([1, 2, 3]) # numpy
df = pd.DataFrame({'a': [1, 2]}) # pandas
plt.plot([1, 2, 3]); plt.show() # matplotlib

# Standard Library
print(os.getcwd()) # os
data = json.dumps({'key': 'value'}) # json
result = math.sqrt(16) # math

# Submodules (auto-loading)
svd_result = np.linalg.svd(matrix) # numpy.linalg.svd()

Method 2: Namespace Prefix (Recommended)

from laziest_import import lz

arr = lz.np.array([1, 2, 3])
df = lz.pd.DataFrame({'a': [1, 2]})

Method 3: Lazy Proxy (with Auto-Correction)

from laziest_import import lazy

# Automatic typo correction
arr = lazy.nump.array([1, 2, 3]) # nump -> numpy 
df = lazy.pnda.DataFrame() # pnda -> pandas 
arr2 = lazy.nupi.array([4, 5, 6]) # nupi -> numpy 

# Submodule shortcuts
layer = lazy.nn.Linear(10, 5) # nn -> torch.nn 
relu = lazy.F.relu(tensor) # F -> torch.nn.functional 

Key Features

Feature Description
Modular architecture Clean 13-module _api/ package for maintainability
Lazy loading Modules import only on first access, reducing startup overhead
Lazy function loading Symbol functions loaded on-demand for faster startup
Background index build Symbol index builds in background thread
Symbol sharding Large packages split into shards for faster access
Submodule support np.linalg.svd() chains submodules automatically
Auto-discovery Unregistered names search installed modules automatically
Typo correction Misspelling auto-correction (numpnumpy, matplotlipmatplotlib)
Abbreviation expansion 300+ abbreviations (nntorch.nn, Ftorch.nn.functional)
Fuzzy matching Typo correction via Levenshtein distance algorithm
Strict mode Raise AmbiguousSymbolError on symbol conflicts
CLI interface laziest-import freeze and laziest-import init
Symbol location lz.which() finds where symbols are defined
Auto-install Optional: missing modules can be pip-installed automatically
Multi-level cache Three-tier caching (stdlib/third-party/memory) for fast lookups
Cache persistence Symbol index saved to disk with configurable TTL
Cache statistics Track hits/misses and optimize performance
Version checking Automatic compatibility warnings for aliases/mappings
Type hints support LazySymbol.__class_getitem__ for generic type hints
Dependency tree analysis lz.dependency_tree() - analyze module dependencies
Performance benchmarking lz.benchmark() - benchmark functions and imports
Dependency pre-analysis Scan code to predict required imports
Import profiler Record module load times and memory usage
Environment detection Detect virtual environments (venv/conda/virtualenv)
Conflict visualization Find and display symbol conflicts across modules
Persistent preferences Save/load user preferences to ~/.laziestrc
1000+ aliases Predefined aliases for common packages
985+ tests Comprehensive test coverage

What's New

v0.1.0-pre12 (Current)

  • Phase 3 — API Semantic Simplification: Flattened cache namespace — lz.cache.clear_symbols(), lz.cache.file_info(), lz.cache.symbol_count replace 3-level paths; lz.cache.stats now returns a plain dict
  • Config Dataclass Caching: Dataclass instances (lz.config.symbol_search, lz.config.cache, etc.) are now cached after first access with bidirectional sync to internal state
  • Fixed ConfigContext: with lz.config.temp_config(debug=True): now correctly saves and restores state
  • 985+ tests: Comprehensive test coverage

v0.1.0-pre10

  • Phase 2 — __init__.py Slim: Collapsed from 965 to 741 lines (−23%)
  • Extracted _hooks.py: Module-level hook API (add_pre_import_hook, etc.) moved to dedicated module
  • Extracted _lazy_registry.py: Lazy function registration/replacement mechanism
  • Extracted _analysis/: Analysis convenience functions (analyze_file, analyze_source, analyze_directory)
  • Simplified __getattr__: Unified 5-step resolution chain (replaced 10-step chain)
  • 985+ tests: Comprehensive test coverage

v0.1.0-pre9

  • Strict Mode: lz.symbol.config.strict = True — raises AmbiguousSymbolError on symbol conflicts; use lz.symbol.prefer() to resolve
  • CLI Interface: laziest-import freeze scans source files to generate imports.laziest.json; laziest-import init creates .laziestrc
  • Phase 1 API Merge: 2196-line _api.py refactored into 13 files under _api/ package; _public_api.py deleted
  • Shorthand Alias Tests: 28 tests covering stdlib aliases, third-party aliases, bare-name lazy loading, and edge cases
  • 985+ tests: Comprehensive test coverage

Examples

Symbol Search & Location

import laziest_import as lz

# Search for a symbol across all modules
results = lz.search_symbol('DataFrame')
for result in results:
 print(f"{result.module_name}.{result.symbol_name}")

# Find where a symbol is defined
loc = lz.which('sqrt')
print(f"Found at: {loc}") # numpy.sqrt

# Find all occurrences
locs = lz.which_all('sqrt')
for loc in locs:
 print(f"{loc.module_name}.{loc.symbol_name}")

Dependency Tree Analysis

import laziest_import as lz

# Analyze a module's dependency tree
tree = lz.dependency_tree('numpy', max_depth=2)
print(f"Total modules: {tree.total_modules}")
print(f"Stdlib: {tree.stdlib_count}, Third-party: {tree.third_party_count}")

# Print formatted tree
lz.print_dependency_tree(tree)

Performance Benchmarking

import laziest_import as lz

# Benchmark a function
result = lz.benchmark(
 lambda: sum(range(10000)),
 name="sum_test",
 iterations=100,
 warmup=10
)
print(f"Avg: {result.avg_time*1000:.4f}ms")
print(f"Min: {result.min_time*1000:.4f}ms")
print(f"Max: {result.max_time*1000:.4f}ms")

# Benchmark module imports
report = lz.benchmark_imports(['numpy', 'pandas', 'matplotlib'])
lz.print_benchmark_report(report)

Strict Mode (Symbol Conflict Detection)

from laziest_import import lz

# Enable strict mode
lz.symbol.config.strict = True

# Multiple modules define `sqrt` — raises AmbiguousSymbolError
# result = lz.sqrt  # Error: sqrt found in numpy, math, scipy, ...

# Use prefer() to resolve ambiguity
lz.symbol.prefer("sqrt", "numpy")
result = lz.sqrt(16)  # Now resolves to numpy.sqrt

CLI: Freeze & Init

# Scan project and freeze alias usage
laziest-import freeze

# Generate .laziestrc config file
laziest-import init

The freeze command produces imports.laziest.json — a manifest of all lazy imports used across your project, ideal for CI validation.

Auto-Install (Optional)

from laziest_import import *

# Enable auto-install
lz.enable_auto_install()

# Accessing uninstalled modules triggers installation
arr = np.array([1, 2, 3]) # If numpy missing, prompts to install

Configuration

User Configuration

import laziest_import as lz

# Create default config file
lz.create_rc_file()

# Load config
config = lz.load_rc_config()

# Get specific value
value = lz.get_rc_value('debug', default=False)

# Config info
info = lz.get_rc_info()

Cache Configuration

import laziest_import as lz

# Set custom cache directory
lz.set_cache_dir('./my_cache')

# Configure cache settings
lz.set_cache_config(
 symbol_index_ttl=3600, # Symbol index TTL: 1 hour
 stdlib_cache_ttl=2592000, # Stdlib cache TTL: 30 days
 max_cache_size_mb=200 # Max cache size: 200 MB
)

# Get cache statistics
stats = lz.get_cache_stats()
print(f"Hit rate: {stats['hit_rate']:.1%}")

# View cache status
info = lz.get_file_cache_info()
print(f"Cache size: {info['cache_size_mb']:.2f} MB")

API Reference

Alias Management

Function Description
register_alias(alias, module_name) Register an alias
register_aliases(dict) Register multiple aliases
unregister_alias(alias) Remove an alias
list_loaded() List loaded modules
list_available() List all available aliases
get_module(alias) Get module object
clear_cache() Clear memory cache

Symbol Search

Function Description
enable_symbol_search() Enable symbol search
disable_symbol_search() Disable symbol search
search_symbol(name) Search for classes/functions
rebuild_symbol_index() Rebuild symbol index
which(symbol) Find symbol location
which_all(symbol) Find all symbol locations

Auto-Install

Function Description
enable_auto_install() Enable auto-install
disable_auto_install() Disable auto-install
install_package(name) Install a package manually
set_pip_index(url) Set mirror URL

Cache Management

Function Description
get_cache_version() Get cache version
set_cache_config(...) Configure cache settings
get_cache_config() Get cache configuration
get_cache_stats() Get cache statistics
reset_cache_stats() Reset cache statistics
invalidate_package_cache(pkg) Invalidate package cache
get_file_cache_info() Get file cache info
clear_file_cache() Clear file cache
set_cache_dir(path) Set cache directory

Analysis & Profiling

Function Description
analyze_file(path) Analyze Python file for imports
analyze_source(code) Analyze source code string
analyze_directory(path) Analyze all files in directory
start_profiling() Start import profiler
stop_profiling() Stop import profiler
get_profile_report() Get profiling report
print_profile_report() Print formatted report
dependency_tree(module) Analyze module dependency tree
print_dependency_tree(tree) Print dependency tree
benchmark(func) Benchmark a function
benchmark_imports(modules) Benchmark module imports
detect_environment() Detect Python environment
show_environment() Display environment info
find_symbol_conflicts() Find symbol conflicts
show_conflicts() Display conflicts table

Preferences

Function Description
set_symbol_preference(name, module) Set symbol preference
get_symbol_preference(name) Get symbol preference
clear_symbol_preference(name) Clear symbol preference
save_preferences() Save preferences to file
load_preferences() Load preferences from file
apply_preferences(prefs) Apply loaded preferences
clear_preferences() Clear all preferences

Troubleshooting

Common Issues

Q: Module not found (AttributeError)

AttributeError: module 'laziest_import' has no attribute 'mymodule'

Solution: The module is not registered. Use lz.enable_auto_search() to enable auto-discovery, or register it manually:

lz.register_alias('mymodule', 'mypackage.mymodule')

Q: Slow first import The symbol index may be building. Check status with:

lz.is_index_building() # True if building
lz.wait_for_index(30) # Wait up to 30 seconds

Q: Typo correction not working Ensure the module is in the alias list:

lz.register_alias('nump', 'numpy') # Add misspelling
arr = lz.nump.array([1, 2, 3]) # Now works

Q: Symbol conflicts (same name in multiple modules) Use module hints or preferences:

lz.set_symbol_preference('DataFrame', 'pandas') # Prefer pandas
result = lz.DataFrame # Gets pandas.DataFrame

Debug Mode

Enable detailed logging:

lz.enable_debug_mode()
import laziest_import as lz
arr = lz.np.array([1, 2, 3]) # See import details in logs

Cache Issues

Clear caches if experiencing stale data:

lz.clear_cache() # Clear memory cache
lz.clear_file_cache() # Clear disk cache
lz.rebuild_symbol_index() # Rebuild symbol index

Performance Tips

  1. First run: ~2s to build index
  2. Cached run: ~0.003s (700x faster!)
  3. Use lz.enable_background_build() to avoid blocking on first import
  4. For CI/CD, set LAZY_BG_BUILD=1 to pre-build cache

How It Works

Architecture

  1. Proxy objects: Each alias maps to a LazyModule proxy
  2. On-demand import: Real import triggers on first attribute access via __getattr__
  3. Caching: Imported modules cache within the proxy object
  4. Chain proxies: LazySubmodule handles recursive lazy loading
  5. Fuzzy search: Levenshtein distance algorithm for fault-tolerant matching

Multi-Level Cache Architecture

The library uses a three-tier caching system for optimal performance:

Cache Level Description Default TTL
Stdlib cache Standard library symbols 7 days
Third-party cache Installed package symbols 24 hours
Memory cache Hot cache for current session Session

Cache files are stored in ~/.laziest_import/cache/ and automatically:

  • Expire based on TTL settings
  • Clean up when exceeding size limit (default: 100 MB)
  • Invalidate on Python version changes

Predefined Aliases

Data Science

np, pd, plt, sns, scipy

Machine Learning

torch, tf, keras, sklearn, xgboost, lightgbm

Deep Learning

transformers, langchain, llama_index

Web Frameworks

flask, django, fastapi, starlette

HTTP Clients

requests, httpx, aiohttp

Databases

sqlalchemy, pymongo, redis, duckdb

Cloud Services

boto3 (AWS), google.cloud, azure

Image Processing

cv2, PIL.Image, skimage

GUI

PyQt6, tkinter, flet, nicegui

DevOps

docker, kubernetes, ansible

NLP

spacy, nltk, transformers

Visualization

plotly, bokeh, streamlit, gradio


Contributing

We love contributions! Check out our Contributing Guide for more information.

How to Contribute

  1. Fork the repo and create your branch from main
  2. Read our Code of Conduct
  3. Make sure your code lints (flake8)
  4. Add tests for any new functionality
  5. Ensure the test suite passes (pytest tests/)
  6. Commit your changes
  7. Push to your branch and open a Pull Request!

Development Setup

# Clone the repo
git clone https://github.com/ChidcGithub/Laziest-import.git
cd Laziest-import

# Install in development mode
pip install -e ".[dev,test]"

# Run tests
pytest tests/ -v

# Run linting
flake8 laziest_import/

Good First Issues

Looking for a place to start? Check out:

Ways to Contribute

  • Report bugs
  • Propose new features
  • Improve documentation
  • Fix existing issues
  • Add more tests
  • Help with translations
  • Design improvements

Contributors

Thanks goes to these wonderful people:

Made with contrib.rocks.


Star History

Star History Chart


Get In Touch


Acknowledgments

  • Thanks to all the contributors who have helped make this project better!
  • Inspired by the Python community's love for clean, simple APIs

License

This project is licensed under the MIT License - see the LICENSE file for details.


Show Your Support

If you find this project useful, please consider:

  • Starring this repo on GitHub
  • Reporting bugs or suggesting features
  • Sharing it with friends and colleagues
  • Blogging about it if you use it
  • Contributing to the project

Thank you!


Made by Chidc and contributors

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

laziest_import-0.1.0rc12.tar.gz (200.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

laziest_import-0.1.0rc12-py3-none-any.whl (160.3 kB view details)

Uploaded Python 3

File details

Details for the file laziest_import-0.1.0rc12.tar.gz.

File metadata

  • Download URL: laziest_import-0.1.0rc12.tar.gz
  • Upload date:
  • Size: 200.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for laziest_import-0.1.0rc12.tar.gz
Algorithm Hash digest
SHA256 402265229e47d5619aca51590b46e3c2ae24bb84741e48ded0a13f79d7da7bed
MD5 44feb24f91fe6aeff3126c6e4aecde27
BLAKE2b-256 5be650949cbcc7a67049bd34b06e10ad0110516a2f2006219a80a7d43e50519c

See more details on using hashes here.

Provenance

The following attestation bundles were made for laziest_import-0.1.0rc12.tar.gz:

Publisher: build-publish.yml on ChidcGithub/Laziest-import

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file laziest_import-0.1.0rc12-py3-none-any.whl.

File metadata

File hashes

Hashes for laziest_import-0.1.0rc12-py3-none-any.whl
Algorithm Hash digest
SHA256 f92b776121c534b5e6da379e06a3a0026180e7a99eec035592c2d6c9dcfc11a2
MD5 0d62dd70197b4108ee480806fa5840e4
BLAKE2b-256 d1301821fd2a1b442af5a3180d2e913479fa3f626da32233590997bbb686a55a

See more details on using hashes here.

Provenance

The following attestation bundles were made for laziest_import-0.1.0rc12-py3-none-any.whl:

Publisher: build-publish.yml on ChidcGithub/Laziest-import

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page