exonware-xwlazy 0.1.0.11__py3-none-any.whl → 0.1.0.20__py3-none-any.whl
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/__init__.py +26 -0
- exonware/xwlazy/__init__.py +0 -0
- exonware/xwlazy/common/__init__.py +47 -0
- exonware/xwlazy/common/base.py +56 -0
- exonware/xwlazy/common/cache.py +504 -0
- exonware/xwlazy/common/logger.py +257 -0
- exonware/xwlazy/common/services/__init__.py +72 -0
- exonware/xwlazy/common/services/dependency_mapper.py +232 -0
- exonware/xwlazy/common/services/install_async_utils.py +165 -0
- exonware/xwlazy/common/services/install_cache_utils.py +245 -0
- exonware/xwlazy/common/services/keyword_detection.py +283 -0
- exonware/xwlazy/common/services/spec_cache.py +165 -0
- xwlazy/lazy/lazy_state.py → exonware/xwlazy/common/services/state_manager.py +0 -2
- exonware/xwlazy/common/strategies/__init__.py +28 -0
- exonware/xwlazy/common/strategies/caching_dict.py +44 -0
- exonware/xwlazy/common/strategies/caching_installation.py +88 -0
- exonware/xwlazy/common/strategies/caching_lfu.py +66 -0
- exonware/xwlazy/common/strategies/caching_lru.py +63 -0
- exonware/xwlazy/common/strategies/caching_multitier.py +59 -0
- exonware/xwlazy/common/strategies/caching_ttl.py +59 -0
- {xwlazy/lazy → exonware/xwlazy}/config.py +51 -21
- exonware/xwlazy/contracts.py +1396 -0
- exonware/xwlazy/defs.py +378 -0
- xwlazy/lazy/lazy_errors.py → exonware/xwlazy/errors.py +21 -16
- exonware/xwlazy/facade.py +991 -0
- exonware/xwlazy/module/__init__.py +18 -0
- exonware/xwlazy/module/base.py +565 -0
- exonware/xwlazy/module/data.py +17 -0
- exonware/xwlazy/module/facade.py +246 -0
- exonware/xwlazy/module/importer_engine.py +2117 -0
- exonware/xwlazy/module/strategies/__init__.py +22 -0
- exonware/xwlazy/module/strategies/module_helper_lazy.py +93 -0
- exonware/xwlazy/module/strategies/module_helper_simple.py +65 -0
- exonware/xwlazy/module/strategies/module_manager_advanced.py +111 -0
- exonware/xwlazy/module/strategies/module_manager_simple.py +95 -0
- exonware/xwlazy/package/__init__.py +18 -0
- exonware/xwlazy/package/base.py +798 -0
- xwlazy/lazy/host_conf.py → exonware/xwlazy/package/conf.py +61 -16
- exonware/xwlazy/package/data.py +17 -0
- exonware/xwlazy/package/facade.py +480 -0
- exonware/xwlazy/package/services/__init__.py +84 -0
- exonware/xwlazy/package/services/async_install_handle.py +87 -0
- exonware/xwlazy/package/services/config_manager.py +245 -0
- exonware/xwlazy/package/services/discovery.py +370 -0
- {xwlazy/lazy → exonware/xwlazy/package/services}/host_packages.py +43 -20
- exonware/xwlazy/package/services/install_async.py +277 -0
- exonware/xwlazy/package/services/install_cache.py +145 -0
- exonware/xwlazy/package/services/install_interactive.py +59 -0
- exonware/xwlazy/package/services/install_policy.py +156 -0
- exonware/xwlazy/package/services/install_registry.py +54 -0
- exonware/xwlazy/package/services/install_result.py +17 -0
- exonware/xwlazy/package/services/install_sbom.py +153 -0
- exonware/xwlazy/package/services/install_utils.py +79 -0
- exonware/xwlazy/package/services/installer_engine.py +406 -0
- exonware/xwlazy/package/services/lazy_installer.py +718 -0
- {xwlazy/lazy → exonware/xwlazy/package/services}/manifest.py +40 -33
- exonware/xwlazy/package/services/strategy_registry.py +186 -0
- exonware/xwlazy/package/strategies/__init__.py +57 -0
- exonware/xwlazy/package/strategies/package_discovery_file.py +129 -0
- exonware/xwlazy/package/strategies/package_discovery_hybrid.py +84 -0
- exonware/xwlazy/package/strategies/package_discovery_manifest.py +101 -0
- exonware/xwlazy/package/strategies/package_execution_async.py +113 -0
- exonware/xwlazy/package/strategies/package_execution_cached.py +90 -0
- exonware/xwlazy/package/strategies/package_execution_pip.py +99 -0
- exonware/xwlazy/package/strategies/package_execution_wheel.py +106 -0
- exonware/xwlazy/package/strategies/package_mapping_discovery_first.py +100 -0
- exonware/xwlazy/package/strategies/package_mapping_hybrid.py +105 -0
- exonware/xwlazy/package/strategies/package_mapping_manifest_first.py +100 -0
- exonware/xwlazy/package/strategies/package_policy_allow_list.py +57 -0
- exonware/xwlazy/package/strategies/package_policy_deny_list.py +57 -0
- exonware/xwlazy/package/strategies/package_policy_permissive.py +46 -0
- exonware/xwlazy/package/strategies/package_timing_clean.py +67 -0
- exonware/xwlazy/package/strategies/package_timing_full.py +66 -0
- exonware/xwlazy/package/strategies/package_timing_smart.py +68 -0
- exonware/xwlazy/package/strategies/package_timing_temporary.py +66 -0
- exonware/xwlazy/runtime/__init__.py +18 -0
- exonware/xwlazy/runtime/adaptive_learner.py +129 -0
- exonware/xwlazy/runtime/base.py +274 -0
- exonware/xwlazy/runtime/facade.py +94 -0
- exonware/xwlazy/runtime/intelligent_selector.py +170 -0
- exonware/xwlazy/runtime/metrics.py +60 -0
- exonware/xwlazy/runtime/performance.py +37 -0
- exonware/xwlazy/version.py +2 -2
- {exonware_xwlazy-0.1.0.11.dist-info → exonware_xwlazy-0.1.0.20.dist-info}/METADATA +89 -11
- exonware_xwlazy-0.1.0.20.dist-info/RECORD +87 -0
- exonware_xwlazy-0.1.0.11.dist-info/RECORD +0 -20
- xwlazy/__init__.py +0 -34
- xwlazy/lazy/__init__.py +0 -301
- xwlazy/lazy/bootstrap.py +0 -106
- xwlazy/lazy/lazy_base.py +0 -465
- xwlazy/lazy/lazy_contracts.py +0 -290
- xwlazy/lazy/lazy_core.py +0 -3727
- xwlazy/lazy/logging_utils.py +0 -194
- xwlazy/version.py +0 -77
- {exonware_xwlazy-0.1.0.11.dist-info → exonware_xwlazy-0.1.0.20.dist-info}/WHEEL +0 -0
- {exonware_xwlazy-0.1.0.11.dist-info → exonware_xwlazy-0.1.0.20.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module Operations Facade
|
|
3
|
+
|
|
4
|
+
Main facade: XWModuleHelper extends AModuleHelper
|
|
5
|
+
Provides concrete implementation for all module operations.
|
|
6
|
+
Uses strategy pattern for caching, helper, and manager strategies.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sys
|
|
10
|
+
import importlib
|
|
11
|
+
import importlib.util
|
|
12
|
+
from typing import Optional, Dict
|
|
13
|
+
from types import ModuleType
|
|
14
|
+
|
|
15
|
+
from .base import AModuleHelper, APackageHelper
|
|
16
|
+
# Lazy import to avoid circular dependency
|
|
17
|
+
from typing import TYPE_CHECKING
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from ..package.facade import XWPackageHelper
|
|
20
|
+
|
|
21
|
+
# Import from importer_engine for hook and module operations
|
|
22
|
+
from . import importer_engine
|
|
23
|
+
|
|
24
|
+
# Import strategy interfaces
|
|
25
|
+
from ..contracts import ICachingStrategy, IModuleHelperStrategy, IModuleManagerStrategy
|
|
26
|
+
|
|
27
|
+
# Import default strategies
|
|
28
|
+
from ..common.strategies import LRUCache
|
|
29
|
+
from .strategies import LazyHelper, AdvancedManager
|
|
30
|
+
from ..package.services.strategy_registry import StrategyRegistry
|
|
31
|
+
|
|
32
|
+
class XWModuleHelper(AModuleHelper):
|
|
33
|
+
"""
|
|
34
|
+
Concrete implementation of AModuleHelper.
|
|
35
|
+
|
|
36
|
+
Provides simple, clean API for working with modules (what you import).
|
|
37
|
+
Uses XWPackageHelper for package operations and DependencyMapper for module-to-package mapping.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
def __init__(
|
|
41
|
+
self,
|
|
42
|
+
package_name: str = 'default',
|
|
43
|
+
package_helper: Optional[APackageHelper] = None,
|
|
44
|
+
*,
|
|
45
|
+
# Strategy injection
|
|
46
|
+
caching_strategy: Optional[ICachingStrategy] = None,
|
|
47
|
+
helper_strategy: Optional[IModuleHelperStrategy] = None,
|
|
48
|
+
manager_strategy: Optional[IModuleManagerStrategy] = None
|
|
49
|
+
):
|
|
50
|
+
"""
|
|
51
|
+
Initialize XW module helper.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
package_name: Package name for isolation (defaults to 'default')
|
|
55
|
+
package_helper: Optional package helper instance. If None, creates XWPackageHelper.
|
|
56
|
+
caching_strategy: Optional caching strategy. If None, uses LRUCache.
|
|
57
|
+
helper_strategy: Optional helper strategy. If None, uses LazyHelper.
|
|
58
|
+
manager_strategy: Optional manager strategy. If None, uses AdvancedManager.
|
|
59
|
+
"""
|
|
60
|
+
if package_helper is None:
|
|
61
|
+
# Lazy import to avoid circular dependency
|
|
62
|
+
from ..package.facade import XWPackageHelper
|
|
63
|
+
package_helper = XWPackageHelper(package_name)
|
|
64
|
+
super().__init__(package_name, package_helper)
|
|
65
|
+
self._package_name = package_name
|
|
66
|
+
self._package_helper = package_helper
|
|
67
|
+
|
|
68
|
+
# Check registry for stored strategies, otherwise use defaults
|
|
69
|
+
if caching_strategy is None:
|
|
70
|
+
caching_strategy = StrategyRegistry.get_module_strategy(package_name, 'caching')
|
|
71
|
+
if caching_strategy is None:
|
|
72
|
+
caching_strategy = LRUCache(max_size=1000)
|
|
73
|
+
if helper_strategy is None:
|
|
74
|
+
helper_strategy = StrategyRegistry.get_module_strategy(package_name, 'helper')
|
|
75
|
+
if helper_strategy is None:
|
|
76
|
+
helper_strategy = LazyHelper()
|
|
77
|
+
if manager_strategy is None:
|
|
78
|
+
manager_strategy = StrategyRegistry.get_module_strategy(package_name, 'manager')
|
|
79
|
+
if manager_strategy is None:
|
|
80
|
+
manager_strategy = AdvancedManager(
|
|
81
|
+
package_name,
|
|
82
|
+
package_helper,
|
|
83
|
+
caching_strategy,
|
|
84
|
+
helper_strategy
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# Store strategies
|
|
88
|
+
self._caching = caching_strategy
|
|
89
|
+
self._helper = helper_strategy
|
|
90
|
+
self._manager = manager_strategy
|
|
91
|
+
|
|
92
|
+
def _check_module_importability(self, module_name: str) -> bool:
|
|
93
|
+
"""
|
|
94
|
+
Check if module is importable.
|
|
95
|
+
|
|
96
|
+
Uses importlib.util.find_spec to check if module can be imported.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
module_name: Module name to check
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
True if importable, False otherwise
|
|
103
|
+
"""
|
|
104
|
+
try:
|
|
105
|
+
spec = importlib.util.find_spec(module_name)
|
|
106
|
+
return spec is not None
|
|
107
|
+
except (ValueError, AttributeError, ImportError):
|
|
108
|
+
return False
|
|
109
|
+
|
|
110
|
+
def _import_module(self, module_name: str) -> ModuleType:
|
|
111
|
+
"""
|
|
112
|
+
Import a module.
|
|
113
|
+
|
|
114
|
+
Uses importlib.import_module to import the module.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
module_name: Module name to import
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
Imported module
|
|
121
|
+
|
|
122
|
+
Raises:
|
|
123
|
+
ImportError: If module cannot be imported
|
|
124
|
+
"""
|
|
125
|
+
return importlib.import_module(module_name)
|
|
126
|
+
|
|
127
|
+
def _invalidate_import_caches(self) -> None:
|
|
128
|
+
"""
|
|
129
|
+
Invalidate import caches.
|
|
130
|
+
|
|
131
|
+
Uses importlib.invalidate_caches() to clear Python's import caches.
|
|
132
|
+
"""
|
|
133
|
+
importlib.invalidate_caches()
|
|
134
|
+
sys.path_importer_cache.clear()
|
|
135
|
+
|
|
136
|
+
def _create_package_helper(self) -> APackageHelper:
|
|
137
|
+
"""
|
|
138
|
+
Create a package helper instance.
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
XWPackageHelper instance
|
|
142
|
+
"""
|
|
143
|
+
from ..package.facade import XWPackageHelper
|
|
144
|
+
return XWPackageHelper(self._package_name)
|
|
145
|
+
|
|
146
|
+
# Strategy swapping methods
|
|
147
|
+
def swap_cache_strategy(self, new_strategy: ICachingStrategy) -> None:
|
|
148
|
+
"""
|
|
149
|
+
Swap cache strategy at runtime.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
new_strategy: New caching strategy to use
|
|
153
|
+
"""
|
|
154
|
+
self._caching = new_strategy
|
|
155
|
+
# Update manager if it uses caching
|
|
156
|
+
if hasattr(self._manager, '_caching'):
|
|
157
|
+
self._manager._caching = new_strategy
|
|
158
|
+
|
|
159
|
+
def swap_helper_strategy(self, new_strategy: IModuleHelperStrategy) -> None:
|
|
160
|
+
"""
|
|
161
|
+
Swap helper/engine strategy at runtime.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
new_strategy: New helper strategy to use
|
|
165
|
+
"""
|
|
166
|
+
self._helper = new_strategy
|
|
167
|
+
# Update manager if it uses helper
|
|
168
|
+
if hasattr(self._manager, '_helper'):
|
|
169
|
+
self._manager._helper = new_strategy
|
|
170
|
+
|
|
171
|
+
def swap_manager_strategy(self, new_strategy: IModuleManagerStrategy) -> None:
|
|
172
|
+
"""
|
|
173
|
+
Swap manager strategy at runtime.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
new_strategy: New manager strategy to use
|
|
177
|
+
"""
|
|
178
|
+
self._manager = new_strategy
|
|
179
|
+
|
|
180
|
+
# Abstract methods from AModule that need implementation
|
|
181
|
+
def install_hook(self) -> None:
|
|
182
|
+
"""
|
|
183
|
+
Install the import hook into sys.meta_path.
|
|
184
|
+
|
|
185
|
+
Delegates to manager strategy.
|
|
186
|
+
"""
|
|
187
|
+
self._manager.install_hook()
|
|
188
|
+
|
|
189
|
+
def uninstall_hook(self) -> None:
|
|
190
|
+
"""
|
|
191
|
+
Uninstall the import hook from sys.meta_path.
|
|
192
|
+
|
|
193
|
+
Delegates to manager strategy.
|
|
194
|
+
"""
|
|
195
|
+
self._manager.uninstall_hook()
|
|
196
|
+
|
|
197
|
+
def is_hook_installed(self) -> bool:
|
|
198
|
+
"""
|
|
199
|
+
Check if import hook is installed.
|
|
200
|
+
|
|
201
|
+
Uses importer_engine.is_import_hook_installed() to check hook status.
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
True if hook is installed, False otherwise
|
|
205
|
+
"""
|
|
206
|
+
return importer_engine.is_import_hook_installed(self._package_name)
|
|
207
|
+
|
|
208
|
+
def handle_import_error(self, module_name: str) -> Optional[ModuleType]:
|
|
209
|
+
"""
|
|
210
|
+
Handle ImportError by attempting to install and re-import.
|
|
211
|
+
|
|
212
|
+
Delegates to manager strategy.
|
|
213
|
+
|
|
214
|
+
Args:
|
|
215
|
+
module_name: Name of module that failed to import
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
Imported module if successful, None otherwise
|
|
219
|
+
"""
|
|
220
|
+
return self._manager.handle_import_error(module_name)
|
|
221
|
+
|
|
222
|
+
def load_module(self, module_path: str) -> ModuleType:
|
|
223
|
+
"""
|
|
224
|
+
Load a module lazily.
|
|
225
|
+
|
|
226
|
+
Delegates to manager strategy.
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
module_path: Full module path to load
|
|
230
|
+
|
|
231
|
+
Returns:
|
|
232
|
+
Loaded module
|
|
233
|
+
"""
|
|
234
|
+
return self._manager.load_module(module_path)
|
|
235
|
+
|
|
236
|
+
def unload_module(self, module_path: str) -> None:
|
|
237
|
+
"""
|
|
238
|
+
Unload a module from cache.
|
|
239
|
+
|
|
240
|
+
Delegates to manager strategy.
|
|
241
|
+
|
|
242
|
+
Args:
|
|
243
|
+
module_path: Module path to unload
|
|
244
|
+
"""
|
|
245
|
+
self._manager.unload_module(module_path)
|
|
246
|
+
|