exonware-xwlazy 0.1.0.23__py3-none-any.whl → 1.0.1.2__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.
Files changed (96) hide show
  1. exonware/__init__.py +85 -34
  2. exonware/xwlazy/version.py +5 -5
  3. exonware/xwlazy.py +2546 -0
  4. exonware/xwlazy_external_libs.toml +716 -0
  5. {exonware_xwlazy-0.1.0.23.dist-info → exonware_xwlazy-1.0.1.2.dist-info}/METADATA +5 -1
  6. exonware_xwlazy-1.0.1.2.dist-info/RECORD +8 -0
  7. exonware/xwlazy/__init__.py +0 -379
  8. exonware/xwlazy/common/__init__.py +0 -55
  9. exonware/xwlazy/common/base.py +0 -65
  10. exonware/xwlazy/common/cache.py +0 -504
  11. exonware/xwlazy/common/logger.py +0 -257
  12. exonware/xwlazy/common/services/__init__.py +0 -72
  13. exonware/xwlazy/common/services/dependency_mapper.py +0 -250
  14. exonware/xwlazy/common/services/install_async_utils.py +0 -170
  15. exonware/xwlazy/common/services/install_cache_utils.py +0 -245
  16. exonware/xwlazy/common/services/keyword_detection.py +0 -283
  17. exonware/xwlazy/common/services/spec_cache.py +0 -165
  18. exonware/xwlazy/common/services/state_manager.py +0 -84
  19. exonware/xwlazy/common/strategies/__init__.py +0 -28
  20. exonware/xwlazy/common/strategies/caching_dict.py +0 -44
  21. exonware/xwlazy/common/strategies/caching_installation.py +0 -88
  22. exonware/xwlazy/common/strategies/caching_lfu.py +0 -66
  23. exonware/xwlazy/common/strategies/caching_lru.py +0 -63
  24. exonware/xwlazy/common/strategies/caching_multitier.py +0 -59
  25. exonware/xwlazy/common/strategies/caching_ttl.py +0 -59
  26. exonware/xwlazy/common/utils.py +0 -142
  27. exonware/xwlazy/config.py +0 -193
  28. exonware/xwlazy/contracts.py +0 -1533
  29. exonware/xwlazy/defs.py +0 -378
  30. exonware/xwlazy/errors.py +0 -276
  31. exonware/xwlazy/facade.py +0 -1137
  32. exonware/xwlazy/host/__init__.py +0 -8
  33. exonware/xwlazy/host/conf.py +0 -16
  34. exonware/xwlazy/module/__init__.py +0 -18
  35. exonware/xwlazy/module/base.py +0 -622
  36. exonware/xwlazy/module/data.py +0 -17
  37. exonware/xwlazy/module/facade.py +0 -246
  38. exonware/xwlazy/module/importer_engine.py +0 -2964
  39. exonware/xwlazy/module/partial_module_detector.py +0 -275
  40. exonware/xwlazy/module/strategies/__init__.py +0 -22
  41. exonware/xwlazy/module/strategies/module_helper_lazy.py +0 -93
  42. exonware/xwlazy/module/strategies/module_helper_simple.py +0 -65
  43. exonware/xwlazy/module/strategies/module_manager_advanced.py +0 -111
  44. exonware/xwlazy/module/strategies/module_manager_simple.py +0 -95
  45. exonware/xwlazy/package/__init__.py +0 -18
  46. exonware/xwlazy/package/base.py +0 -863
  47. exonware/xwlazy/package/conf.py +0 -324
  48. exonware/xwlazy/package/data.py +0 -17
  49. exonware/xwlazy/package/facade.py +0 -480
  50. exonware/xwlazy/package/services/__init__.py +0 -84
  51. exonware/xwlazy/package/services/async_install_handle.py +0 -87
  52. exonware/xwlazy/package/services/config_manager.py +0 -249
  53. exonware/xwlazy/package/services/discovery.py +0 -435
  54. exonware/xwlazy/package/services/host_packages.py +0 -180
  55. exonware/xwlazy/package/services/install_async.py +0 -291
  56. exonware/xwlazy/package/services/install_cache.py +0 -145
  57. exonware/xwlazy/package/services/install_interactive.py +0 -59
  58. exonware/xwlazy/package/services/install_policy.py +0 -156
  59. exonware/xwlazy/package/services/install_registry.py +0 -54
  60. exonware/xwlazy/package/services/install_result.py +0 -17
  61. exonware/xwlazy/package/services/install_sbom.py +0 -153
  62. exonware/xwlazy/package/services/install_utils.py +0 -79
  63. exonware/xwlazy/package/services/installer_engine.py +0 -406
  64. exonware/xwlazy/package/services/lazy_installer.py +0 -803
  65. exonware/xwlazy/package/services/manifest.py +0 -503
  66. exonware/xwlazy/package/services/strategy_registry.py +0 -324
  67. exonware/xwlazy/package/strategies/__init__.py +0 -57
  68. exonware/xwlazy/package/strategies/package_discovery_file.py +0 -129
  69. exonware/xwlazy/package/strategies/package_discovery_hybrid.py +0 -84
  70. exonware/xwlazy/package/strategies/package_discovery_manifest.py +0 -101
  71. exonware/xwlazy/package/strategies/package_execution_async.py +0 -113
  72. exonware/xwlazy/package/strategies/package_execution_cached.py +0 -90
  73. exonware/xwlazy/package/strategies/package_execution_pip.py +0 -99
  74. exonware/xwlazy/package/strategies/package_execution_wheel.py +0 -106
  75. exonware/xwlazy/package/strategies/package_mapping_discovery_first.py +0 -100
  76. exonware/xwlazy/package/strategies/package_mapping_hybrid.py +0 -105
  77. exonware/xwlazy/package/strategies/package_mapping_manifest_first.py +0 -100
  78. exonware/xwlazy/package/strategies/package_policy_allow_list.py +0 -57
  79. exonware/xwlazy/package/strategies/package_policy_deny_list.py +0 -57
  80. exonware/xwlazy/package/strategies/package_policy_permissive.py +0 -46
  81. exonware/xwlazy/package/strategies/package_timing_clean.py +0 -67
  82. exonware/xwlazy/package/strategies/package_timing_full.py +0 -66
  83. exonware/xwlazy/package/strategies/package_timing_smart.py +0 -68
  84. exonware/xwlazy/package/strategies/package_timing_temporary.py +0 -66
  85. exonware/xwlazy/runtime/__init__.py +0 -18
  86. exonware/xwlazy/runtime/adaptive_learner.py +0 -129
  87. exonware/xwlazy/runtime/base.py +0 -274
  88. exonware/xwlazy/runtime/facade.py +0 -94
  89. exonware/xwlazy/runtime/intelligent_selector.py +0 -170
  90. exonware/xwlazy/runtime/metrics.py +0 -60
  91. exonware/xwlazy/runtime/performance.py +0 -37
  92. exonware_xwlazy-0.1.0.23.dist-info/RECORD +0 -93
  93. xwlazy/__init__.py +0 -14
  94. xwlazy/lazy.py +0 -30
  95. {exonware_xwlazy-0.1.0.23.dist-info → exonware_xwlazy-1.0.1.2.dist-info}/WHEEL +0 -0
  96. {exonware_xwlazy-0.1.0.23.dist-info → exonware_xwlazy-1.0.1.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,324 +0,0 @@
1
- """
2
- #exonware/xwlazy/src/exonware/xwlazy/package/conf.py
3
-
4
- Host-facing configuration helpers for enabling lazy mode via `exonware.conf`.
5
-
6
- This module centralizes the legacy configuration surface so host packages no
7
- longer need to ship their own lazy bootstrap logic. Consumers import
8
- ``exonware.conf`` as before, while the real implementation now lives in
9
- ``xwlazy.package.conf`` to keep lazy concerns within the xwlazy project.
10
-
11
- Company: eXonware.com
12
- Author: Eng. Muhammad AlShehri
13
- Email: connect@exonware.com
14
-
15
- Generation Date: 10-Oct-2025
16
- """
17
-
18
- from __future__ import annotations
19
-
20
- import importlib
21
- import importlib.metadata
22
- import subprocess
23
- import sys
24
- import types
25
- import warnings
26
- from typing import Any, Optional
27
-
28
- # Import from new structure
29
- from .services.host_packages import refresh_host_package
30
- from ..facade import (
31
- config_package_lazy_install_enabled,
32
- install_import_hook,
33
- uninstall_import_hook,
34
- is_import_hook_installed,
35
- is_lazy_install_enabled,
36
- )
37
- from ..defs import get_preset_mode
38
- from .services.config_manager import LazyInstallConfig
39
-
40
- __all__ = ['get_conf_module', '_PackageConfig', '_FilteredStderr', '_LazyConfModule', '_setup_global_warning_filter']
41
-
42
- class _PackageConfig:
43
- """Per-package configuration wrapper."""
44
-
45
- def __init__(self, package_name: str, parent_conf: "_LazyConfModule"):
46
- self._package_name = package_name
47
- self._parent_conf = parent_conf
48
-
49
- @property
50
- def lazy_install(self) -> bool:
51
- """Return lazy install status for this package."""
52
- return is_lazy_install_enabled(self._package_name)
53
-
54
- @lazy_install.setter
55
- def lazy_install(self, value: bool) -> None:
56
- """Enable/disable lazy mode for this package."""
57
- if value:
58
- # Default to "smart" mode when enabling lazy install
59
- # config_package_lazy_install_enabled will register package and install global hook
60
- config_package_lazy_install_enabled(self._package_name, True, mode="smart", install_hook=True)
61
- refresh_host_package(self._package_name)
62
- else:
63
- config_package_lazy_install_enabled(self._package_name, False, install_hook=False)
64
- uninstall_import_hook(self._package_name)
65
-
66
- def lazy_install_status(self) -> dict[str, Any]:
67
- """Return runtime status for this package."""
68
- return {
69
- "package": self._package_name,
70
- "enabled": is_lazy_install_enabled(self._package_name),
71
- "hook_installed": is_import_hook_installed(self._package_name),
72
- "active": is_lazy_install_enabled(self._package_name)
73
- and is_import_hook_installed(self._package_name),
74
- }
75
-
76
- def is_lazy_active(self) -> bool:
77
- """Return True if lazy install + hook are active."""
78
- return self.lazy_install_status()["active"]
79
-
80
- class _FilteredStderr:
81
- """Stderr wrapper that filters out specific warning messages."""
82
-
83
- def __init__(self, original_stderr: Any, filter_patterns: list[str]):
84
- self._original = original_stderr
85
- self._filter_patterns = filter_patterns
86
-
87
- def write(self, text: str) -> int:
88
- """Write to stderr, filtering out unwanted warnings."""
89
- # Case-insensitive matching to catch all variations
90
- if any(pattern.lower() in text.lower() for pattern in self._filter_patterns):
91
- return len(text) # Pretend we wrote it, but don't actually write
92
- return self._original.write(text)
93
-
94
- def flush(self) -> None:
95
- """Flush the original stderr."""
96
- self._original.flush()
97
-
98
- def reconfigure(self, *args, **kwargs):
99
- """Handle reconfigure calls - update original reference and reapply filter."""
100
- result = self._original.reconfigure(*args, **kwargs)
101
- # Ensure filter stays active
102
- if sys.stderr is not self:
103
- sys.stderr = self # type: ignore[assignment]
104
- return result
105
-
106
- def __getattr__(self, name: str):
107
- """Delegate all other attributes to original stderr."""
108
- return getattr(self._original, name)
109
-
110
- class _LazyConfModule(types.ModuleType):
111
- """Configuration module for all exonware packages."""
112
-
113
- def __init__(self, name: str, doc: Optional[str]) -> None:
114
- super().__init__(name, doc)
115
- self._package_configs: dict[str, _PackageConfig] = {}
116
- self._suppress_warnings: bool = True # Default: suppress warnings
117
- self._original_stderr: Optional[Any] = None
118
- self._filtered_stderr: Optional[_FilteredStderr] = None
119
- # Set up warning suppression by default
120
- self._setup_warning_filter()
121
-
122
- # ------------------------------------------------------------------ helpers
123
- def _is_xwlazy_installed(self) -> bool:
124
- try:
125
- importlib.metadata.distribution("exonware-xwlazy")
126
- return True
127
- except importlib.metadata.PackageNotFoundError:
128
- try:
129
- importlib.metadata.distribution("xwlazy")
130
- return True
131
- except importlib.metadata.PackageNotFoundError:
132
- return False
133
- except Exception:
134
- try:
135
- import exonware.xwlazy # noqa: F401
136
- return True
137
- except ImportError:
138
- return False
139
-
140
- def _ensure_xwlazy_installed(self) -> None:
141
- if self._is_xwlazy_installed():
142
- return
143
- try:
144
- result = subprocess.run(
145
- [sys.executable, "-m", "pip", "install", "exonware-xwlazy"],
146
- capture_output=True,
147
- text=True,
148
- check=False,
149
- )
150
- if result.returncode == 0:
151
- print("[OK] Installed exonware-xwlazy for lazy mode")
152
- else:
153
- print(f"[WARN] Failed to install exonware-xwlazy: {result.stderr}")
154
- except Exception as exc: # pragma: no cover - best effort
155
- print(f"[WARN] Could not install exonware-xwlazy: {exc}")
156
-
157
- def _uninstall_xwlazy(self) -> None:
158
- if not self._is_xwlazy_installed():
159
- return
160
- try:
161
- subprocess.run(
162
- [sys.executable, "-m", "pip", "uninstall", "-y", "exonware-xwlazy", "xwlazy"],
163
- capture_output=True,
164
- text=True,
165
- check=False,
166
- )
167
- print("[OK] Uninstalled exonware-xwlazy (lazy mode disabled)")
168
- except Exception as exc: # pragma: no cover
169
- print(f"[WARN] Could not uninstall exonware-xwlazy: {exc}")
170
-
171
- def _get_global_lazy_status(self) -> dict[str, Any]:
172
- """Return aggregate status for DX tooling."""
173
- installed = self._is_xwlazy_installed()
174
- # Check all known packages, not just those in _package_configs
175
- # This ensures we catch hooks installed via register_host_package
176
- known_packages = list(self._package_configs.keys())
177
- # Also check common package names that might have hooks installed
178
- for pkg_name in ("xwsystem", "xwnode", "xwdata", "xwschema", "xwaction", "xwentity"):
179
- if pkg_name not in known_packages and is_import_hook_installed(pkg_name):
180
- known_packages.append(pkg_name)
181
-
182
- hook_installed = any(is_import_hook_installed(pkg) for pkg in known_packages)
183
- # Check if any package has lazy active (including those not yet in _package_configs)
184
- active_configs = any(cfg.is_lazy_active() for cfg in self._package_configs.values())
185
- # Also check directly for packages with hooks and enabled lazy install
186
- active_direct = any(
187
- is_import_hook_installed(pkg) and is_lazy_install_enabled(pkg)
188
- for pkg in known_packages
189
- )
190
-
191
- return {
192
- "xwlazy_installed": installed,
193
- "enabled": installed,
194
- "hook_installed": hook_installed,
195
- "active": active_configs or active_direct,
196
- }
197
-
198
- def _setup_warning_filter(self) -> None:
199
- """Set up or remove the stderr warning filter based on current setting."""
200
- global _ORIGINAL_STDERR, _FILTERED_STDERR
201
- if self._suppress_warnings:
202
- # Use global filter (already set up at module import)
203
- if _FILTERED_STDERR is not None and sys.stderr is not _FILTERED_STDERR:
204
- sys.stderr = _FILTERED_STDERR # type: ignore[assignment]
205
- else:
206
- # Restore original stderr if we were filtering
207
- if _ORIGINAL_STDERR is not None and sys.stderr is _FILTERED_STDERR:
208
- sys.stderr = _ORIGINAL_STDERR
209
-
210
- # ---------------------------------------------------------------- attr API
211
- def __getattr__(self, name: str):
212
- package_names = ("xwsystem", "xwnode", "xwdata", "xwschema", "xwaction", "xwentity")
213
- if name in package_names:
214
- if name not in self._package_configs:
215
- self._package_configs[name] = _PackageConfig(name, self)
216
- return self._package_configs[name]
217
-
218
- if name == "lazy_install":
219
- return self._is_xwlazy_installed()
220
- if name == "lazy":
221
- # Return current lazy mode setting
222
- # Check if any package has lazy enabled and return its mode
223
- for pkg_name in package_names:
224
- if is_lazy_install_enabled(pkg_name):
225
- mode_config = LazyInstallConfig.get_mode_config(pkg_name)
226
- if mode_config:
227
- # Return preset name if matches, otherwise return mode string
228
- from ..defs import PRESET_MODES
229
- for preset_name, preset_config in PRESET_MODES.items():
230
- if (preset_config.load_mode == mode_config.load_mode and
231
- preset_config.install_mode == mode_config.install_mode):
232
- return preset_name
233
- return LazyInstallConfig.get_mode(pkg_name)
234
- return "none"
235
- if name == "lazy_install_status":
236
- return self._get_global_lazy_status
237
- if name == "is_lazy_active":
238
- return any(cfg.is_lazy_active() for cfg in self._package_configs.values())
239
- if name == "suppress_warnings":
240
- return self._suppress_warnings
241
-
242
- raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
243
-
244
- def __setattr__(self, name: str, value) -> None:
245
- if name.startswith("_"):
246
- super().__setattr__(name, value)
247
- return
248
- if name == "lazy_install":
249
- if value:
250
- self._ensure_xwlazy_installed()
251
- # Enable with "smart" mode by default
252
- package_names = ("xwsystem", "xwnode", "xwdata", "xwschema", "xwaction", "xwentity")
253
- for pkg_name in package_names:
254
- config_package_lazy_install_enabled(pkg_name, True, mode="smart", install_hook=True)
255
- else:
256
- package_names = ("xwsystem", "xwnode", "xwdata", "xwschema", "xwaction", "xwentity")
257
- for pkg_name in package_names:
258
- config_package_lazy_install_enabled(pkg_name, False, install_hook=False)
259
- uninstall_import_hook(pkg_name)
260
- self._uninstall_xwlazy()
261
- return
262
- if name == "lazy":
263
- # Support exonware.conf.lazy = "lite"/"smart"/"full"/"clean"/"auto"
264
- mode_map = {
265
- "lite": "lite",
266
- "smart": "smart",
267
- "full": "full",
268
- "clean": "clean",
269
- "auto": "auto",
270
- "temporary": "temporary",
271
- "size_aware": "size_aware",
272
- "none": "none",
273
- }
274
- mode = mode_map.get(str(value).lower(), "smart") # Default to "smart" instead of "auto"
275
- # Apply to all known packages
276
- package_names = ("xwsystem", "xwnode", "xwdata", "xwschema", "xwaction", "xwentity")
277
- for pkg_name in package_names:
278
- config_package_lazy_install_enabled(pkg_name, True, mode, install_hook=True)
279
- return
280
- if name == "suppress_warnings":
281
- self._suppress_warnings = bool(value)
282
- self._setup_warning_filter()
283
- return
284
- super().__setattr__(name, value)
285
-
286
- _CONF_INSTANCE: Optional[_LazyConfModule] = None
287
- _ORIGINAL_STDERR: Optional[Any] = None
288
- _FILTERED_STDERR: Optional[_FilteredStderr] = None
289
-
290
- def _setup_global_warning_filter() -> None:
291
- """Set up global stderr filter for decimal module warnings (called at module import)."""
292
- global _ORIGINAL_STDERR, _FILTERED_STDERR
293
- # Check if a filter is already active (e.g., from exonware/__init__.py or conf.py)
294
- # Check for both our filter class and the early filter class
295
- if (hasattr(sys.stderr, '_original') or
296
- isinstance(sys.stderr, _FilteredStderr) or
297
- type(sys.stderr).__name__ == '_EarlyStderrFilter'):
298
- # Filter already active, use existing one
299
- _FILTERED_STDERR = sys.stderr # type: ignore[assignment]
300
- return
301
- if _ORIGINAL_STDERR is None:
302
- # If stderr has _original, it's already wrapped - use that as original
303
- if hasattr(sys.stderr, '_original'):
304
- _ORIGINAL_STDERR = sys.stderr._original
305
- else:
306
- _ORIGINAL_STDERR = sys.stderr
307
- if _FILTERED_STDERR is None:
308
- _FILTERED_STDERR = _FilteredStderr(
309
- _ORIGINAL_STDERR,
310
- ["mpd_setminalloc", "MPD_MINALLOC", "ignoring request to set", "libmpdec", "context.c:57"]
311
- )
312
- if sys.stderr is not _FILTERED_STDERR:
313
- sys.stderr = _FILTERED_STDERR # type: ignore[assignment]
314
-
315
- # Set up warning filter immediately when module is imported (default: suppress warnings)
316
- # Note: conf.py may have already set up a filter, which is fine
317
- _setup_global_warning_filter()
318
-
319
- def get_conf_module(name: str = "exonware.conf", doc: Optional[str] = None) -> types.ModuleType:
320
- """Return (and memoize) the shared conf module instance."""
321
- global _CONF_INSTANCE
322
- if _CONF_INSTANCE is None:
323
- _CONF_INSTANCE = _LazyConfModule(name, doc)
324
- return _CONF_INSTANCE
@@ -1,17 +0,0 @@
1
- """
2
- Package Data - Immutable data structure for packages.
3
-
4
- Company: eXonware.com
5
- Author: Eng. Muhammad AlShehri
6
- Email: connect@exonware.com
7
-
8
- Generation Date: 15-Nov-2025
9
-
10
- Re-export PackageData from defs.py for backward compatibility.
11
- """
12
-
13
- # Re-export from defs.py
14
- from ..defs import PackageData
15
-
16
- __all__ = ['PackageData']
17
-