exonware-xwlazy 0.1.0.19__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.
Files changed (82) hide show
  1. exonware/__init__.py +6 -2
  2. exonware/xwlazy/__init__.py +0 -1
  3. exonware/xwlazy/common/__init__.py +1 -1
  4. exonware/xwlazy/common/base.py +1 -3
  5. exonware/xwlazy/common/cache.py +1 -3
  6. exonware/xwlazy/common/logger.py +1 -12
  7. exonware/xwlazy/common/services/dependency_mapper.py +0 -2
  8. exonware/xwlazy/common/services/install_async_utils.py +1 -5
  9. exonware/xwlazy/common/services/install_cache_utils.py +1 -13
  10. exonware/xwlazy/common/services/keyword_detection.py +0 -9
  11. exonware/xwlazy/common/services/spec_cache.py +1 -9
  12. exonware/xwlazy/common/services/state_manager.py +0 -2
  13. exonware/xwlazy/common/strategies/__init__.py +1 -1
  14. exonware/xwlazy/common/strategies/caching_dict.py +1 -2
  15. exonware/xwlazy/common/strategies/caching_installation.py +1 -2
  16. exonware/xwlazy/common/strategies/caching_lfu.py +1 -2
  17. exonware/xwlazy/common/strategies/caching_lru.py +1 -2
  18. exonware/xwlazy/common/strategies/caching_multitier.py +1 -2
  19. exonware/xwlazy/common/strategies/caching_ttl.py +1 -2
  20. exonware/xwlazy/config.py +1 -3
  21. exonware/xwlazy/contracts.py +1 -15
  22. exonware/xwlazy/defs.py +0 -19
  23. exonware/xwlazy/errors.py +1 -9
  24. exonware/xwlazy/facade.py +1 -59
  25. exonware/xwlazy/module/base.py +1 -5
  26. exonware/xwlazy/module/data.py +1 -1
  27. exonware/xwlazy/module/facade.py +0 -1
  28. exonware/xwlazy/module/importer_engine.py +1 -45
  29. exonware/xwlazy/module/strategies/__init__.py +1 -1
  30. exonware/xwlazy/module/strategies/module_helper_lazy.py +1 -2
  31. exonware/xwlazy/module/strategies/module_helper_simple.py +1 -2
  32. exonware/xwlazy/module/strategies/module_manager_advanced.py +1 -2
  33. exonware/xwlazy/module/strategies/module_manager_simple.py +1 -2
  34. exonware/xwlazy/package/base.py +1 -10
  35. exonware/xwlazy/package/conf.py +1 -8
  36. exonware/xwlazy/package/data.py +1 -1
  37. exonware/xwlazy/package/facade.py +0 -1
  38. exonware/xwlazy/package/services/async_install_handle.py +1 -3
  39. exonware/xwlazy/package/services/config_manager.py +0 -1
  40. exonware/xwlazy/package/services/discovery.py +1 -5
  41. exonware/xwlazy/package/services/host_packages.py +0 -4
  42. exonware/xwlazy/package/services/install_async.py +1 -2
  43. exonware/xwlazy/package/services/install_cache.py +1 -2
  44. exonware/xwlazy/package/services/install_interactive.py +1 -2
  45. exonware/xwlazy/package/services/install_policy.py +1 -3
  46. exonware/xwlazy/package/services/install_registry.py +1 -3
  47. exonware/xwlazy/package/services/install_result.py +1 -1
  48. exonware/xwlazy/package/services/install_sbom.py +1 -2
  49. exonware/xwlazy/package/services/install_utils.py +1 -5
  50. exonware/xwlazy/package/services/installer_engine.py +1 -3
  51. exonware/xwlazy/package/services/lazy_installer.py +1 -3
  52. exonware/xwlazy/package/services/manifest.py +0 -10
  53. exonware/xwlazy/package/services/strategy_registry.py +1 -3
  54. exonware/xwlazy/package/strategies/package_discovery_file.py +1 -2
  55. exonware/xwlazy/package/strategies/package_discovery_hybrid.py +1 -2
  56. exonware/xwlazy/package/strategies/package_discovery_manifest.py +1 -2
  57. exonware/xwlazy/package/strategies/package_execution_async.py +1 -2
  58. exonware/xwlazy/package/strategies/package_execution_cached.py +1 -2
  59. exonware/xwlazy/package/strategies/package_execution_pip.py +1 -2
  60. exonware/xwlazy/package/strategies/package_execution_wheel.py +1 -2
  61. exonware/xwlazy/package/strategies/package_mapping_discovery_first.py +1 -2
  62. exonware/xwlazy/package/strategies/package_mapping_hybrid.py +1 -2
  63. exonware/xwlazy/package/strategies/package_mapping_manifest_first.py +1 -2
  64. exonware/xwlazy/package/strategies/package_policy_allow_list.py +1 -2
  65. exonware/xwlazy/package/strategies/package_policy_deny_list.py +1 -2
  66. exonware/xwlazy/package/strategies/package_policy_permissive.py +1 -2
  67. exonware/xwlazy/package/strategies/package_timing_clean.py +1 -2
  68. exonware/xwlazy/package/strategies/package_timing_full.py +1 -2
  69. exonware/xwlazy/package/strategies/package_timing_smart.py +1 -2
  70. exonware/xwlazy/package/strategies/package_timing_temporary.py +1 -2
  71. exonware/xwlazy/runtime/adaptive_learner.py +1 -3
  72. exonware/xwlazy/runtime/base.py +1 -3
  73. exonware/xwlazy/runtime/facade.py +0 -1
  74. exonware/xwlazy/runtime/intelligent_selector.py +1 -4
  75. exonware/xwlazy/runtime/metrics.py +0 -4
  76. exonware/xwlazy/runtime/performance.py +0 -2
  77. exonware/xwlazy/version.py +2 -2
  78. {exonware_xwlazy-0.1.0.19.dist-info → exonware_xwlazy-0.1.0.20.dist-info}/METADATA +4 -2
  79. exonware_xwlazy-0.1.0.20.dist-info/RECORD +87 -0
  80. exonware_xwlazy-0.1.0.19.dist-info/RECORD +0 -87
  81. {exonware_xwlazy-0.1.0.19.dist-info → exonware_xwlazy-0.1.0.20.dist-info}/WHEEL +0 -0
  82. {exonware_xwlazy-0.1.0.19.dist-info → exonware_xwlazy-0.1.0.20.dist-info}/licenses/LICENSE +0 -0
@@ -6,7 +6,7 @@ Import Engine - Unified engine for all import-related operations.
6
6
  Company: eXonware.com
7
7
  Author: Eng. Muhammad AlShehri
8
8
  Email: connect@exonware.com
9
- Version: 0.1.0.19
9
+
10
10
  Generation Date: 15-Nov-2025
11
11
 
12
12
  This module provides unified import engine for all import-related functionality.
@@ -86,14 +86,12 @@ from ..common.cache import MultiTierCache, BytecodeCache
86
86
  from ..runtime.adaptive_learner import AdaptiveLearner
87
87
  from ..runtime.intelligent_selector import IntelligentModeSelector, LoadLevel
88
88
 
89
-
90
89
  # =============================================================================
91
90
  # LOGGER (from common.logger)
92
91
  # =============================================================================
93
92
 
94
93
  logger = get_logger("xwlazy.importer_engine")
95
94
 
96
-
97
95
  # =============================================================================
98
96
  # IMPORT TRACKING (from import_tracking.py)
99
97
  # =============================================================================
@@ -105,39 +103,32 @@ _installing = threading.local()
105
103
  _installation_depth = 0
106
104
  _installation_depth_lock = threading.Lock()
107
105
 
108
-
109
106
  def _get_thread_imports() -> Set[str]:
110
107
  """Get thread-local import set (creates if needed)."""
111
108
  if not hasattr(_thread_local, 'imports'):
112
109
  _thread_local.imports = set()
113
110
  return _thread_local.imports
114
111
 
115
-
116
112
  def _is_import_in_progress(module_name: str) -> bool:
117
113
  """Check if a module import is currently in progress for this thread."""
118
114
  return module_name in _get_thread_imports()
119
115
 
120
-
121
116
  def _mark_import_started(module_name: str) -> None:
122
117
  """Mark a module import as started for this thread."""
123
118
  _get_thread_imports().add(module_name)
124
119
 
125
-
126
120
  def _mark_import_finished(module_name: str) -> None:
127
121
  """Mark a module import as finished for this thread."""
128
122
  _get_thread_imports().discard(module_name)
129
123
 
130
-
131
124
  def get_importing_state() -> threading.local:
132
125
  """Get thread-local importing state."""
133
126
  return _importing
134
127
 
135
-
136
128
  def get_installing_state() -> threading.local:
137
129
  """Get thread-local installing state."""
138
130
  return _installing
139
131
 
140
-
141
132
  # Thread-local storage for installation state
142
133
  _installing_state = get_installing_state()
143
134
  _importing_state = get_importing_state()
@@ -146,7 +137,6 @@ _importing_state = get_importing_state()
146
137
  _installation_depth = 0
147
138
  _installation_depth_lock = threading.Lock()
148
139
 
149
-
150
140
  # =============================================================================
151
141
  # PREFIX TRIE (from prefix_trie.py)
152
142
  # =============================================================================
@@ -183,7 +173,6 @@ class _PrefixTrie:
183
173
  matches.append(end_value)
184
174
  return tuple(matches)
185
175
 
186
-
187
176
  # =============================================================================
188
177
  # WATCHED REGISTRY (from watched_registry.py)
189
178
  # =============================================================================
@@ -315,7 +304,6 @@ class WatchedPrefixRegistry:
315
304
  self._root_snapshot_dirty = False
316
305
  return root_name in self._root_snapshot
317
306
 
318
-
319
307
  # Global registry instance
320
308
  _DEFAULT_WATCHED_PREFIXES = tuple(
321
309
  filter(
@@ -328,12 +316,10 @@ _DEFAULT_WATCHED_PREFIXES = tuple(
328
316
  )
329
317
  _watched_registry = WatchedPrefixRegistry(list(_DEFAULT_WATCHED_PREFIXES))
330
318
 
331
-
332
319
  def get_watched_registry() -> WatchedPrefixRegistry:
333
320
  """Get the global watched prefix registry."""
334
321
  return _watched_registry
335
322
 
336
-
337
323
  # =============================================================================
338
324
  # DEFERRED LOADER (from deferred_loader.py)
339
325
  # =============================================================================
@@ -350,7 +336,6 @@ class _DeferredModuleLoader(importlib.abc.Loader):
350
336
  def exec_module(self, module): # noqa: D401 - nothing to execute
351
337
  return None
352
338
 
353
-
354
339
  # =============================================================================
355
340
  # CACHE (from common.cache)
356
341
  # =============================================================================
@@ -419,7 +404,6 @@ class ParallelLoader:
419
404
  self._executor.shutdown(wait=wait)
420
405
  self._executor = None
421
406
 
422
-
423
407
  class DependencyGraph:
424
408
  """Manages module dependencies for optimal parallel loading."""
425
409
 
@@ -470,14 +454,12 @@ class DependencyGraph:
470
454
 
471
455
  return levels
472
456
 
473
-
474
457
  # =============================================================================
475
458
  # MODULE PATCHING (from module_patching.py)
476
459
  # =============================================================================
477
460
 
478
461
  _original_import_module = importlib.import_module
479
462
 
480
-
481
463
  def _lazy_aware_import_module(name: str, package: Optional[str] = None) -> ModuleType:
482
464
  """Lazy-aware version of importlib.import_module."""
483
465
  if _is_import_in_progress(name):
@@ -489,19 +471,16 @@ def _lazy_aware_import_module(name: str, package: Optional[str] = None) -> Modul
489
471
  finally:
490
472
  _mark_import_finished(name)
491
473
 
492
-
493
474
  def _patch_import_module() -> None:
494
475
  """Patch importlib.import_module to be lazy-aware."""
495
476
  importlib.import_module = _lazy_aware_import_module
496
477
  logger.debug("Patched importlib.import_module to be lazy-aware")
497
478
 
498
-
499
479
  def _unpatch_import_module() -> None:
500
480
  """Restore original importlib.import_module."""
501
481
  importlib.import_module = _original_import_module
502
482
  logger.debug("Restored original importlib.import_module")
503
483
 
504
-
505
484
  # =============================================================================
506
485
  # ARCHIVE IMPORTS (from archive_imports.py)
507
486
  # =============================================================================
@@ -509,7 +488,6 @@ def _unpatch_import_module() -> None:
509
488
  _archive_path = None
510
489
  _archive_added = False
511
490
 
512
-
513
491
  def get_archive_path() -> Path:
514
492
  """Get the path to the _archive folder."""
515
493
  global _archive_path
@@ -518,7 +496,6 @@ def get_archive_path() -> Path:
518
496
  _archive_path = current_file.parent.parent.parent.parent.parent.parent / "_archive"
519
497
  return _archive_path
520
498
 
521
-
522
499
  def ensure_archive_in_path() -> None:
523
500
  """Ensure the archive folder is in sys.path for imports."""
524
501
  global _archive_added
@@ -529,13 +506,11 @@ def ensure_archive_in_path() -> None:
529
506
  sys.path.insert(0, archive_str)
530
507
  _archive_added = True
531
508
 
532
-
533
509
  def import_from_archive(module_name: str):
534
510
  """Import a module from the archived lazy code."""
535
511
  ensure_archive_in_path()
536
512
  return __import__(module_name, fromlist=[''])
537
513
 
538
-
539
514
  # =============================================================================
540
515
  # BOOTSTRAP (from bootstrap.py)
541
516
  # =============================================================================
@@ -550,7 +525,6 @@ def _env_enabled(env_value: Optional[str]) -> Optional[bool]:
550
525
  return False
551
526
  return None
552
527
 
553
-
554
528
  def bootstrap_lazy_mode(package_name: str) -> None:
555
529
  """Detect whether lazy mode should be enabled for ``package_name`` and bootstrap hooks."""
556
530
  package_name = package_name.lower()
@@ -573,7 +547,6 @@ def bootstrap_lazy_mode(package_name: str) -> None:
573
547
  install_hook=True,
574
548
  )
575
549
 
576
-
577
550
  def bootstrap_lazy_mode_deferred(package_name: str) -> None:
578
551
  """Schedule lazy mode bootstrap to run AFTER the calling package finishes importing."""
579
552
  package_name_lower = package_name.lower()
@@ -605,7 +578,6 @@ def bootstrap_lazy_mode_deferred(package_name: str) -> None:
605
578
  import builtins
606
579
  builtins.__import__ = _import_hook
607
580
 
608
-
609
581
  # =============================================================================
610
582
  # LAZY LOADER (from loader.py)
611
583
  # =============================================================================
@@ -668,7 +640,6 @@ class LazyLoader(AModuleHelper):
668
640
  module = self.load_module()
669
641
  return dir(module)
670
642
 
671
-
672
643
  # =============================================================================
673
644
  # LAZY MODULE REGISTRY (from registry.py)
674
645
  # =============================================================================
@@ -739,7 +710,6 @@ class LazyModuleRegistry:
739
710
  loader.unload_module(loader._module_path)
740
711
  log_event("config", logger.info, "Cleared all cached modules")
741
712
 
742
-
743
713
  # =============================================================================
744
714
  # LAZY IMPORTER (from importer.py)
745
715
  # =============================================================================
@@ -1306,7 +1276,6 @@ class LazyImporter:
1306
1276
  'total_loaded': len(self._loaded_modules)
1307
1277
  }
1308
1278
 
1309
-
1310
1279
  # =============================================================================
1311
1280
  # IMPORT HOOK (from import_hook.py)
1312
1281
  # =============================================================================
@@ -1347,7 +1316,6 @@ class LazyImportHook(AModuleHelper):
1347
1316
  """Check if hook is installed."""
1348
1317
  return is_import_hook_installed(self._package_name)
1349
1318
 
1350
-
1351
1319
  # =============================================================================
1352
1320
  # META PATH FINDER (from meta_path_finder.py)
1353
1321
  # =============================================================================
@@ -1371,7 +1339,6 @@ _lazy_prefix_method_registry: Dict[str, Tuple[str, ...]] = {}
1371
1339
  _package_class_hints: Dict[str, Tuple[str, ...]] = {}
1372
1340
  _class_hint_lock = threading.RLock()
1373
1341
 
1374
-
1375
1342
  def _set_package_class_hints(package_name: str, hints: Iterable[str]) -> None:
1376
1343
  """Set class hints for a package."""
1377
1344
  normalized: Tuple[str, ...] = tuple(
@@ -1383,19 +1350,16 @@ def _set_package_class_hints(package_name: str, hints: Iterable[str]) -> None:
1383
1350
  else:
1384
1351
  _package_class_hints.pop(package_name, None)
1385
1352
 
1386
-
1387
1353
  def _get_package_class_hints(package_name: str) -> Tuple[str, ...]:
1388
1354
  """Get class hints for a package."""
1389
1355
  with _class_hint_lock:
1390
1356
  return _package_class_hints.get(package_name, ())
1391
1357
 
1392
-
1393
1358
  def _clear_all_package_class_hints() -> None:
1394
1359
  """Clear all package class hints."""
1395
1360
  with _class_hint_lock:
1396
1361
  _package_class_hints.clear()
1397
1362
 
1398
-
1399
1363
  def register_lazy_module_methods(prefix: str, methods: Tuple[str, ...]) -> None:
1400
1364
  """Register method names to enhance for all classes under a module prefix."""
1401
1365
  prefix = prefix.strip()
@@ -1408,7 +1372,6 @@ def register_lazy_module_methods(prefix: str, methods: Tuple[str, ...]) -> None:
1408
1372
  _lazy_prefix_method_registry[prefix] = methods
1409
1373
  log_event("config", logger.info, f"Registered lazy module methods for prefix {prefix}: {methods}")
1410
1374
 
1411
-
1412
1375
  def _spec_for_existing_module(
1413
1376
  fullname: str,
1414
1377
  module: ModuleType,
@@ -1426,7 +1389,6 @@ def _spec_for_existing_module(
1426
1389
  module.__spec__ = spec
1427
1390
  return spec
1428
1391
 
1429
-
1430
1392
  class LazyMetaPathFinder:
1431
1393
  """
1432
1394
  Custom meta path finder that intercepts failed imports.
@@ -2037,12 +1999,10 @@ class LazyMetaPathFinder:
2037
1999
 
2038
2000
  return LazyClassWrapper
2039
2001
 
2040
-
2041
2002
  # Registry of installed hooks per package
2042
2003
  _installed_hooks: Dict[str, LazyMetaPathFinder] = {}
2043
2004
  _hook_lock = threading.RLock()
2044
2005
 
2045
-
2046
2006
  def install_import_hook(package_name: str = 'default') -> None:
2047
2007
  """Install performant import hook for automatic lazy installation."""
2048
2008
  global _installed_hooks
@@ -2063,7 +2023,6 @@ def install_import_hook(package_name: str = 'default') -> None:
2063
2023
 
2064
2024
  log_event("hook", logger.info, f"✅ [HOOK INSTALL] Lazy import hook installed for {package_name} (now {len(sys.meta_path)} meta_path entries)")
2065
2025
 
2066
-
2067
2026
  def uninstall_import_hook(package_name: str = 'default') -> None:
2068
2027
  """Uninstall import hook for a package."""
2069
2028
  global _installed_hooks
@@ -2078,12 +2037,10 @@ def uninstall_import_hook(package_name: str = 'default') -> None:
2078
2037
  del _installed_hooks[package_name]
2079
2038
  log_event("hook", logger.info, f"Lazy import hook uninstalled for {package_name}")
2080
2039
 
2081
-
2082
2040
  def is_import_hook_installed(package_name: str = 'default') -> bool:
2083
2041
  """Check if import hook is installed for a package."""
2084
2042
  return package_name in _installed_hooks
2085
2043
 
2086
-
2087
2044
  def register_lazy_module_prefix(prefix: str) -> None:
2088
2045
  """Register an import prefix for lazy wrapping."""
2089
2046
  _watched_registry = get_watched_registry()
@@ -2092,7 +2049,6 @@ def register_lazy_module_prefix(prefix: str) -> None:
2092
2049
  if normalized:
2093
2050
  log_event("config", logger.info, "Registered lazy module prefix: %s", normalized)
2094
2051
 
2095
-
2096
2052
  # =============================================================================
2097
2053
  # EXPORTS
2098
2054
  # =============================================================================
@@ -4,7 +4,7 @@ Module Strategies - Helper and Manager implementations.
4
4
  Company: eXonware.com
5
5
  Author: Eng. Muhammad AlShehri
6
6
  Email: connect@exonware.com
7
- Version: 0.1.0.19
7
+
8
8
  Generation Date: 15-Nov-2025
9
9
  """
10
10
 
@@ -4,7 +4,7 @@ Lazy Module Helper Strategy - Deferred loading.
4
4
  Company: eXonware.com
5
5
  Author: Eng. Muhammad AlShehri
6
6
  Email: connect@exonware.com
7
- Version: 0.1.0.19
7
+
8
8
  Generation Date: 15-Nov-2025
9
9
 
10
10
  Lazy loading - loads module on first access with caching.
@@ -18,7 +18,6 @@ from typing import Any, Optional, Dict
18
18
  from ...module.base import AModuleHelperStrategy
19
19
  from ..data import ModuleData
20
20
 
21
-
22
21
  class LazyHelper(AModuleHelperStrategy):
23
22
  """
24
23
  Lazy helper - deferred loading with caching.
@@ -4,7 +4,7 @@ Simple Module Helper Strategy - Basic synchronous loading.
4
4
  Company: eXonware.com
5
5
  Author: Eng. Muhammad AlShehri
6
6
  Email: connect@exonware.com
7
- Version: 0.1.0.19
7
+
8
8
  Generation Date: 15-Nov-2025
9
9
 
10
10
  Simple synchronous module loading - no lazy loading.
@@ -15,7 +15,6 @@ from types import ModuleType
15
15
  from typing import Any
16
16
  from ...module.base import AModuleHelperStrategy
17
17
 
18
-
19
18
  class SimpleHelper(AModuleHelperStrategy):
20
19
  """
21
20
  Simple helper - standard synchronous import.
@@ -4,7 +4,7 @@ Advanced Module Manager Strategy - Full features.
4
4
  Company: eXonware.com
5
5
  Author: Eng. Muhammad AlShehri
6
6
  Email: connect@exonware.com
7
- Version: 0.1.0.19
7
+
8
8
  Generation Date: 15-Nov-2025
9
9
 
10
10
  Advanced manager - with hooks, error handling, and full features.
@@ -18,7 +18,6 @@ from ...contracts import ICachingStrategy, IModuleHelperStrategy
18
18
  from ...package.base import APackageHelper
19
19
  from ...module import importer_engine
20
20
 
21
-
22
21
  class AdvancedManager(AModuleManagerStrategy):
23
22
  """
24
23
  Advanced manager - full features with hooks and error handling.
@@ -4,7 +4,7 @@ Simple Module Manager Strategy - Basic operations.
4
4
  Company: eXonware.com
5
5
  Author: Eng. Muhammad AlShehri
6
6
  Email: connect@exonware.com
7
- Version: 0.1.0.19
7
+
8
8
  Generation Date: 15-Nov-2025
9
9
 
10
10
  Simple manager - basic module loading/unloading only.
@@ -15,7 +15,6 @@ from typing import Optional
15
15
  from ...module.base import AModuleManagerStrategy
16
16
  from ...contracts import ICachingStrategy, IModuleHelperStrategy
17
17
 
18
-
19
18
  class SimpleManager(AModuleManagerStrategy):
20
19
  """
21
20
  Simple manager - basic module operations only.
@@ -4,7 +4,7 @@
4
4
  Company: eXonware.com
5
5
  Author: Eng. Muhammad AlShehri
6
6
  Email: connect@exonware.com
7
- Version: 0.1.0.19
7
+
8
8
  Generation Date: 10-Oct-2025
9
9
 
10
10
  Abstract Base Class for Package Operations
@@ -33,7 +33,6 @@ from ..contracts import (
33
33
  IMappingStrategy,
34
34
  )
35
35
 
36
-
37
36
  # =============================================================================
38
37
  # ABSTRACT PACKAGE (Unified - Merges APackageDiscovery + APackageInstaller + APackageCache + APackageHelper)
39
38
  # =============================================================================
@@ -604,7 +603,6 @@ class APackageHelper(IPackageHelper, ABC):
604
603
  """Get watched prefixes from manifest (from IManifestLoader)."""
605
604
  raise NotImplementedError("Subclasses must implement get_watched_prefixes")
606
605
 
607
-
608
606
  # =============================================================================
609
607
  # DEPRECATED CLASSES (for backward compatibility)
610
608
  # =============================================================================
@@ -641,7 +639,6 @@ class APackageHelperStrategy(IPackageHelperStrategy, ABC):
641
639
  """Get installed version."""
642
640
  ...
643
641
 
644
-
645
642
  # =============================================================================
646
643
  # ABSTRACT PACKAGE MANAGER STRATEGY
647
644
  # =============================================================================
@@ -674,7 +671,6 @@ class APackageManagerStrategy(IPackageManagerStrategy, ABC):
674
671
  """Check security policy."""
675
672
  ...
676
673
 
677
-
678
674
  # =============================================================================
679
675
  # ABSTRACT INSTALLATION EXECUTION STRATEGY
680
676
  # =============================================================================
@@ -696,7 +692,6 @@ class AInstallExecutionStrategy(IInstallExecutionStrategy, ABC):
696
692
  """Execute uninstallation of a package."""
697
693
  ...
698
694
 
699
-
700
695
  # =============================================================================
701
696
  # ABSTRACT INSTALLATION TIMING STRATEGY
702
697
  # =============================================================================
@@ -723,7 +718,6 @@ class AInstallTimingStrategy(IInstallTimingStrategy, ABC):
723
718
  """Get priority order for installing packages."""
724
719
  ...
725
720
 
726
-
727
721
  # =============================================================================
728
722
  # ABSTRACT DISCOVERY STRATEGY
729
723
  # =============================================================================
@@ -745,7 +739,6 @@ class ADiscoveryStrategy(IDiscoveryStrategy, ABC):
745
739
  """Get the source of a discovered dependency."""
746
740
  ...
747
741
 
748
-
749
742
  # =============================================================================
750
743
  # ABSTRACT POLICY STRATEGY
751
744
  # =============================================================================
@@ -767,7 +760,6 @@ class APolicyStrategy(IPolicyStrategy, ABC):
767
760
  """Get pip arguments based on policy."""
768
761
  ...
769
762
 
770
-
771
763
  # =============================================================================
772
764
  # ABSTRACT MAPPING STRATEGY
773
765
  # =============================================================================
@@ -789,7 +781,6 @@ class AMappingStrategy(IMappingStrategy, ABC):
789
781
  """Map package name to possible import names."""
790
782
  ...
791
783
 
792
-
793
784
  # =============================================================================
794
785
  # EXPORT ALL
795
786
  # =============================================================================
@@ -11,7 +11,7 @@ longer need to ship their own lazy bootstrap logic. Consumers import
11
11
  Company: eXonware.com
12
12
  Author: Eng. Muhammad AlShehri
13
13
  Email: connect@exonware.com
14
- Version: 0.1.0.19
14
+
15
15
  Generation Date: 10-Oct-2025
16
16
  """
17
17
 
@@ -39,7 +39,6 @@ from .services.config_manager import LazyInstallConfig
39
39
 
40
40
  __all__ = ['get_conf_module', '_PackageConfig', '_FilteredStderr', '_LazyConfModule', '_setup_global_warning_filter']
41
41
 
42
-
43
42
  class _PackageConfig:
44
43
  """Per-package configuration wrapper."""
45
44
 
@@ -78,7 +77,6 @@ class _PackageConfig:
78
77
  """Return True if lazy install + hook are active."""
79
78
  return self.lazy_install_status()["active"]
80
79
 
81
-
82
80
  class _FilteredStderr:
83
81
  """Stderr wrapper that filters out specific warning messages."""
84
82
 
@@ -109,7 +107,6 @@ class _FilteredStderr:
109
107
  """Delegate all other attributes to original stderr."""
110
108
  return getattr(self._original, name)
111
109
 
112
-
113
110
  class _LazyConfModule(types.ModuleType):
114
111
  """Configuration module for all exonware packages."""
115
112
 
@@ -286,12 +283,10 @@ class _LazyConfModule(types.ModuleType):
286
283
  return
287
284
  super().__setattr__(name, value)
288
285
 
289
-
290
286
  _CONF_INSTANCE: Optional[_LazyConfModule] = None
291
287
  _ORIGINAL_STDERR: Optional[Any] = None
292
288
  _FILTERED_STDERR: Optional[_FilteredStderr] = None
293
289
 
294
-
295
290
  def _setup_global_warning_filter() -> None:
296
291
  """Set up global stderr filter for decimal module warnings (called at module import)."""
297
292
  global _ORIGINAL_STDERR, _FILTERED_STDERR
@@ -317,12 +312,10 @@ def _setup_global_warning_filter() -> None:
317
312
  if sys.stderr is not _FILTERED_STDERR:
318
313
  sys.stderr = _FILTERED_STDERR # type: ignore[assignment]
319
314
 
320
-
321
315
  # Set up warning filter immediately when module is imported (default: suppress warnings)
322
316
  # Note: conf.py may have already set up a filter, which is fine
323
317
  _setup_global_warning_filter()
324
318
 
325
-
326
319
  def get_conf_module(name: str = "exonware.conf", doc: Optional[str] = None) -> types.ModuleType:
327
320
  """Return (and memoize) the shared conf module instance."""
328
321
  global _CONF_INSTANCE
@@ -4,7 +4,7 @@ Package Data - Immutable data structure for packages.
4
4
  Company: eXonware.com
5
5
  Author: Eng. Muhammad AlShehri
6
6
  Email: connect@exonware.com
7
- Version: 0.1.0.19
7
+
8
8
  Generation Date: 15-Nov-2025
9
9
 
10
10
  Re-export PackageData from defs.py for backward compatibility.
@@ -47,7 +47,6 @@ from .strategies import (
47
47
  ManifestFirstMapping,
48
48
  )
49
49
 
50
-
51
50
  class XWPackageHelper(APackageHelper):
52
51
  """
53
52
  Concrete implementation of APackageHelper.
@@ -4,7 +4,7 @@ Async Install Handle
4
4
  Company: eXonware.com
5
5
  Author: Eng. Muhammad AlShehri
6
6
  Email: connect@exonware.com
7
- Version: 0.1.0.19
7
+
8
8
  Generation Date: 15-Nov-2025
9
9
 
10
10
  Lightweight handle for background installation jobs.
@@ -13,7 +13,6 @@ Lightweight handle for background installation jobs.
13
13
  import asyncio
14
14
  from typing import Optional, Any
15
15
 
16
-
17
16
  class AsyncInstallHandle:
18
17
  """Lightweight handle for background installation jobs."""
19
18
 
@@ -84,6 +83,5 @@ class AsyncInstallHandle:
84
83
  return self._task_or_future.done()
85
84
  return False
86
85
 
87
-
88
86
  __all__ = ['AsyncInstallHandle']
89
87
 
@@ -45,7 +45,6 @@ _MODE_ENUM_MAP = {
45
45
  "lazy": LazyInstallMode.SMART,
46
46
  }
47
47
 
48
-
49
48
  class LazyInstallConfig:
50
49
  """Global configuration for lazy installation per package."""
51
50
  _configs: Dict[str, bool] = {}
@@ -6,7 +6,7 @@ Package discovery implementation.
6
6
  Company: eXonware.com
7
7
  Author: Eng. Muhammad AlShehri
8
8
  Email: connect@exonware.com
9
- Version: 0.1.0.19
9
+
10
10
  Generation Date: 10-Oct-2025
11
11
 
12
12
  This module provides LazyDiscovery class that discovers dependencies from
@@ -27,7 +27,6 @@ from ...common.logger import get_logger, log_event as _log
27
27
 
28
28
  logger = get_logger("xwlazy.discovery")
29
29
 
30
-
31
30
  class LazyDiscovery(APackageHelper):
32
31
  """
33
32
  Discovers dependencies from project configuration sources.
@@ -355,12 +354,10 @@ class LazyDiscovery(APackageHelper):
355
354
  with open(file_path, 'w', encoding='utf-8') as f:
356
355
  json.dump(data, f, indent=2, ensure_ascii=False)
357
356
 
358
-
359
357
  # Global discovery instance
360
358
  _discovery: Optional[LazyDiscovery] = None
361
359
  _discovery_lock = threading.RLock()
362
360
 
363
-
364
361
  def get_lazy_discovery(project_root: Optional[str] = None) -> LazyDiscovery:
365
362
  """Get or create global discovery instance."""
366
363
  global _discovery
@@ -369,6 +366,5 @@ def get_lazy_discovery(project_root: Optional[str] = None) -> LazyDiscovery:
369
366
  _discovery = LazyDiscovery(project_root)
370
367
  return _discovery
371
368
 
372
-
373
369
  __all__ = ['LazyDiscovery', 'get_lazy_discovery']
374
370
 
@@ -46,7 +46,6 @@ class LazyMetaPathFinder:
46
46
  _TRUTHY = {"1", "true", "yes", "on"}
47
47
  _REGISTERED: dict[str, dict[str, Tuple[str, ...]]] = {}
48
48
 
49
-
50
49
  def _normalized(items: Iterable[str]) -> Tuple[str, ...]:
51
50
  seen = []
52
51
  for item in items:
@@ -54,7 +53,6 @@ def _normalized(items: Iterable[str]) -> Tuple[str, ...]:
54
53
  seen.append(item)
55
54
  return tuple(seen)
56
55
 
57
-
58
56
  def register_host_package(
59
57
  package_name: str,
60
58
  module_prefixes: Iterable[str] = (),
@@ -114,7 +112,6 @@ def register_host_package(
114
112
  # Best-effort: package import must continue even if hook installation fails
115
113
  pass
116
114
 
117
-
118
115
  def refresh_host_package(package_name: str) -> None:
119
116
  """Re-apply wrappers for a registered package."""
120
117
  data = _REGISTERED.get(package_name.lower())
@@ -126,7 +123,6 @@ def refresh_host_package(package_name: str) -> None:
126
123
  data["method_prefixes"],
127
124
  )
128
125
 
129
-
130
126
  def _apply_wrappers_for_loaded_modules(
131
127
  package_name: str,
132
128
  module_prefixes: Iterable[str],
@@ -4,7 +4,7 @@ Async Installation Mixin
4
4
  Company: eXonware.com
5
5
  Author: Eng. Muhammad AlShehri
6
6
  Email: connect@exonware.com
7
- Version: 0.1.0.19
7
+
8
8
  Generation Date: 15-Nov-2025
9
9
 
10
10
  Mixin for async installation operations.
@@ -48,7 +48,6 @@ def _ensure_logging_initialized():
48
48
  if _log is None:
49
49
  _log = _get_log_event()
50
50
 
51
-
52
51
  class AsyncInstallMixin:
53
52
  """Mixin for async installation operations."""
54
53
 
@@ -4,7 +4,7 @@ Installation Cache Mixin
4
4
  Company: eXonware.com
5
5
  Author: Eng. Muhammad AlShehri
6
6
  Email: connect@exonware.com
7
- Version: 0.1.0.19
7
+
8
8
  Generation Date: 15-Nov-2025
9
9
 
10
10
  Mixin for cache management (wheels, install trees, known missing modules).
@@ -49,7 +49,6 @@ def _ensure_spec_cache_initialized():
49
49
  if _spec_cache_clear is None:
50
50
  _spec_cache_clear = _get_spec_cache_clear()
51
51
 
52
-
53
52
  class InstallCacheMixin:
54
53
  """Mixin for cache management (wheels, install trees, known missing modules)."""
55
54