exonware-xwlazy 0.1.0.11__tar.gz → 0.1.0.20__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.
- {exonware_xwlazy-0.1.0.11 → exonware_xwlazy-0.1.0.20}/PKG-INFO +89 -11
- {exonware_xwlazy-0.1.0.11 → exonware_xwlazy-0.1.0.20}/README.md +88 -10
- {exonware_xwlazy-0.1.0.11 → exonware_xwlazy-0.1.0.20}/pyproject.toml +1 -1
- exonware_xwlazy-0.1.0.20/src/exonware/__init__.py +26 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/__init__.py +367 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/common/__init__.py +47 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/common/base.py +56 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/common/cache.py +504 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/common/logger.py +257 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/common/services/__init__.py +72 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/common/services/dependency_mapper.py +232 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/common/services/install_async_utils.py +165 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/common/services/install_cache_utils.py +245 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/common/services/keyword_detection.py +283 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/common/services/spec_cache.py +165 -0
- exonware_xwlazy-0.1.0.11/src/xwlazy/lazy/lazy_state.py → exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/common/services/state_manager.py +0 -2
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/common/strategies/__init__.py +28 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/common/strategies/caching_dict.py +44 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/common/strategies/caching_installation.py +88 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/common/strategies/caching_lfu.py +66 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/common/strategies/caching_lru.py +63 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/common/strategies/caching_multitier.py +59 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/common/strategies/caching_ttl.py +59 -0
- {exonware_xwlazy-0.1.0.11/src/xwlazy/lazy → exonware_xwlazy-0.1.0.20/src/exonware/xwlazy}/config.py +51 -21
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/contracts.py +1396 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/defs.py +378 -0
- exonware_xwlazy-0.1.0.11/src/xwlazy/lazy/lazy_errors.py → exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/errors.py +21 -16
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/facade.py +991 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/module/__init__.py +18 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/module/base.py +565 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/module/data.py +17 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/module/facade.py +246 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/module/importer_engine.py +2117 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/module/strategies/__init__.py +22 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/module/strategies/module_helper_lazy.py +93 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/module/strategies/module_helper_simple.py +65 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/module/strategies/module_manager_advanced.py +111 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/module/strategies/module_manager_simple.py +95 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/__init__.py +18 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/base.py +798 -0
- exonware_xwlazy-0.1.0.11/src/xwlazy/lazy/host_conf.py → exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/conf.py +61 -16
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/data.py +17 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/facade.py +480 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/services/__init__.py +84 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/services/async_install_handle.py +87 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/services/config_manager.py +245 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/services/discovery.py +370 -0
- {exonware_xwlazy-0.1.0.11/src/xwlazy/lazy → exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/services}/host_packages.py +43 -20
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/services/install_async.py +277 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/services/install_cache.py +145 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/services/install_interactive.py +59 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/services/install_policy.py +156 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/services/install_registry.py +54 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/services/install_result.py +17 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/services/install_sbom.py +153 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/services/install_utils.py +79 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/services/installer_engine.py +406 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/services/lazy_installer.py +718 -0
- {exonware_xwlazy-0.1.0.11/src/xwlazy/lazy → exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/services}/manifest.py +40 -33
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/services/strategy_registry.py +186 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/strategies/__init__.py +57 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/strategies/package_discovery_file.py +129 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/strategies/package_discovery_hybrid.py +84 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/strategies/package_discovery_manifest.py +101 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/strategies/package_execution_async.py +113 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/strategies/package_execution_cached.py +90 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/strategies/package_execution_pip.py +99 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/strategies/package_execution_wheel.py +106 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/strategies/package_mapping_discovery_first.py +100 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/strategies/package_mapping_hybrid.py +105 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/strategies/package_mapping_manifest_first.py +100 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/strategies/package_policy_allow_list.py +57 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/strategies/package_policy_deny_list.py +57 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/strategies/package_policy_permissive.py +46 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/strategies/package_timing_clean.py +67 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/strategies/package_timing_full.py +66 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/strategies/package_timing_smart.py +68 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/package/strategies/package_timing_temporary.py +66 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/runtime/__init__.py +18 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/runtime/adaptive_learner.py +129 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/runtime/base.py +274 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/runtime/facade.py +94 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/runtime/intelligent_selector.py +170 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/runtime/metrics.py +60 -0
- exonware_xwlazy-0.1.0.20/src/exonware/xwlazy/runtime/performance.py +37 -0
- {exonware_xwlazy-0.1.0.11/src → exonware_xwlazy-0.1.0.20/src/exonware}/xwlazy/version.py +2 -2
- exonware_xwlazy-0.1.0.20/src/xwlazy.py +43 -0
- exonware_xwlazy-0.1.0.20/src/xwlazy_wrapper.py +20 -0
- exonware_xwlazy-0.1.0.11/src/exonware/xwlazy/__init__.py +0 -0
- exonware_xwlazy-0.1.0.11/src/exonware/xwlazy/version.py +0 -77
- exonware_xwlazy-0.1.0.11/src/xwlazy/__init__.py +0 -34
- exonware_xwlazy-0.1.0.11/src/xwlazy/lazy/__init__.py +0 -301
- exonware_xwlazy-0.1.0.11/src/xwlazy/lazy/bootstrap.py +0 -106
- exonware_xwlazy-0.1.0.11/src/xwlazy/lazy/lazy_base.py +0 -465
- exonware_xwlazy-0.1.0.11/src/xwlazy/lazy/lazy_contracts.py +0 -290
- exonware_xwlazy-0.1.0.11/src/xwlazy/lazy/lazy_core.py +0 -3727
- exonware_xwlazy-0.1.0.11/src/xwlazy/lazy/logging_utils.py +0 -194
- {exonware_xwlazy-0.1.0.11 → exonware_xwlazy-0.1.0.20}/.gitignore +0 -0
- {exonware_xwlazy-0.1.0.11 → exonware_xwlazy-0.1.0.20}/LICENSE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: exonware-xwlazy
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.20
|
|
4
4
|
Summary: Marker package that enables lazy install features across the eXonware suite.
|
|
5
5
|
Project-URL: Homepage, https://exonware.com
|
|
6
6
|
Project-URL: Repository, https://github.com/exonware/xwlazy
|
|
@@ -76,14 +76,40 @@ Built-in tracking of module load times, access counts, memory usage, and cache h
|
|
|
76
76
|
|
|
77
77
|
**Why it matters:** Visibility into lazy loading performance helps identify bottlenecks and optimize import strategies.
|
|
78
78
|
|
|
79
|
-
### 🎨 **
|
|
80
|
-
|
|
81
|
-
- **
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
### 🎨 **Two-Dimensional Mode System**
|
|
80
|
+
|
|
81
|
+
xwlazy uses a powerful two-dimensional mode system that separates **loading behavior** from **installation behavior**, giving you precise control over how modules are loaded and when packages are installed.
|
|
82
|
+
|
|
83
|
+
#### **Lazy Load Modes** (When modules load)
|
|
84
|
+
- **NONE:** Standard imports (no lazy loading)
|
|
85
|
+
- **AUTO:** Lazy loading enabled (deferred module loading)
|
|
86
|
+
- **PRELOAD:** Preload all modules on start (parallel loading)
|
|
87
|
+
- **BACKGROUND:** Load modules in background threads (non-blocking)
|
|
88
|
+
- **CACHED:** Cache loaded modules but allow unloading
|
|
89
|
+
|
|
90
|
+
#### **Lazy Install Modes** (When packages install)
|
|
91
|
+
- **NONE:** No auto-installation
|
|
92
|
+
- **SMART:** Install on first usage (on-demand)
|
|
93
|
+
- **FULL:** Install all dependencies on start (parallel batch)
|
|
94
|
+
- **CLEAN:** Install on usage + uninstall after completion
|
|
95
|
+
- **TEMPORARY:** Always uninstall after use (aggressive cleanup)
|
|
96
|
+
- **SIZE_AWARE:** Install small packages, skip large ones
|
|
97
|
+
- **INTERACTIVE:** Ask user before installing
|
|
98
|
+
- **WARN:** Log warning but don't install (monitoring mode)
|
|
99
|
+
- **DISABLED:** Don't install anything (explicit)
|
|
84
100
|
- **DRY_RUN:** Show what would be installed
|
|
85
101
|
|
|
86
|
-
**
|
|
102
|
+
#### **Preset Modes** (Quick combinations)
|
|
103
|
+
- **none:** NONE load + NONE install (standard imports)
|
|
104
|
+
- **lite:** AUTO load + NONE install (lazy loading only)
|
|
105
|
+
- **smart:** AUTO load + SMART install (on-demand installation)
|
|
106
|
+
- **full:** AUTO load + FULL install (install all on start)
|
|
107
|
+
- **clean:** AUTO load + CLEAN install (install + cleanup)
|
|
108
|
+
- **temporary:** AUTO load + TEMPORARY install (aggressive cleanup)
|
|
109
|
+
- **size_aware:** AUTO load + SIZE_AWARE install (smart sizing)
|
|
110
|
+
- **auto:** AUTO load + SMART install + auto-uninstall large packages
|
|
111
|
+
|
|
112
|
+
**Why it matters:** Different environments need different policies. Development might use `smart`, production might use `lite` or `warn`, CI/CD might use `clean` or `temporary`.
|
|
87
113
|
|
|
88
114
|
## 🏆 Performance Benchmarks
|
|
89
115
|
|
|
@@ -215,26 +241,76 @@ import suspicious_package # ❌ Blocked by security policy
|
|
|
215
241
|
|
|
216
242
|
## 🔧 Advanced Configuration
|
|
217
243
|
|
|
218
|
-
###
|
|
244
|
+
### Two-Dimensional Mode Configuration
|
|
245
|
+
|
|
246
|
+
#### Using Preset Modes (Recommended)
|
|
247
|
+
|
|
248
|
+
```python
|
|
249
|
+
from xwlazy.lazy import config_package_lazy_install_enabled
|
|
250
|
+
|
|
251
|
+
# Quick preset modes
|
|
252
|
+
config_package_lazy_install_enabled("xwsystem", enabled=True, mode="smart") # On-demand install
|
|
253
|
+
config_package_lazy_install_enabled("xwsystem", enabled=True, mode="full") # Install all on start
|
|
254
|
+
config_package_lazy_install_enabled("xwsystem", enabled=True, mode="clean") # Install + cleanup
|
|
255
|
+
config_package_lazy_install_enabled("xwsystem", enabled=True, mode="lite") # Lazy load only
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
#### Using Explicit Mode Configuration
|
|
219
259
|
|
|
220
260
|
```python
|
|
221
261
|
from xwlazy.lazy import (
|
|
222
262
|
config_package_lazy_install_enabled,
|
|
263
|
+
LazyLoadMode,
|
|
223
264
|
LazyInstallMode,
|
|
265
|
+
LazyModeConfig,
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
# Explicit two-dimensional configuration
|
|
269
|
+
config_package_lazy_install_enabled(
|
|
270
|
+
"xwsystem",
|
|
271
|
+
enabled=True,
|
|
272
|
+
load_mode=LazyLoadMode.PRELOAD, # Preload all modules
|
|
273
|
+
install_mode=LazyInstallMode.SMART # Install on-demand
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
# Or use LazyModeConfig for full control
|
|
277
|
+
config = LazyModeConfig(
|
|
278
|
+
load_mode=LazyLoadMode.BACKGROUND,
|
|
279
|
+
install_mode=LazyInstallMode.SIZE_AWARE,
|
|
280
|
+
large_package_threshold_mb=100.0, # Skip packages > 100MB
|
|
281
|
+
background_workers=4 # 4 background workers
|
|
224
282
|
)
|
|
283
|
+
config_package_lazy_install_enabled(
|
|
284
|
+
"xwsystem",
|
|
285
|
+
enabled=True,
|
|
286
|
+
mode_config=config
|
|
287
|
+
)
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
#### Using exonware.conf (Global Configuration)
|
|
225
291
|
|
|
292
|
+
```python
|
|
293
|
+
import exonware.conf as conf
|
|
294
|
+
|
|
295
|
+
# Set global lazy mode for all packages
|
|
296
|
+
conf.lazy = "smart" # or "lite", "full", "clean", "auto", etc.
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
#### Special Purpose Modes
|
|
300
|
+
|
|
301
|
+
```python
|
|
226
302
|
# Interactive mode: Ask user before installing
|
|
227
303
|
config_package_lazy_install_enabled(
|
|
228
304
|
"xwsystem",
|
|
229
305
|
enabled=True,
|
|
230
|
-
mode=LazyInstallMode.INTERACTIVE
|
|
306
|
+
mode="interactive" # or LazyInstallMode.INTERACTIVE
|
|
231
307
|
)
|
|
232
308
|
|
|
233
309
|
# Warn mode: Log but don't install (monitoring)
|
|
234
310
|
config_package_lazy_install_enabled(
|
|
235
311
|
"xwsystem",
|
|
236
312
|
enabled=True,
|
|
237
|
-
mode=LazyInstallMode.WARN
|
|
313
|
+
mode="warn" # or LazyInstallMode.WARN
|
|
238
314
|
)
|
|
239
315
|
```
|
|
240
316
|
|
|
@@ -376,5 +452,7 @@ xwlazy is built with inspiration from the Python lazy import ecosystem, particul
|
|
|
376
452
|
|
|
377
453
|
**Part of the eXonware ecosystem** - Enterprise-grade Python libraries for modern software development.
|
|
378
454
|
|
|
379
|
-
*
|
|
455
|
+
*Last Updated: 17-Nov-2025*
|
|
456
|
+
|
|
457
|
+
> **Note:** For the current version, use `from exonware.xwlazy import __version__` or `import exonware.xwlazy; print(exonware.xwlazy.__version__)`
|
|
380
458
|
|
|
@@ -49,14 +49,40 @@ Built-in tracking of module load times, access counts, memory usage, and cache h
|
|
|
49
49
|
|
|
50
50
|
**Why it matters:** Visibility into lazy loading performance helps identify bottlenecks and optimize import strategies.
|
|
51
51
|
|
|
52
|
-
### 🎨 **
|
|
53
|
-
|
|
54
|
-
- **
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
### 🎨 **Two-Dimensional Mode System**
|
|
53
|
+
|
|
54
|
+
xwlazy uses a powerful two-dimensional mode system that separates **loading behavior** from **installation behavior**, giving you precise control over how modules are loaded and when packages are installed.
|
|
55
|
+
|
|
56
|
+
#### **Lazy Load Modes** (When modules load)
|
|
57
|
+
- **NONE:** Standard imports (no lazy loading)
|
|
58
|
+
- **AUTO:** Lazy loading enabled (deferred module loading)
|
|
59
|
+
- **PRELOAD:** Preload all modules on start (parallel loading)
|
|
60
|
+
- **BACKGROUND:** Load modules in background threads (non-blocking)
|
|
61
|
+
- **CACHED:** Cache loaded modules but allow unloading
|
|
62
|
+
|
|
63
|
+
#### **Lazy Install Modes** (When packages install)
|
|
64
|
+
- **NONE:** No auto-installation
|
|
65
|
+
- **SMART:** Install on first usage (on-demand)
|
|
66
|
+
- **FULL:** Install all dependencies on start (parallel batch)
|
|
67
|
+
- **CLEAN:** Install on usage + uninstall after completion
|
|
68
|
+
- **TEMPORARY:** Always uninstall after use (aggressive cleanup)
|
|
69
|
+
- **SIZE_AWARE:** Install small packages, skip large ones
|
|
70
|
+
- **INTERACTIVE:** Ask user before installing
|
|
71
|
+
- **WARN:** Log warning but don't install (monitoring mode)
|
|
72
|
+
- **DISABLED:** Don't install anything (explicit)
|
|
57
73
|
- **DRY_RUN:** Show what would be installed
|
|
58
74
|
|
|
59
|
-
**
|
|
75
|
+
#### **Preset Modes** (Quick combinations)
|
|
76
|
+
- **none:** NONE load + NONE install (standard imports)
|
|
77
|
+
- **lite:** AUTO load + NONE install (lazy loading only)
|
|
78
|
+
- **smart:** AUTO load + SMART install (on-demand installation)
|
|
79
|
+
- **full:** AUTO load + FULL install (install all on start)
|
|
80
|
+
- **clean:** AUTO load + CLEAN install (install + cleanup)
|
|
81
|
+
- **temporary:** AUTO load + TEMPORARY install (aggressive cleanup)
|
|
82
|
+
- **size_aware:** AUTO load + SIZE_AWARE install (smart sizing)
|
|
83
|
+
- **auto:** AUTO load + SMART install + auto-uninstall large packages
|
|
84
|
+
|
|
85
|
+
**Why it matters:** Different environments need different policies. Development might use `smart`, production might use `lite` or `warn`, CI/CD might use `clean` or `temporary`.
|
|
60
86
|
|
|
61
87
|
## 🏆 Performance Benchmarks
|
|
62
88
|
|
|
@@ -188,26 +214,76 @@ import suspicious_package # ❌ Blocked by security policy
|
|
|
188
214
|
|
|
189
215
|
## 🔧 Advanced Configuration
|
|
190
216
|
|
|
191
|
-
###
|
|
217
|
+
### Two-Dimensional Mode Configuration
|
|
218
|
+
|
|
219
|
+
#### Using Preset Modes (Recommended)
|
|
220
|
+
|
|
221
|
+
```python
|
|
222
|
+
from xwlazy.lazy import config_package_lazy_install_enabled
|
|
223
|
+
|
|
224
|
+
# Quick preset modes
|
|
225
|
+
config_package_lazy_install_enabled("xwsystem", enabled=True, mode="smart") # On-demand install
|
|
226
|
+
config_package_lazy_install_enabled("xwsystem", enabled=True, mode="full") # Install all on start
|
|
227
|
+
config_package_lazy_install_enabled("xwsystem", enabled=True, mode="clean") # Install + cleanup
|
|
228
|
+
config_package_lazy_install_enabled("xwsystem", enabled=True, mode="lite") # Lazy load only
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
#### Using Explicit Mode Configuration
|
|
192
232
|
|
|
193
233
|
```python
|
|
194
234
|
from xwlazy.lazy import (
|
|
195
235
|
config_package_lazy_install_enabled,
|
|
236
|
+
LazyLoadMode,
|
|
196
237
|
LazyInstallMode,
|
|
238
|
+
LazyModeConfig,
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
# Explicit two-dimensional configuration
|
|
242
|
+
config_package_lazy_install_enabled(
|
|
243
|
+
"xwsystem",
|
|
244
|
+
enabled=True,
|
|
245
|
+
load_mode=LazyLoadMode.PRELOAD, # Preload all modules
|
|
246
|
+
install_mode=LazyInstallMode.SMART # Install on-demand
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
# Or use LazyModeConfig for full control
|
|
250
|
+
config = LazyModeConfig(
|
|
251
|
+
load_mode=LazyLoadMode.BACKGROUND,
|
|
252
|
+
install_mode=LazyInstallMode.SIZE_AWARE,
|
|
253
|
+
large_package_threshold_mb=100.0, # Skip packages > 100MB
|
|
254
|
+
background_workers=4 # 4 background workers
|
|
197
255
|
)
|
|
256
|
+
config_package_lazy_install_enabled(
|
|
257
|
+
"xwsystem",
|
|
258
|
+
enabled=True,
|
|
259
|
+
mode_config=config
|
|
260
|
+
)
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
#### Using exonware.conf (Global Configuration)
|
|
198
264
|
|
|
265
|
+
```python
|
|
266
|
+
import exonware.conf as conf
|
|
267
|
+
|
|
268
|
+
# Set global lazy mode for all packages
|
|
269
|
+
conf.lazy = "smart" # or "lite", "full", "clean", "auto", etc.
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
#### Special Purpose Modes
|
|
273
|
+
|
|
274
|
+
```python
|
|
199
275
|
# Interactive mode: Ask user before installing
|
|
200
276
|
config_package_lazy_install_enabled(
|
|
201
277
|
"xwsystem",
|
|
202
278
|
enabled=True,
|
|
203
|
-
mode=LazyInstallMode.INTERACTIVE
|
|
279
|
+
mode="interactive" # or LazyInstallMode.INTERACTIVE
|
|
204
280
|
)
|
|
205
281
|
|
|
206
282
|
# Warn mode: Log but don't install (monitoring)
|
|
207
283
|
config_package_lazy_install_enabled(
|
|
208
284
|
"xwsystem",
|
|
209
285
|
enabled=True,
|
|
210
|
-
mode=LazyInstallMode.WARN
|
|
286
|
+
mode="warn" # or LazyInstallMode.WARN
|
|
211
287
|
)
|
|
212
288
|
```
|
|
213
289
|
|
|
@@ -349,5 +425,7 @@ xwlazy is built with inspiration from the Python lazy import ecosystem, particul
|
|
|
349
425
|
|
|
350
426
|
**Part of the eXonware ecosystem** - Enterprise-grade Python libraries for modern software development.
|
|
351
427
|
|
|
352
|
-
*
|
|
428
|
+
*Last Updated: 17-Nov-2025*
|
|
429
|
+
|
|
430
|
+
> **Note:** For the current version, use `from exonware.xwlazy import __version__` or `import exonware.xwlazy; print(exonware.xwlazy.__version__)`
|
|
353
431
|
|
|
@@ -40,7 +40,7 @@ Documentation = "https://github.com/exonware/xwlazy#readme"
|
|
|
40
40
|
Subtree = "https://github.com/Exonware/XWLazy.git"
|
|
41
41
|
|
|
42
42
|
[tool.hatch.version]
|
|
43
|
-
path = "src/xwlazy/version.py"
|
|
43
|
+
path = "src/exonware/xwlazy/version.py"
|
|
44
44
|
|
|
45
45
|
[tool.hatch.build.targets.wheel]
|
|
46
46
|
packages = ["src/exonware", "src/xwlazy"]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""
|
|
2
|
+
exonware package - Enterprise-grade Python framework ecosystem
|
|
3
|
+
|
|
4
|
+
Company: eXonware.com
|
|
5
|
+
Author: Eng. Muhammad AlShehri
|
|
6
|
+
Email: connect@exonware.com
|
|
7
|
+
Generation Date: 2025-01-03
|
|
8
|
+
|
|
9
|
+
This is a namespace package allowing multiple exonware subpackages
|
|
10
|
+
to coexist (xwsystem, xwnode, xwdata, xwlazy, etc.)
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
# Make this a namespace package - DO NOT set __path__
|
|
14
|
+
# This allows both exonware.xwsystem and exonware.xwlazy to coexist
|
|
15
|
+
__path__ = __import__('pkgutil').extend_path(__path__, __name__)
|
|
16
|
+
|
|
17
|
+
# Import version from xwlazy if available, otherwise use default
|
|
18
|
+
try:
|
|
19
|
+
from exonware.xwlazy.version import __version__
|
|
20
|
+
except ImportError:
|
|
21
|
+
__version__ = '0.0.1' # Fallback for namespace package when xwlazy not installed
|
|
22
|
+
|
|
23
|
+
__author__ = 'Eng. Muhammad AlShehri'
|
|
24
|
+
__email__ = 'connect@exonware.com'
|
|
25
|
+
__company__ = 'eXonware.com'
|
|
26
|
+
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
"""
|
|
2
|
+
#exonware/xwlazy/src/exonware/xwlazy/__init__.py
|
|
3
|
+
|
|
4
|
+
xwlazy: Lazy loading and on-demand package installation for Python.
|
|
5
|
+
|
|
6
|
+
The xwlazy library provides automatic dependency installation and lazy loading
|
|
7
|
+
capabilities, allowing packages to declare optional dependencies that are
|
|
8
|
+
installed only when needed.
|
|
9
|
+
|
|
10
|
+
Company: eXonware.com
|
|
11
|
+
Author: Eng. Muhammad AlShehri
|
|
12
|
+
Email: connect@exonware.com
|
|
13
|
+
Generation Date: 10-Oct-2025
|
|
14
|
+
|
|
15
|
+
Main Features:
|
|
16
|
+
- Automatic dependency discovery from pyproject.toml and requirements.txt
|
|
17
|
+
- On-demand package installation via import hooks
|
|
18
|
+
- Two-stage lazy loading for optimal performance
|
|
19
|
+
- Per-package lazy mode configuration
|
|
20
|
+
- Security policies and allow/deny lists
|
|
21
|
+
- SBOM generation and lockfile management
|
|
22
|
+
|
|
23
|
+
Example:
|
|
24
|
+
>>> from exonware.xwlazy import enable_lazy_mode, xwimport
|
|
25
|
+
>>>
|
|
26
|
+
>>> # Enable lazy mode for your package
|
|
27
|
+
>>> enable_lazy_mode(package_name="my_package", lazy_install_mode="smart")
|
|
28
|
+
>>>
|
|
29
|
+
>>> # Import with automatic installation
|
|
30
|
+
>>> pandas = xwimport("pandas") # Installs pandas if not available
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
# =============================================================================
|
|
34
|
+
# VERSION
|
|
35
|
+
# =============================================================================
|
|
36
|
+
|
|
37
|
+
from .version import (
|
|
38
|
+
__version__,
|
|
39
|
+
VERSION_MAJOR,
|
|
40
|
+
VERSION_MINOR,
|
|
41
|
+
VERSION_PATCH,
|
|
42
|
+
VERSION_BUILD,
|
|
43
|
+
VERSION_SUFFIX,
|
|
44
|
+
VERSION_STRING,
|
|
45
|
+
get_version,
|
|
46
|
+
get_version_info,
|
|
47
|
+
get_version_dict,
|
|
48
|
+
is_dev_version,
|
|
49
|
+
is_release_version,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# =============================================================================
|
|
53
|
+
# IMPORTS - Standard Python Imports (No Defensive Code!)
|
|
54
|
+
# =============================================================================
|
|
55
|
+
|
|
56
|
+
# Import from facade - provides unified public API
|
|
57
|
+
from .facade import (
|
|
58
|
+
# Facade functions
|
|
59
|
+
enable_lazy_mode,
|
|
60
|
+
disable_lazy_mode,
|
|
61
|
+
is_lazy_mode_enabled,
|
|
62
|
+
get_lazy_mode_stats,
|
|
63
|
+
configure_lazy_mode,
|
|
64
|
+
preload_modules,
|
|
65
|
+
optimize_lazy_mode,
|
|
66
|
+
# Public API functions
|
|
67
|
+
enable_lazy_install,
|
|
68
|
+
disable_lazy_install,
|
|
69
|
+
is_lazy_install_enabled,
|
|
70
|
+
set_lazy_install_mode,
|
|
71
|
+
get_lazy_install_mode,
|
|
72
|
+
install_missing_package,
|
|
73
|
+
install_and_import,
|
|
74
|
+
get_lazy_install_stats,
|
|
75
|
+
get_all_lazy_install_stats,
|
|
76
|
+
lazy_import_with_install,
|
|
77
|
+
xwimport,
|
|
78
|
+
# Hook functions
|
|
79
|
+
install_import_hook,
|
|
80
|
+
uninstall_import_hook,
|
|
81
|
+
is_import_hook_installed,
|
|
82
|
+
# Lazy loading functions
|
|
83
|
+
enable_lazy_imports,
|
|
84
|
+
disable_lazy_imports,
|
|
85
|
+
is_lazy_import_enabled,
|
|
86
|
+
lazy_import,
|
|
87
|
+
register_lazy_module,
|
|
88
|
+
preload_module,
|
|
89
|
+
get_lazy_module,
|
|
90
|
+
get_loading_stats,
|
|
91
|
+
preload_frequently_used,
|
|
92
|
+
get_lazy_import_stats,
|
|
93
|
+
# Configuration
|
|
94
|
+
config_package_lazy_install_enabled,
|
|
95
|
+
config_module_lazy_load_enabled,
|
|
96
|
+
sync_manifest_configuration,
|
|
97
|
+
refresh_lazy_manifests,
|
|
98
|
+
# Security & Policy
|
|
99
|
+
set_package_allow_list,
|
|
100
|
+
set_package_deny_list,
|
|
101
|
+
add_to_package_allow_list,
|
|
102
|
+
add_to_package_deny_list,
|
|
103
|
+
set_package_index_url,
|
|
104
|
+
set_package_extra_index_urls,
|
|
105
|
+
add_package_trusted_host,
|
|
106
|
+
set_package_lockfile,
|
|
107
|
+
generate_package_sbom,
|
|
108
|
+
check_externally_managed_environment,
|
|
109
|
+
register_lazy_module_prefix,
|
|
110
|
+
register_lazy_module_methods,
|
|
111
|
+
# Keyword-based detection
|
|
112
|
+
enable_keyword_detection,
|
|
113
|
+
is_keyword_detection_enabled,
|
|
114
|
+
get_keyword_detection_keyword,
|
|
115
|
+
check_package_keywords,
|
|
116
|
+
# Discovery functions
|
|
117
|
+
get_lazy_discovery,
|
|
118
|
+
discover_dependencies,
|
|
119
|
+
export_dependency_mappings,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
# Import contracts and base for advanced usage
|
|
123
|
+
from .defs import PRESET_MODES, get_preset_mode
|
|
124
|
+
from .defs import (
|
|
125
|
+
LazyLoadMode,
|
|
126
|
+
LazyInstallMode,
|
|
127
|
+
PathType,
|
|
128
|
+
DependencyInfo,
|
|
129
|
+
LazyModeConfig,
|
|
130
|
+
)
|
|
131
|
+
from .contracts import (
|
|
132
|
+
IPackageHelper,
|
|
133
|
+
IModuleHelper,
|
|
134
|
+
IRuntime,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
# Import errors
|
|
138
|
+
from .errors import (
|
|
139
|
+
LazySystemError,
|
|
140
|
+
LazyInstallError,
|
|
141
|
+
LazyDiscoveryError,
|
|
142
|
+
LazyHookError,
|
|
143
|
+
LazySecurityError,
|
|
144
|
+
ExternallyManagedError,
|
|
145
|
+
DeferredImportError,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# Import config
|
|
149
|
+
from .config import LazyConfig, DEFAULT_LAZY_CONFIG
|
|
150
|
+
|
|
151
|
+
# Import abstract base classes directly from submodules
|
|
152
|
+
from .package.base import APackageHelper
|
|
153
|
+
from .module.base import AModuleHelper
|
|
154
|
+
from .runtime.base import ARuntimeHelper
|
|
155
|
+
|
|
156
|
+
# Import concrete implementations (lazy to prevent circular imports)
|
|
157
|
+
from typing import Any
|
|
158
|
+
|
|
159
|
+
def __getattr__(name: str) -> Any:
|
|
160
|
+
"""Lazy import for concrete facades to prevent circular dependencies."""
|
|
161
|
+
if name == "XWPackageHelper":
|
|
162
|
+
from .package import XWPackageHelper
|
|
163
|
+
return XWPackageHelper
|
|
164
|
+
elif name == "XWModuleHelper":
|
|
165
|
+
from .module import XWModuleHelper
|
|
166
|
+
return XWModuleHelper
|
|
167
|
+
elif name == "XWRuntimeHelper":
|
|
168
|
+
from .runtime import XWRuntimeHelper
|
|
169
|
+
return XWRuntimeHelper
|
|
170
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
171
|
+
|
|
172
|
+
# Import core classes for advanced usage
|
|
173
|
+
from .package.services.config_manager import LazyInstallConfig
|
|
174
|
+
from .package.services import LazyInstallerRegistry, AsyncInstallHandle, LazyInstaller
|
|
175
|
+
from .common.services.dependency_mapper import DependencyMapper
|
|
176
|
+
from .module.importer_engine import (
|
|
177
|
+
LazyMetaPathFinder,
|
|
178
|
+
WatchedPrefixRegistry,
|
|
179
|
+
LazyLoader,
|
|
180
|
+
)
|
|
181
|
+
from .package.services.manifest import LazyManifestLoader, PackageManifest
|
|
182
|
+
from .facade import _lazy_importer
|
|
183
|
+
|
|
184
|
+
# Import internal utilities (for advanced usage)
|
|
185
|
+
from .common.services import (
|
|
186
|
+
check_package_keywords,
|
|
187
|
+
_detect_lazy_installation,
|
|
188
|
+
_detect_meta_info_mode,
|
|
189
|
+
)
|
|
190
|
+
from .module.importer_engine import (
|
|
191
|
+
_set_package_class_hints,
|
|
192
|
+
_get_package_class_hints,
|
|
193
|
+
_clear_all_package_class_hints,
|
|
194
|
+
_spec_for_existing_module,
|
|
195
|
+
)
|
|
196
|
+
from .common.services.spec_cache import (
|
|
197
|
+
_cached_stdlib_check,
|
|
198
|
+
_spec_cache_get,
|
|
199
|
+
_spec_cache_put,
|
|
200
|
+
_spec_cache_clear,
|
|
201
|
+
_cache_spec_if_missing,
|
|
202
|
+
_spec_cache_prune_locked,
|
|
203
|
+
)
|
|
204
|
+
from .package.services import (
|
|
205
|
+
is_externally_managed as _is_externally_managed,
|
|
206
|
+
check_pip_audit_available as _check_pip_audit_available,
|
|
207
|
+
)
|
|
208
|
+
from .module.importer_engine import (
|
|
209
|
+
_is_import_in_progress,
|
|
210
|
+
_mark_import_started,
|
|
211
|
+
_mark_import_finished,
|
|
212
|
+
_lazy_aware_import_module,
|
|
213
|
+
_patch_import_module,
|
|
214
|
+
_unpatch_import_module,
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
# Version info
|
|
218
|
+
__author__ = 'Eng. Muhammad AlShehri'
|
|
219
|
+
__email__ = 'connect@exonware.com'
|
|
220
|
+
__company__ = 'eXonware.com'
|
|
221
|
+
|
|
222
|
+
# =============================================================================
|
|
223
|
+
# PUBLIC API
|
|
224
|
+
# =============================================================================
|
|
225
|
+
|
|
226
|
+
__all__ = [
|
|
227
|
+
# Version
|
|
228
|
+
"__version__",
|
|
229
|
+
"VERSION_MAJOR",
|
|
230
|
+
"VERSION_MINOR",
|
|
231
|
+
"VERSION_PATCH",
|
|
232
|
+
"VERSION_BUILD",
|
|
233
|
+
"VERSION_SUFFIX",
|
|
234
|
+
"VERSION_STRING",
|
|
235
|
+
"get_version",
|
|
236
|
+
"get_version_info",
|
|
237
|
+
"get_version_dict",
|
|
238
|
+
"is_dev_version",
|
|
239
|
+
"is_release_version",
|
|
240
|
+
# Facade functions
|
|
241
|
+
"enable_lazy_mode",
|
|
242
|
+
"disable_lazy_mode",
|
|
243
|
+
"is_lazy_mode_enabled",
|
|
244
|
+
"get_lazy_mode_stats",
|
|
245
|
+
"configure_lazy_mode",
|
|
246
|
+
"preload_modules",
|
|
247
|
+
"optimize_lazy_mode",
|
|
248
|
+
# Public API functions
|
|
249
|
+
"enable_lazy_install",
|
|
250
|
+
"disable_lazy_install",
|
|
251
|
+
"is_lazy_install_enabled",
|
|
252
|
+
"set_lazy_install_mode",
|
|
253
|
+
"get_lazy_install_mode",
|
|
254
|
+
"install_missing_package",
|
|
255
|
+
"install_and_import",
|
|
256
|
+
"get_lazy_install_stats",
|
|
257
|
+
"get_all_lazy_install_stats",
|
|
258
|
+
"lazy_import_with_install",
|
|
259
|
+
"xwimport",
|
|
260
|
+
# Hook functions
|
|
261
|
+
"install_import_hook",
|
|
262
|
+
"uninstall_import_hook",
|
|
263
|
+
"is_import_hook_installed",
|
|
264
|
+
# Lazy loading functions
|
|
265
|
+
"enable_lazy_imports",
|
|
266
|
+
"disable_lazy_imports",
|
|
267
|
+
"is_lazy_import_enabled",
|
|
268
|
+
"lazy_import",
|
|
269
|
+
"register_lazy_module",
|
|
270
|
+
"preload_module",
|
|
271
|
+
"get_lazy_module",
|
|
272
|
+
"get_loading_stats",
|
|
273
|
+
"preload_frequently_used",
|
|
274
|
+
"get_lazy_import_stats",
|
|
275
|
+
# Configuration
|
|
276
|
+
"config_package_lazy_install_enabled",
|
|
277
|
+
"sync_manifest_configuration",
|
|
278
|
+
"refresh_lazy_manifests",
|
|
279
|
+
# Security & Policy
|
|
280
|
+
"set_package_allow_list",
|
|
281
|
+
"set_package_deny_list",
|
|
282
|
+
"add_to_package_allow_list",
|
|
283
|
+
"add_to_package_deny_list",
|
|
284
|
+
"set_package_index_url",
|
|
285
|
+
"set_package_extra_index_urls",
|
|
286
|
+
"add_package_trusted_host",
|
|
287
|
+
"set_package_lockfile",
|
|
288
|
+
"generate_package_sbom",
|
|
289
|
+
"check_externally_managed_environment",
|
|
290
|
+
"register_lazy_module_prefix",
|
|
291
|
+
"register_lazy_module_methods",
|
|
292
|
+
# Keyword-based detection
|
|
293
|
+
"enable_keyword_detection",
|
|
294
|
+
"is_keyword_detection_enabled",
|
|
295
|
+
"get_keyword_detection_keyword",
|
|
296
|
+
"check_package_keywords",
|
|
297
|
+
# Discovery functions
|
|
298
|
+
"get_lazy_discovery",
|
|
299
|
+
"discover_dependencies",
|
|
300
|
+
"export_dependency_mappings",
|
|
301
|
+
# Contracts
|
|
302
|
+
"LazyLoadMode",
|
|
303
|
+
"LazyInstallMode",
|
|
304
|
+
"PathType",
|
|
305
|
+
"DependencyInfo",
|
|
306
|
+
"LazyModeConfig",
|
|
307
|
+
"PRESET_MODES",
|
|
308
|
+
"get_preset_mode",
|
|
309
|
+
"IPackageHelper",
|
|
310
|
+
"IModuleHelper",
|
|
311
|
+
"IRuntime",
|
|
312
|
+
# Abstract base classes
|
|
313
|
+
"APackageHelper",
|
|
314
|
+
"AModuleHelper",
|
|
315
|
+
"ARuntimeHelper",
|
|
316
|
+
# Concrete implementations
|
|
317
|
+
"XWPackageHelper",
|
|
318
|
+
"XWModuleHelper",
|
|
319
|
+
"XWRuntimeHelper",
|
|
320
|
+
# Errors
|
|
321
|
+
"LazySystemError",
|
|
322
|
+
"LazyInstallError",
|
|
323
|
+
"LazyDiscoveryError",
|
|
324
|
+
"LazyHookError",
|
|
325
|
+
"LazySecurityError",
|
|
326
|
+
"ExternallyManagedError",
|
|
327
|
+
"DeferredImportError",
|
|
328
|
+
# Config
|
|
329
|
+
"LazyConfig",
|
|
330
|
+
"DEFAULT_LAZY_CONFIG",
|
|
331
|
+
# Core classes (for advanced usage)
|
|
332
|
+
"LazyInstallConfig",
|
|
333
|
+
"LazyInstallerRegistry",
|
|
334
|
+
"AsyncInstallHandle",
|
|
335
|
+
"LazyInstaller",
|
|
336
|
+
"DependencyMapper",
|
|
337
|
+
"LazyMetaPathFinder",
|
|
338
|
+
"WatchedPrefixRegistry",
|
|
339
|
+
"LazyLoader",
|
|
340
|
+
"LazyManifestLoader",
|
|
341
|
+
"PackageManifest",
|
|
342
|
+
"manifest",
|
|
343
|
+
"_lazy_importer",
|
|
344
|
+
# Internal utilities (for advanced usage)
|
|
345
|
+
"check_package_keywords",
|
|
346
|
+
"_detect_lazy_installation",
|
|
347
|
+
"_detect_meta_info_mode",
|
|
348
|
+
"_set_package_class_hints",
|
|
349
|
+
"_get_package_class_hints",
|
|
350
|
+
"_clear_all_package_class_hints",
|
|
351
|
+
"_spec_for_existing_module",
|
|
352
|
+
"_cached_stdlib_check",
|
|
353
|
+
"_spec_cache_get",
|
|
354
|
+
"_spec_cache_put",
|
|
355
|
+
"_spec_cache_clear",
|
|
356
|
+
"_cache_spec_if_missing",
|
|
357
|
+
"_spec_cache_prune_locked",
|
|
358
|
+
"_is_externally_managed",
|
|
359
|
+
"_check_pip_audit_available",
|
|
360
|
+
"_is_import_in_progress",
|
|
361
|
+
"_mark_import_started",
|
|
362
|
+
"_mark_import_finished",
|
|
363
|
+
"_lazy_aware_import_module",
|
|
364
|
+
"_patch_import_module",
|
|
365
|
+
"_unpatch_import_module",
|
|
366
|
+
]
|
|
367
|
+
|