exonware-xwsystem 0.0.1.409__py3-none-any.whl → 0.0.1.411__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 (260) hide show
  1. exonware/__init__.py +2 -2
  2. exonware/conf.py +10 -20
  3. exonware/xwsystem/__init__.py +6 -16
  4. exonware/xwsystem/caching/__init__.py +1 -1
  5. exonware/xwsystem/caching/base.py +16 -16
  6. exonware/xwsystem/caching/bloom_cache.py +5 -5
  7. exonware/xwsystem/caching/cache_manager.py +2 -2
  8. exonware/xwsystem/caching/conditional.py +4 -4
  9. exonware/xwsystem/caching/contracts.py +12 -12
  10. exonware/xwsystem/caching/decorators.py +2 -2
  11. exonware/xwsystem/caching/defs.py +1 -1
  12. exonware/xwsystem/caching/disk_cache.py +4 -4
  13. exonware/xwsystem/caching/distributed.py +1 -1
  14. exonware/xwsystem/caching/errors.py +1 -1
  15. exonware/xwsystem/caching/events.py +8 -8
  16. exonware/xwsystem/caching/eviction_strategies.py +9 -9
  17. exonware/xwsystem/caching/fluent.py +1 -1
  18. exonware/xwsystem/caching/integrity.py +1 -1
  19. exonware/xwsystem/caching/lfu_cache.py +24 -9
  20. exonware/xwsystem/caching/lfu_optimized.py +21 -21
  21. exonware/xwsystem/caching/lru_cache.py +14 -7
  22. exonware/xwsystem/caching/memory_bounded.py +8 -8
  23. exonware/xwsystem/caching/metrics_exporter.py +6 -6
  24. exonware/xwsystem/caching/observable_cache.py +1 -1
  25. exonware/xwsystem/caching/pluggable_cache.py +9 -9
  26. exonware/xwsystem/caching/rate_limiter.py +1 -1
  27. exonware/xwsystem/caching/read_through.py +6 -6
  28. exonware/xwsystem/caching/secure_cache.py +1 -1
  29. exonware/xwsystem/caching/serializable.py +3 -3
  30. exonware/xwsystem/caching/stats.py +7 -7
  31. exonware/xwsystem/caching/tagging.py +11 -11
  32. exonware/xwsystem/caching/ttl_cache.py +21 -6
  33. exonware/xwsystem/caching/two_tier_cache.py +5 -5
  34. exonware/xwsystem/caching/utils.py +3 -3
  35. exonware/xwsystem/caching/validation.py +1 -1
  36. exonware/xwsystem/caching/warming.py +9 -9
  37. exonware/xwsystem/caching/write_behind.py +5 -5
  38. exonware/xwsystem/cli/__init__.py +1 -1
  39. exonware/xwsystem/cli/args.py +10 -10
  40. exonware/xwsystem/cli/base.py +15 -15
  41. exonware/xwsystem/cli/colors.py +1 -1
  42. exonware/xwsystem/cli/console.py +1 -1
  43. exonware/xwsystem/cli/contracts.py +5 -5
  44. exonware/xwsystem/cli/defs.py +1 -1
  45. exonware/xwsystem/cli/errors.py +1 -1
  46. exonware/xwsystem/cli/progress.py +1 -1
  47. exonware/xwsystem/cli/prompts.py +1 -1
  48. exonware/xwsystem/cli/tables.py +7 -7
  49. exonware/xwsystem/config/__init__.py +1 -1
  50. exonware/xwsystem/config/base.py +14 -14
  51. exonware/xwsystem/config/contracts.py +22 -22
  52. exonware/xwsystem/config/defaults.py +2 -2
  53. exonware/xwsystem/config/defs.py +1 -1
  54. exonware/xwsystem/config/errors.py +2 -2
  55. exonware/xwsystem/config/logging.py +1 -1
  56. exonware/xwsystem/config/logging_setup.py +2 -2
  57. exonware/xwsystem/config/performance.py +7 -7
  58. exonware/xwsystem/config/performance_modes.py +20 -20
  59. exonware/xwsystem/config/version_manager.py +4 -4
  60. exonware/xwsystem/{http → http_client}/__init__.py +1 -1
  61. exonware/xwsystem/{http → http_client}/advanced_client.py +20 -20
  62. exonware/xwsystem/{http → http_client}/base.py +13 -13
  63. exonware/xwsystem/{http → http_client}/client.py +43 -43
  64. exonware/xwsystem/{http → http_client}/contracts.py +5 -5
  65. exonware/xwsystem/{http → http_client}/defs.py +2 -2
  66. exonware/xwsystem/{http → http_client}/errors.py +2 -2
  67. exonware/xwsystem/io/__init__.py +1 -1
  68. exonware/xwsystem/io/archive/__init__.py +1 -1
  69. exonware/xwsystem/io/archive/archive.py +5 -5
  70. exonware/xwsystem/io/archive/archive_files.py +8 -8
  71. exonware/xwsystem/io/archive/archivers.py +3 -3
  72. exonware/xwsystem/io/archive/base.py +17 -17
  73. exonware/xwsystem/io/archive/codec_integration.py +1 -1
  74. exonware/xwsystem/io/archive/compression.py +1 -1
  75. exonware/xwsystem/io/archive/formats/__init__.py +1 -1
  76. exonware/xwsystem/io/archive/formats/brotli_format.py +12 -9
  77. exonware/xwsystem/io/archive/formats/lz4_format.py +12 -9
  78. exonware/xwsystem/io/archive/formats/rar.py +12 -9
  79. exonware/xwsystem/io/archive/formats/sevenzip.py +12 -9
  80. exonware/xwsystem/io/archive/formats/squashfs_format.py +7 -7
  81. exonware/xwsystem/io/archive/formats/tar.py +8 -8
  82. exonware/xwsystem/io/archive/formats/wim_format.py +12 -9
  83. exonware/xwsystem/io/archive/formats/zip.py +8 -8
  84. exonware/xwsystem/io/archive/formats/zpaq_format.py +7 -7
  85. exonware/xwsystem/io/archive/formats/zstandard.py +12 -9
  86. exonware/xwsystem/io/base.py +17 -17
  87. exonware/xwsystem/io/codec/__init__.py +1 -1
  88. exonware/xwsystem/io/codec/base.py +261 -14
  89. exonware/xwsystem/io/codec/contracts.py +3 -6
  90. exonware/xwsystem/io/codec/registry.py +29 -29
  91. exonware/xwsystem/io/common/__init__.py +1 -1
  92. exonware/xwsystem/io/common/atomic.py +2 -2
  93. exonware/xwsystem/io/common/base.py +1 -1
  94. exonware/xwsystem/io/common/lock.py +1 -1
  95. exonware/xwsystem/io/common/watcher.py +4 -4
  96. exonware/xwsystem/io/contracts.py +34 -39
  97. exonware/xwsystem/io/data_operations.py +480 -0
  98. exonware/xwsystem/io/defs.py +2 -2
  99. exonware/xwsystem/io/errors.py +32 -3
  100. exonware/xwsystem/io/facade.py +4 -4
  101. exonware/xwsystem/io/file/__init__.py +1 -1
  102. exonware/xwsystem/io/file/base.py +2 -2
  103. exonware/xwsystem/io/file/conversion.py +1 -1
  104. exonware/xwsystem/io/file/file.py +10 -8
  105. exonware/xwsystem/io/file/paged_source.py +8 -1
  106. exonware/xwsystem/io/file/paging/__init__.py +1 -1
  107. exonware/xwsystem/io/file/paging/byte_paging.py +1 -1
  108. exonware/xwsystem/io/file/paging/line_paging.py +1 -1
  109. exonware/xwsystem/io/file/paging/record_paging.py +1 -1
  110. exonware/xwsystem/io/file/paging/registry.py +5 -5
  111. exonware/xwsystem/io/file/source.py +22 -11
  112. exonware/xwsystem/io/filesystem/__init__.py +1 -1
  113. exonware/xwsystem/io/filesystem/base.py +1 -1
  114. exonware/xwsystem/io/filesystem/local.py +9 -1
  115. exonware/xwsystem/io/folder/__init__.py +1 -1
  116. exonware/xwsystem/io/folder/base.py +2 -2
  117. exonware/xwsystem/io/folder/folder.py +6 -6
  118. exonware/xwsystem/io/serialization/__init__.py +1 -1
  119. exonware/xwsystem/io/serialization/auto_serializer.py +53 -40
  120. exonware/xwsystem/io/serialization/base.py +248 -35
  121. exonware/xwsystem/io/serialization/contracts.py +93 -4
  122. exonware/xwsystem/io/serialization/defs.py +1 -1
  123. exonware/xwsystem/io/serialization/errors.py +1 -1
  124. exonware/xwsystem/io/serialization/flyweight.py +22 -22
  125. exonware/xwsystem/io/serialization/format_detector.py +18 -15
  126. exonware/xwsystem/io/serialization/formats/__init__.py +1 -1
  127. exonware/xwsystem/io/serialization/formats/binary/bson.py +1 -1
  128. exonware/xwsystem/io/serialization/formats/binary/cbor.py +1 -1
  129. exonware/xwsystem/io/serialization/formats/binary/marshal.py +1 -1
  130. exonware/xwsystem/io/serialization/formats/binary/msgpack.py +1 -1
  131. exonware/xwsystem/io/serialization/formats/binary/pickle.py +1 -1
  132. exonware/xwsystem/io/serialization/formats/binary/plistlib.py +1 -1
  133. exonware/xwsystem/io/serialization/formats/database/dbm.py +53 -1
  134. exonware/xwsystem/io/serialization/formats/database/shelve.py +48 -1
  135. exonware/xwsystem/io/serialization/formats/database/sqlite3.py +85 -1
  136. exonware/xwsystem/io/serialization/formats/text/configparser.py +2 -2
  137. exonware/xwsystem/io/serialization/formats/text/csv.py +2 -2
  138. exonware/xwsystem/io/serialization/formats/text/formdata.py +2 -2
  139. exonware/xwsystem/io/serialization/formats/text/json.py +23 -5
  140. exonware/xwsystem/io/serialization/formats/text/json5.py +98 -13
  141. exonware/xwsystem/io/serialization/formats/text/jsonlines.py +230 -20
  142. exonware/xwsystem/io/serialization/formats/text/multipart.py +2 -2
  143. exonware/xwsystem/io/serialization/formats/text/toml.py +65 -4
  144. exonware/xwsystem/io/serialization/formats/text/xml.py +451 -69
  145. exonware/xwsystem/io/serialization/formats/text/yaml.py +52 -2
  146. exonware/xwsystem/io/serialization/registry.py +5 -5
  147. exonware/xwsystem/io/serialization/serializer.py +184 -12
  148. exonware/xwsystem/io/serialization/utils/__init__.py +1 -1
  149. exonware/xwsystem/io/serialization/utils/path_ops.py +3 -3
  150. exonware/xwsystem/io/stream/__init__.py +1 -1
  151. exonware/xwsystem/io/stream/async_operations.py +3 -3
  152. exonware/xwsystem/io/stream/base.py +3 -7
  153. exonware/xwsystem/io/stream/codec_io.py +4 -7
  154. exonware/xwsystem/ipc/async_fabric.py +7 -8
  155. exonware/xwsystem/ipc/base.py +9 -9
  156. exonware/xwsystem/ipc/contracts.py +5 -5
  157. exonware/xwsystem/ipc/defs.py +1 -1
  158. exonware/xwsystem/ipc/errors.py +2 -2
  159. exonware/xwsystem/ipc/message_queue.py +4 -6
  160. exonware/xwsystem/ipc/pipes.py +2 -2
  161. exonware/xwsystem/ipc/process_manager.py +7 -7
  162. exonware/xwsystem/ipc/process_pool.py +8 -8
  163. exonware/xwsystem/ipc/shared_memory.py +7 -7
  164. exonware/xwsystem/monitoring/base.py +33 -33
  165. exonware/xwsystem/monitoring/contracts.py +27 -27
  166. exonware/xwsystem/monitoring/defs.py +1 -1
  167. exonware/xwsystem/monitoring/error_recovery.py +16 -16
  168. exonware/xwsystem/monitoring/errors.py +2 -2
  169. exonware/xwsystem/monitoring/memory_monitor.py +12 -12
  170. exonware/xwsystem/monitoring/metrics.py +8 -8
  171. exonware/xwsystem/monitoring/performance_manager_generic.py +20 -20
  172. exonware/xwsystem/monitoring/performance_monitor.py +11 -11
  173. exonware/xwsystem/monitoring/performance_validator.py +21 -21
  174. exonware/xwsystem/monitoring/system_monitor.py +17 -17
  175. exonware/xwsystem/monitoring/tracing.py +20 -20
  176. exonware/xwsystem/monitoring/tracker.py +7 -7
  177. exonware/xwsystem/operations/__init__.py +5 -5
  178. exonware/xwsystem/operations/base.py +3 -3
  179. exonware/xwsystem/operations/contracts.py +3 -3
  180. exonware/xwsystem/operations/defs.py +5 -5
  181. exonware/xwsystem/operations/diff.py +5 -5
  182. exonware/xwsystem/operations/merge.py +2 -2
  183. exonware/xwsystem/operations/patch.py +5 -5
  184. exonware/xwsystem/patterns/base.py +4 -4
  185. exonware/xwsystem/patterns/context_manager.py +7 -7
  186. exonware/xwsystem/patterns/contracts.py +29 -31
  187. exonware/xwsystem/patterns/defs.py +1 -1
  188. exonware/xwsystem/patterns/dynamic_facade.py +9 -9
  189. exonware/xwsystem/patterns/errors.py +10 -10
  190. exonware/xwsystem/patterns/handler_factory.py +15 -14
  191. exonware/xwsystem/patterns/import_registry.py +22 -22
  192. exonware/xwsystem/patterns/object_pool.py +14 -13
  193. exonware/xwsystem/patterns/registry.py +45 -32
  194. exonware/xwsystem/plugins/__init__.py +1 -1
  195. exonware/xwsystem/plugins/base.py +25 -25
  196. exonware/xwsystem/plugins/contracts.py +28 -28
  197. exonware/xwsystem/plugins/defs.py +1 -1
  198. exonware/xwsystem/plugins/errors.py +9 -9
  199. exonware/xwsystem/runtime/__init__.py +1 -1
  200. exonware/xwsystem/runtime/base.py +42 -42
  201. exonware/xwsystem/runtime/contracts.py +9 -9
  202. exonware/xwsystem/runtime/defs.py +1 -1
  203. exonware/xwsystem/runtime/env.py +9 -9
  204. exonware/xwsystem/runtime/errors.py +1 -1
  205. exonware/xwsystem/runtime/reflection.py +15 -15
  206. exonware/xwsystem/security/auth.py +47 -15
  207. exonware/xwsystem/security/base.py +17 -17
  208. exonware/xwsystem/security/contracts.py +30 -30
  209. exonware/xwsystem/security/crypto.py +8 -8
  210. exonware/xwsystem/security/defs.py +1 -1
  211. exonware/xwsystem/security/errors.py +2 -2
  212. exonware/xwsystem/security/hazmat.py +7 -7
  213. exonware/xwsystem/security/path_validator.py +1 -1
  214. exonware/xwsystem/shared/__init__.py +1 -1
  215. exonware/xwsystem/shared/base.py +14 -14
  216. exonware/xwsystem/shared/contracts.py +6 -6
  217. exonware/xwsystem/shared/defs.py +1 -1
  218. exonware/xwsystem/shared/errors.py +1 -1
  219. exonware/xwsystem/structures/__init__.py +1 -1
  220. exonware/xwsystem/structures/base.py +29 -29
  221. exonware/xwsystem/structures/circular_detector.py +15 -15
  222. exonware/xwsystem/structures/contracts.py +9 -9
  223. exonware/xwsystem/structures/defs.py +1 -1
  224. exonware/xwsystem/structures/errors.py +2 -2
  225. exonware/xwsystem/structures/tree_walker.py +8 -8
  226. exonware/xwsystem/threading/async_primitives.py +7 -7
  227. exonware/xwsystem/threading/base.py +19 -19
  228. exonware/xwsystem/threading/contracts.py +13 -13
  229. exonware/xwsystem/threading/defs.py +1 -1
  230. exonware/xwsystem/threading/errors.py +2 -2
  231. exonware/xwsystem/threading/safe_factory.py +13 -12
  232. exonware/xwsystem/utils/base.py +34 -34
  233. exonware/xwsystem/utils/contracts.py +9 -9
  234. exonware/xwsystem/utils/dt/__init__.py +1 -1
  235. exonware/xwsystem/utils/dt/base.py +6 -6
  236. exonware/xwsystem/utils/dt/contracts.py +2 -2
  237. exonware/xwsystem/utils/dt/defs.py +1 -1
  238. exonware/xwsystem/utils/dt/errors.py +2 -2
  239. exonware/xwsystem/utils/dt/formatting.py +3 -3
  240. exonware/xwsystem/utils/dt/humanize.py +2 -2
  241. exonware/xwsystem/utils/dt/parsing.py +2 -2
  242. exonware/xwsystem/utils/dt/timezone_utils.py +5 -5
  243. exonware/xwsystem/utils/errors.py +2 -2
  244. exonware/xwsystem/utils/test_runner.py +6 -6
  245. exonware/xwsystem/utils/utils_contracts.py +1 -1
  246. exonware/xwsystem/validation/__init__.py +1 -1
  247. exonware/xwsystem/validation/base.py +48 -48
  248. exonware/xwsystem/validation/contracts.py +8 -8
  249. exonware/xwsystem/validation/data_validator.py +10 -0
  250. exonware/xwsystem/validation/declarative.py +15 -15
  251. exonware/xwsystem/validation/defs.py +1 -1
  252. exonware/xwsystem/validation/errors.py +2 -2
  253. exonware/xwsystem/validation/fluent_validator.py +10 -10
  254. exonware/xwsystem/version.py +2 -2
  255. {exonware_xwsystem-0.0.1.409.dist-info → exonware_xwsystem-0.0.1.411.dist-info}/METADATA +9 -11
  256. exonware_xwsystem-0.0.1.411.dist-info/RECORD +274 -0
  257. {exonware_xwsystem-0.0.1.409.dist-info → exonware_xwsystem-0.0.1.411.dist-info}/WHEEL +1 -1
  258. exonware/xwsystem/lazy_bootstrap.py +0 -79
  259. exonware_xwsystem-0.0.1.409.dist-info/RECORD +0 -274
  260. {exonware_xwsystem-0.0.1.409.dist-info → exonware_xwsystem-0.0.1.411.dist-info}/licenses/LICENSE +0 -0
@@ -1,3 +1,4 @@
1
+ #exonware/xwsystem/patterns/object_pool.py
1
2
  """
2
3
  Generic object pool implementation for XSystem framework.
3
4
 
@@ -6,12 +7,12 @@ components to reduce memory allocation overhead and improve performance.
6
7
  """
7
8
 
8
9
  import threading
9
- from typing import Any, Callable, Dict, List, Optional, Type, TypeVar
10
+ from typing import Any, Callable, Optional
11
+ # Root cause: Migrating to Python 3.12 built-in generic syntax for consistency
12
+ # Priority #3: Maintainability - Modern type annotations improve code clarity
10
13
 
11
14
  from ..config.logging_setup import get_logger
12
15
 
13
- T = TypeVar("T")
14
-
15
16
 
16
17
  class ObjectPool:
17
18
  """
@@ -35,13 +36,13 @@ class ObjectPool:
35
36
  enable_thread_safety: Whether to use thread-safe operations
36
37
  component_name: Name for logging purposes
37
38
  """
38
- self._pools: Dict[Type, List[Any]] = {}
39
+ self._pools: dict[type, list[Any]] = {}
39
40
  self._max_size = max_size
40
41
  self._lock = threading.RLock() if enable_thread_safety else None
41
42
  self._logger = get_logger(f"{component_name}.object_pool")
42
43
  self._stats = {"created": 0, "reused": 0, "released": 0, "discarded": 0}
43
44
 
44
- def get(self, obj_type: Type[T], *args, **kwargs) -> T:
45
+ def get[T](self, obj_type: type[T], *args, **kwargs) -> T:
45
46
  """
46
47
  Get an object from the pool or create a new one if the pool is empty.
47
48
 
@@ -61,7 +62,7 @@ class ObjectPool:
61
62
  else:
62
63
  return self._get_from_pool(obj_type, pool, *args, **kwargs)
63
64
 
64
- def _get_from_pool(self, obj_type: Type[T], pool: List[Any], *args, **kwargs) -> T:
65
+ def _get_from_pool[T](self, obj_type: type[T], pool: list[Any], *args, **kwargs) -> T:
65
66
  """Internal method to get object from pool."""
66
67
  if pool:
67
68
  obj = pool.pop()
@@ -99,7 +100,7 @@ class ObjectPool:
99
100
  else:
100
101
  self._release_to_pool(obj, obj_type)
101
102
 
102
- def _release_to_pool(self, obj: Any, obj_type: Type) -> None:
103
+ def _release_to_pool(self, obj: Any, obj_type: type) -> None:
103
104
  """Internal method to release object to pool."""
104
105
  if obj_type not in self._pools:
105
106
  self._pools[obj_type] = []
@@ -114,7 +115,7 @@ class ObjectPool:
114
115
  self._stats["discarded"] += 1
115
116
  self._logger.debug(f"Discarded {obj_type.__name__} (pool full)")
116
117
 
117
- def clear(self, obj_type: Optional[Type] = None) -> None:
118
+ def clear(self, obj_type: Optional[type] = None) -> None:
118
119
  """
119
120
  Clear objects from the pool.
120
121
 
@@ -127,7 +128,7 @@ class ObjectPool:
127
128
  else:
128
129
  self._clear_pool(obj_type)
129
130
 
130
- def _clear_pool(self, obj_type: Optional[Type] = None) -> None:
131
+ def _clear_pool(self, obj_type: Optional[type] = None) -> None:
131
132
  """Internal method to clear pool."""
132
133
  if obj_type is None:
133
134
  # Clear all pools
@@ -140,7 +141,7 @@ class ObjectPool:
140
141
  self._pools[obj_type].clear()
141
142
  self._logger.info(f"Cleared pool for {obj_type.__name__}")
142
143
 
143
- def get_stats(self) -> Dict[str, Any]:
144
+ def get_stats(self) -> dict[str, Any]:
144
145
  """
145
146
  Get pool statistics.
146
147
 
@@ -153,7 +154,7 @@ class ObjectPool:
153
154
  else:
154
155
  return self._get_pool_stats()
155
156
 
156
- def _get_pool_stats(self) -> Dict[str, Any]:
157
+ def _get_pool_stats(self) -> dict[str, Any]:
157
158
  """Internal method to get pool statistics."""
158
159
  pool_sizes = {t.__name__: len(pool) for t, pool in self._pools.items()}
159
160
 
@@ -199,7 +200,7 @@ class PooledObject:
199
200
 
200
201
 
201
202
  # Global object pool registry
202
- _pool_registry: Dict[str, ObjectPool] = {}
203
+ _pool_registry: dict[str, ObjectPool] = {}
203
204
  _pool_registry_lock = threading.RLock()
204
205
 
205
206
 
@@ -242,7 +243,7 @@ def clear_object_pool(component_name: str) -> None:
242
243
  del _pool_registry[component_name]
243
244
 
244
245
 
245
- def get_all_pool_stats() -> Dict[str, Dict[str, Any]]:
246
+ def get_all_pool_stats() -> dict[str, dict[str, Any]]:
246
247
  """
247
248
  Get statistics for all object pools.
248
249
 
@@ -1,9 +1,10 @@
1
1
  #!/usr/bin/env python3
2
+ #exonware/xwsystem/patterns/registry.py
2
3
  """
3
4
  Company: eXonware.com
4
5
  Author: Eng. Muhammad AlShehri
5
6
  Email: connect@exonware.com
6
- Version: 0.0.1.409
7
+ Version: 0.0.1.411
7
8
  Generation Date: October 26, 2025
8
9
 
9
10
  Generic registry pattern for dynamic registration and discovery.
@@ -11,25 +12,30 @@ Generic registry pattern for dynamic registration and discovery.
11
12
 
12
13
  import threading
13
14
  import time
14
- from typing import Any, Dict, List, Optional, Type, TypeVar, Callable, Set
15
+ from typing import Any, Optional, Callable
16
+ # Root cause: Migrating to Python 3.12 built-in generic syntax for consistency
17
+ # Priority #3: Maintainability - Modern type annotations improve code clarity
15
18
  from abc import ABC, abstractmethod
16
19
  from ..config.logging_setup import get_logger
17
20
 
18
21
  logger = get_logger("xwsystem.patterns.registry")
19
22
 
20
- T = TypeVar('T')
21
-
22
23
 
23
24
  class RegistryError(Exception):
24
25
  """Registry-specific error."""
25
26
  pass
26
27
 
27
28
 
28
- class IRegistry(ABC):
29
- """Interface for registry implementations."""
29
+ class IRegistry[T](ABC):
30
+ """
31
+ Interface for registry implementations.
32
+
33
+ Root cause: Adding generic type parameter for better type safety.
34
+ Priority #3: Maintainability - Generic types improve code clarity and type checking.
35
+ """
30
36
 
31
37
  @abstractmethod
32
- def register(self, name: str, item: Any, metadata: Optional[Dict[str, Any]] = None) -> bool:
38
+ def register(self, name: str, item: T, metadata: Optional[dict[str, Any]] = None) -> bool:
33
39
  """Register an item with optional metadata."""
34
40
  pass
35
41
 
@@ -39,12 +45,12 @@ class IRegistry(ABC):
39
45
  pass
40
46
 
41
47
  @abstractmethod
42
- def get(self, name: str) -> Optional[Any]:
48
+ def get(self, name: str) -> Optional[T]:
43
49
  """Get an item by name."""
44
50
  pass
45
51
 
46
52
  @abstractmethod
47
- def list_names(self) -> List[str]:
53
+ def list_names(self) -> list[str]:
48
54
  """List all registered names."""
49
55
  pass
50
56
 
@@ -59,7 +65,7 @@ class IRegistry(ABC):
59
65
  pass
60
66
 
61
67
 
62
- class GenericRegistry(IRegistry):
68
+ class GenericRegistry[T](IRegistry[T]):
63
69
  """
64
70
  Generic registry for dynamic registration and discovery.
65
71
 
@@ -75,7 +81,7 @@ class GenericRegistry(IRegistry):
75
81
  def __init__(
76
82
  self,
77
83
  name: str = "generic",
78
- item_type: Optional[Type] = None,
84
+ item_type: Optional[type] = None,
79
85
  allow_overwrite: bool = False,
80
86
  auto_discovery: bool = False
81
87
  ):
@@ -97,13 +103,13 @@ class GenericRegistry(IRegistry):
97
103
  self._lock = threading.RLock()
98
104
 
99
105
  # Storage
100
- self._items: Dict[str, Any] = {}
101
- self._metadata: Dict[str, Dict[str, Any]] = {}
102
- self._factories: Dict[str, Callable[[], Any]] = {}
106
+ self._items: dict[str, T] = {}
107
+ self._metadata: dict[str, dict[str, Any]] = {}
108
+ self._factories: dict[str, Callable[[], T]] = {}
103
109
 
104
110
  # Callbacks
105
- self._registration_callbacks: List[Callable[[str, Any, Dict[str, Any]], None]] = []
106
- self._unregistration_callbacks: List[Callable[[str, Any], None]] = []
111
+ self._registration_callbacks: list[Callable[[str, T, dict[str, Any]], None]] = []
112
+ self._unregistration_callbacks: list[Callable[[str, T], None]] = []
107
113
 
108
114
  # Statistics
109
115
  self._stats = {
@@ -119,9 +125,9 @@ class GenericRegistry(IRegistry):
119
125
  def register(
120
126
  self,
121
127
  name: str,
122
- item: Any,
123
- metadata: Optional[Dict[str, Any]] = None,
124
- factory: Optional[Callable[[], Any]] = None
128
+ item: T,
129
+ metadata: Optional[dict[str, Any]] = None,
130
+ factory: Optional[Callable[[], T]] = None
125
131
  ) -> bool:
126
132
  """
127
133
  Register an item with optional metadata and factory.
@@ -229,7 +235,7 @@ class GenericRegistry(IRegistry):
229
235
  logger.error(f"Failed to unregister item '{name}': {e}")
230
236
  return False
231
237
 
232
- def get(self, name: str) -> Optional[Any]:
238
+ def get(self, name: str) -> Optional[T]:
233
239
  """
234
240
  Get an item by name.
235
241
 
@@ -265,7 +271,7 @@ class GenericRegistry(IRegistry):
265
271
  self._stats['misses'] += 1
266
272
  return None
267
273
 
268
- def list_names(self) -> List[str]:
274
+ def list_names(self) -> list[str]:
269
275
  """List all registered names."""
270
276
  with self._lock:
271
277
  return list(self._items.keys())
@@ -299,12 +305,12 @@ class GenericRegistry(IRegistry):
299
305
  logger.error(f"Failed to clear registry '{self.name}': {e}")
300
306
  return False
301
307
 
302
- def get_metadata(self, name: str) -> Optional[Dict[str, Any]]:
308
+ def get_metadata(self, name: str) -> Optional[dict[str, Any]]:
303
309
  """Get metadata for an item."""
304
310
  with self._lock:
305
311
  return self._metadata.get(name)
306
312
 
307
- def update_metadata(self, name: str, metadata: Dict[str, Any]) -> bool:
313
+ def update_metadata(self, name: str, metadata: dict[str, Any]) -> bool:
308
314
  """Update metadata for an item."""
309
315
  with self._lock:
310
316
  if name not in self._items:
@@ -316,17 +322,17 @@ class GenericRegistry(IRegistry):
316
322
  self._metadata[name].update(metadata)
317
323
  return True
318
324
 
319
- def add_registration_callback(self, callback: Callable[[str, Any, Dict[str, Any]], None]):
325
+ def add_registration_callback(self, callback: Callable[[str, T, dict[str, Any]], None]):
320
326
  """Add callback for registration events."""
321
327
  with self._lock:
322
328
  self._registration_callbacks.append(callback)
323
329
 
324
- def add_unregistration_callback(self, callback: Callable[[str, Any], None]):
330
+ def add_unregistration_callback(self, callback: Callable[[str, T], None]):
325
331
  """Add callback for unregistration events."""
326
332
  with self._lock:
327
333
  self._unregistration_callbacks.append(callback)
328
334
 
329
- def get_stats(self) -> Dict[str, Any]:
335
+ def get_stats(self) -> dict[str, Any]:
330
336
  """Get registry statistics."""
331
337
  with self._lock:
332
338
  total_lookups = self._stats['hits'] + self._stats['misses']
@@ -346,7 +352,7 @@ class GenericRegistry(IRegistry):
346
352
  'auto_discovery': self.auto_discovery,
347
353
  }
348
354
 
349
- def discover_items(self, discovery_func: Callable[[], List[tuple]]) -> int:
355
+ def discover_items(self, discovery_func: Callable[[], list[tuple[str, T, dict[str, Any]]]]) -> int:
350
356
  """
351
357
  Discover and register items using a discovery function.
352
358
 
@@ -374,28 +380,35 @@ class GenericRegistry(IRegistry):
374
380
 
375
381
 
376
382
  # Global registry manager
377
- _registries: Dict[str, GenericRegistry] = {}
383
+ _registries: dict[str, GenericRegistry[Any]] = {}
378
384
  _registry_lock = threading.RLock()
379
385
 
380
386
 
381
- def get_registry(name: str, **kwargs) -> GenericRegistry:
387
+ def get_registry(name: str, **kwargs) -> GenericRegistry[Any]:
382
388
  """
383
389
  Get or create a registry by name.
384
390
 
391
+ Root cause: Global registry storage uses GenericRegistry[Any] for flexibility.
392
+ Users can create typed registries directly: GenericRegistry[MyType]().
393
+ Priority #3: Maintainability - Clear API design.
394
+
385
395
  Args:
386
396
  name: Registry name
387
397
  **kwargs: Additional arguments for registry creation
388
398
 
389
399
  Returns:
390
- Registry instance
400
+ Registry instance (untyped for global registry flexibility)
401
+
402
+ Note:
403
+ For type-safe registries, create directly: GenericRegistry[MyType]()
391
404
  """
392
405
  with _registry_lock:
393
406
  if name not in _registries:
394
- _registries[name] = GenericRegistry(name=name, **kwargs)
407
+ _registries[name] = GenericRegistry[Any](name=name, **kwargs)
395
408
  return _registries[name]
396
409
 
397
410
 
398
- def list_registries() -> List[str]:
411
+ def list_registries() -> list[str]:
399
412
  """List all registry names."""
400
413
  with _registry_lock:
401
414
  return list(_registries.keys())
@@ -2,7 +2,7 @@
2
2
  Company: eXonware.com
3
3
  Author: Eng. Muhammad AlShehri
4
4
  Email: connect@exonware.com
5
- Version: 0.0.1.409
5
+ Version: 0.0.1.411
6
6
  Generation Date: September 04, 2025
7
7
 
8
8
  XSystem Plugins Package
@@ -1,9 +1,9 @@
1
- #exonware/xsystem/plugins/base.py
1
+ #exonware/xwsystem/plugins/base.py
2
2
  """
3
3
  Company: eXonware.com
4
4
  Author: Eng. Muhammad AlShehri
5
5
  Email: connect@exonware.com
6
- Version: 0.0.1.409
6
+ Version: 0.0.1.411
7
7
  Generation Date: September 04, 2025
8
8
 
9
9
  Plugin system base classes and management.
@@ -15,7 +15,7 @@ import threading
15
15
  from abc import ABC, abstractmethod
16
16
  from dataclasses import dataclass, field
17
17
  from pathlib import Path
18
- from typing import Any, Dict, List, Optional, Set, Type, Union
18
+ from typing import Any, Optional, Union
19
19
 
20
20
  from importlib.metadata import entry_points
21
21
 
@@ -24,7 +24,7 @@ from ..runtime.reflection import ReflectionUtils
24
24
  from .contracts import IPlugin, PluginState, PluginType, PluginPriority
25
25
  from .errors import PluginError
26
26
 
27
- logger = get_logger("xsystem.plugins.base")
27
+ logger = get_logger("xwsystem.plugins.base")
28
28
 
29
29
 
30
30
  @dataclass
@@ -39,8 +39,8 @@ class APluginInfo:
39
39
  class_name: str = ""
40
40
  enabled: bool = True
41
41
  priority: int = 100
42
- dependencies: List[str] = field(default_factory=list)
43
- metadata: Dict[str, Any] = field(default_factory=dict)
42
+ dependencies: list[str] = field(default_factory=list)
43
+ metadata: dict[str, Any] = field(default_factory=dict)
44
44
 
45
45
 
46
46
  class APlugin(IPlugin):
@@ -50,7 +50,7 @@ class APlugin(IPlugin):
50
50
  Plugins should inherit from this class and implement the required methods.
51
51
  """
52
52
 
53
- def __init__(self, config: Optional[Dict[str, Any]] = None) -> None:
53
+ def __init__(self, config: Optional[dict[str, Any]] = None) -> None:
54
54
  """
55
55
  Initialize plugin with optional configuration.
56
56
 
@@ -84,7 +84,7 @@ class APlugin(IPlugin):
84
84
  return ""
85
85
 
86
86
  @property
87
- def dependencies(self) -> List[str]:
87
+ def dependencies(self) -> list[str]:
88
88
  """List of plugin dependencies."""
89
89
  return []
90
90
 
@@ -102,7 +102,7 @@ class APlugin(IPlugin):
102
102
  """Check if plugin is initialized."""
103
103
  return self._initialized
104
104
 
105
- def get_info(self) -> Dict[str, Any]:
105
+ def get_info(self) -> dict[str, Any]:
106
106
  """Get plugin information."""
107
107
  return {
108
108
  'name': self.name,
@@ -133,7 +133,7 @@ class APlugin(IPlugin):
133
133
  """Get plugin priority."""
134
134
  return PluginPriority.NORMAL
135
135
 
136
- def get_dependencies(self) -> List[str]:
136
+ def get_dependencies(self) -> list[str]:
137
137
  """Get plugin dependencies."""
138
138
  return self.dependencies
139
139
 
@@ -169,9 +169,9 @@ class APluginRegistry:
169
169
 
170
170
  def __init__(self) -> None:
171
171
  """Initialize plugin registry."""
172
- self._plugins: Dict[str, APlugin] = {}
173
- self._plugin_info: Dict[str, APluginInfo] = {}
174
- self._enabled_plugins: Set[str] = set()
172
+ self._plugins: dict[str, APlugin] = {}
173
+ self._plugin_info: dict[str, APluginInfo] = {}
174
+ self._enabled_plugins: set[str] = set()
175
175
  self._lock = threading.RLock()
176
176
 
177
177
  def register(self, plugin: APlugin) -> None:
@@ -234,12 +234,12 @@ class APluginRegistry:
234
234
  with self._lock:
235
235
  return self._plugins.get(plugin_name)
236
236
 
237
- def get_all(self) -> Dict[str, APlugin]:
237
+ def get_all(self) -> dict[str, APlugin]:
238
238
  """Get all registered plugins."""
239
239
  with self._lock:
240
240
  return self._plugins.copy()
241
241
 
242
- def get_enabled(self) -> Dict[str, APlugin]:
242
+ def get_enabled(self) -> dict[str, APlugin]:
243
243
  """Get all enabled plugins."""
244
244
  with self._lock:
245
245
  return {name: plugin for name, plugin in self._plugins.items()
@@ -290,7 +290,7 @@ class APluginRegistry:
290
290
  logger.info(f"Disabled plugin: {plugin_name}")
291
291
  return True
292
292
 
293
- def list_plugins(self) -> List[APluginInfo]:
293
+ def list_plugins(self) -> list[APluginInfo]:
294
294
  """Get information about all registered plugins."""
295
295
  with self._lock:
296
296
  return list(self._plugin_info.values())
@@ -326,9 +326,9 @@ class APluginManager:
326
326
  registry: Optional plugin registry to use
327
327
  """
328
328
  self.registry = registry or APluginRegistry()
329
- self._discovered_plugins: Dict[str, Dict[str, Any]] = {}
329
+ self._discovered_plugins: dict[str, dict[str, Any]] = {}
330
330
 
331
- def load_plugin_from_module(self, module_path: str, class_name: str, config: Optional[Dict[str, Any]] = None) -> APlugin:
331
+ def load_plugin_from_module(self, module_path: str, class_name: str, config: Optional[dict[str, Any]] = None) -> APlugin:
332
332
  """
333
333
  Load plugin from module path and class name.
334
334
 
@@ -357,7 +357,7 @@ class APluginManager:
357
357
  except Exception as e:
358
358
  raise PluginError(f"Failed to load plugin {module_path}.{class_name}: {e}") from e
359
359
 
360
- def load_plugin_from_file(self, file_path: Union[str, Path], class_name: str, config: Optional[Dict[str, Any]] = None) -> APlugin:
360
+ def load_plugin_from_file(self, file_path: Union[str, Path], class_name: str, config: Optional[dict[str, Any]] = None) -> APlugin:
361
361
  """
362
362
  Load plugin from Python file.
363
363
 
@@ -403,7 +403,7 @@ class APluginManager:
403
403
  except Exception as e:
404
404
  raise PluginError(f"Failed to load plugin from {file_path}: {e}") from e
405
405
 
406
- def discover_entry_points(self, group: str = "xsystem.plugins") -> Dict[str, Dict[str, Any]]:
406
+ def discover_entry_points(self, group: str = "xwsystem.plugins") -> dict[str, dict[str, Any]]:
407
407
  """
408
408
  Discover plugins through entry points.
409
409
 
@@ -439,7 +439,7 @@ class APluginManager:
439
439
 
440
440
  return discovered
441
441
 
442
- def discover_directory(self, directory: Union[str, Path], pattern: str = "*.py") -> Dict[str, Dict[str, Any]]:
442
+ def discover_directory(self, directory: Union[str, Path], pattern: str = "*.py") -> dict[str, dict[str, Any]]:
443
443
  """
444
444
  Discover plugins in a directory.
445
445
 
@@ -492,7 +492,7 @@ class APluginManager:
492
492
 
493
493
  return discovered
494
494
 
495
- def load_discovered_plugins(self, plugin_names: Optional[List[str]] = None, config: Optional[Dict[str, Dict[str, Any]]] = None) -> List[APlugin]:
495
+ def load_discovered_plugins(self, plugin_names: Optional[list[str]] = None, config: Optional[dict[str, dict[str, Any]]] = None) -> list[APlugin]:
496
496
  """
497
497
  Load discovered plugins.
498
498
 
@@ -539,7 +539,7 @@ class APluginManager:
539
539
  logger.info(f"Loaded {len(loaded)} plugins")
540
540
  return loaded
541
541
 
542
- def initialize_plugins(self, plugin_names: Optional[List[str]] = None) -> None:
542
+ def initialize_plugins(self, plugin_names: Optional[list[str]] = None) -> None:
543
543
  """
544
544
  Initialize plugins with dependency resolution.
545
545
 
@@ -585,7 +585,7 @@ class APluginManager:
585
585
  except Exception as e:
586
586
  logger.error(f"Error shutting down plugin {plugin.name}: {e}")
587
587
 
588
- def get_discovered_plugins(self) -> Dict[str, Dict[str, Any]]:
588
+ def get_discovered_plugins(self) -> dict[str, dict[str, Any]]:
589
589
  """Get all discovered plugins."""
590
590
  return self._discovered_plugins.copy()
591
591
 
@@ -605,7 +605,7 @@ def get_plugin_manager() -> APluginManager:
605
605
  class BasePlugin(APlugin):
606
606
  """Base plugin class for backward compatibility."""
607
607
 
608
- def __init__(self, config: Optional[Dict[str, Any]] = None):
608
+ def __init__(self, config: Optional[dict[str, Any]] = None):
609
609
  """Initialize base plugin."""
610
610
  super().__init__(config)
611
611
  self._name = "BasePlugin"