lazyload-py 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lazyload_py-0.1.0/.gitignore +100 -0
- lazyload_py-0.1.0/CHANGELOG.md +28 -0
- lazyload_py-0.1.0/CONTRIBUTING.md +165 -0
- lazyload_py-0.1.0/LICENSE +21 -0
- lazyload_py-0.1.0/PKG-INFO +209 -0
- lazyload_py-0.1.0/README.md +149 -0
- lazyload_py-0.1.0/lazyload/__init__.py +42 -0
- lazyload_py-0.1.0/lazyload/_api.py +257 -0
- lazyload_py-0.1.0/lazyload/_compat.py +627 -0
- lazyload_py-0.1.0/lazyload/_context.py +50 -0
- lazyload_py-0.1.0/lazyload/_decorator.py +51 -0
- lazyload_py-0.1.0/lazyload/_exceptions.py +407 -0
- lazyload_py-0.1.0/lazyload/_lazy.py +34 -0
- lazyload_py-0.1.0/lazyload/_native.py +366 -0
- lazyload_py-0.1.0/lazyload/_types.py +22 -0
- lazyload_py-0.1.0/lazyload/_version.py +153 -0
- lazyload_py-0.1.0/lazyload/py.typed +2 -0
- lazyload_py-0.1.0/pyproject.toml +390 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# ──────────────────────────────────────────────
|
|
2
|
+
# Python-specific
|
|
3
|
+
# ──────────────────────────────────────────────
|
|
4
|
+
__pycache__/
|
|
5
|
+
*.py[cod]
|
|
6
|
+
*$py.class
|
|
7
|
+
*.pyo
|
|
8
|
+
*.pyd
|
|
9
|
+
|
|
10
|
+
# Distribution / packaging
|
|
11
|
+
dist/
|
|
12
|
+
build/
|
|
13
|
+
eggs/
|
|
14
|
+
.eggs/
|
|
15
|
+
*.egg-info/
|
|
16
|
+
*.egg
|
|
17
|
+
MANIFEST
|
|
18
|
+
|
|
19
|
+
# Virtual environments
|
|
20
|
+
.venv/
|
|
21
|
+
venv/
|
|
22
|
+
env/
|
|
23
|
+
ENV/
|
|
24
|
+
.env/
|
|
25
|
+
|
|
26
|
+
# Installer logs
|
|
27
|
+
pip-log.txt
|
|
28
|
+
pip-delete-this-directory.txt
|
|
29
|
+
|
|
30
|
+
# ──────────────────────────────────────────────
|
|
31
|
+
# Testing & coverage
|
|
32
|
+
# ──────────────────────────────────────────────
|
|
33
|
+
.tox/
|
|
34
|
+
.nox/
|
|
35
|
+
.coverage
|
|
36
|
+
.coverage.*
|
|
37
|
+
coverage.xml
|
|
38
|
+
htmlcov/
|
|
39
|
+
.pytest_cache/
|
|
40
|
+
nosetests.xml
|
|
41
|
+
|
|
42
|
+
# ──────────────────────────────────────────────
|
|
43
|
+
# Type checkers
|
|
44
|
+
# ──────────────────────────────────────────────
|
|
45
|
+
.mypy_cache/
|
|
46
|
+
.dmypy.json
|
|
47
|
+
dmypy.json
|
|
48
|
+
.pyright/
|
|
49
|
+
pyrightconfig.json
|
|
50
|
+
|
|
51
|
+
# ──────────────────────────────────────────────
|
|
52
|
+
# Linters / formatters
|
|
53
|
+
# ──────────────────────────────────────────────
|
|
54
|
+
.ruff_cache/
|
|
55
|
+
|
|
56
|
+
# ──────────────────────────────────────────────
|
|
57
|
+
# Documentation
|
|
58
|
+
# ──────────────────────────────────────────────
|
|
59
|
+
docs/_build/
|
|
60
|
+
docs/api/
|
|
61
|
+
site/
|
|
62
|
+
.readthedocs.yaml # keep if you add it intentionally
|
|
63
|
+
|
|
64
|
+
# ──────────────────────────────────────────────
|
|
65
|
+
# Benchmarks
|
|
66
|
+
# ──────────────────────────────────────────────
|
|
67
|
+
benchmarks/.benchmarks/
|
|
68
|
+
benchmarks/results/
|
|
69
|
+
|
|
70
|
+
# ──────────────────────────────────────────────
|
|
71
|
+
# IDEs & editors
|
|
72
|
+
# ──────────────────────────────────────────────
|
|
73
|
+
.vscode/
|
|
74
|
+
.idea/
|
|
75
|
+
*.sublime-project
|
|
76
|
+
*.sublime-workspace
|
|
77
|
+
*.swp
|
|
78
|
+
*.swo
|
|
79
|
+
*~
|
|
80
|
+
|
|
81
|
+
# ──────────────────────────────────────────────
|
|
82
|
+
# OS artifacts
|
|
83
|
+
# ──────────────────────────────────────────────
|
|
84
|
+
.DS_Store
|
|
85
|
+
Thumbs.db
|
|
86
|
+
desktop.ini
|
|
87
|
+
|
|
88
|
+
# ──────────────────────────────────────────────
|
|
89
|
+
# Jupyter / IPython
|
|
90
|
+
# ──────────────────────────────────────────────
|
|
91
|
+
.ipynb_checkpoints/
|
|
92
|
+
*.ipynb
|
|
93
|
+
|
|
94
|
+
# ──────────────────────────────────────────────
|
|
95
|
+
# Secrets & local config
|
|
96
|
+
# ──────────────────────────────────────────────
|
|
97
|
+
.env
|
|
98
|
+
*.env
|
|
99
|
+
.secrets
|
|
100
|
+
secrets.toml
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## [Unreleased]
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Initial project scaffold and package structure.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
### Deprecated
|
|
18
|
+
|
|
19
|
+
### Removed
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
### Security
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
<!-- Releases will be added below this line in the format: -->
|
|
28
|
+
<!-- ## [X.Y.Z] - YYYY-MM-DD -->
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Contributing to lazyload
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to **lazyload**!
|
|
4
|
+
|
|
5
|
+
Whether you're fixing a typo in documentation, reporting a bug, optimizing performance, or implementing a new feature, your contribution is greatly appreciated. We strive to make this project welcoming and accessible to everyone—including first-time open-source contributors.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Table of Contents
|
|
10
|
+
|
|
11
|
+
1. [Code of Conduct](#code-of-conduct)
|
|
12
|
+
2. [First-Time Contributors](#first-time-contributors)
|
|
13
|
+
3. [Development Setup](#development-setup)
|
|
14
|
+
4. [Running Tests](#running-tests)
|
|
15
|
+
5. [Linting & Type Checking](#linting--type-checking)
|
|
16
|
+
6. [Running Benchmarks](#running-benchmarks)
|
|
17
|
+
7. [Submitting a Pull Request](#submitting-a-pull-request)
|
|
18
|
+
8. [Getting Help](#getting-help)
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Code of Conduct
|
|
23
|
+
|
|
24
|
+
This project adheres to the [Contributor Covenant](https://www.contributor-covenant.org/) Code of Conduct. By participating in this project, you agree to maintain a respectful, supportive, and welcoming environment for everyone.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## First-Time Contributors
|
|
29
|
+
|
|
30
|
+
If this is your first time contributing to an open-source Python project:
|
|
31
|
+
- Don't worry if you get stuck or make a mistake! We are happy to help answer questions and guide you through the process.
|
|
32
|
+
- Check out issues labeled [`good first issue`](https://github.com/jithubaiju55/lazyload/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) for beginner-friendly tasks.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Development Setup
|
|
37
|
+
|
|
38
|
+
### 1. Fork & Clone
|
|
39
|
+
|
|
40
|
+
1. Click the **Fork** button at the top-right of the [`lazyload` GitHub repository](https://github.com/jithubaiju55/lazyload).
|
|
41
|
+
2. Clone your fork to your local machine:
|
|
42
|
+
```bash
|
|
43
|
+
git clone https://github.com/jithubaiju55/lazyload.git
|
|
44
|
+
cd lazyload
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 2. Create a Virtual Environment
|
|
48
|
+
|
|
49
|
+
Create and activate an isolated Python 3.10+ virtual environment:
|
|
50
|
+
|
|
51
|
+
**Linux / macOS:**
|
|
52
|
+
```bash
|
|
53
|
+
python3 -m venv .venv
|
|
54
|
+
source .venv/bin/activate
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Windows (PowerShell):**
|
|
58
|
+
```powershell
|
|
59
|
+
python -m venv .venv
|
|
60
|
+
.\.venv\Scripts\Activate.ps1
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 3. Install in Editable Mode
|
|
64
|
+
|
|
65
|
+
Install `lazyload` in editable development mode along with all developer tools (`pytest`, `pytest-cov`, `ruff`, `mypy`):
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install --upgrade pip
|
|
69
|
+
pip install -e ".[dev]"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Running Tests
|
|
75
|
+
|
|
76
|
+
We use **[pytest](https://docs.pytest.org/)** for testing and **pytest-cov** for coverage analysis.
|
|
77
|
+
|
|
78
|
+
Run the entire test suite:
|
|
79
|
+
```bash
|
|
80
|
+
pytest
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Run tests with line-by-line coverage output:
|
|
84
|
+
```bash
|
|
85
|
+
pytest --cov=lazyload --cov-report=term-missing
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Run a specific test file:
|
|
89
|
+
```bash
|
|
90
|
+
pytest tests/test_api.py
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Linting & Type Checking
|
|
96
|
+
|
|
97
|
+
We maintain strict code quality standards using **Ruff** and **Mypy**.
|
|
98
|
+
|
|
99
|
+
### 1. Code Formatting & Linting (Ruff)
|
|
100
|
+
|
|
101
|
+
Check for linting errors across the codebase:
|
|
102
|
+
```bash
|
|
103
|
+
ruff check .
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Automatically fix format and lint issues:
|
|
107
|
+
```bash
|
|
108
|
+
ruff format .
|
|
109
|
+
ruff check --fix .
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 2. Static Type Checking (Mypy)
|
|
113
|
+
|
|
114
|
+
Verify type annotations with Mypy strict mode:
|
|
115
|
+
```bash
|
|
116
|
+
mypy lazyload
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Running Benchmarks
|
|
122
|
+
|
|
123
|
+
`lazyload` includes two standalone benchmark scripts in the `benchmarks/` folder:
|
|
124
|
+
|
|
125
|
+
1. **Startup Deferral Benchmark**:
|
|
126
|
+
```bash
|
|
127
|
+
python benchmarks/bench_startup.py
|
|
128
|
+
```
|
|
129
|
+
2. **Runtime Overhead Benchmark**:
|
|
130
|
+
```bash
|
|
131
|
+
python benchmarks/bench_overhead.py
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Submitting a Pull Request
|
|
137
|
+
|
|
138
|
+
1. **Create a topic branch** off `main`:
|
|
139
|
+
```bash
|
|
140
|
+
git checkout -b feat/my-new-feature
|
|
141
|
+
```
|
|
142
|
+
2. **Make your code changes** following the existing code style and adding tests for any new functionality.
|
|
143
|
+
3. **Verify all checks pass**:
|
|
144
|
+
```bash
|
|
145
|
+
pytest
|
|
146
|
+
ruff check .
|
|
147
|
+
ruff format --check .
|
|
148
|
+
mypy lazyload
|
|
149
|
+
```
|
|
150
|
+
4. **Commit your changes** with descriptive commit messages:
|
|
151
|
+
```bash
|
|
152
|
+
git add .
|
|
153
|
+
git commit -m "feat: add support for custom deferred proxy repr"
|
|
154
|
+
```
|
|
155
|
+
5. **Push your branch** to your fork:
|
|
156
|
+
```bash
|
|
157
|
+
git push origin feat/my-new-feature
|
|
158
|
+
```
|
|
159
|
+
6. **Open a Pull Request** on GitHub against the `main` branch. Provide a concise summary of what your PR changes and why.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Getting Help
|
|
164
|
+
|
|
165
|
+
If you run into any questions, feel free to open a [GitHub Issue](https://github.com/jithubaiju55/lazyload/issues) or comment directly on your active Pull Request. We're excited to collaborate with you!
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 lazyload Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: lazyload-py
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Lazy imports for Python 3.10 through 3.15+ — one API, every version.
|
|
5
|
+
Project-URL: Homepage, https://github.com/jithubaiju55/lazyload
|
|
6
|
+
Project-URL: Repository, https://github.com/jithubaiju55/lazyload
|
|
7
|
+
Project-URL: Issues, https://github.com/jithubaiju55/lazyload/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/jithubaiju55/lazyload/blob/main/CHANGELOG.md
|
|
9
|
+
Author-email: jithubaiju55 <jithubaiju124@gmail.com>
|
|
10
|
+
Maintainer-email: jithubaiju55 <jithubaiju124@gmail.com>
|
|
11
|
+
License: MIT License
|
|
12
|
+
|
|
13
|
+
Copyright (c) 2026 lazyload Contributors
|
|
14
|
+
|
|
15
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
16
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
17
|
+
in the Software without restriction, including without limitation the rights
|
|
18
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
19
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
20
|
+
furnished to do so, subject to the following conditions:
|
|
21
|
+
|
|
22
|
+
The above copyright notice and this permission notice shall be included in all
|
|
23
|
+
copies or substantial portions of the Software.
|
|
24
|
+
|
|
25
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
26
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
27
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
28
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
29
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
30
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
31
|
+
SOFTWARE.
|
|
32
|
+
License-File: LICENSE
|
|
33
|
+
Keywords: cli,import-hooks,imports,lazy,lazy-loading,performance,startup
|
|
34
|
+
Classifier: Development Status :: 3 - Alpha
|
|
35
|
+
Classifier: Intended Audience :: Developers
|
|
36
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
37
|
+
Classifier: Operating System :: OS Independent
|
|
38
|
+
Classifier: Programming Language :: Python :: 3
|
|
39
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
42
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
43
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
44
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
45
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
46
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
47
|
+
Classifier: Topic :: System :: Boot
|
|
48
|
+
Classifier: Topic :: Utilities
|
|
49
|
+
Classifier: Typing :: Typed
|
|
50
|
+
Requires-Python: >=3.10
|
|
51
|
+
Provides-Extra: bench
|
|
52
|
+
Requires-Dist: memory-profiler>=0.61; extra == 'bench'
|
|
53
|
+
Requires-Dist: pytest-benchmark>=4.0; extra == 'bench'
|
|
54
|
+
Provides-Extra: dev
|
|
55
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
56
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
57
|
+
Requires-Dist: pytest>=8.2; extra == 'dev'
|
|
58
|
+
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
59
|
+
Description-Content-Type: text/markdown
|
|
60
|
+
|
|
61
|
+
# lazyload
|
|
62
|
+
|
|
63
|
+
> Eliminate Python startup latency caused by heavy, eager imports.
|
|
64
|
+
|
|
65
|
+
[](https://pypi.org/project/lazyload-py/)
|
|
66
|
+
[](https://pypi.org/project/lazyload-py/)
|
|
67
|
+
[](https://opensource.org/licenses/MIT)
|
|
68
|
+
[](https://github.com/jithubaiju55/lazyload)
|
|
69
|
+
|
|
70
|
+
`lazyload` defers Python module loading until the exact moment an attribute is accessed for the first time, delivering instant application startup with zero configuration.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## The Problem
|
|
75
|
+
|
|
76
|
+
Standard Python imports execute eagerly at module load time. If your CLI tool or web service imports PyTorch, Pandas, or NumPy at the top of the file, Python parses C-extensions, allocates memory, and runs module initialization code immediately—even when executing simple flags like `--help` or handling fast paths that never use those dependencies. Loading heavy libraries eagerly turns what should be a sub-10ms CLI command into a frustating 4-second wait.
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
# Standard eager imports pay 4,000ms startup cost on EVERY execution
|
|
80
|
+
import torch
|
|
81
|
+
import pandas as pd
|
|
82
|
+
import numpy as np
|
|
83
|
+
|
|
84
|
+
def main():
|
|
85
|
+
if "--help" in sys.argv:
|
|
86
|
+
print_help() # Loaded PyTorch just to print text!
|
|
87
|
+
return
|
|
88
|
+
model = torch.load("model.pt")
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## The Solution
|
|
94
|
+
|
|
95
|
+
`lazyload` replaces eager module loading with deferred proxies that register in `sys.modules` instantly. One line of code defers all import work until an attribute is actually accessed during execution. If an execution branch never uses the imported library, the import overhead is eliminated completely.
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
# One line changes everything — <15ms startup time
|
|
99
|
+
import lazyload
|
|
100
|
+
|
|
101
|
+
torch = lazyload.lazy("torch")
|
|
102
|
+
pd = lazyload.lazy("pandas")
|
|
103
|
+
np = lazyload.lazy("numpy")
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Running `--help` now returns in 12 milliseconds.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Features
|
|
111
|
+
|
|
112
|
+
- **Universal Python Support**: Works across Python 3.10, 3.11, 3.12, 3.13, 3.14, and 3.15+.
|
|
113
|
+
- **Zero External Dependencies**: Lightweight pure-Python implementation.
|
|
114
|
+
- **Three Import Styles**: Support for explicit function deferral (`lazy`), context blocks (`lazy_imports`), and function decorators (`@lazy_module`).
|
|
115
|
+
- **Native 3.15 Fast Path**: Automatically leverages Python 3.15+ native PEP 810 lazy module capabilities for interpreter-level execution.
|
|
116
|
+
- **Compatible Shim for Older Versions**: Provides an identical deferred proxy pattern for Python 3.10–3.14.
|
|
117
|
+
- **Drop-in Integration**: No codebase restructuring or module layout changes required.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Installation
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
pip install lazyload-py
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Quick Start
|
|
130
|
+
|
|
131
|
+
### 1. Single Module Deferral (`lazy`)
|
|
132
|
+
|
|
133
|
+
Defer a single heavy library by passing its module name as a string.
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
import lazyload
|
|
137
|
+
|
|
138
|
+
# Registers a deferred proxy instantly (<0.01ms)
|
|
139
|
+
torch = lazyload.lazy("torch")
|
|
140
|
+
|
|
141
|
+
# PyTorch is loaded here, on first attribute access
|
|
142
|
+
tensor = torch.tensor([1.0, 2.0, 3.0])
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 2. Grouped Import Block (`lazy_imports`)
|
|
146
|
+
|
|
147
|
+
Defer multiple standard import statements inside a clean context manager block without altering your import syntax.
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
import lazyload
|
|
151
|
+
|
|
152
|
+
# All imports declared inside the block are deferred automatically
|
|
153
|
+
with lazyload.lazy_imports():
|
|
154
|
+
import numpy as np
|
|
155
|
+
import pandas as pd
|
|
156
|
+
import scipy
|
|
157
|
+
|
|
158
|
+
# Execution continues instantly; modules load on first attribute lookup
|
|
159
|
+
df = pd.DataFrame({"data": [1, 2, 3]})
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### 3. Function Decorator (`lazy_module`)
|
|
163
|
+
|
|
164
|
+
Decorate entry points or CLI handlers to defer all top-level imports inside the function until the function is called for the first time.
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
import lazyload
|
|
168
|
+
|
|
169
|
+
@lazyload.lazy_module
|
|
170
|
+
def run_training_pipeline():
|
|
171
|
+
# Imports inside the function are deferred until execution
|
|
172
|
+
import torch
|
|
173
|
+
import torchvision
|
|
174
|
+
|
|
175
|
+
print("Pipeline started.")
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## How It Works
|
|
181
|
+
|
|
182
|
+
On Python 3.15 and above, `lazyload` delegates directly to the Python interpreter's native PEP 810 lazy module mechanism, leveraging internal engine hooks to eliminate proxy wrapping overhead and allowing the interpreter itself to handle deferred module evaluation.
|
|
183
|
+
|
|
184
|
+
On Python 3.10 through 3.14, `lazyload` installs a lightweight proxy object into `sys.modules` under the target module name. The proxy transparently intercepts attribute lookups, performs the real import on first access, replaces itself in `sys.modules` with the real module, and updates its internal attribute dictionary so subsequent lookups carry zero ongoing overhead.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Benchmarks
|
|
189
|
+
|
|
190
|
+
Measured on a CLI entry point importing PyTorch, Pandas, and NumPy on Python 3.10:
|
|
191
|
+
|
|
192
|
+
| Import Approach | Startup Time | Deferred Overhead | Speedup |
|
|
193
|
+
| :--- | :--- | :--- | :--- |
|
|
194
|
+
| **Eager Standard (`import torch, pandas, numpy`)** | `4,112 ms` | `0 ms` | `1.0×` |
|
|
195
|
+
| **`lazyload` Proxy (`lazyload.lazy(...)`)** | **`12 ms`** | **`4,100 ms`** | **`342.6×`** |
|
|
196
|
+
|
|
197
|
+
*Run the benchmark suite locally using `python benchmarks/bench_startup.py` and `python benchmarks/bench_overhead.py`.*
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Contributing
|
|
202
|
+
|
|
203
|
+
Contributions are welcome! Please review [CONTRIBUTING.md](CONTRIBUTING.md) for developer setup, code guidelines, and testing procedures.
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## License
|
|
208
|
+
|
|
209
|
+
`lazyload` is licensed under the [MIT License](LICENSE).
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# lazyload
|
|
2
|
+
|
|
3
|
+
> Eliminate Python startup latency caused by heavy, eager imports.
|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/lazyload-py/)
|
|
6
|
+
[](https://pypi.org/project/lazyload-py/)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
[](https://github.com/jithubaiju55/lazyload)
|
|
9
|
+
|
|
10
|
+
`lazyload` defers Python module loading until the exact moment an attribute is accessed for the first time, delivering instant application startup with zero configuration.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## The Problem
|
|
15
|
+
|
|
16
|
+
Standard Python imports execute eagerly at module load time. If your CLI tool or web service imports PyTorch, Pandas, or NumPy at the top of the file, Python parses C-extensions, allocates memory, and runs module initialization code immediately—even when executing simple flags like `--help` or handling fast paths that never use those dependencies. Loading heavy libraries eagerly turns what should be a sub-10ms CLI command into a frustating 4-second wait.
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
# Standard eager imports pay 4,000ms startup cost on EVERY execution
|
|
20
|
+
import torch
|
|
21
|
+
import pandas as pd
|
|
22
|
+
import numpy as np
|
|
23
|
+
|
|
24
|
+
def main():
|
|
25
|
+
if "--help" in sys.argv:
|
|
26
|
+
print_help() # Loaded PyTorch just to print text!
|
|
27
|
+
return
|
|
28
|
+
model = torch.load("model.pt")
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## The Solution
|
|
34
|
+
|
|
35
|
+
`lazyload` replaces eager module loading with deferred proxies that register in `sys.modules` instantly. One line of code defers all import work until an attribute is actually accessed during execution. If an execution branch never uses the imported library, the import overhead is eliminated completely.
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
# One line changes everything — <15ms startup time
|
|
39
|
+
import lazyload
|
|
40
|
+
|
|
41
|
+
torch = lazyload.lazy("torch")
|
|
42
|
+
pd = lazyload.lazy("pandas")
|
|
43
|
+
np = lazyload.lazy("numpy")
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Running `--help` now returns in 12 milliseconds.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Features
|
|
51
|
+
|
|
52
|
+
- **Universal Python Support**: Works across Python 3.10, 3.11, 3.12, 3.13, 3.14, and 3.15+.
|
|
53
|
+
- **Zero External Dependencies**: Lightweight pure-Python implementation.
|
|
54
|
+
- **Three Import Styles**: Support for explicit function deferral (`lazy`), context blocks (`lazy_imports`), and function decorators (`@lazy_module`).
|
|
55
|
+
- **Native 3.15 Fast Path**: Automatically leverages Python 3.15+ native PEP 810 lazy module capabilities for interpreter-level execution.
|
|
56
|
+
- **Compatible Shim for Older Versions**: Provides an identical deferred proxy pattern for Python 3.10–3.14.
|
|
57
|
+
- **Drop-in Integration**: No codebase restructuring or module layout changes required.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Installation
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install lazyload-py
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Quick Start
|
|
70
|
+
|
|
71
|
+
### 1. Single Module Deferral (`lazy`)
|
|
72
|
+
|
|
73
|
+
Defer a single heavy library by passing its module name as a string.
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
import lazyload
|
|
77
|
+
|
|
78
|
+
# Registers a deferred proxy instantly (<0.01ms)
|
|
79
|
+
torch = lazyload.lazy("torch")
|
|
80
|
+
|
|
81
|
+
# PyTorch is loaded here, on first attribute access
|
|
82
|
+
tensor = torch.tensor([1.0, 2.0, 3.0])
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 2. Grouped Import Block (`lazy_imports`)
|
|
86
|
+
|
|
87
|
+
Defer multiple standard import statements inside a clean context manager block without altering your import syntax.
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
import lazyload
|
|
91
|
+
|
|
92
|
+
# All imports declared inside the block are deferred automatically
|
|
93
|
+
with lazyload.lazy_imports():
|
|
94
|
+
import numpy as np
|
|
95
|
+
import pandas as pd
|
|
96
|
+
import scipy
|
|
97
|
+
|
|
98
|
+
# Execution continues instantly; modules load on first attribute lookup
|
|
99
|
+
df = pd.DataFrame({"data": [1, 2, 3]})
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 3. Function Decorator (`lazy_module`)
|
|
103
|
+
|
|
104
|
+
Decorate entry points or CLI handlers to defer all top-level imports inside the function until the function is called for the first time.
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
import lazyload
|
|
108
|
+
|
|
109
|
+
@lazyload.lazy_module
|
|
110
|
+
def run_training_pipeline():
|
|
111
|
+
# Imports inside the function are deferred until execution
|
|
112
|
+
import torch
|
|
113
|
+
import torchvision
|
|
114
|
+
|
|
115
|
+
print("Pipeline started.")
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## How It Works
|
|
121
|
+
|
|
122
|
+
On Python 3.15 and above, `lazyload` delegates directly to the Python interpreter's native PEP 810 lazy module mechanism, leveraging internal engine hooks to eliminate proxy wrapping overhead and allowing the interpreter itself to handle deferred module evaluation.
|
|
123
|
+
|
|
124
|
+
On Python 3.10 through 3.14, `lazyload` installs a lightweight proxy object into `sys.modules` under the target module name. The proxy transparently intercepts attribute lookups, performs the real import on first access, replaces itself in `sys.modules` with the real module, and updates its internal attribute dictionary so subsequent lookups carry zero ongoing overhead.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Benchmarks
|
|
129
|
+
|
|
130
|
+
Measured on a CLI entry point importing PyTorch, Pandas, and NumPy on Python 3.10:
|
|
131
|
+
|
|
132
|
+
| Import Approach | Startup Time | Deferred Overhead | Speedup |
|
|
133
|
+
| :--- | :--- | :--- | :--- |
|
|
134
|
+
| **Eager Standard (`import torch, pandas, numpy`)** | `4,112 ms` | `0 ms` | `1.0×` |
|
|
135
|
+
| **`lazyload` Proxy (`lazyload.lazy(...)`)** | **`12 ms`** | **`4,100 ms`** | **`342.6×`** |
|
|
136
|
+
|
|
137
|
+
*Run the benchmark suite locally using `python benchmarks/bench_startup.py` and `python benchmarks/bench_overhead.py`.*
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Contributing
|
|
142
|
+
|
|
143
|
+
Contributions are welcome! Please review [CONTRIBUTING.md](CONTRIBUTING.md) for developer setup, code guidelines, and testing procedures.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## License
|
|
148
|
+
|
|
149
|
+
`lazyload` is licensed under the [MIT License](LICENSE).
|