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,142 +0,0 @@
1
- """
2
- Common utility functions for xwlazy.
3
-
4
- Company: eXonware.com
5
- Author: Eng. Muhammad AlShehri
6
- Email: connect@exonware.com
7
-
8
- This module provides shared utility functions used across xwlazy,
9
- including path operations and project root detection.
10
- """
11
-
12
- import sys
13
- from pathlib import Path
14
- from typing import Optional
15
-
16
-
17
- def find_project_root(start_path: Optional[Path] = None) -> Path:
18
- """
19
- Find the project root directory by looking for markers.
20
-
21
- Package-agnostic: Finds root from running script location, not xwlazy's location.
22
- This function is designed to work with any project that uses xwlazy.
23
-
24
- Args:
25
- start_path: Optional starting path. If None, attempts to find from:
26
- 1. __main__ module location
27
- 2. sys.path[0] (script directory)
28
- 3. Current working directory
29
-
30
- Returns:
31
- Path to the project root directory
32
-
33
- Examples:
34
- >>> root = find_project_root()
35
- >>> # Finds pyproject.toml or setup.py from running script
36
-
37
- >>> root = find_project_root(Path(__file__).parent)
38
- >>> # Finds from specific starting path
39
- """
40
- start_paths = []
41
-
42
- # If explicit start path provided, use it first
43
- if start_path:
44
- try:
45
- start_paths.append(start_path.resolve())
46
- except (ValueError, OSError):
47
- pass
48
-
49
- # Option 1: Use __main__ module location if available
50
- if '__main__' in sys.modules:
51
- main_module = sys.modules['__main__']
52
- if hasattr(main_module, '__file__') and main_module.__file__:
53
- try:
54
- main_path = Path(main_module.__file__).resolve().parent
55
- start_paths.append(main_path)
56
- except (ValueError, OSError):
57
- pass
58
-
59
- # Option 2: Use sys.path[0] (script directory)
60
- if sys.path and sys.path[0]:
61
- try:
62
- script_path = Path(sys.path[0]).resolve()
63
- if script_path.exists():
64
- start_paths.append(script_path)
65
- except (ValueError, OSError):
66
- pass
67
-
68
- # Option 3: Use current working directory
69
- try:
70
- cwd = Path.cwd().resolve()
71
- if cwd.exists():
72
- start_paths.append(cwd)
73
- except (OSError, ValueError):
74
- pass
75
-
76
- # Option 4: Fallback to xwlazy location (for backwards compatibility)
77
- try:
78
- xwlazy_path = Path(__file__).parent.parent.parent.parent
79
- if xwlazy_path.exists():
80
- start_paths.append(xwlazy_path)
81
- except (ValueError, OSError):
82
- pass
83
-
84
- # Try each starting path
85
- for start_path_item in start_paths:
86
- current = start_path_item
87
- max_levels = 20 # Prevent infinite loops
88
- levels = 0
89
-
90
- while current != current.parent and levels < max_levels:
91
- # Check for project markers
92
- markers = ['pyproject.toml', 'setup.py', 'requirements.txt', '.git']
93
- if any((current / marker).exists() for marker in markers):
94
- return current
95
- current = current.parent
96
- levels += 1
97
-
98
- # Final fallback: current working directory
99
- try:
100
- return Path.cwd().resolve()
101
- except (OSError, ValueError):
102
- # Ultimate fallback: return the xwlazy package directory
103
- return Path(__file__).parent.parent.parent.parent
104
-
105
-
106
- def find_config_file(filename: str, start_path: Optional[Path] = None) -> Optional[Path]:
107
- """
108
- Find a configuration file by walking up from the start path.
109
-
110
- Args:
111
- filename: Name of the config file to find (e.g., 'pyproject.toml', 'requirements.txt')
112
- start_path: Optional starting path. If None, uses find_project_root()
113
-
114
- Returns:
115
- Path to the config file if found, None otherwise
116
-
117
- Examples:
118
- >>> pyproject = find_config_file('pyproject.toml')
119
- >>> requirements = find_config_file('requirements.txt')
120
- """
121
- if start_path is None:
122
- root = find_project_root()
123
- else:
124
- root = start_path
125
-
126
- # Check in root and walk up
127
- current = root
128
- max_levels = 10
129
- levels = 0
130
-
131
- while current != current.parent and levels < max_levels:
132
- config_path = current / filename
133
- if config_path.exists():
134
- return config_path
135
- current = current.parent
136
- levels += 1
137
-
138
- return None
139
-
140
-
141
- __all__ = ['find_project_root', 'find_config_file']
142
-
exonware/xwlazy/config.py DELETED
@@ -1,193 +0,0 @@
1
- """
2
- #exonware/xwlazy/src/exonware/xwlazy/config.py
3
-
4
- Company: eXonware.com
5
- Author: Eng. Muhammad AlShehri
6
- Email: connect@exonware.com
7
-
8
- Generation Date: 10-Oct-2025
9
-
10
- Configuration for Lazy Loading System
11
-
12
- This module defines configuration classes for the lazy loading system
13
- following GUIDE_ARCH.md structure.
14
- """
15
-
16
- from __future__ import annotations
17
-
18
- from typing import Optional, Any
19
-
20
- # Import LazyConfig dataclass from defs.py
21
- from .defs import LazyConfig as _LazyConfigBase
22
-
23
- # Extend LazyConfig with methods (dataclass is in defs.py)
24
- class LazyConfig(_LazyConfigBase):
25
- """Bridge configuration settings with the lazy package implementation."""
26
-
27
- def __post_init__(self) -> None:
28
- """Normalize package names."""
29
- super().__post_init__()
30
-
31
- # High-level API -----------------------------------------------------
32
- @property
33
- def lazy_import(self) -> bool:
34
- """Return whether lazy mode is currently active."""
35
- # Import from facade
36
- from .facade import is_lazy_mode_enabled
37
- return is_lazy_mode_enabled()
38
-
39
- @lazy_import.setter
40
- def lazy_import(self, value: bool) -> None:
41
- self.set_lazy_import(bool(value))
42
-
43
- def set_lazy_import(
44
- self,
45
- enabled: bool,
46
- *,
47
- lazy_imports: bool = True,
48
- lazy_install: bool = True,
49
- install_hook: bool = True,
50
- mode: str = "auto",
51
- ) -> None:
52
- """
53
- Toggle lazy mode with optional fine-grained controls.
54
-
55
- Includes re-hooking support: If lazy is enabled and install_hook is True,
56
- ensures the import hook is installed even if it wasn't installed initially.
57
- """
58
- # Import from facade
59
- from .facade import (
60
- config_package_lazy_install_enabled,
61
- disable_lazy_mode,
62
- enable_lazy_mode,
63
- is_import_hook_installed,
64
- install_import_hook,
65
- )
66
-
67
- if enabled:
68
- self._configure_packages(True, mode=mode, install_hook=install_hook)
69
- enable_lazy_mode(
70
- package_name=self.packages[0],
71
- enable_lazy_imports=lazy_imports,
72
- enable_lazy_install=lazy_install,
73
- install_hook=install_hook,
74
- lazy_install_mode=mode,
75
- )
76
- # Re-hook: Install hook if lazy is enabled and hook not already installed
77
- # Root cause: Hook not installed when lazy enabled after package load
78
- # Priority impact: Usability (#2) - Users expect lazy to work when enabled
79
- if install_hook:
80
- self._ensure_hook_installed()
81
- else:
82
- disable_lazy_mode()
83
- self._configure_packages(False, install_hook=False)
84
-
85
- def enable(
86
- self,
87
- *,
88
- lazy_imports: bool = True,
89
- lazy_install: bool = True,
90
- install_hook: bool = True,
91
- mode: str = "auto",
92
- ) -> None:
93
- """Enable lazy mode using the provided options."""
94
- self.set_lazy_import(
95
- True,
96
- lazy_imports=lazy_imports,
97
- lazy_install=lazy_install,
98
- install_hook=install_hook,
99
- mode=mode,
100
- )
101
-
102
- def disable(self) -> None:
103
- """Disable lazy mode entirely."""
104
- self.set_lazy_import(False)
105
-
106
- # DX: Status check methods -------------------------------------------
107
- def get_lazy_status(self) -> dict:
108
- """
109
- Get detailed lazy installation status (DX enhancement).
110
-
111
- Returns:
112
- Dictionary with lazy mode status information
113
- """
114
- # Import from facade
115
- from .facade import (
116
- is_import_hook_installed,
117
- is_lazy_install_enabled,
118
- )
119
-
120
- try:
121
- primary_package = self.packages[0] if self.packages else "default"
122
- return {
123
- 'enabled': self.lazy_import,
124
- 'hook_installed': is_import_hook_installed(primary_package),
125
- 'lazy_install_enabled': is_lazy_install_enabled(primary_package),
126
- 'active': self.lazy_import and is_import_hook_installed(primary_package)
127
- }
128
- except Exception:
129
- return {
130
- 'enabled': self.lazy_import,
131
- 'hook_installed': False,
132
- 'lazy_install_enabled': False,
133
- 'active': False,
134
- 'error': 'Could not check hook status'
135
- }
136
-
137
- def is_lazy_active(self) -> bool:
138
- """
139
- Check if lazy mode is active (DX enhancement).
140
-
141
- Returns:
142
- True if lazy mode is enabled and hook is installed
143
- """
144
- # Import from facade
145
- from .facade import is_import_hook_installed
146
-
147
- try:
148
- primary_package = self.packages[0] if self.packages else "default"
149
- return self.lazy_import and is_import_hook_installed(primary_package)
150
- except Exception:
151
- return False
152
-
153
- # Internal helpers ---------------------------------------------------
154
- def _configure_packages(
155
- self,
156
- enabled: bool,
157
- *,
158
- mode: str = "auto",
159
- install_hook: bool = True,
160
- ) -> None:
161
- # Import from facade
162
- from .facade import config_package_lazy_install_enabled
163
-
164
- for package in self.packages:
165
- config_package_lazy_install_enabled(
166
- package,
167
- enabled,
168
- mode,
169
- install_hook=install_hook,
170
- )
171
-
172
- def _ensure_hook_installed(self) -> None:
173
- """
174
- Ensure import hook is installed for primary package.
175
-
176
- Re-hooking support: Install hook if not already installed.
177
- """
178
- # Import from facade
179
- from .facade import (
180
- is_import_hook_installed,
181
- install_import_hook,
182
- )
183
-
184
- try:
185
- primary_package = self.packages[0] if self.packages else "default"
186
- if not is_import_hook_installed(primary_package):
187
- install_import_hook(primary_package)
188
- except Exception:
189
- # Fail silently - hook installation failure shouldn't break package
190
- pass
191
-
192
- DEFAULT_LAZY_CONFIG = LazyConfig()
193
-