Automatic lazy import library - use common libraries without explicit import statements
Project description
laziest-import
A zero-configuration lazy import library. Import and use any installed module with a single line.
from laziest_import import *
arr = np.array([1, 2, 3]) # numpy
df = pd.DataFrame({'a': [1]}) # pandas
plt.plot([1, 2, 3]) # matplotlib
No import numpy as np, no import pandas as pd required.
Installation
pip install laziest-import
Quick Start
Show examples
Method 1: Wildcard import (recommended)
from laziest_import import *
# Common libraries work immediately
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
# Submodules load automatically
result = np.linalg.svd(matrix) # numpy.linalg
Method 2: Namespace prefix
import laziest_import as 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 ✅
# Submodule shortcuts
layer = lazy.nn.Linear(10, 5) # nn -> torch.nn ✅
Key Features
| Feature | Description |
|---|---|
| Modular architecture | Clean 10-module codebase 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 |
| 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 |
| 820+ tests | Comprehensive test coverage |
What's New in v0.0.5-pre1
- Dependency Tree Analysis:
lz.dependency_tree()- analyze module dependency trees - Performance Benchmarking:
lz.benchmark()- benchmark functions and imports - 820+ tests: Comprehensive test coverage across 17+ test files
What's New in v0.0.4
- Background Index Building: Symbol index builds in background thread, no blocking
- Lazy-loaded Functions: Reduced startup time by lazy-loading symbol functions
- Symbol Sharding: Large package symbols stored in shards for faster access
- Symbol Location Finder:
lz.which()- find where symbols are defined - Interactive Help:
lz.help()- comprehensive help system with topics - Jupyter Magics:
%%lazy,%lazyimport,%lazylist,%lazysearch - User Config File:
~/.laziestrcfor persistent configuration - Type Hints Support:
LazySymbol.__class_getitem__for generic type hints - 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
Auto-Install
When enabled, accessing an uninstalled module triggers automatic installation:
from laziest_import import *
# Enable auto-install with interactive confirmation
enable_auto_install()
# Use a mirror for faster downloads
enable_auto_install(index="https://pypi.org/simple")
# Now accessing uninstalled modules prompts for installation
arr = np.array([1, 2, 3]) # If numpy is missing, prompts to install
Auto-install API
| Function | Description |
|---|---|
enable_auto_install(interactive=True, index=None) |
Enable auto-install |
disable_auto_install() |
Disable auto-install |
is_auto_install_enabled() |
Check status |
install_package(name) |
Manually install a package |
set_pip_index(url) |
Set mirror URL |
Predefined Aliases
Show full list
| Category | 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 |
Advanced Features
Dependency Tree Analysis
Analyze module dependencies and visualize import relationships:
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)
# Exclude certain module types
tree = lz.dependency_tree(
'pandas',
max_depth=3,
include_stdlib=False, # Exclude stdlib
include_third_party=True, # Include third-party
include_local=True # Include local modules
)
Performance Benchmarking
Benchmark function execution and import performance:
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")
print(f"Std dev: {result.std_dev*1000:.4f}ms")
# Benchmark module imports
report = lz.benchmark_imports(['numpy', 'pandas', 'matplotlib'])
lz.print_benchmark_report(report)
# Compare lazy vs regular imports
report = lz.benchmark_imports(['numpy'], compare_lazy=True)
for result in report.results:
print(f"{result.name}: {result.avg_time*1000:.2f}ms")
File-based cache
Cache imported modules for faster subsequent runs:
import laziest_import as lz
# View cache status
info = lz.get_file_cache_info()
# {'cache_size_bytes': 12345, 'cache_size_mb': 0.01, 'max_cache_size_mb': 100, ...}
# Set custom cache directory
lz.set_cache_dir('./my_cache')
# Clear cache
lz.clear_file_cache()
Cache configuration
import laziest_import as lz
# Get cache version
version = lz.get_cache_version() # '0.0.2.3'
# 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()
# {'symbol_hits': 10, 'symbol_misses': 2, 'module_hits': 5,
# 'module_misses': 1, 'hit_rate': 0.875, ...}
# Reset statistics
lz.reset_cache_stats()
# Invalidate cache for a specific package (after upgrade)
lz.invalidate_package_cache('numpy')
# Rebuild symbol index
lz.rebuild_symbol_index()
Debug and statistics
import laziest_import as lz
# Enable debug mode
lz.enable_debug_mode()
# Get import statistics
stats = lz.get_import_stats()
# {'total_imports': 3, 'total_time': 0.15, 'module_times': {...}}
# Reset statistics
lz.reset_import_stats()
Import hooks
import laziest_import as lz
def before_import(module_name):
print(f"About to import: {module_name}")
def after_import(module_name, module):
print(f"Imported: {module_name}")
lz.add_pre_import_hook(before_import)
lz.add_post_import_hook(after_import)
Async import
import laziest_import as lz
import asyncio
async def main():
# Import multiple modules in parallel
modules = await lz.import_multiple_async(['numpy', 'pandas', 'torch'])
np, pd = modules['numpy'], modules['pandas']
asyncio.run(main())
Symbol Location Finder
import laziest_import as lz
# Find where a symbol is defined
loc = lz.which('sqrt')
print(loc) # numpy.sqrt
# Find in a specific module
loc = lz.which('DataFrame', 'pandas')
# Find all locations
locs = lz.which_all('sqrt')
for loc in locs:
print(f"{loc.module_name}.{loc.symbol_name}")
Interactive Help
import laziest_import as lz
# General help
print(lz.help())
# Specific topics
print(lz.help('quickstart'))
print(lz.help('which'))
print(lz.help('jupyter'))
Jupyter/IPython Magics
# Load the extension
%load_ext laziest_import
# Import modules lazily in current session
%lazyimport numpy pandas
# List available modules
%lazylist
# Search for symbols
%lazysearch sqrt
%lazysearch DataFrame
# Cell magic for lazy import
%%lazy -m numpy
arr = np.array([1, 2, 3])
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()
Custom aliases
from laziest_import import *
# Register a single alias
register_alias("mylib", "my_awesome_library")
# Register multiple aliases
register_aliases({
"api": "my_api_client",
"db": "my_database_lib",
})
Dependency Pre-Analysis
Scan Python code to predict required imports before execution:
import laziest_import as lz
# Analyze a file
result = lz.analyze_file('my_script.py')
print(result.predicted_imports) # {'numpy', 'pandas', ...}
# Analyze source code directly
code = '''
import numpy as np
import pandas as pd
'''
result = lz.analyze_source(code)
print(result.used_symbols) # {'np', 'pd'}
# Analyze a directory
results = lz.analyze_directory('./src', recursive=True)
for r in results:
print(f"{r.file_path}: {r.predicted_imports}")
Import Profiler
Record module load times and memory usage:
import laziest_import as lz
# Start profiling
lz.start_profiling()
# Your code here
import numpy as np
import pandas as pd
# Stop profiling
lz.stop_profiling()
# Get report
report = lz.get_profile_report()
for name, profile in report.modules.items():
print(f"{name}: {profile.load_time_ms:.2f}ms, {profile.memory_kb:.1f}KB")
# Print formatted report
lz.print_profile_report()
Environment Detection
Detect the current Python environment:
import laziest_import as lz
# Get environment info
env = lz.detect_environment()
print(f"Python: {env.python_version}")
print(f"Executable: {env.executable}")
print(f"Virtual env: {env.virtual_env}")
print(f"Venv type: {env.venv_type}") # 'venv', 'conda', 'virtualenv', None
print(f"Site packages: {env.site_packages}")
# Show formatted info
lz.show_environment()
Conflict Visualization
Find symbols that exist in multiple modules:
import laziest_import as lz
# Find all symbol conflicts
conflicts = lz.find_symbol_conflicts()
for symbol, conflict in conflicts.items():
print(f"{symbol}: {conflict.modules}")
# Show formatted table
lz.show_conflicts()
# Get summary
summary = lz.get_conflicts_summary()
print(f"Total conflicts: {summary['total_conflicts']}")
Persistent Preferences
Save and load user preferences:
import laziest_import as lz
# Set symbol preference
lz.set_symbol_preference('DataFrame', 'pandas')
lz.set_symbol_preference('sqrt', 'math')
# Save to ~/.laziestrc
lz.save_preferences()
# Load preferences
prefs = lz.load_preferences()
# Apply loaded preferences
lz.apply_preferences(prefs)
# Clear preferences
lz.clear_preferences()
API Reference
Show full API
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 cache |
Auto-Search
| Function | Description |
|---|---|
enable_auto_search() |
Enable auto-discovery |
disable_auto_search() |
Disable auto-discovery |
search_module(name) |
Search for a module |
search_class(class_name) |
Search by class name |
rebuild_module_cache() |
Rebuild cache |
Symbol Search
| Function | Description |
|---|---|
enable_symbol_search() |
Enable symbol search |
search_symbol(name) |
Search for classes/functions |
rebuild_symbol_index() |
Rebuild index |
Auto-Install
| Function | Description |
|---|---|
enable_auto_install() |
Enable auto-install |
disable_auto_install() |
Disable auto-install |
install_package(name) |
Install manually |
set_pip_index(url) |
Set mirror URL |
Other
| Function | Description |
|---|---|
get_version(alias) |
Get module version |
reload_module(alias) |
Reload a module |
enable_retry() |
Enable retry mechanism |
enable_file_cache() |
Enable file cache |
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
| Function | Description |
|---|---|
dependency_tree(module, max_depth=3) |
Analyze module dependency tree |
print_dependency_tree(tree) |
Print formatted dependency tree |
Benchmarking
| Function | Description |
|---|---|
benchmark(func, name, iterations=10) |
Benchmark a function |
benchmark_imports(modules, iterations=5) |
Benchmark module imports |
print_benchmark_report(report) |
Print formatted benchmark report |
Environment Detection
| Function | Description |
|---|---|
detect_environment() |
Detect Python environment |
show_environment() |
Display environment info |
Conflict Detection
| Function | Description |
|---|---|
find_symbol_conflicts() |
Find symbol conflicts |
show_conflicts() |
Display conflicts table |
get_conflicts_summary() |
Get conflicts summary |
Preferences
| Function | Description |
|---|---|
save_preferences() |
Save preferences to file |
load_preferences() |
Load preferences from file |
apply_preferences(prefs) |
Apply loaded preferences |
clear_preferences() |
Clear saved preferences |
Configuration
Custom aliases can be configured in:
~/.laziest_import/aliases/A.json,B.json, ... (user global, letter-based)./.laziest_import/A.json,B.json, ... (project level)
// ~/.laziest_import/aliases/M.json
{
"mylib": "my_awesome_library",
"mpl": "matplotlib"
}
Letter-based files load faster - only the relevant file is loaded on demand.
JSON Mappings
All mappings are stored in laziest_import/mappings/ directory:
| File | Description |
|---|---|
abbreviations.json |
Module abbreviations (np → numpy) |
misspellings.json |
Common misspellings (numpi → numpy) |
submodules.json |
Submodule shortcuts (nn → torch.nn) |
package_rename.json |
Package rename mappings (sklearn → scikit-learn) |
symbol_misspellings.json |
Symbol misspellings (dataframe → DataFrame) |
priorities.json |
Module priorities for conflict resolution |
Version Management
Version compatibility is managed centrally in version.json:
{
"_current_version": "0.0.3.1",
"_cache_version": "0.0.3.1",
"aliases": {
"_min_version": "0.0.3",
"_max_version": "0.0.4"
},
"mappings": {
"_min_version": "0.0.3",
"_max_version": "0.0.4"
}
}
If the current version is outside the specified range, a warning is issued:
UserWarning: [laziest-import] aliases: Version 0.0.4 is at or above maximum 0.0.4.
Some alias features may not work correctly.
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
Enable background build to avoid blocking:
lz.enable_background_build()
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
- First run: ~2s to build index
- Cached run: ~0.003s (700x faster!)
- Use
lz.enable_background_build()to avoid blocking on first import - For CI/CD, set
LAZY_BG_BUILD=1to pre-build cache
How It Works
- 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
Requirements
- Python 3.8+
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file laziest_import-0.0.5rc1.tar.gz.
File metadata
- Download URL: laziest_import-0.0.5rc1.tar.gz
- Upload date:
- Size: 171.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9d8e87715ab68366907c82de44c4a23b3441a7c62197909a00b91e40b816a85a
|
|
| MD5 |
a52b64a60427439a92b44b08ec02f4db
|
|
| BLAKE2b-256 |
b0c3516c0814167739bd0cd81f071a393d25f0d018cf767421062d63eec1ef46
|
Provenance
The following attestation bundles were made for laziest_import-0.0.5rc1.tar.gz:
Publisher:
build-publish.yml on ChidcGithub/Laziest-import
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
laziest_import-0.0.5rc1.tar.gz -
Subject digest:
9d8e87715ab68366907c82de44c4a23b3441a7c62197909a00b91e40b816a85a - Sigstore transparency entry: 1293699043
- Sigstore integration time:
-
Permalink:
ChidcGithub/Laziest-import@1391ec340333cbe262a73e60b5c553c2925bc03b -
Branch / Tag:
refs/tags/v0.0.5-pre1 - Owner: https://github.com/ChidcGithub
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build-publish.yml@1391ec340333cbe262a73e60b5c553c2925bc03b -
Trigger Event:
push
-
Statement type:
File details
Details for the file laziest_import-0.0.5rc1-py3-none-any.whl.
File metadata
- Download URL: laziest_import-0.0.5rc1-py3-none-any.whl
- Upload date:
- Size: 138.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e44489c674a2b8946184be5913e89e7f5c647e609b67c428d49738f285905b11
|
|
| MD5 |
6a3215eca3d4f8d1845b2477ad0e8e7c
|
|
| BLAKE2b-256 |
d6887625c1a1fbaafa71d94f8bb032dbceaee60c929f8ab0f62f6089b1f0a427
|
Provenance
The following attestation bundles were made for laziest_import-0.0.5rc1-py3-none-any.whl:
Publisher:
build-publish.yml on ChidcGithub/Laziest-import
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
laziest_import-0.0.5rc1-py3-none-any.whl -
Subject digest:
e44489c674a2b8946184be5913e89e7f5c647e609b67c428d49738f285905b11 - Sigstore transparency entry: 1293699048
- Sigstore integration time:
-
Permalink:
ChidcGithub/Laziest-import@1391ec340333cbe262a73e60b5c553c2925bc03b -
Branch / Tag:
refs/tags/v0.0.5-pre1 - Owner: https://github.com/ChidcGithub
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build-publish.yml@1391ec340333cbe262a73e60b5c553c2925bc03b -
Trigger Event:
push
-
Statement type: