laziest-import
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
- Quick Start
- Installation
- Terminal Demo
- Examples
- Configuration
- API Reference
- Troubleshooting
- How It Works
- Contributing
- License
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 (nump → numpy) |
|
| 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 / fix commands |
|
| Symbol Autocomplete | Prefix-based symbol name completion | |
| 1065+ 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 (nump → numpy, matplotlip → matplotlib) |
| Abbreviation expansion | 300+ abbreviations (nn → torch.nn, F → torch.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 |
| 1065+ tests | Comprehensive test coverage |
What's New
v1.0.1.0 (Current)
- Type-stub (.pyi) symbol indexing — the index builder now parses
.pyistub files first, falling back to import-based scanning only when no stub exists:- Zero import side effects: modules are never executed during index building
- Much faster on heavy packages (matplotlib: ~4ms vs ~160ms)
- Precise type signatures extracted for free
- Toggle:
_config._STUB_INDEX_CONFIG["enabled"]; stats:get_symbol_cache_info()["stub_scanned_modules"]
v1.0.0.7
- Safety: auto-install fallback now respects the
enabledswitch (default off) — no unexpected pip prompts or subprocesses on import failure - Correctness: module priorities now loaded from
mappings/priorities.json; incremental symbol builds no longer overwrite a complete index with partial data; single exact-match symbols resolve reliably - Concurrency: snapshot iteration over shared caches eliminates
RuntimeErrorduring background index builds;BackgroundIndexBuilderrace/stop/timeout semantics fixed - Persistence: atomic (tmp + replace) JSON cache writes; corrupt-tolerant cache loading; cache size accounting and cleanup actually work
- Windows/CJK: pip output forced to UTF-8 decoding; file-unlink protection when caches are held by other processes
- Benchmarks & Profiler: failed iterations excluded from timings, submodule caches cleared between runs, memory profiling uses
tracemalloc.get_traced_memory() - Plus 10+ smaller fixes: underscore-probe guards on proxies, alias remap/reload consistency, async retry wiring, hook error logging, dependency-tree accuracy
v1.0.0.6
- Comprehensive Bug Fixes: 8 critical bugs fixed including
module_access_countsreset,LazySymbolNone-value infinite re-import, hash/eq contract violation,_scan_path_modulesreturning after firstsys.pathentry,reset_all()wrong module reference, andget_symbol_help()broken attribute access - Thread Safety: Lock protection added to
_ALIAS_MAPwrites, negative cache,invalidate_package_cache, and hook removal - Python 3.9 Compatibility:
Any | Noneunion syntax replaced withOptional[Any]for older Python support - Version Comparison Fix: Prerelease version strings now correctly compare numeric suffixes (e.g.
alpha10vsalpha2) - Config System Fix: Environment variables now have highest priority;
interactiveoverride parameter respected in auto-install - Cache Fixes: Cleanup limited to
laziest_*.jsonprefix;max_cache_size_mb=0treated as unlimited; partial cache load no longer prevents full rebuild which()Improvement: ReturnsNoneon module hint mismatch instead of silent wrong fallback- License/CI:
timeout-minutesadded to GitHub Actions workflows preventing 6-hour CI hangs - Environmental Cleanup: Removed outdated migration guide, orphaned debug scripts, and unused binary artifacts
New Features
- Reflected Operators:
LazySymbolnow supports__radd__,__rsub__,__rmul__,__rtruediv__,__rfloordiv__,__rmod__,__rpow__,__rmatmul__,__neg__,__pos__,__abs__,__invert__ - Async Retry Logic:
_async_ops.pynow implements actual retry based on_RETRY_CONFIG - CLI
fixCommand:laziest-import fixgenerates standardimportstatements from lazy alias usage - Symbol Autocomplete:
symbol_autocomplete(prefix)for prefix-based symbol name completion - Build Progress API:
BackgroundIndexBuilder.get_progress()for querying current build state which_allLive Search: Now performs live search even after index is built, catching newly installed modules- Lazy Registry Management: Added
unregister()andlist_registered()to_lazy_registry.py - Terminal Demo: Interactive animated demo at
examples/terminal_demo.py
Code Quality
- 10+ broad
except Exceptionnarrowed to specific exceptions sys.path.insert(0, '.')removed from test files- Trivially-true
is True or is Falseassertions replaced withisinstance(bool) - Redundant
x as ximports removed from_symbol/redirect files - Duplicated
SymbolIndexCachedataclass consolidated to single definition _is_stdlib_moduleperformance improved via module-level constant setimport timerelocated to top of_cache/_file_cache.py- Test count and version unified across READMEs
v0.1.0
- Phase 5 — Fake Code Audit & Fix: All placeholder/fake code replaced with real logic
- Fixed
assert Truetests: 4 tests replaced with real assertions - Fixed silent
except Exception: pass: 4 tests,HookList.__call__(),_benchmark.pywarmup/measure,_state_setters.pynarrowed toexcept ImportError - Fixed 48 zero-assertion smoke tests: Added type/value assertions
- Fixed
_jupyter.pyunload_ipython_extension(): No-oppassreplaced withunregister_magics() - Fixed
_cache/_api.pyinvalidate_package_cache(): Added missing_STDLIB_SYMBOL_CACHEcleanup - Fixed circular import in
_build_known_modules_cache(): Skip scanning CWD (''/'.'paths) to prevent re-import of scripts in working directory - 1065 tests: All passing, comprehensive coverage
Terminal Demo
Run the interactive terminal demo to see laziest-import in action with animated visuals:
python examples/terminal_demo.py
/=======================================\
| laziest-import Terminal Demo |
\=======================================/
[1] Import everything with one line
-> np.array([1,2,3]) = [1 2 3]
-> math.sqrt(144) = 12.0
-> os.getcwd() = /home/user
[2] Submodules auto-load
-> os.path.join('a','b') = a/b
[3] Symbol search across all modules
-> math.sqrt (function)
-> numpy.sqrt (function)
...
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, Fix & Init
# Scan project and freeze alias usage
laziest-import freeze
# Generate standard import statements from lazy alias usage
laziest-import fix
# 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.
The fix command generates standard Python import X as Y statements from detected lazy alias usage — useful when migrating from lazy imports to explicit imports.
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.config.auto_search = True to enable auto-discovery, or register it manually:
lz.alias.register('mymodule', 'mypackage.mymodule')
Q: Slow first import The symbol index may be building. Check status with:
lz.background.is_building # True if building
lz.background.wait(timeout=30) # Wait up to 30 seconds
Q: Typo correction not working Ensure the module is in the alias list:
lz.alias.register('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.symbol.prefer('DataFrame', 'pandas') # Prefer pandas
result = lz.DataFrame # Gets pandas.DataFrame
Debug Mode
Enable detailed logging:
lz.config.debug = True
arr = lz.np.array([1, 2, 3]) # See import details in logs
Cache Issues
Clear caches if experiencing stale data:
lz.cache.clear() # Clear memory cache
lz.cache.files.clear() # Clear disk cache
lz.symbol.index.rebuild() # Rebuild symbol index
Performance Tips
- First run: ~2s to build index
- Cached run: ~0.003s (700x faster!)
- Use
lz.background.enable(True)to avoid blocking on first import - For CI/CD, set
LAZY_BG_BUILD=1to pre-build cache
How It Works
Architecture
- Proxy objects: Each alias maps to a
LazyModuleproxy - On-demand import: Real import triggers on first attribute access via
__getattr__ - Caching: Imported modules cache within the proxy object
- Chain proxies:
LazySubmodulehandles recursive lazy loading - 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
- Fork the repo and create your branch from
main - Read our Code of Conduct
- Make sure your code lints (
flake8) - Add tests for any new functionality
- Ensure the test suite passes (
pytest tests/) - Commit your changes
- 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:
- Good first issues: Issues labeled "good first issue"
- Help wanted: Issues labeled "help wanted"
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
Get In Touch
- Email: (your email)
- GitHub: ChidcGithub/Laziest-import
- Discussions: GitHub Discussions
- Issues: GitHub Issues
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!
Release files for laziest-import 1.0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| laziest_import-1.0.1.0.tar.gz | 215.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| laziest_import-1.0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 388.9 kB
Release files / laziest_import-1.0.1.0.tar.gz
| Download URL | laziest_import-1.0.1.0.tar.gz |
|---|---|
| Size | 215.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7436c0126ee410dd5060b6d9464e6ebe33fb71c993b3e9e833c2ca1840bdefc4
|
|
BLAKE2b-256 checksum How to use checksums |
363b8bc6a26c8b3f3ea5eb0c547ff5c30f60009f9af9cb99e40f477ee96fa594
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 26, 2026.
Transparency logRelease files / laziest_import-1.0.1.0-py3-none-any.whl
| Download URL | laziest_import-1.0.1.0-py3-none-any.whl |
|---|---|
| Size | 173.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0b38996c646a521deea91e1ed681b3ed6b94a0b7d5ab35c2f007b1c5f0cce016
|
|
BLAKE2b-256 checksum How to use checksums |
1df61d630013c9482ebaefe854266b1fb6175c16f9c9e1c965444f9360d87b98
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 26, 2026.
Transparency log