exonware-xwlazy 0.1.0.23__tar.gz → 1.0.1.2__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.
Files changed (100) hide show
  1. {exonware_xwlazy-0.1.0.23 → exonware_xwlazy-1.0.1.2}/.gitignore +4 -0
  2. {exonware_xwlazy-0.1.0.23 → exonware_xwlazy-1.0.1.2}/PKG-INFO +5 -1
  3. {exonware_xwlazy-0.1.0.23 → exonware_xwlazy-1.0.1.2}/README.md +4 -0
  4. {exonware_xwlazy-0.1.0.23 → exonware_xwlazy-1.0.1.2}/pyproject.toml +3 -0
  5. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/__init__.py +0 -1
  6. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/common/__init__.py +0 -1
  7. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/common/base.py +0 -1
  8. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/common/cache.py +19 -19
  9. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/common/logger.py +0 -1
  10. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/common/services/__init__.py +0 -1
  11. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/common/services/dependency_mapper.py +0 -1
  12. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/common/services/install_async_utils.py +4 -3
  13. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/common/services/install_cache_utils.py +0 -1
  14. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/common/services/keyword_detection.py +0 -1
  15. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/common/services/spec_cache.py +0 -1
  16. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/common/services/state_manager.py +8 -8
  17. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/common/strategies/__init__.py +0 -1
  18. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/common/strategies/caching_dict.py +0 -1
  19. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/common/strategies/caching_installation.py +0 -1
  20. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/common/strategies/caching_lfu.py +0 -1
  21. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/common/strategies/caching_lru.py +0 -1
  22. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/common/strategies/caching_multitier.py +0 -1
  23. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/common/strategies/caching_ttl.py +0 -1
  24. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/common/utils.py +0 -1
  25. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/config.py +0 -1
  26. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/contracts.py +0 -1
  27. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/defs.py +4 -3
  28. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/errors.py +0 -1
  29. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/host/__init__.py +0 -1
  30. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/host/conf.py +0 -1
  31. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/module/base.py +42 -22
  32. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/module/data.py +0 -1
  33. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/module/facade.py +3 -4
  34. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/module/importer_engine.py +0 -1
  35. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/module/partial_module_detector.py +0 -1
  36. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/module/strategies/__init__.py +0 -1
  37. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/module/strategies/module_helper_lazy.py +0 -1
  38. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/module/strategies/module_helper_simple.py +0 -1
  39. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/module/strategies/module_manager_advanced.py +0 -1
  40. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/module/strategies/module_manager_simple.py +0 -1
  41. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/base.py +27 -14
  42. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/data.py +0 -1
  43. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/facade.py +0 -1
  44. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/services/__init__.py +0 -1
  45. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/services/async_install_handle.py +0 -1
  46. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/services/config_manager.py +0 -1
  47. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/services/discovery.py +8 -35
  48. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/services/install_async.py +0 -1
  49. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/services/install_cache.py +0 -1
  50. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/services/install_interactive.py +0 -1
  51. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/services/install_policy.py +0 -1
  52. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/services/install_registry.py +5 -4
  53. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/services/install_result.py +0 -1
  54. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/services/install_sbom.py +7 -11
  55. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/services/install_utils.py +0 -1
  56. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/services/installer_engine.py +0 -1
  57. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/services/lazy_installer.py +79 -2
  58. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/services/manifest.py +12 -17
  59. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/services/strategy_registry.py +19 -18
  60. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/strategies/package_discovery_file.py +0 -1
  61. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/strategies/package_discovery_hybrid.py +0 -1
  62. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/strategies/package_discovery_manifest.py +0 -1
  63. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/strategies/package_execution_async.py +0 -1
  64. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/strategies/package_execution_cached.py +0 -1
  65. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/strategies/package_execution_pip.py +0 -1
  66. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/strategies/package_execution_wheel.py +0 -1
  67. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/strategies/package_mapping_discovery_first.py +0 -1
  68. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/strategies/package_mapping_hybrid.py +0 -1
  69. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/strategies/package_mapping_manifest_first.py +0 -1
  70. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/strategies/package_policy_allow_list.py +1 -2
  71. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/strategies/package_policy_deny_list.py +1 -2
  72. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/strategies/package_policy_permissive.py +1 -2
  73. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/strategies/package_timing_clean.py +0 -1
  74. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/strategies/package_timing_full.py +0 -1
  75. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/strategies/package_timing_smart.py +0 -1
  76. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/strategies/package_timing_temporary.py +0 -1
  77. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/runtime/adaptive_learner.py +1 -2
  78. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/runtime/base.py +0 -1
  79. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/runtime/facade.py +0 -1
  80. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/runtime/intelligent_selector.py +0 -1
  81. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/runtime/metrics.py +0 -1
  82. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/runtime/performance.py +0 -1
  83. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/version.py +2 -2
  84. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/xwlazy/__init__.py +0 -1
  85. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/xwlazy/lazy.py +0 -1
  86. exonware_xwlazy-1.0.1.2/src/exonware/__init__.py +93 -0
  87. exonware_xwlazy-1.0.1.2/src/exonware/xwlazy/version.py +77 -0
  88. exonware_xwlazy-1.0.1.2/src/exonware/xwlazy.py +2546 -0
  89. exonware_xwlazy-1.0.1.2/src/exonware/xwlazy_external_libs.toml +716 -0
  90. {exonware_xwlazy-0.1.0.23 → exonware_xwlazy-1.0.1.2}/src/xwlazy.py +3 -16
  91. {exonware_xwlazy-0.1.0.23 → exonware_xwlazy-1.0.1.2}/src/xwlazy_wrapper.py +0 -1
  92. {exonware_xwlazy-0.1.0.23 → exonware_xwlazy-1.0.1.2}/LICENSE +0 -0
  93. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/__init__.py +0 -0
  94. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/facade.py +0 -0
  95. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/module/__init__.py +0 -0
  96. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/__init__.py +0 -0
  97. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/conf.py +0 -0
  98. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/services/host_packages.py +0 -0
  99. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/package/strategies/__init__.py +0 -0
  100. {exonware_xwlazy-0.1.0.23/src → exonware_xwlazy-1.0.1.2/src/_old}/exonware/xwlazy/runtime/__init__.py +0 -0
@@ -5,6 +5,10 @@
5
5
  # CI/CD Tools (keep private)
6
6
  .ci/
7
7
 
8
+ # Migration/legacy directories (may contain paths too long for Windows)
9
+ MIGRAT/
10
+ MIGRATE/
11
+
8
12
  # ========================================
9
13
  # Python
10
14
  # ========================================
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: exonware-xwlazy
3
- Version: 0.1.0.23
3
+ Version: 1.0.1.2
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
@@ -174,6 +174,10 @@ After `pip install -e .`, xwlazy automatically enables lazy loading for your pac
174
174
  ## 📖 Documentation
175
175
 
176
176
  - **[Architecture Reference](docs/REF_ARCH.md)** - System design, patterns, and structure
177
+ - **[Integration Guide](docs/INTEGRATION_GUIDE.md)** - Integration with xw libraries
178
+ - **[Best Practices](docs/BEST_PRACTICES.md)** - Usage guidelines and recommendations
179
+ - **[Troubleshooting Guide](docs/TROUBLESHOOTING.md)** - Common issues and solutions
180
+ - **[Production Deployment](docs/PRODUCTION_DEPLOYMENT.md)** - Production deployment guide
177
181
  - **[Keyword Detection Guide](docs/KEYWORD_DETECTION.md)** - Zero-code integration
178
182
  - **[Competition Benchmarks](benchmarks/competition_tests/)** - Performance comparisons
179
183
  - **[Performance Analysis](benchmarks/competition_tests/PERFORMANCE_ANALYSIS.md)** - Optimization recommendations
@@ -151,6 +151,10 @@ After `pip install -e .`, xwlazy automatically enables lazy loading for your pac
151
151
  ## 📖 Documentation
152
152
 
153
153
  - **[Architecture Reference](docs/REF_ARCH.md)** - System design, patterns, and structure
154
+ - **[Integration Guide](docs/INTEGRATION_GUIDE.md)** - Integration with xw libraries
155
+ - **[Best Practices](docs/BEST_PRACTICES.md)** - Usage guidelines and recommendations
156
+ - **[Troubleshooting Guide](docs/TROUBLESHOOTING.md)** - Common issues and solutions
157
+ - **[Production Deployment](docs/PRODUCTION_DEPLOYMENT.md)** - Production deployment guide
154
158
  - **[Keyword Detection Guide](docs/KEYWORD_DETECTION.md)** - Zero-code integration
155
159
  - **[Competition Benchmarks](benchmarks/competition_tests/)** - Performance comparisons
156
160
  - **[Performance Analysis](benchmarks/competition_tests/PERFORMANCE_ANALYSIS.md)** - Optimization recommendations
@@ -38,6 +38,9 @@ Subtree = "https://github.com/Exonware/XWLazy.git"
38
38
  [tool.hatch.version]
39
39
  path = "src/exonware/xwlazy/version.py"
40
40
 
41
+ # Fallback: use static version if version.py doesn't exist
42
+ # __version__ = "1.0.1"
43
+
41
44
  [tool.hatch.build.targets.wheel]
42
45
  packages = ["src/exonware", "src/xwlazy"]
43
46
 
@@ -376,4 +376,3 @@ __all__ = [
376
376
  # "_patch_import_module", # Removed - deprecated, use sys.meta_path hooks instead
377
377
  "_unpatch_import_module",
378
378
  ]
379
-
@@ -52,4 +52,3 @@ __all__ = [
52
52
  'find_project_root',
53
53
  'find_config_file',
54
54
  ]
55
-
@@ -62,4 +62,3 @@ __all__ = [
62
62
  'ACachingStrategy', # Legacy name
63
63
  'ACacheStrategy', # New name for ICacheStrategy interface
64
64
  ]
65
-
@@ -15,7 +15,6 @@ All cache code is centralized here to avoid duplication.
15
15
 
16
16
  import os
17
17
  import sys
18
- import json
19
18
  import time
20
19
  import pickle
21
20
  import struct
@@ -27,6 +26,7 @@ from typing import Optional, Any
27
26
  from collections import OrderedDict
28
27
  from queue import Queue
29
28
 
29
+ from exonware.xwsystem.io.serialization.auto_serializer import AutoSerializer
30
30
  from .logger import get_logger
31
31
 
32
32
  logger = get_logger("xwlazy.cache")
@@ -384,15 +384,15 @@ class InstallationCache:
384
384
 
385
385
  try:
386
386
  with self._lock:
387
- with open(self._cache_file, 'r', encoding='utf-8') as f:
388
- data = json.load(f)
389
- # Validate format
390
- if isinstance(data, dict):
391
- self._cache = {k: v for k, v in data.items()
392
- if isinstance(v, dict) and 'installed' in v}
393
- else:
394
- self._cache = {}
395
- except (json.JSONDecodeError, IOError, OSError) as e:
387
+ auto_serializer = AutoSerializer()
388
+ data = auto_serializer.auto_load_file(self._cache_file, format_hint='json')
389
+ # Validate format
390
+ if isinstance(data, dict):
391
+ self._cache = {k: v for k, v in data.items()
392
+ if isinstance(v, dict) and 'installed' in v}
393
+ else:
394
+ self._cache = {}
395
+ except Exception as e:
396
396
  logger.debug(f"Failed to load installation cache: {e}")
397
397
  self._cache = {}
398
398
 
@@ -406,15 +406,16 @@ class InstallationCache:
406
406
  # Create parent directory if needed
407
407
  self._cache_file.parent.mkdir(parents=True, exist_ok=True)
408
408
 
409
- # Write atomically using temp file
410
- temp_file = self._cache_file.with_suffix('.tmp')
411
- with open(temp_file, 'w', encoding='utf-8') as f:
412
- json.dump(self._cache, f, indent=2, sort_keys=True)
413
-
414
- # Atomic rename
415
- temp_file.replace(self._cache_file)
409
+ auto_serializer = AutoSerializer()
410
+ auto_serializer.auto_save_file(
411
+ self._cache,
412
+ self._cache_file,
413
+ format_hint='json',
414
+ indent=2,
415
+ sort_keys=True
416
+ )
416
417
  self._dirty = False
417
- except (IOError, OSError) as e:
418
+ except Exception as e:
418
419
  logger.warning(f"Failed to save installation cache: {e}")
419
420
 
420
421
  def is_installed(self, package_name: str) -> bool:
@@ -501,4 +502,3 @@ class InstallationCache:
501
502
  def __len__(self) -> int:
502
503
  """Return number of cached packages."""
503
504
  return len(self._cache)
504
-
@@ -254,4 +254,3 @@ def print_formatted(flag: str, message: str, same_line: bool = False) -> None:
254
254
  sys.stdout.flush()
255
255
  else:
256
256
  print(formatted)
257
-
@@ -69,4 +69,3 @@ __all__ = [
69
69
  'async_install_package',
70
70
  'async_uninstall_package',
71
71
  ]
72
-
@@ -247,4 +247,3 @@ class DependencyMapper:
247
247
  return self._import_package_mapping.copy()
248
248
 
249
249
  __all__ = ['DependencyMapper']
250
-
@@ -13,11 +13,12 @@ Used by both execution strategies and LazyInstaller.
13
13
 
14
14
  import os
15
15
  import sys
16
- import json
17
16
  import asyncio
18
17
  import subprocess
19
18
  from typing import Optional
20
19
 
20
+ from exonware.xwsystem.io.serialization.auto_serializer import AutoSerializer
21
+
21
22
  # Lazy imports
22
23
  def _get_logger():
23
24
  """Get logger (lazy import to avoid circular dependency)."""
@@ -78,7 +79,8 @@ async def get_package_size_mb(package_name: str) -> Optional[float]:
78
79
  import urllib.request
79
80
  url = f"https://pypi.org/pypi/{package_name}/json"
80
81
  with urllib.request.urlopen(url, timeout=5) as response:
81
- data = json.loads(response.read())
82
+ auto_serializer = AutoSerializer()
83
+ data = auto_serializer.detect_and_deserialize(response.read(), format_hint='json')
82
84
  if 'urls' in data and data['urls']:
83
85
  latest = data['urls'][0]
84
86
  if 'size' in latest:
@@ -167,4 +169,3 @@ __all__ = [
167
169
  'async_install_package',
168
170
  'async_uninstall_package',
169
171
  ]
170
-
@@ -242,4 +242,3 @@ __all__ = [
242
242
  'has_cached_install_tree',
243
243
  'install_from_cached_wheel',
244
244
  ]
245
-
@@ -280,4 +280,3 @@ def _detect_lazy_installation(package_name: str) -> bool:
280
280
  _lazy_detection_cache[package_name] = detected
281
281
 
282
282
  return detected
283
-
@@ -162,4 +162,3 @@ __all__ = [
162
162
  '_cache_spec_if_missing',
163
163
  'get_stdlib_module_set',
164
164
  ]
165
-
@@ -1,10 +1,11 @@
1
1
  from __future__ import annotations
2
2
 
3
- import json
4
3
  import os
5
4
  from pathlib import Path
6
5
  from typing import Optional
7
6
 
7
+ from exonware.xwsystem.io.serialization.auto_serializer import AutoSerializer
8
+
8
9
  def _get_base_config_dir() -> Path:
9
10
  """Determine a cross-platform directory for storing lazy configuration."""
10
11
  if os.name == "nt":
@@ -34,18 +35,18 @@ class LazyStateManager:
34
35
  if not self._state_path.exists():
35
36
  return {}
36
37
  try:
37
- with self._state_path.open("r", encoding="utf-8") as fh:
38
- data = json.load(fh)
39
- if isinstance(data, dict):
40
- return data
38
+ auto_serializer = AutoSerializer()
39
+ data = auto_serializer.auto_load_file(self._state_path, format_hint='json')
40
+ if isinstance(data, dict):
41
+ return data
41
42
  except Exception:
42
43
  pass
43
44
  return {}
44
45
 
45
46
  def _save_state(self) -> None:
46
47
  self._state_path.parent.mkdir(parents=True, exist_ok=True)
47
- with self._state_path.open("w", encoding="utf-8") as fh:
48
- json.dump(self._state, fh, indent=2, sort_keys=True)
48
+ auto_serializer = AutoSerializer()
49
+ auto_serializer.auto_save_file(self._state, self._state_path, format_hint='json', indent=2, sort_keys=True)
49
50
 
50
51
  def _ensure_entry(self) -> dict[str, bool]:
51
52
  return self._state.setdefault(self._package, {})
@@ -81,4 +82,3 @@ class LazyStateManager:
81
82
  else:
82
83
  entry["auto"] = bool(value)
83
84
  self._save_state()
84
-
@@ -25,4 +25,3 @@ __all__ = [
25
25
  'MultiTierCacheStrategy',
26
26
  'InstallationCacheWrapper',
27
27
  ]
28
-
@@ -41,4 +41,3 @@ class DictCache(ACachingStrategy):
41
41
  def clear(self) -> None:
42
42
  """Clear all cached values."""
43
43
  self._cache.clear()
44
-
@@ -85,4 +85,3 @@ class InstallationCacheWrapper(ACachingStrategy):
85
85
  # InstallationCache doesn't have clear, so we'd need to extend it
86
86
  # For now, just mark all as uninstalled (would need cache iteration)
87
87
  pass
88
-
@@ -63,4 +63,3 @@ class LFUCache(ACachingStrategy):
63
63
  """Clear all cached values."""
64
64
  self._cache.clear()
65
65
  self._freq.clear()
66
-
@@ -60,4 +60,3 @@ class LRUCache(ACachingStrategy):
60
60
  def clear(self) -> None:
61
61
  """Clear all cached values."""
62
62
  self._cache.clear()
63
-
@@ -56,4 +56,3 @@ class MultiTierCacheStrategy(ACachingStrategy):
56
56
  def shutdown(self) -> None:
57
57
  """Shutdown cache (flush L2, cleanup threads)."""
58
58
  self._cache.shutdown()
59
-
@@ -56,4 +56,3 @@ class TTLCache(ACachingStrategy):
56
56
  def clear(self) -> None:
57
57
  """Clear all cached values."""
58
58
  self._cache.clear()
59
-
@@ -139,4 +139,3 @@ def find_config_file(filename: str, start_path: Optional[Path] = None) -> Option
139
139
 
140
140
 
141
141
  __all__ = ['find_project_root', 'find_config_file']
142
-
@@ -190,4 +190,3 @@ class LazyConfig(_LazyConfigBase):
190
190
  pass
191
191
 
192
192
  DEFAULT_LAZY_CONFIG = LazyConfig()
193
-
@@ -1530,4 +1530,3 @@ __all__ = [
1530
1530
  'ILoadStrategy',
1531
1531
  'ICacheStrategy',
1532
1532
  ]
1533
-
@@ -12,6 +12,8 @@ This module defines type definitions, constants, and TypedDict structures
12
12
  for the lazy loading system following GUIDE_ARCH.md structure.
13
13
  """
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  from enum import Enum
16
18
  from typing import TypedDict, Optional, Any
17
19
  from dataclasses import dataclass, field
@@ -158,7 +160,7 @@ class PackageData:
158
160
  installed: bool = False
159
161
  install_time: Optional[float] = None
160
162
  access_count: int = 0
161
- install_mode: Optional['LazyInstallMode'] = None
163
+ install_mode: Optional[LazyInstallMode] = None
162
164
  error: Optional[Exception] = None
163
165
  metadata: dict[str, Any] = field(default_factory=dict)
164
166
 
@@ -170,7 +172,7 @@ class ModuleData:
170
172
  This data structure is used by all module caching, helper, and manager strategies.
171
173
  """
172
174
  path: str
173
- loaded_module: Optional['ModuleType'] = None
175
+ loaded_module: Optional[ModuleType] = None
174
176
  loading: bool = False
175
177
  load_time: Optional[float] = None
176
178
  access_count: int = 0
@@ -375,4 +377,3 @@ __all__ = [
375
377
  'PRESET_MODES',
376
378
  'get_preset_mode',
377
379
  ]
378
-
@@ -273,4 +273,3 @@ __all__ = [
273
273
  # Two-stage loading
274
274
  'DeferredImportError',
275
275
  ]
276
-
@@ -5,4 +5,3 @@ This package provides compatibility interfaces for host packages like xwsystem.
5
5
  """
6
6
 
7
7
  __all__ = []
8
-
@@ -13,4 +13,3 @@ Email: connect@exonware.com
13
13
  from ..package.conf import get_conf_module
14
14
 
15
15
  __all__ = ['get_conf_module']
16
-
@@ -406,89 +406,110 @@ class AModuleHelper(IModuleHelper, ABC):
406
406
  # Note: Many methods from IModuleHelper are already implemented above.
407
407
  # The following are stubs that need concrete implementations:
408
408
 
409
+ @abstractmethod
409
410
  def install_and_import(self, module_name: str, package_name: Optional[str] = None) -> tuple[Optional[ModuleType], bool]:
410
411
  """Install package and import module (from IModuleInstaller)."""
411
- raise NotImplementedError("Subclasses must implement install_and_import")
412
+ pass
412
413
 
414
+ @abstractmethod
413
415
  def is_package_installed(self, package_name: str) -> bool:
414
416
  """Check if package is installed (from IModuleInstaller)."""
415
- raise NotImplementedError("Subclasses must implement is_package_installed")
417
+ pass
416
418
 
419
+ @abstractmethod
417
420
  def mark_installed(self, package_name: str, version: Optional[str] = None) -> None:
418
421
  """Mark package as installed in persistent cache (from IModuleInstaller)."""
419
- raise NotImplementedError("Subclasses must implement mark_installed")
422
+ pass
420
423
 
424
+ @abstractmethod
421
425
  def is_hook_installed(self) -> bool:
422
426
  """Check if hook is installed (from IImportHook)."""
423
- raise NotImplementedError("Subclasses must implement is_hook_installed")
427
+ pass
424
428
 
429
+ @abstractmethod
425
430
  def find_spec(self, fullname: str, path: Optional[str] = None, target=None) -> Optional[Any]:
426
431
  """Find module spec (from IMetaPathFinder)."""
427
- raise NotImplementedError("Subclasses must implement find_spec")
432
+ pass
428
433
 
434
+ @abstractmethod
429
435
  def should_intercept(self, fullname: str) -> bool:
430
436
  """Determine if a module should be intercepted (from IMetaPathFinder)."""
431
- raise NotImplementedError("Subclasses must implement should_intercept")
437
+ pass
432
438
 
439
+ @abstractmethod
433
440
  def is_module_installed(self, fullname: str) -> bool:
434
441
  """Check if module is already installed (from IMetaPathFinder)."""
435
- raise NotImplementedError("Subclasses must implement is_module_installed")
442
+ pass
436
443
 
444
+ @abstractmethod
437
445
  def intercept_missing_import(self, module_name: str) -> Optional[ModuleType]:
438
446
  """Intercept a missing import (from IImportInterceptor)."""
439
- raise NotImplementedError("Subclasses must implement intercept_missing_import")
447
+ pass
440
448
 
449
+ @abstractmethod
441
450
  def should_intercept_module(self, module_name: str) -> bool:
442
451
  """Determine if a module should be intercepted (from IImportInterceptor)."""
443
- raise NotImplementedError("Subclasses must implement should_intercept_module")
452
+ pass
444
453
 
454
+ @abstractmethod
445
455
  def prevent_recursion(self, module_name: str) -> bool:
446
456
  """Check if we should prevent recursion (from IImportInterceptor)."""
447
- raise NotImplementedError("Subclasses must implement prevent_recursion")
457
+ pass
448
458
 
459
+ @abstractmethod
449
460
  def import_module(self, module_name: str, package_name: Optional[str] = None) -> Any:
450
461
  """Import a module with lazy loading (from ILazyImporter)."""
451
- raise NotImplementedError("Subclasses must implement import_module")
462
+ pass
452
463
 
464
+ @abstractmethod
453
465
  def enable_lazy_loading(self, load_mode: Any) -> None:
454
466
  """Enable lazy loading with a mode (from ILazyImporter)."""
455
- raise NotImplementedError("Subclasses must implement enable_lazy_loading")
467
+ pass
456
468
 
469
+ @abstractmethod
457
470
  def disable_lazy_loading(self) -> None:
458
471
  """Disable lazy loading (from ILazyImporter)."""
459
- raise NotImplementedError("Subclasses must implement disable_lazy_loading")
472
+ pass
460
473
 
474
+ @abstractmethod
461
475
  def is_lazy_loading_enabled(self) -> bool:
462
476
  """Check if lazy loading is enabled (from ILazyImporter)."""
463
- raise NotImplementedError("Subclasses must implement is_lazy_loading_enabled")
477
+ pass
464
478
 
479
+ @abstractmethod
465
480
  def has_root(self, root_name: str) -> bool:
466
481
  """Check if a root module name is being watched (from IWatchedRegistry)."""
467
- raise NotImplementedError("Subclasses must implement has_root")
482
+ pass
468
483
 
484
+ @abstractmethod
469
485
  def get_matching_prefixes(self, fullname: str) -> tuple[str, ...]:
470
486
  """Get all watched prefixes that match a module name (from IWatchedRegistry)."""
471
- raise NotImplementedError("Subclasses must implement get_matching_prefixes")
487
+ pass
472
488
 
489
+ @abstractmethod
473
490
  def is_prefix_owned_by(self, prefix: str, package_name: str) -> bool:
474
491
  """Check if a prefix is owned by a package (from IWatchedRegistry)."""
475
- raise NotImplementedError("Subclasses must implement is_prefix_owned_by")
492
+ pass
476
493
 
494
+ @abstractmethod
477
495
  def is_watched_registry_empty(self) -> bool:
478
496
  """Check if registry is empty (from IWatchedRegistry)."""
479
- raise NotImplementedError("Subclasses must implement is_watched_registry_empty")
497
+ pass
480
498
 
499
+ @abstractmethod
481
500
  def get_bytecode(self, module_path: str, source_code: str) -> Optional[bytes]:
482
501
  """Get cached bytecode for module (from IBytecodeCache)."""
483
- raise NotImplementedError("Subclasses must implement get_bytecode")
502
+ pass
484
503
 
504
+ @abstractmethod
485
505
  def cache_bytecode(self, module_path: str, source_code: str, bytecode: bytes) -> None:
486
506
  """Cache bytecode for module (from IBytecodeCache)."""
487
- raise NotImplementedError("Subclasses must implement cache_bytecode")
507
+ pass
488
508
 
509
+ @abstractmethod
489
510
  def clear_bytecode_cache(self) -> None:
490
511
  """Clear bytecode cache (from IBytecodeCache)."""
491
- raise NotImplementedError("Subclasses must implement clear_bytecode_cache")
512
+ pass
492
513
 
493
514
  # =============================================================================
494
515
  # ABSTRACT MODULE HELPER STRATEGY
@@ -619,4 +640,3 @@ __all__ = [
619
640
  # Enhanced Strategy Interfaces for Runtime Swapping
620
641
  'ALoadStrategy',
621
642
  ]
622
-
@@ -14,4 +14,3 @@ Re-export ModuleData from defs.py for backward compatibility.
14
14
  from ..defs import ModuleData
15
15
 
16
16
  __all__ = ['ModuleData']
17
-
@@ -25,7 +25,7 @@ from . import importer_engine
25
25
  from ..contracts import ICachingStrategy, IModuleHelperStrategy, IModuleManagerStrategy
26
26
 
27
27
  # Import default strategies
28
- from ..common.strategies import LRUCache
28
+ from ..common.strategies import LFUCache
29
29
  from .strategies import LazyHelper, AdvancedManager
30
30
  from ..package.services.strategy_registry import StrategyRegistry
31
31
 
@@ -53,7 +53,7 @@ class XWModuleHelper(AModuleHelper):
53
53
  Args:
54
54
  package_name: Package name for isolation (defaults to 'default')
55
55
  package_helper: Optional package helper instance. If None, creates XWPackageHelper.
56
- caching_strategy: Optional caching strategy. If None, uses LRUCache.
56
+ caching_strategy: Optional caching strategy. If None, uses LFUCache (fastest cache type).
57
57
  helper_strategy: Optional helper strategy. If None, uses LazyHelper.
58
58
  manager_strategy: Optional manager strategy. If None, uses AdvancedManager.
59
59
  """
@@ -69,7 +69,7 @@ class XWModuleHelper(AModuleHelper):
69
69
  if caching_strategy is None:
70
70
  caching_strategy = StrategyRegistry.get_module_strategy(package_name, 'caching')
71
71
  if caching_strategy is None:
72
- caching_strategy = LRUCache(max_size=1000)
72
+ caching_strategy = LFUCache(max_size=1000)
73
73
  if helper_strategy is None:
74
74
  helper_strategy = StrategyRegistry.get_module_strategy(package_name, 'helper')
75
75
  if helper_strategy is None:
@@ -243,4 +243,3 @@ class XWModuleHelper(AModuleHelper):
243
243
  module_path: Module path to unload
244
244
  """
245
245
  self._manager.unload_module(module_path)
246
-
@@ -2961,4 +2961,3 @@ __all__ = [
2961
2961
  'clear_global_import_caches',
2962
2962
  'get_global_import_cache_stats',
2963
2963
  ]
2964
-
@@ -272,4 +272,3 @@ def is_partially_initialized(module_name: str, module: ModuleType,
272
272
  detector = PartialModuleDetector(strategy)
273
273
  return detector.is_partially_initialized(module_name, module)
274
274
  return _default_detector.is_partially_initialized(module_name, module)
275
-
@@ -19,4 +19,3 @@ __all__ = [
19
19
  'SimpleManager',
20
20
  'AdvancedManager',
21
21
  ]
22
-
@@ -90,4 +90,3 @@ class LazyHelper(AModuleHelperStrategy):
90
90
  return spec is not None
91
91
  except (ValueError, AttributeError, ImportError):
92
92
  return False
93
-
@@ -62,4 +62,3 @@ class SimpleHelper(AModuleHelperStrategy):
62
62
  return spec is not None
63
63
  except (ValueError, AttributeError, ImportError):
64
64
  return False
65
-
@@ -108,4 +108,3 @@ class AdvancedManager(AModuleManagerStrategy):
108
108
  self._package_helper
109
109
  )
110
110
  return self._import_hook.handle_import_error(module_name)
111
-
@@ -92,4 +92,3 @@ class SimpleManager(AModuleManagerStrategy):
92
92
  None (simple mode doesn't handle errors)
93
93
  """
94
94
  return None
95
-