exonware-xwsystem 0.1.0.1__py3-none-any.whl → 0.1.0.3__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 (341) hide show
  1. exonware/__init__.py +2 -1
  2. exonware/conf.py +2 -2
  3. exonware/xwsystem/__init__.py +115 -43
  4. exonware/xwsystem/base.py +30 -0
  5. exonware/xwsystem/caching/__init__.py +39 -13
  6. exonware/xwsystem/caching/base.py +24 -6
  7. exonware/xwsystem/caching/bloom_cache.py +2 -2
  8. exonware/xwsystem/caching/cache_manager.py +2 -1
  9. exonware/xwsystem/caching/conditional.py +2 -2
  10. exonware/xwsystem/caching/contracts.py +85 -139
  11. exonware/xwsystem/caching/decorators.py +6 -19
  12. exonware/xwsystem/caching/defs.py +2 -1
  13. exonware/xwsystem/caching/disk_cache.py +2 -1
  14. exonware/xwsystem/caching/distributed.py +2 -1
  15. exonware/xwsystem/caching/errors.py +2 -1
  16. exonware/xwsystem/caching/events.py +110 -27
  17. exonware/xwsystem/caching/eviction_strategies.py +2 -2
  18. exonware/xwsystem/caching/external_caching_python.py +701 -0
  19. exonware/xwsystem/caching/facade.py +253 -0
  20. exonware/xwsystem/caching/factory.py +300 -0
  21. exonware/xwsystem/caching/fluent.py +14 -12
  22. exonware/xwsystem/caching/integrity.py +21 -6
  23. exonware/xwsystem/caching/lfu_cache.py +2 -1
  24. exonware/xwsystem/caching/lfu_optimized.py +18 -6
  25. exonware/xwsystem/caching/lru_cache.py +7 -4
  26. exonware/xwsystem/caching/memory_bounded.py +2 -2
  27. exonware/xwsystem/caching/metrics_exporter.py +2 -2
  28. exonware/xwsystem/caching/observable_cache.py +2 -2
  29. exonware/xwsystem/caching/pluggable_cache.py +2 -2
  30. exonware/xwsystem/caching/rate_limiter.py +2 -2
  31. exonware/xwsystem/caching/read_through.py +2 -2
  32. exonware/xwsystem/caching/secure_cache.py +81 -28
  33. exonware/xwsystem/caching/serializable.py +9 -7
  34. exonware/xwsystem/caching/stats.py +2 -2
  35. exonware/xwsystem/caching/tagging.py +2 -2
  36. exonware/xwsystem/caching/ttl_cache.py +4 -3
  37. exonware/xwsystem/caching/two_tier_cache.py +6 -3
  38. exonware/xwsystem/caching/utils.py +30 -12
  39. exonware/xwsystem/caching/validation.py +2 -2
  40. exonware/xwsystem/caching/warming.py +6 -3
  41. exonware/xwsystem/caching/write_behind.py +15 -6
  42. exonware/xwsystem/config/__init__.py +11 -17
  43. exonware/xwsystem/config/base.py +5 -5
  44. exonware/xwsystem/config/contracts.py +93 -153
  45. exonware/xwsystem/config/defaults.py +3 -2
  46. exonware/xwsystem/config/defs.py +3 -2
  47. exonware/xwsystem/config/errors.py +2 -5
  48. exonware/xwsystem/config/logging.py +12 -8
  49. exonware/xwsystem/config/logging_setup.py +3 -2
  50. exonware/xwsystem/config/performance.py +1 -46
  51. exonware/xwsystem/config/performance_modes.py +9 -8
  52. exonware/xwsystem/config/version_manager.py +1 -0
  53. exonware/xwsystem/config.py +27 -0
  54. exonware/xwsystem/console/__init__.py +53 -0
  55. exonware/xwsystem/console/base.py +133 -0
  56. exonware/xwsystem/console/cli/__init__.py +61 -0
  57. exonware/xwsystem/{cli → console/cli}/args.py +27 -24
  58. exonware/xwsystem/{cli → console/cli}/base.py +18 -87
  59. exonware/xwsystem/{cli → console/cli}/colors.py +15 -13
  60. exonware/xwsystem/console/cli/console.py +98 -0
  61. exonware/xwsystem/{cli → console/cli}/contracts.py +51 -69
  62. exonware/xwsystem/console/cli/defs.py +87 -0
  63. exonware/xwsystem/console/cli/encoding.py +69 -0
  64. exonware/xwsystem/{cli → console/cli}/errors.py +8 -3
  65. exonware/xwsystem/console/cli/event_logger.py +166 -0
  66. exonware/xwsystem/{cli → console/cli}/progress.py +25 -21
  67. exonware/xwsystem/{cli → console/cli}/prompts.py +3 -2
  68. exonware/xwsystem/{cli → console/cli}/tables.py +27 -24
  69. exonware/xwsystem/console/contracts.py +113 -0
  70. exonware/xwsystem/console/defs.py +154 -0
  71. exonware/xwsystem/console/errors.py +34 -0
  72. exonware/xwsystem/console/event_logger.py +385 -0
  73. exonware/xwsystem/console/writer.py +132 -0
  74. exonware/xwsystem/contracts.py +28 -0
  75. exonware/xwsystem/data_structures/__init__.py +23 -0
  76. exonware/xwsystem/data_structures/trie.py +34 -0
  77. exonware/xwsystem/data_structures/union_find.py +144 -0
  78. exonware/xwsystem/defs.py +17 -0
  79. exonware/xwsystem/errors.py +23 -0
  80. exonware/xwsystem/facade.py +62 -0
  81. exonware/xwsystem/http_client/__init__.py +22 -1
  82. exonware/xwsystem/http_client/advanced_client.py +8 -5
  83. exonware/xwsystem/http_client/base.py +3 -2
  84. exonware/xwsystem/http_client/client.py +7 -4
  85. exonware/xwsystem/http_client/contracts.py +42 -56
  86. exonware/xwsystem/http_client/defs.py +2 -1
  87. exonware/xwsystem/http_client/errors.py +2 -1
  88. exonware/xwsystem/http_client/facade.py +156 -0
  89. exonware/xwsystem/io/__init__.py +22 -3
  90. exonware/xwsystem/io/archive/__init__.py +8 -2
  91. exonware/xwsystem/io/archive/archive.py +1 -1
  92. exonware/xwsystem/io/archive/archive_files.py +4 -7
  93. exonware/xwsystem/io/archive/archivers.py +120 -10
  94. exonware/xwsystem/io/archive/base.py +4 -5
  95. exonware/xwsystem/io/archive/codec_integration.py +1 -2
  96. exonware/xwsystem/io/archive/compression.py +1 -2
  97. exonware/xwsystem/io/archive/facade.py +263 -0
  98. exonware/xwsystem/io/archive/formats/__init__.py +2 -3
  99. exonware/xwsystem/io/archive/formats/brotli_format.py +20 -7
  100. exonware/xwsystem/io/archive/formats/lz4_format.py +20 -7
  101. exonware/xwsystem/io/archive/formats/rar.py +11 -5
  102. exonware/xwsystem/io/archive/formats/sevenzip.py +12 -6
  103. exonware/xwsystem/io/archive/formats/squashfs_format.py +1 -2
  104. exonware/xwsystem/io/archive/formats/tar.py +52 -7
  105. exonware/xwsystem/io/archive/formats/wim_format.py +11 -5
  106. exonware/xwsystem/io/archive/formats/zip.py +1 -2
  107. exonware/xwsystem/io/archive/formats/zpaq_format.py +1 -2
  108. exonware/xwsystem/io/archive/formats/zstandard.py +20 -7
  109. exonware/xwsystem/io/base.py +119 -115
  110. exonware/xwsystem/io/codec/__init__.py +4 -2
  111. exonware/xwsystem/io/codec/base.py +19 -13
  112. exonware/xwsystem/io/codec/contracts.py +59 -2
  113. exonware/xwsystem/io/codec/registry.py +67 -21
  114. exonware/xwsystem/io/common/__init__.py +1 -1
  115. exonware/xwsystem/io/common/atomic.py +29 -16
  116. exonware/xwsystem/io/common/base.py +11 -10
  117. exonware/xwsystem/io/common/lock.py +6 -5
  118. exonware/xwsystem/io/common/path_manager.py +2 -1
  119. exonware/xwsystem/io/common/watcher.py +1 -2
  120. exonware/xwsystem/io/contracts.py +301 -433
  121. exonware/xwsystem/io/contracts_1.py +1180 -0
  122. exonware/xwsystem/io/data_operations.py +19 -20
  123. exonware/xwsystem/io/defs.py +4 -3
  124. exonware/xwsystem/io/errors.py +3 -2
  125. exonware/xwsystem/io/facade.py +87 -61
  126. exonware/xwsystem/io/file/__init__.py +1 -1
  127. exonware/xwsystem/io/file/base.py +8 -9
  128. exonware/xwsystem/io/file/conversion.py +2 -3
  129. exonware/xwsystem/io/file/file.py +61 -18
  130. exonware/xwsystem/io/file/paged_source.py +8 -8
  131. exonware/xwsystem/io/file/paging/__init__.py +1 -2
  132. exonware/xwsystem/io/file/paging/byte_paging.py +4 -5
  133. exonware/xwsystem/io/file/paging/line_paging.py +2 -3
  134. exonware/xwsystem/io/file/paging/record_paging.py +2 -3
  135. exonware/xwsystem/io/file/paging/registry.py +1 -2
  136. exonware/xwsystem/io/file/source.py +13 -17
  137. exonware/xwsystem/io/filesystem/__init__.py +1 -1
  138. exonware/xwsystem/io/filesystem/base.py +1 -2
  139. exonware/xwsystem/io/filesystem/local.py +3 -4
  140. exonware/xwsystem/io/folder/__init__.py +1 -1
  141. exonware/xwsystem/io/folder/base.py +1 -2
  142. exonware/xwsystem/io/folder/folder.py +16 -7
  143. exonware/xwsystem/io/indexing/__init__.py +14 -0
  144. exonware/xwsystem/io/indexing/facade.py +443 -0
  145. exonware/xwsystem/io/path_parser.py +98 -0
  146. exonware/xwsystem/io/serialization/__init__.py +21 -3
  147. exonware/xwsystem/io/serialization/auto_serializer.py +146 -20
  148. exonware/xwsystem/io/serialization/base.py +84 -34
  149. exonware/xwsystem/io/serialization/contracts.py +50 -73
  150. exonware/xwsystem/io/serialization/defs.py +2 -1
  151. exonware/xwsystem/io/serialization/errors.py +2 -1
  152. exonware/xwsystem/io/serialization/flyweight.py +154 -7
  153. exonware/xwsystem/io/serialization/format_detector.py +15 -14
  154. exonware/xwsystem/io/serialization/formats/__init__.py +8 -5
  155. exonware/xwsystem/io/serialization/formats/binary/bson.py +15 -6
  156. exonware/xwsystem/io/serialization/formats/binary/cbor.py +5 -5
  157. exonware/xwsystem/io/serialization/formats/binary/marshal.py +5 -5
  158. exonware/xwsystem/io/serialization/formats/binary/msgpack.py +5 -5
  159. exonware/xwsystem/io/serialization/formats/binary/pickle.py +5 -5
  160. exonware/xwsystem/io/serialization/formats/binary/plistlib.py +5 -5
  161. exonware/xwsystem/io/serialization/formats/database/dbm.py +7 -7
  162. exonware/xwsystem/io/serialization/formats/database/shelve.py +7 -7
  163. exonware/xwsystem/io/serialization/formats/database/sqlite3.py +7 -7
  164. exonware/xwsystem/io/serialization/formats/tabular/__init__.py +27 -0
  165. exonware/xwsystem/io/serialization/formats/tabular/base.py +89 -0
  166. exonware/xwsystem/io/serialization/formats/tabular/csv.py +319 -0
  167. exonware/xwsystem/io/serialization/formats/tabular/df.py +249 -0
  168. exonware/xwsystem/io/serialization/formats/tabular/excel.py +291 -0
  169. exonware/xwsystem/io/serialization/formats/tabular/googlesheets.py +374 -0
  170. exonware/xwsystem/io/serialization/formats/text/__init__.py +1 -1
  171. exonware/xwsystem/io/serialization/formats/text/append_only_log.py +5 -7
  172. exonware/xwsystem/io/serialization/formats/text/configparser.py +5 -5
  173. exonware/xwsystem/io/serialization/formats/text/csv.py +7 -5
  174. exonware/xwsystem/io/serialization/formats/text/formdata.py +5 -5
  175. exonware/xwsystem/io/serialization/formats/text/json.py +27 -18
  176. exonware/xwsystem/io/serialization/formats/text/json5.py +8 -4
  177. exonware/xwsystem/io/serialization/formats/text/jsonlines.py +18 -14
  178. exonware/xwsystem/io/serialization/formats/text/multipart.py +5 -5
  179. exonware/xwsystem/io/serialization/formats/text/toml.py +8 -6
  180. exonware/xwsystem/io/serialization/formats/text/xml.py +25 -20
  181. exonware/xwsystem/io/serialization/formats/text/yaml.py +8 -6
  182. exonware/xwsystem/io/serialization/parsers/__init__.py +3 -2
  183. exonware/xwsystem/io/serialization/parsers/base.py +6 -5
  184. exonware/xwsystem/io/serialization/parsers/hybrid_parser.py +7 -6
  185. exonware/xwsystem/io/serialization/parsers/msgspec_parser.py +10 -7
  186. exonware/xwsystem/io/serialization/parsers/orjson_direct_parser.py +7 -6
  187. exonware/xwsystem/io/serialization/parsers/orjson_parser.py +11 -8
  188. exonware/xwsystem/io/serialization/parsers/pysimdjson_parser.py +13 -9
  189. exonware/xwsystem/io/serialization/parsers/rapidjson_parser.py +10 -7
  190. exonware/xwsystem/io/serialization/parsers/registry.py +11 -10
  191. exonware/xwsystem/io/serialization/parsers/standard.py +7 -6
  192. exonware/xwsystem/io/serialization/parsers/ujson_parser.py +10 -7
  193. exonware/xwsystem/io/serialization/registry.py +4 -4
  194. exonware/xwsystem/io/serialization/serializer.py +168 -79
  195. exonware/xwsystem/io/serialization/universal_options.py +367 -0
  196. exonware/xwsystem/io/serialization/utils/__init__.py +1 -2
  197. exonware/xwsystem/io/serialization/utils/path_ops.py +5 -6
  198. exonware/xwsystem/io/source_reader.py +223 -0
  199. exonware/xwsystem/io/stream/__init__.py +1 -1
  200. exonware/xwsystem/io/stream/async_operations.py +61 -14
  201. exonware/xwsystem/io/stream/base.py +1 -2
  202. exonware/xwsystem/io/stream/codec_io.py +6 -7
  203. exonware/xwsystem/ipc/__init__.py +1 -0
  204. exonware/xwsystem/ipc/async_fabric.py +4 -4
  205. exonware/xwsystem/ipc/base.py +6 -5
  206. exonware/xwsystem/ipc/contracts.py +41 -66
  207. exonware/xwsystem/ipc/defs.py +2 -1
  208. exonware/xwsystem/ipc/errors.py +2 -1
  209. exonware/xwsystem/ipc/message_queue.py +5 -2
  210. exonware/xwsystem/ipc/pipes.py +70 -34
  211. exonware/xwsystem/ipc/process_manager.py +7 -5
  212. exonware/xwsystem/ipc/process_pool.py +6 -5
  213. exonware/xwsystem/ipc/shared_memory.py +64 -11
  214. exonware/xwsystem/monitoring/__init__.py +7 -0
  215. exonware/xwsystem/monitoring/base.py +11 -8
  216. exonware/xwsystem/monitoring/contracts.py +86 -144
  217. exonware/xwsystem/monitoring/defs.py +2 -1
  218. exonware/xwsystem/monitoring/error_recovery.py +16 -3
  219. exonware/xwsystem/monitoring/errors.py +2 -1
  220. exonware/xwsystem/monitoring/facade.py +183 -0
  221. exonware/xwsystem/monitoring/memory_monitor.py +1 -0
  222. exonware/xwsystem/monitoring/metrics.py +1 -0
  223. exonware/xwsystem/monitoring/performance_manager_generic.py +7 -7
  224. exonware/xwsystem/monitoring/performance_monitor.py +1 -0
  225. exonware/xwsystem/monitoring/performance_validator.py +1 -0
  226. exonware/xwsystem/monitoring/system_monitor.py +6 -5
  227. exonware/xwsystem/monitoring/tracing.py +18 -16
  228. exonware/xwsystem/monitoring/tracker.py +2 -1
  229. exonware/xwsystem/operations/__init__.py +5 -50
  230. exonware/xwsystem/operations/base.py +3 -44
  231. exonware/xwsystem/operations/contracts.py +25 -15
  232. exonware/xwsystem/operations/defs.py +1 -1
  233. exonware/xwsystem/operations/diff.py +5 -4
  234. exonware/xwsystem/operations/errors.py +1 -1
  235. exonware/xwsystem/operations/merge.py +6 -4
  236. exonware/xwsystem/operations/patch.py +5 -4
  237. exonware/xwsystem/patterns/__init__.py +1 -0
  238. exonware/xwsystem/patterns/base.py +2 -1
  239. exonware/xwsystem/patterns/context_manager.py +2 -1
  240. exonware/xwsystem/patterns/contracts.py +215 -256
  241. exonware/xwsystem/patterns/defs.py +2 -1
  242. exonware/xwsystem/patterns/dynamic_facade.py +1 -0
  243. exonware/xwsystem/patterns/errors.py +2 -4
  244. exonware/xwsystem/patterns/handler_factory.py +2 -3
  245. exonware/xwsystem/patterns/import_registry.py +1 -0
  246. exonware/xwsystem/patterns/object_pool.py +1 -0
  247. exonware/xwsystem/patterns/registry.py +4 -43
  248. exonware/xwsystem/plugins/__init__.py +2 -1
  249. exonware/xwsystem/plugins/base.py +6 -5
  250. exonware/xwsystem/plugins/contracts.py +94 -158
  251. exonware/xwsystem/plugins/defs.py +2 -1
  252. exonware/xwsystem/plugins/errors.py +2 -1
  253. exonware/xwsystem/py.typed +3 -0
  254. exonware/xwsystem/query/__init__.py +36 -0
  255. exonware/xwsystem/query/contracts.py +56 -0
  256. exonware/xwsystem/query/errors.py +22 -0
  257. exonware/xwsystem/query/registry.py +128 -0
  258. exonware/xwsystem/runtime/__init__.py +2 -1
  259. exonware/xwsystem/runtime/base.py +4 -3
  260. exonware/xwsystem/runtime/contracts.py +39 -60
  261. exonware/xwsystem/runtime/defs.py +2 -1
  262. exonware/xwsystem/runtime/env.py +11 -9
  263. exonware/xwsystem/runtime/errors.py +2 -1
  264. exonware/xwsystem/runtime/reflection.py +3 -2
  265. exonware/xwsystem/security/__init__.py +68 -11
  266. exonware/xwsystem/security/audit.py +167 -0
  267. exonware/xwsystem/security/base.py +121 -24
  268. exonware/xwsystem/security/contracts.py +91 -146
  269. exonware/xwsystem/security/crypto.py +17 -16
  270. exonware/xwsystem/security/defs.py +2 -1
  271. exonware/xwsystem/security/errors.py +2 -1
  272. exonware/xwsystem/security/facade.py +321 -0
  273. exonware/xwsystem/security/file_security.py +330 -0
  274. exonware/xwsystem/security/hazmat.py +11 -8
  275. exonware/xwsystem/security/monitor.py +372 -0
  276. exonware/xwsystem/security/path_validator.py +140 -18
  277. exonware/xwsystem/security/policy.py +357 -0
  278. exonware/xwsystem/security/resource_limits.py +1 -0
  279. exonware/xwsystem/security/validator.py +455 -0
  280. exonware/xwsystem/shared/__init__.py +14 -1
  281. exonware/xwsystem/shared/base.py +285 -2
  282. exonware/xwsystem/shared/contracts.py +415 -126
  283. exonware/xwsystem/shared/defs.py +2 -1
  284. exonware/xwsystem/shared/errors.py +2 -2
  285. exonware/xwsystem/shared/xwobject.py +316 -0
  286. exonware/xwsystem/structures/__init__.py +1 -0
  287. exonware/xwsystem/structures/base.py +3 -2
  288. exonware/xwsystem/structures/circular_detector.py +15 -14
  289. exonware/xwsystem/structures/contracts.py +53 -76
  290. exonware/xwsystem/structures/defs.py +2 -1
  291. exonware/xwsystem/structures/errors.py +2 -1
  292. exonware/xwsystem/structures/tree_walker.py +2 -1
  293. exonware/xwsystem/threading/__init__.py +21 -4
  294. exonware/xwsystem/threading/async_primitives.py +6 -5
  295. exonware/xwsystem/threading/base.py +3 -2
  296. exonware/xwsystem/threading/contracts.py +87 -143
  297. exonware/xwsystem/threading/defs.py +2 -1
  298. exonware/xwsystem/threading/errors.py +2 -1
  299. exonware/xwsystem/threading/facade.py +175 -0
  300. exonware/xwsystem/threading/locks.py +1 -0
  301. exonware/xwsystem/threading/safe_factory.py +1 -0
  302. exonware/xwsystem/utils/__init__.py +40 -0
  303. exonware/xwsystem/utils/base.py +22 -21
  304. exonware/xwsystem/utils/contracts.py +50 -73
  305. exonware/xwsystem/utils/dt/__init__.py +19 -3
  306. exonware/xwsystem/utils/dt/base.py +5 -4
  307. exonware/xwsystem/utils/dt/contracts.py +22 -29
  308. exonware/xwsystem/utils/dt/defs.py +2 -1
  309. exonware/xwsystem/utils/dt/errors.py +2 -5
  310. exonware/xwsystem/utils/dt/formatting.py +88 -2
  311. exonware/xwsystem/utils/dt/humanize.py +10 -9
  312. exonware/xwsystem/utils/dt/parsing.py +56 -5
  313. exonware/xwsystem/utils/dt/timezone_utils.py +2 -24
  314. exonware/xwsystem/utils/errors.py +2 -4
  315. exonware/xwsystem/utils/paths.py +1 -0
  316. exonware/xwsystem/utils/string.py +49 -0
  317. exonware/xwsystem/utils/test_runner.py +185 -0
  318. exonware/xwsystem/utils/utils_contracts.py +2 -1
  319. exonware/xwsystem/utils/web.py +110 -0
  320. exonware/xwsystem/validation/__init__.py +25 -1
  321. exonware/xwsystem/validation/base.py +6 -5
  322. exonware/xwsystem/validation/contracts.py +29 -41
  323. exonware/xwsystem/validation/data_validator.py +1 -0
  324. exonware/xwsystem/validation/declarative.py +11 -8
  325. exonware/xwsystem/validation/defs.py +2 -1
  326. exonware/xwsystem/validation/errors.py +2 -1
  327. exonware/xwsystem/validation/facade.py +198 -0
  328. exonware/xwsystem/validation/fluent_validator.py +22 -19
  329. exonware/xwsystem/validation/schema_discovery.py +210 -0
  330. exonware/xwsystem/validation/type_safety.py +2 -1
  331. exonware/xwsystem/version.py +2 -2
  332. {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.3.dist-info}/METADATA +71 -4
  333. exonware_xwsystem-0.1.0.3.dist-info/RECORD +337 -0
  334. exonware/xwsystem/cli/__init__.py +0 -43
  335. exonware/xwsystem/cli/console.py +0 -113
  336. exonware/xwsystem/cli/defs.py +0 -134
  337. exonware/xwsystem/conf.py +0 -44
  338. exonware/xwsystem/security/auth.py +0 -484
  339. exonware_xwsystem-0.1.0.1.dist-info/RECORD +0 -284
  340. {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.3.dist-info}/WHEEL +0 -0
  341. {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,10 +1,11 @@
1
1
  #!/usr/bin/env python3
2
+ #exonware/xwsystem/src/exonware/xwsystem/io/codec/__init__.py
2
3
  # exonware/xwsystem/io/codec/__init__.py
3
4
  """
4
5
  Company: eXonware.com
5
6
  Author: Eng. Muhammad AlShehri
6
7
  Email: connect@exonware.com
7
- Version: 0.1.0.1
8
+ Version: 0.1.0.3
8
9
  Generation Date: October 30, 2025
9
10
 
10
11
  Universal Codec Abstraction for eXonware.
@@ -71,6 +72,7 @@ from ..contracts import (
71
72
  DecodeOptions,
72
73
  ICodecMetadata,
73
74
  )
75
+ from .contracts import IFormatConfig
74
76
  from .base import (
75
77
  ACodec,
76
78
  MediaKey,
@@ -167,6 +169,7 @@ __all__ = [
167
169
  'EncodeOptions',
168
170
  'DecodeOptions',
169
171
  'ICodecMetadata',
172
+ 'IFormatConfig',
170
173
 
171
174
  # Capabilities
172
175
  'CodecCapability',
@@ -193,4 +196,3 @@ __all__ = [
193
196
  'DecodeError',
194
197
  'CodecNotFoundError',
195
198
  ]
196
-
@@ -1,17 +1,18 @@
1
1
  #!/usr/bin/env python3
2
+ #exonware/xwsystem/src/exonware/xwsystem/io/codec/base.py
2
3
  # exonware/xwsystem/io/codec/base.py
3
4
  """
4
5
  Company: eXonware.com
5
6
  Author: Eng. Muhammad AlShehri
6
7
  Email: connect@exonware.com
7
- Version: 0.1.0.1
8
+ Version: 0.1.0.3
8
9
  Generation Date: October 30, 2025
9
10
 
10
11
  Base classes, registry, adapters, and helper functions for codec system.
11
12
  """
12
13
 
13
14
  from __future__ import annotations
14
- from typing import Optional, Any, IO, Union
15
+ from typing import Optional, Any, IO
15
16
  # Root cause: Migrating to Python 3.12 built-in generic syntax for consistency
16
17
  # Priority #3: Maintainability - Modern type annotations improve code clarity
17
18
  from pathlib import Path
@@ -415,7 +416,9 @@ class ACodec[T, R](ICodec[T, R], ICodecMetadata, ABC):
415
416
  self._get_data_depth(v, cache, visited, current_depth + 1) - current_depth - 1
416
417
  for v in data.values()
417
418
  ]
418
- max_relative_depth = max(child_depths) if child_depths else 1
419
+ # Get max relative depth from children (how deep from this dict)
420
+ # Add 1 for the dict itself
421
+ max_relative_depth = max(child_depths) + 1 if child_depths else 1
419
422
  else:
420
423
  max_relative_depth = 1 # Empty dict still counts as one level
421
424
 
@@ -425,7 +428,9 @@ class ACodec[T, R](ICodec[T, R], ICodecMetadata, ABC):
425
428
  self._get_data_depth(item, cache, visited, current_depth + 1) - current_depth - 1
426
429
  for item in data
427
430
  ]
428
- max_relative_depth = max(child_depths) if child_depths else 1
431
+ # Get max relative depth from children (how deep from this list)
432
+ # Add 1 for the list itself
433
+ max_relative_depth = max(child_depths) + 1 if child_depths else 1
429
434
  else:
430
435
  max_relative_depth = 1 # Empty list still counts as one level
431
436
 
@@ -435,7 +440,9 @@ class ACodec[T, R](ICodec[T, R], ICodecMetadata, ABC):
435
440
  self._get_data_depth(v, cache, visited, current_depth + 1) - current_depth - 1
436
441
  for v in vars(data).values()
437
442
  ]
438
- max_relative_depth = max(child_depths) if child_depths else 0
443
+ # Get max relative depth from children (how deep from this object)
444
+ # Add 1 for the object itself
445
+ max_relative_depth = max(child_depths) + 1 if child_depths else 1
439
446
 
440
447
  # Cache the result (maximum relative depth from this object)
441
448
  cache[obj_id] = max_relative_depth
@@ -507,7 +514,7 @@ class ACodec[T, R](ICodec[T, R], ICodecMetadata, ABC):
507
514
  self,
508
515
  data: Any,
509
516
  operation: str = "encode",
510
- file_path: Optional[Union[str, Path]] = None,
517
+ file_path: Optional[str | Path] = None,
511
518
  skip_size_check: bool = False
512
519
  ) -> None:
513
520
  """
@@ -536,7 +543,7 @@ class ACodec[T, R](ICodec[T, R], ICodecMetadata, ABC):
536
543
  self._depth_cache.clear()
537
544
  self._size_cache.clear()
538
545
 
539
- # ALWAYS check depth - this prevents infinite recursion which is the real security issue
546
+ # Check depth - prevents infinite recursion which is the security issue
540
547
  depth = self._get_data_depth(data)
541
548
  if depth > self._max_depth:
542
549
  raise SerializationError(
@@ -558,7 +565,7 @@ class ACodec[T, R](ICodec[T, R], ICodecMetadata, ABC):
558
565
  if path_obj.exists():
559
566
  file_size_mb = path_obj.stat().st_size / (1024 * 1024)
560
567
  # If file is > 1GB, assume it's meant to be large and skip size validation
561
- # Large files should use lazy loading/streaming features
568
+ # Large files use lazy loading/streaming features
562
569
  if file_size_mb > 1024: # 1GB threshold
563
570
  return # Skip size check for large files
564
571
  except (OSError, ValueError):
@@ -576,7 +583,7 @@ class ACodec[T, R](ICodec[T, R], ICodecMetadata, ABC):
576
583
  )
577
584
 
578
585
  # ========================================================================
579
- # CORE METHODS (Must implement in subclasses)
586
+ # CORE METHODS (Implement in subclasses)
580
587
  # ========================================================================
581
588
 
582
589
  @abstractmethod
@@ -590,7 +597,7 @@ class ACodec[T, R](ICodec[T, R], ICodecMetadata, ABC):
590
597
  pass
591
598
 
592
599
  # ========================================================================
593
- # METADATA PROPERTIES (Must implement in subclasses)
600
+ # METADATA PROPERTIES (Implement in subclasses)
594
601
  # ========================================================================
595
602
 
596
603
  @property
@@ -689,8 +696,8 @@ class ACodec[T, R](ICodec[T, R], ICodecMetadata, ABC):
689
696
  if isinstance(self._get_repr_type_hint(), str):
690
697
  # Text codec, decode bytes to str
691
698
  repr = repr.decode('utf-8')
692
- except:
693
- # Fall back to text
699
+ except (OSError, UnicodeDecodeError, FileNotFoundError, PermissionError):
700
+ # Fall back to text - catch specific exceptions only
694
701
  repr = path.read_text(encoding='utf-8')
695
702
 
696
703
  return self.decode(repr, options=opts or None)
@@ -879,4 +886,3 @@ class SerializerToFormatter[T]:
879
886
  """Decode from string via bytes."""
880
887
  data = repr.encode(self._encoding, errors=self._errors)
881
888
  return self._serializer.decode(data, options=options)
882
-
@@ -1,14 +1,15 @@
1
+ #exonware/xwsystem/src/exonware/xwsystem/io/codec/contracts.py
1
2
  """
2
3
  Company: eXonware.com
3
4
  Author: Eng. Muhammad AlShehri
4
5
  Email: connect@exonware.com
5
- Version: 0.1.0.1
6
+ Version: 0.1.0.3
6
7
  Generation Date: September 04, 2025
7
8
 
8
9
  Codec module contracts - interfaces for codec operations.
9
10
  """
10
11
 
11
- from typing import Protocol, Optional, runtime_checkable
12
+ from typing import Protocol, Optional, runtime_checkable, Any
12
13
  from pathlib import Path
13
14
 
14
15
  from ..contracts import EncodeOptions, DecodeOptions, CodecCapability
@@ -211,3 +212,59 @@ class ICodecMetadata(Protocol):
211
212
  """
212
213
  ...
213
214
 
215
+
216
+ @runtime_checkable
217
+ class IFormatConfig(Protocol):
218
+ """
219
+ Interface for format configuration.
220
+
221
+ This interface represents configuration for codec/format selection
222
+ and is used across xwsystem for format-aware operations. It provides
223
+ a standardized way to specify and validate codec/format configurations
224
+ with integration to the codec registry.
225
+
226
+ Originally defined in xwstorage, moved to xwsystem.io.codec as it
227
+ is a general-purpose codec configuration abstraction.
228
+ """
229
+
230
+ @property
231
+ def format_type(self) -> str:
232
+ """
233
+ Get the format type identifier (codec_id).
234
+
235
+ Returns:
236
+ Format type identifier (e.g., "json", "yaml", "xml")
237
+ """
238
+ ...
239
+
240
+ @property
241
+ def codec_id(self) -> str:
242
+ """
243
+ Get the codec identifier from xwsystem codec registry.
244
+
245
+ This should match a codec_id in the UniversalCodecRegistry.
246
+
247
+ Returns:
248
+ Codec identifier (typically same as format_type)
249
+ """
250
+ ...
251
+
252
+ def to_dict(self) -> dict[str, Any]:
253
+ """
254
+ Convert configuration to dictionary.
255
+
256
+ Returns:
257
+ Dictionary representation of the format configuration
258
+ """
259
+ ...
260
+
261
+ def validate(self) -> bool:
262
+ """
263
+ Validate format configuration.
264
+
265
+ Checks if the codec_id is available in the xwsystem codec registry.
266
+
267
+ Returns:
268
+ True if format is valid and available in codec registry
269
+ """
270
+ ...
@@ -1,14 +1,15 @@
1
+ #exonware/xwsystem/src/exonware/xwsystem/io/codec/registry.py
1
2
  """
2
3
  Company: eXonware.com
3
4
  Author: Eng. Muhammad AlShehri
4
5
  Email: connect@exonware.com
5
- Version: 0.1.0.1
6
+ Version: 0.1.0.3
6
7
  Generation Date: November 04, 2025
7
8
 
8
9
  Universal Codec Registry - High-performance registry for all codec types.
9
10
  """
10
11
 
11
- from typing import Optional, Union, Any, Callable
12
+ from typing import Optional, Any, Callable
12
13
  from pathlib import Path
13
14
  from threading import RLock
14
15
  from functools import lru_cache
@@ -103,7 +104,7 @@ class UniversalCodecRegistry:
103
104
 
104
105
  def __init__(self):
105
106
  """Initialize the universal codec registry."""
106
- # Core mappings (codec_id is always lowercase)
107
+ # Core mappings (codec_id is lowercase)
107
108
  self._by_id: dict[str, type[ICodec]] = {}
108
109
  self._by_extension: dict[str, list[tuple[str, int]]] = {} # ext -> [(codec_id, priority)]
109
110
  self._by_mime_type: dict[str, list[tuple[str, int]]] = {} # mime -> [(codec_id, priority)]
@@ -324,7 +325,11 @@ class UniversalCodecRegistry:
324
325
 
325
326
  def get_by_id(self, codec_id: str) -> Optional[ICodec]:
326
327
  """
327
- Get codec by ID (unique lookup).
328
+ Get codec by ID with O(1) caching (unique lookup).
329
+
330
+ OPTIMIZED: Lockless fast path for cached instances.
331
+ First call: validates and instantiates (10-100μs)
332
+ Subsequent calls: cache lookup (< 1μs) ✅
328
333
 
329
334
  Args:
330
335
  codec_id: Codec identifier
@@ -332,10 +337,15 @@ class UniversalCodecRegistry:
332
337
  Returns:
333
338
  Codec instance or None
334
339
  """
340
+ codec_id_lower = codec_id.lower()
341
+
342
+ # FAST PATH: Lockless cache check (O(1))
343
+ if codec_id_lower in self._instances:
344
+ return self._instances[codec_id_lower] # O(1) cache hit! ✅
345
+
346
+ # SLOW PATH: Need to instantiate (acquire lock)
335
347
  with self._lock:
336
- codec_id_lower = codec_id.lower()
337
-
338
- # Check instance cache first
348
+ # Double-check cache after acquiring lock
339
349
  if codec_id_lower in self._instances:
340
350
  return self._instances[codec_id_lower]
341
351
 
@@ -344,13 +354,19 @@ class UniversalCodecRegistry:
344
354
  if not codec_class:
345
355
  return None
346
356
 
347
- instance = codec_class()
348
- self._instances[codec_id_lower] = instance
349
- return instance
357
+ try:
358
+ instance = codec_class()
359
+ self._instances[codec_id_lower] = instance
360
+ return instance
361
+ except Exception:
362
+ # Failed to instantiate - don't cache the failure
363
+ return None
350
364
 
351
365
  def get_by_extension(self, ext: str) -> Optional[ICodec]:
352
366
  """
353
- Get codec by extension (highest priority match).
367
+ Get codec by extension with O(1) caching (highest priority match).
368
+
369
+ OPTIMIZED: Reduced lock contention by doing normalization outside lock.
354
370
 
355
371
  Args:
356
372
  ext: File extension (with or without dot)
@@ -358,18 +374,22 @@ class UniversalCodecRegistry:
358
374
  Returns:
359
375
  Highest priority codec instance or None
360
376
  """
377
+ # Normalize outside lock (no shared state access)
378
+ normalized_ext = ext.lower()
379
+ if not normalized_ext.startswith('.'):
380
+ normalized_ext = f'.{normalized_ext}'
381
+
382
+ # Quick lookup with lock
361
383
  with self._lock:
362
- normalized_ext = ext.lower()
363
- if not normalized_ext.startswith('.'):
364
- normalized_ext = f'.{normalized_ext}'
365
-
366
384
  codec_list = self._by_extension.get(normalized_ext, [])
367
385
  if not codec_list:
368
386
  return None
369
387
 
370
388
  # Return highest priority (first in sorted list)
371
389
  codec_id = codec_list[0][0]
372
- return self.get_by_id(codec_id)
390
+
391
+ # Get instance outside lock (uses lockless cache)
392
+ return self.get_by_id(codec_id)
373
393
 
374
394
  def get_by_mime_type(self, mime: str) -> Optional[ICodec]:
375
395
  """
@@ -407,7 +427,7 @@ class UniversalCodecRegistry:
407
427
  return self.get_by_id(codec_id)
408
428
 
409
429
  @lru_cache(maxsize=256)
410
- def detect(self, path: Union[str, Path], codec_type: Optional[str] = None) -> Optional[ICodec]:
430
+ def detect(self, path: str | Path, codec_type: Optional[str] = None) -> Optional[ICodec]:
411
431
  """
412
432
  Auto-detect codec from file path (best match with optional type filter).
413
433
 
@@ -429,7 +449,7 @@ class UniversalCodecRegistry:
429
449
  with self._lock:
430
450
  return self._detect_internal(path, codec_type)
431
451
 
432
- def _detect_internal(self, path: Union[str, Path], codec_type: Optional[str] = None) -> Optional[ICodec]:
452
+ def _detect_internal(self, path: str | Path, codec_type: Optional[str] = None) -> Optional[ICodec]:
433
453
  """Internal detection implementation (not cached)."""
434
454
  path_obj = Path(path)
435
455
 
@@ -574,7 +594,7 @@ class UniversalCodecRegistry:
574
594
  results.append(codec)
575
595
  return results
576
596
 
577
- def detect_all(self, path: Union[str, Path], codec_type: Optional[str] = None) -> list[ICodec]:
597
+ def detect_all(self, path: str | Path, codec_type: Optional[str] = None) -> list[ICodec]:
578
598
  """
579
599
  Detect all possible codecs for a file path.
580
600
 
@@ -732,10 +752,10 @@ class UniversalCodecRegistry:
732
752
 
733
753
  def get_statistics(self) -> dict[str, int]:
734
754
  """
735
- Get registry statistics.
755
+ Get registry statistics including cache performance.
736
756
 
737
757
  Returns:
738
- Dictionary with counts of registered items
758
+ Dictionary with counts of registered items and cache stats
739
759
  """
740
760
  with self._lock:
741
761
  return {
@@ -746,6 +766,32 @@ class UniversalCodecRegistry:
746
766
  'types': len(self._by_type),
747
767
  'magic_bytes': len(self._magic_bytes),
748
768
  'cached_instances': len(self._instances),
769
+ 'cache_hit_rate': len(self._instances) / max(1, len(self._by_id)), # % of codecs cached
770
+ 'detect_cache_info': self.detect.cache_info()._asdict(), # LRU cache stats
771
+ }
772
+
773
+ def get_cache_stats(self) -> dict:
774
+ """
775
+ Get detailed cache statistics for performance monitoring.
776
+
777
+ Returns:
778
+ Dictionary with cache performance metrics
779
+ """
780
+ with self._lock:
781
+ detect_info = self.detect.cache_info()
782
+ return {
783
+ 'instance_cache': {
784
+ 'size': len(self._instances),
785
+ 'max_codecs': len(self._by_id),
786
+ 'hit_rate': len(self._instances) / max(1, len(self._by_id)),
787
+ },
788
+ 'detect_cache': {
789
+ 'hits': detect_info.hits,
790
+ 'misses': detect_info.misses,
791
+ 'size': detect_info.currsize,
792
+ 'max_size': detect_info.maxsize,
793
+ 'hit_rate': detect_info.hits / max(1, detect_info.hits + detect_info.misses),
794
+ }
749
795
  }
750
796
 
751
797
 
@@ -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.1
7
+ Version: 0.1.0.3
8
8
  Generation Date: 30-Oct-2025
9
9
 
10
10
  Common utilities shared across IO operations.
@@ -1,15 +1,17 @@
1
+ #exonware/xwsystem/src/exonware/xwsystem/io/common/atomic.py
1
2
  """
2
3
  Atomic file operations to prevent data corruption during writes.
3
4
  """
4
5
 
5
6
  import logging
6
7
  import os
8
+ import platform
7
9
  import shutil
8
10
  import tempfile
9
11
  import time
10
12
  from contextlib import contextmanager
11
13
  from pathlib import Path
12
- from typing import Any, BinaryIO, Optional, TextIO, Union
14
+ from typing import Any, BinaryIO, Optional, TextIO
13
15
 
14
16
  logger = logging.getLogger(__name__)
15
17
 
@@ -31,11 +33,11 @@ class AtomicFileWriter:
31
33
 
32
34
  def __init__(
33
35
  self,
34
- target_path: Union[str, Path],
36
+ target_path: str | Path,
35
37
  mode: str = "w",
36
38
  encoding: Optional[str] = "utf-8",
37
39
  backup: bool = False,
38
- temp_dir: Optional[Union[str, Path]] = None,
40
+ temp_dir: Optional[str | Path] = None,
39
41
  ):
40
42
  """
41
43
  Initialize atomic file writer.
@@ -55,11 +57,11 @@ class AtomicFileWriter:
55
57
 
56
58
  self.temp_path: Optional[Path] = None
57
59
  self.backup_path: Optional[Path] = None
58
- self.file_handle: Optional[Union[BinaryIO, TextIO]] = None
60
+ self.file_handle: Optional[BinaryIO | TextIO] = None
59
61
  self._committed = False
60
62
  self._started = False
61
63
 
62
- def __enter__(self) -> Union[BinaryIO, TextIO]:
64
+ def __enter__(self) -> BinaryIO | TextIO:
63
65
  """Context manager entry - create temporary file."""
64
66
  return self.start()
65
67
 
@@ -73,7 +75,7 @@ class AtomicFileWriter:
73
75
  self.rollback()
74
76
  return False # Don't suppress exceptions
75
77
 
76
- def start(self) -> Union[BinaryIO, TextIO]:
78
+ def start(self) -> BinaryIO | TextIO:
77
79
  """
78
80
  Start the atomic write operation.
79
81
 
@@ -150,8 +152,8 @@ class AtomicFileWriter:
150
152
  logger.warning(f"Temporary file is empty: {self.temp_path}")
151
153
 
152
154
  # Atomic move to target location
153
- # On Windows, need to remove target first if it exists
154
- if os.name == "nt" and self.target_path.exists():
155
+ # On Windows, need to remove target first if it exists (Windows filesystem limitation)
156
+ if platform.system() == 'Windows' and self.target_path.exists():
155
157
  self.target_path.unlink()
156
158
 
157
159
  # Perform the atomic move
@@ -250,11 +252,11 @@ class AtomicFileWriter:
250
252
 
251
253
  @contextmanager
252
254
  def atomic_write(
253
- target_path: Union[str, Path],
255
+ target_path: str | Path,
254
256
  mode: str = "w",
255
257
  encoding: Optional[str] = "utf-8",
256
258
  backup: bool = True,
257
- temp_dir: Optional[Union[str, Path]] = None,
259
+ temp_dir: Optional[str | Path] = None,
258
260
  ):
259
261
  """
260
262
  Context manager for atomic file writing.
@@ -286,10 +288,11 @@ def atomic_write(
286
288
 
287
289
 
288
290
  def safe_write_text(
289
- target_path: Union[str, Path],
291
+ target_path: str | Path,
290
292
  content: str,
291
293
  encoding: str = "utf-8",
292
294
  backup: bool = True,
295
+ append: bool = False,
293
296
  ) -> None:
294
297
  """
295
298
  Safely write text content to a file atomically.
@@ -300,12 +303,22 @@ def safe_write_text(
300
303
  encoding: Text encoding
301
304
  backup: Whether to create backup
302
305
  """
306
+ target_path = Path(target_path)
307
+ target_path.parent.mkdir(parents=True, exist_ok=True)
308
+
309
+ # For append operations, atomic write semantics don't apply cleanly (we are not replacing the file).
310
+ # Tests and typical usage protect append with a lock (see FileLock usage in core tests).
311
+ if append:
312
+ with open(target_path, "a", encoding=encoding) as f:
313
+ f.write(content)
314
+ return
315
+
303
316
  with atomic_write(target_path, "w", encoding=encoding, backup=backup) as f:
304
317
  f.write(content)
305
318
 
306
319
 
307
320
  def safe_write_bytes(
308
- target_path: Union[str, Path], content: bytes, backup: bool = True
321
+ target_path: str | Path, content: bytes, backup: bool = True
309
322
  ) -> None:
310
323
  """
311
324
  Safely write binary content to a file atomically.
@@ -320,7 +333,7 @@ def safe_write_bytes(
320
333
 
321
334
 
322
335
  def safe_read_text(
323
- file_path: Union[str, Path], encoding: str = "utf-8", max_size_mb: float = 100.0
336
+ file_path: str | Path, encoding: str = "utf-8", max_size_mb: float = 100.0
324
337
  ) -> str:
325
338
  """
326
339
  Safely read text content from a file with size validation.
@@ -372,7 +385,7 @@ def safe_read_text(
372
385
  raise FileOperationError(f"IOError reading file '{file_path}': {e}") from e
373
386
 
374
387
 
375
- def safe_read_bytes(file_path: Union[str, Path], max_size_mb: float = 100.0) -> bytes:
388
+ def safe_read_bytes(file_path: str | Path, max_size_mb: float = 100.0) -> bytes:
376
389
  """
377
390
  Safely read binary content from a file with size validation.
378
391
 
@@ -419,7 +432,7 @@ def safe_read_bytes(file_path: Union[str, Path], max_size_mb: float = 100.0) ->
419
432
 
420
433
 
421
434
  def safe_read_with_fallback(
422
- file_path: Union[str, Path],
435
+ file_path: str | Path,
423
436
  preferred_encoding: str = "utf-8",
424
437
  fallback_encodings: Optional[list[str]] = None,
425
438
  max_size_mb: float = 100.0,
@@ -442,7 +455,7 @@ def safe_read_with_fallback(
442
455
  if fallback_encodings is None:
443
456
  fallback_encodings = ["latin1", "cp1252", "iso-8859-1"]
444
457
 
445
- # Try preferred encoding first
458
+ # Try encoding first
446
459
  try:
447
460
  return safe_read_text(file_path, preferred_encoding, max_size_mb)
448
461
  except FileOperationError as e:
@@ -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.1
7
+ Version: 0.1.0.3
8
8
  Generation Date: 30-Oct-2025
9
9
 
10
10
  Base classes and utilities for common IO operations.
@@ -21,8 +21,10 @@ Priority 4 (Performance): Efficient operations
21
21
  Priority 5 (Extensibility): Ready for new utilities
22
22
  """
23
23
 
24
+ from __future__ import annotations
25
+
24
26
  from abc import ABC, abstractmethod
25
- from typing import Optional, Union, Callable
27
+ from typing import Optional, Callable
26
28
  from pathlib import Path
27
29
 
28
30
  from ..contracts import IAtomicWriter, IPathValidator, IFileWatcher, IFileLock
@@ -43,7 +45,7 @@ class AAtomicWriter(IAtomicWriter, ABC):
43
45
  Provides skeletal implementation for atomic write operations.
44
46
  """
45
47
 
46
- def __init__(self, path: Union[str, Path], mode: AtomicMode = AtomicMode.WRITE_BACKUP):
48
+ def __init__(self, path: str | Path, mode: AtomicMode = AtomicMode.WRITE_BACKUP):
47
49
  """Initialize atomic writer."""
48
50
  self.path = Path(path)
49
51
  self.mode = mode
@@ -55,7 +57,7 @@ class AAtomicWriter(IAtomicWriter, ABC):
55
57
  """Write data atomically."""
56
58
  pass
57
59
 
58
- def __enter__(self) -> 'AAtomicWriter':
60
+ def __enter__(self) -> AAtomicWriter:
59
61
  """Enter context manager."""
60
62
  return self
61
63
 
@@ -77,18 +79,18 @@ class APathValidator(IPathValidator, ABC):
77
79
  self.security_level = security_level
78
80
 
79
81
  @abstractmethod
80
- def validate_path(self, path: Union[str, Path]) -> bool:
82
+ def validate_path(self, path: str | Path) -> bool:
81
83
  """Validate path safety."""
82
84
  pass
83
85
 
84
- def is_safe_path(self, path: Union[str, Path]) -> bool:
86
+ def is_safe_path(self, path: str | Path) -> bool:
85
87
  """Check if path is safe to use."""
86
88
  try:
87
89
  return self.validate_path(path)
88
90
  except Exception:
89
91
  return False
90
92
 
91
- def normalize_path(self, path: Union[str, Path]) -> Path:
93
+ def normalize_path(self, path: str | Path) -> Path:
92
94
  """Normalize and resolve path."""
93
95
  return Path(path).resolve()
94
96
 
@@ -134,7 +136,7 @@ class AFileLock(IFileLock, ABC):
134
136
  Provides common locking logic.
135
137
  """
136
138
 
137
- def __init__(self, path: Union[str, Path], mode: LockMode = LockMode.EXCLUSIVE):
139
+ def __init__(self, path: str | Path, mode: LockMode = LockMode.EXCLUSIVE):
138
140
  """Initialize lock."""
139
141
  self.path = Path(path)
140
142
  self.mode = mode
@@ -154,7 +156,7 @@ class AFileLock(IFileLock, ABC):
154
156
  """Check if locked."""
155
157
  return self._locked
156
158
 
157
- def __enter__(self) -> 'AFileLock':
159
+ def __enter__(self) -> AFileLock:
158
160
  """Context manager entry."""
159
161
  self.acquire()
160
162
  return self
@@ -162,4 +164,3 @@ class AFileLock(IFileLock, ABC):
162
164
  def __exit__(self, exc_type, exc_val, exc_tb) -> None:
163
165
  """Context manager exit."""
164
166
  self.release()
165
-