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,16 +1,17 @@
1
+ #exonware/xwsystem/src/exonware/xwsystem/io/serialization/auto_serializer.py
1
2
  #exonware\xwsystem\serialization\auto_serializer.py
2
3
  """
3
4
  Company: eXonware.com
4
5
  Author: Eng. Muhammad AlShehri
5
6
  Email: connect@exonware.com
6
- Version: 0.1.0.1
7
+ Version: 0.1.0.3
7
8
  Generation Date: September 04, 2025
8
9
 
9
10
  Automatic serializer that detects format and delegates to appropriate serializer.
10
11
  """
11
12
 
12
13
  from pathlib import Path
13
- from typing import Any, Optional, Union
14
+ from typing import Any, Optional
14
15
 
15
16
  from .format_detector import FormatDetector, detect_format
16
17
  from .contracts import ISerialization
@@ -43,8 +44,11 @@ class AutoSerializer:
43
44
  """
44
45
  Get serializer class for format name.
45
46
 
47
+ First checks UniversalCodecRegistry for auto-registered formats (like XWJSON),
48
+ then falls back to hardcoded module_map for xwsystem formats.
49
+
46
50
  Args:
47
- format_name: Format name (e.g., 'JSON', 'YAML')
51
+ format_name: Format name (e.g., 'JSON', 'YAML', 'XWJSON')
48
52
 
49
53
  Returns:
50
54
  Serializer class
@@ -52,10 +56,40 @@ class AutoSerializer:
52
56
  Raises:
53
57
  ImportError: If format not available
54
58
  """
59
+ # First, try UniversalCodecRegistry for auto-registered formats
60
+ # All auto-registering formats (xwjson, xwformats, xwsyntax, etc.) register themselves
61
+ # when their modules are imported, so we just check the registry - no special cases needed
62
+ try:
63
+ from ..codec.registry import get_registry
64
+ registry = get_registry()
65
+ # Try format name as-is, then lowercase, then uppercase, then aliases
66
+ codec = (registry.get_by_id(format_name) or
67
+ registry.get_by_id(format_name.lower()) or
68
+ registry.get_by_id(format_name.upper()) or
69
+ registry.get_by_alias(format_name) or
70
+ registry.get_by_alias(format_name.lower()) or
71
+ registry.get_by_alias(format_name.upper()))
72
+ if codec:
73
+ # Check if codec implements ISerialization (has dumps/loads)
74
+ # Codec adapters (ICodec only) have encode/decode but NOT dumps/loads
75
+ if hasattr(codec, 'dumps') and hasattr(codec, 'loads'):
76
+ # This is a full ISerialization implementation
77
+ logger.debug(f"Found ISerialization codec in registry for format: {format_name}")
78
+ return type(codec)
79
+ else:
80
+ # This is only ICodec (codec adapter), skip it
81
+ logger.debug(f"Skipping codec adapter (ICodec only) for format: {format_name}, needs ISerialization")
82
+ pass
83
+ except Exception as e:
84
+ # Registry not available or format not found, continue to hardcoded map
85
+ logger.debug(f"Registry lookup failed for {format_name}: {e}")
86
+ pass
87
+
88
+ # Fallback to hardcoded module_map for xwsystem formats
55
89
  # Dynamic import to avoid circular dependencies.
56
90
  # Root cause fix: import concrete serializers from the canonical
57
91
  # xwsystem.io.serialization.formats packages instead of a parallel
58
- # exonware.xwsystem.serialization namespace (which should not exist).
92
+ # exonware.xwsystem.serialization namespace (not expected to exist).
59
93
  module_map = {
60
94
  # Text formats
61
95
  'JSON': ('io.serialization.formats.text.json', 'JsonSerializer'),
@@ -111,6 +145,8 @@ class AutoSerializer:
111
145
  """
112
146
  Get cached serializer instance for format.
113
147
 
148
+ First checks UniversalCodecRegistry for instances, then creates from class.
149
+
114
150
  Args:
115
151
  format_name: Format name
116
152
 
@@ -118,6 +154,36 @@ class AutoSerializer:
118
154
  Serializer instance
119
155
  """
120
156
  if format_name not in self._serializer_cache:
157
+ # First try to get instance from registry (for auto-registered formats)
158
+ try:
159
+ from ..codec.registry import get_registry
160
+ registry = get_registry()
161
+ # Try format name as-is, then lowercase, then uppercase, then aliases
162
+ codec = (registry.get_by_id(format_name) or
163
+ registry.get_by_id(format_name.lower()) or
164
+ registry.get_by_id(format_name.upper()) or
165
+ registry.get_by_alias(format_name) or
166
+ registry.get_by_alias(format_name.lower()) or
167
+ registry.get_by_alias(format_name.upper()))
168
+ # Check if codec has ISerialization interface (dumps/loads methods)
169
+ # Codec adapters (ICodec only) have encode/decode but NOT dumps/loads
170
+ # We need ISerialization (which extends ICodec) with dumps/loads
171
+ if codec and hasattr(codec, 'dumps') and hasattr(codec, 'loads'):
172
+ # This is a full ISerialization implementation
173
+ self._serializer_cache[format_name] = codec
174
+ logger.debug(f"Using registry serializer (ISerialization) for format: {format_name}")
175
+ return codec
176
+ elif codec and hasattr(codec, 'encode') and not hasattr(codec, 'dumps'):
177
+ # This is only ICodec (codec adapter), not ISerialization
178
+ # Skip it - we need a serializer with dumps/loads for detect_and_serialize
179
+ logger.debug(f"Skipping codec adapter (ICodec only) for format: {format_name}, needs ISerialization")
180
+ pass
181
+ except (ImportError, AttributeError, TypeError) as e:
182
+ # Registry not available or codec not compatible, create from class
183
+ logger.debug(f"Registry lookup failed for {format_name}: {e}")
184
+ pass
185
+
186
+ # Fallback: create instance from class
121
187
  serializer_class = self._get_serializer_class(format_name)
122
188
  self._serializer_cache[format_name] = serializer_class()
123
189
  logger.debug(f"Created serializer for format: {format_name}")
@@ -127,10 +193,10 @@ class AutoSerializer:
127
193
  def detect_and_serialize(
128
194
  self,
129
195
  data: Any,
130
- file_path: Optional[Union[str, Path]] = None,
196
+ file_path: Optional[str | Path] = None,
131
197
  format_hint: Optional[str] = None,
132
198
  **opts
133
- ) -> Union[str, bytes]:
199
+ ) -> str | bytes:
134
200
  """
135
201
  Auto-detect format and serialize data.
136
202
 
@@ -139,6 +205,8 @@ class AutoSerializer:
139
205
  file_path: Optional file path for format detection
140
206
  format_hint: Optional format hint to use
141
207
  **opts: Additional serializer-specific options (pretty, indent, etc.)
208
+ Universal options (sorted, pretty, compact, canonical) are automatically
209
+ mapped to format-specific options.
142
210
 
143
211
  Returns:
144
212
  Serialized data
@@ -155,13 +223,34 @@ class AutoSerializer:
155
223
  format_name = self._default_format
156
224
  logger.debug(f"Using default format: {format_name}")
157
225
 
226
+ # Map universal options to format-specific options
227
+ try:
228
+ from .universal_options import map_universal_options
229
+ # Check if any universal options are present
230
+ universal_option_names = {'pretty', 'compact', 'sorted', 'canonical', 'indent',
231
+ 'ensure_ascii', 'allow_nan', 'strip_whitespace',
232
+ 'preserve_quotes', 'declaration', 'encoding',
233
+ 'line_separator', 'item_separator'}
234
+ has_universal_options = any(key in universal_option_names for key in opts.keys())
235
+
236
+ if has_universal_options:
237
+ # Map universal options to format-specific options
238
+ format_specific_opts = map_universal_options(format_name, **opts)
239
+ # Merge with any remaining non-universal options
240
+ remaining_opts = {k: v for k, v in opts.items() if k not in universal_option_names}
241
+ format_specific_opts.update(remaining_opts)
242
+ opts = format_specific_opts
243
+ except ImportError:
244
+ # Universal options module not available, use opts as-is
245
+ logger.debug("Universal options module not available, using options as-is")
246
+
158
247
  serializer = self._get_serializer(format_name)
159
248
  return serializer.dumps(data, **opts)
160
249
 
161
250
  def detect_and_deserialize(
162
251
  self,
163
- data: Union[str, bytes],
164
- file_path: Optional[Union[str, Path]] = None,
252
+ data: str | bytes,
253
+ file_path: Optional[str | Path] = None,
165
254
  format_hint: Optional[str] = None
166
255
  ) -> Any:
167
256
  """
@@ -197,7 +286,7 @@ class AutoSerializer:
197
286
  def auto_save_file(
198
287
  self,
199
288
  data: Any,
200
- file_path: Union[str, Path],
289
+ file_path: str | Path,
201
290
  format_hint: Optional[str] = None
202
291
  ) -> None:
203
292
  """
@@ -222,9 +311,46 @@ class AutoSerializer:
222
311
  serializer.save_file(data, file_path)
223
312
  logger.info(f"Saved data to {file_path} using {format_name} format")
224
313
 
314
+ def save_file(
315
+ self,
316
+ data: Any,
317
+ file_path: str | Path,
318
+ format_hint: Optional[str] = None,
319
+ **opts
320
+ ) -> None:
321
+ """
322
+ Auto-detect format and save to file (alias for auto_save_file).
323
+
324
+ Args:
325
+ data: Data to save
326
+ file_path: File path (format detected from extension)
327
+ format_hint: Optional format hint to override detection
328
+ **opts: Additional options (passed to serializer)
329
+ """
330
+ self.auto_save_file(data, file_path, format_hint)
331
+
332
+ def load_file(
333
+ self,
334
+ file_path: str | Path,
335
+ format_hint: Optional[str] = None,
336
+ **opts
337
+ ) -> Any:
338
+ """
339
+ Auto-detect format and load from file (alias for auto_load_file).
340
+
341
+ Args:
342
+ file_path: File path to load
343
+ format_hint: Optional format hint to override detection
344
+ **opts: Additional options (passed to serializer)
345
+
346
+ Returns:
347
+ Loaded data
348
+ """
349
+ return self.auto_load_file(file_path, format_hint)
350
+
225
351
  def auto_load_file(
226
352
  self,
227
- file_path: Union[str, Path],
353
+ file_path: str | Path,
228
354
  format_hint: Optional[str] = None
229
355
  ) -> Any:
230
356
  """
@@ -280,7 +406,7 @@ class AutoSerializer:
280
406
  async def auto_save_file_async(
281
407
  self,
282
408
  data: Any,
283
- file_path: Union[str, Path],
409
+ file_path: str | Path,
284
410
  format_hint: Optional[str] = None
285
411
  ) -> None:
286
412
  """
@@ -306,7 +432,7 @@ class AutoSerializer:
306
432
 
307
433
  async def auto_load_file_async(
308
434
  self,
309
- file_path: Union[str, Path],
435
+ file_path: str | Path,
310
436
  format_hint: Optional[str] = None
311
437
  ) -> Any:
312
438
  """
@@ -342,8 +468,8 @@ class AutoSerializer:
342
468
 
343
469
  def get_format_suggestions(
344
470
  self,
345
- data: Union[str, bytes],
346
- file_path: Optional[Union[str, Path]] = None
471
+ data: str | bytes,
472
+ file_path: Optional[str | Path] = None
347
473
  ) -> list[tuple[str, float]]:
348
474
  """
349
475
  Get format suggestions for given data.
@@ -372,10 +498,10 @@ _global_auto_serializer = AutoSerializer()
372
498
 
373
499
  def auto_serialize(
374
500
  data: Any,
375
- file_path: Optional[Union[str, Path]] = None,
501
+ file_path: Optional[str | Path] = None,
376
502
  format_hint: Optional[str] = None,
377
503
  **opts
378
- ) -> Union[str, bytes]:
504
+ ) -> str | bytes:
379
505
  """
380
506
  Convenience function for auto-serialization.
381
507
 
@@ -391,8 +517,8 @@ def auto_serialize(
391
517
  return _global_auto_serializer.detect_and_serialize(data, file_path, format_hint, **opts)
392
518
 
393
519
  def auto_deserialize(
394
- data: Union[str, bytes],
395
- file_path: Optional[Union[str, Path]] = None,
520
+ data: str | bytes,
521
+ file_path: Optional[str | Path] = None,
396
522
  format_hint: Optional[str] = None
397
523
  ) -> Any:
398
524
  """
@@ -410,7 +536,7 @@ def auto_deserialize(
410
536
 
411
537
  def auto_save_file(
412
538
  data: Any,
413
- file_path: Union[str, Path],
539
+ file_path: str | Path,
414
540
  format_hint: Optional[str] = None
415
541
  ) -> None:
416
542
  """
@@ -424,7 +550,7 @@ def auto_save_file(
424
550
  return _global_auto_serializer.auto_save_file(data, file_path, format_hint)
425
551
 
426
552
  def auto_load_file(
427
- file_path: Union[str, Path],
553
+ file_path: str | Path,
428
554
  format_hint: Optional[str] = None
429
555
  ) -> Any:
430
556
  """
@@ -1,8 +1,9 @@
1
+ #exonware/xwsystem/src/exonware/xwsystem/io/serialization/base.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 2, 2025
7
8
 
8
9
  Serialization base classes - ASerialization abstract base.
@@ -13,9 +14,11 @@ Following I→A→XW pattern:
13
14
  - XW: XW{Format}Serializer (concrete implementations)
14
15
  """
15
16
 
17
+ from __future__ import annotations
18
+
16
19
  import asyncio
17
20
  from abc import ABC, abstractmethod, ABCMeta
18
- from typing import Any, Union, Optional, BinaryIO, TextIO, AsyncIterator, Iterator, TYPE_CHECKING
21
+ from typing import Any, Optional, BinaryIO, TextIO, AsyncIterator, Iterator, TYPE_CHECKING
19
22
  # Root cause: Migrating to Python 3.12 built-in generic syntax for consistency
20
23
  # Priority #3: Maintainability - Modern type annotations improve code clarity
21
24
  from pathlib import Path
@@ -31,7 +34,41 @@ if TYPE_CHECKING:
31
34
  from .schema_registry import SchemaInfo
32
35
 
33
36
 
34
- class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
37
+ # ============================================================================
38
+ # MODULE-LEVEL CACHE FOR SERIALIZER INSTANCES BY FILE PATH
39
+ # ============================================================================
40
+
41
+ # Module-level cache: file_path -> serializer_instance
42
+ # All serializers (JsonSerializer, YamlSerializer, XWSerializer, etc.) use this
43
+ # Benefits: O(1) lookup, automatic LRU eviction, thread-safe, statistics
44
+ from ...caching import create_cache
45
+ # Use flexible create_cache() to allow configuration via environment/settings
46
+ # Defaults to FunctoolsLRUCache
47
+ _file_serializer_cache = create_cache(capacity=100, namespace='xwsystem.serialization', name="FileSerializerCache")
48
+
49
+
50
+ def get_cached_serializer_for_path(file_path: str | Path) -> Optional[ISerialization]:
51
+ """
52
+ Get cached serializer instance for file path, if available.
53
+
54
+ This function allows retrieving a previously cached serializer instance
55
+ for a given file path. Serializers are automatically cached when
56
+ save_file() or load_file() is called.
57
+
58
+ Args:
59
+ file_path: Path to the file
60
+
61
+ Returns:
62
+ Cached serializer instance if available, None otherwise
63
+ """
64
+ if _file_serializer_cache is None:
65
+ return None
66
+
67
+ path_str = str(Path(file_path).resolve())
68
+ return _file_serializer_cache.get(path_str)
69
+
70
+
71
+ class ASerialization(ACodec[Any, bytes | str], ISerialization):
35
72
  """
36
73
  Abstract base class for serialization - follows I→A→XW pattern.
37
74
 
@@ -69,11 +106,11 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
69
106
  super().__init__(max_depth=max_depth, max_size_mb=max_size_mb)
70
107
 
71
108
  # ========================================================================
72
- # CORE CODEC METHODS (Must implement in subclasses)
109
+ # CORE CODEC METHODS (Implement in subclasses)
73
110
  # ========================================================================
74
111
 
75
112
  @abstractmethod
76
- def encode(self, value: Any, *, options: Optional[EncodeOptions] = None) -> Union[bytes, str]:
113
+ def encode(self, value: Any, *, options: Optional[EncodeOptions] = None) -> bytes | str:
77
114
  """
78
115
  Encode data to representation - must implement in subclass.
79
116
 
@@ -83,7 +120,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
83
120
  pass
84
121
 
85
122
  @abstractmethod
86
- def decode(self, repr: Union[bytes, str], *, options: Optional[DecodeOptions] = None) -> Any:
123
+ def decode(self, repr: bytes | str, *, options: Optional[DecodeOptions] = None) -> Any:
87
124
  """
88
125
  Decode representation to data - must implement in subclass.
89
126
 
@@ -93,7 +130,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
93
130
  pass
94
131
 
95
132
  # ========================================================================
96
- # METADATA PROPERTIES (Must implement in subclasses)
133
+ # METADATA PROPERTIES (Implement in subclasses)
97
134
  # ========================================================================
98
135
 
99
136
  @property
@@ -301,7 +338,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
301
338
  # FILE I/O METHODS (Default implementations using encode/decode)
302
339
  # ========================================================================
303
340
 
304
- def save_file(self, data: Any, file_path: Union[str, Path], **options) -> None:
341
+ def save_file(self, data: Any, file_path: str | Path, **options) -> None:
305
342
  """
306
343
  Save data to file with atomic operations.
307
344
 
@@ -310,6 +347,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
310
347
  2. Encode data using encode()
311
348
  3. Write to file using Path.write_bytes() or write_text()
312
349
  4. Uses atomic operations if configured
350
+ 5. Caches serializer instance by file path for performance
313
351
 
314
352
  Args:
315
353
  data: Data to serialize and save
@@ -321,6 +359,12 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
321
359
  """
322
360
  try:
323
361
  path = Path(file_path)
362
+ path_str = str(path.resolve())
363
+
364
+ # Cache this serializer instance for this file path
365
+ # This enables reuse if the same file is accessed again
366
+ if _file_serializer_cache is not None:
367
+ _file_serializer_cache.put(path_str, self)
324
368
 
325
369
  # Ensure parent directory exists
326
370
  path.parent.mkdir(parents=True, exist_ok=True)
@@ -349,13 +393,14 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
349
393
  original_error=e
350
394
  )
351
395
 
352
- def load_file(self, file_path: Union[str, Path], **options) -> Any:
396
+ def load_file(self, file_path: str | Path, **options) -> Any:
353
397
  """
354
398
  Load data from file.
355
399
 
356
400
  Default implementation:
357
401
  1. Read from file using Path.read_bytes() or read_text()
358
402
  2. Decode data using decode()
403
+ 3. Caches serializer instance by file path for performance
359
404
 
360
405
  Args:
361
406
  file_path: Path to load from
@@ -369,6 +414,12 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
369
414
  """
370
415
  try:
371
416
  path = Path(file_path)
417
+ path_str = str(path.resolve())
418
+
419
+ # Cache this serializer instance for this file path
420
+ # This enables reuse if the same file is accessed again
421
+ if _file_serializer_cache is not None:
422
+ _file_serializer_cache.put(path_str, self)
372
423
 
373
424
  if not path.exists():
374
425
  raise FileNotFoundError(f"File not found: {path}")
@@ -401,7 +452,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
401
452
 
402
453
  def stream_read_record(
403
454
  self,
404
- file_path: Union[str, Path],
455
+ file_path: str | Path,
405
456
  match: callable,
406
457
  projection: Optional[list[Any]] = None,
407
458
  **options: Any,
@@ -430,7 +481,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
430
481
 
431
482
  def stream_update_record(
432
483
  self,
433
- file_path: Union[str, Path],
484
+ file_path: str | Path,
434
485
  match: callable,
435
486
  updater: callable,
436
487
  *,
@@ -469,7 +520,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
469
520
 
470
521
  def get_record_page(
471
522
  self,
472
- file_path: Union[str, Path],
523
+ file_path: str | Path,
473
524
  page_number: int,
474
525
  page_size: int,
475
526
  **options: Any,
@@ -500,7 +551,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
500
551
 
501
552
  def get_record_by_id(
502
553
  self,
503
- file_path: Union[str, Path],
554
+ file_path: str | Path,
504
555
  id_value: Any,
505
556
  *,
506
557
  id_field: str = "id",
@@ -572,7 +623,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
572
623
  # STREAMING METHODS (Default implementations)
573
624
  # ========================================================================
574
625
 
575
- def iter_serialize(self, data: Any, chunk_size: int = 8192) -> Iterator[Union[str, bytes]]:
626
+ def iter_serialize(self, data: Any, chunk_size: int = 8192) -> Iterator[str | bytes]:
576
627
  """
577
628
  Stream serialize data in chunks.
578
629
 
@@ -596,7 +647,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
596
647
  for i in range(0, len(repr_data), chunk_size):
597
648
  yield repr_data[i:i + chunk_size]
598
649
 
599
- def iter_deserialize(self, src: Union[TextIO, BinaryIO, Iterator[Union[str, bytes]]]) -> Any:
650
+ def iter_deserialize(self, src: TextIO | BinaryIO | Iterator[str | bytes]) -> Any:
600
651
  """
601
652
  Stream deserialize data from chunks.
602
653
 
@@ -625,7 +676,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
625
676
  # ASYNC METHODS (Default implementations using asyncio.to_thread)
626
677
  # ========================================================================
627
678
 
628
- async def save_file_async(self, data: Any, file_path: Union[str, Path], **options) -> None:
679
+ async def save_file_async(self, data: Any, file_path: str | Path, **options) -> None:
629
680
  """
630
681
  Async save data to file.
631
682
 
@@ -639,7 +690,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
639
690
  """
640
691
  await asyncio.to_thread(self.save_file, data, file_path, **options)
641
692
 
642
- async def load_file_async(self, file_path: Union[str, Path], **options) -> Any:
693
+ async def load_file_async(self, file_path: str | Path, **options) -> Any:
643
694
  """
644
695
  Async load data from file.
645
696
 
@@ -655,7 +706,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
655
706
  """
656
707
  return await asyncio.to_thread(self.load_file, file_path, **options)
657
708
 
658
- async def stream_serialize(self, data: Any, chunk_size: int = 8192) -> AsyncIterator[Union[str, bytes]]:
709
+ async def stream_serialize(self, data: Any, chunk_size: int = 8192) -> AsyncIterator[str | bytes]:
659
710
  """
660
711
  Async stream serialize data in chunks.
661
712
 
@@ -673,7 +724,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
673
724
  yield chunk
674
725
  await asyncio.sleep(0) # Yield control
675
726
 
676
- async def stream_deserialize(self, data_stream: AsyncIterator[Union[str, bytes]]) -> Any:
727
+ async def stream_deserialize(self, data_stream: AsyncIterator[str | bytes]) -> Any:
677
728
  """
678
729
  Async stream deserialize data from chunks.
679
730
 
@@ -703,7 +754,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
703
754
 
704
755
  def atomic_update_path(
705
756
  self,
706
- file_path: Union[str, Path],
757
+ file_path: str | Path,
707
758
  path: str,
708
759
  value: Any,
709
760
  **options
@@ -743,13 +794,13 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
743
794
 
744
795
  # Load entire file
745
796
  # For large files, skip size validation (they use lazy loading/streaming)
746
- # Root cause: Large files (10GB+) should use atomic path operations without full validation
797
+ # Root cause: Large files (10GB+) use atomic path operations without full validation
747
798
  # Solution: Skip size check for atomic operations (depth check still performed)
748
799
  large_file_options = {**options, 'skip_size_check': True}
749
800
  data = self.load_file(file_path, **large_file_options)
750
801
 
751
802
  # Update path in memory (simple dict/list update for now)
752
- # Subclasses should override with format-specific logic
803
+ # Subclasses override with format-specific logic
753
804
  if isinstance(data, dict) and path.startswith('/'):
754
805
  # Simple JSONPointer-like path handling
755
806
  path_parts = path.strip('/').split('/')
@@ -795,7 +846,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
795
846
 
796
847
  def atomic_read_path(
797
848
  self,
798
- file_path: Union[str, Path],
849
+ file_path: str | Path,
799
850
  path: str,
800
851
  **options
801
852
  ) -> Any:
@@ -832,7 +883,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
832
883
 
833
884
  # Load entire file
834
885
  # For large files, skip size validation (they use lazy loading/streaming)
835
- # Root cause: Large files (10GB+) should use atomic path operations without full validation
886
+ # Root cause: Large files (10GB+) use atomic path operations without full validation
836
887
  # Solution: Skip size check for atomic operations (depth check still performed)
837
888
  large_file_options = {**options, 'skip_size_check': True}
838
889
  data = self.load_file(file_path, **large_file_options)
@@ -898,7 +949,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
898
949
  def incremental_save(
899
950
  self,
900
951
  items: Iterator[Any],
901
- file_path: Union[str, Path],
952
+ file_path: str | Path,
902
953
  **options
903
954
  ) -> None:
904
955
  """
@@ -939,7 +990,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
939
990
 
940
991
  def incremental_load(
941
992
  self,
942
- file_path: Union[str, Path],
993
+ file_path: str | Path,
943
994
  **options
944
995
  ) -> Iterator[Any]:
945
996
  """
@@ -986,7 +1037,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
986
1037
 
987
1038
  def query(
988
1039
  self,
989
- file_path: Union[str, Path],
1040
+ file_path: str | Path,
990
1041
  query_expr: str,
991
1042
  **options
992
1043
  ) -> Any:
@@ -1021,7 +1072,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
1021
1072
  )
1022
1073
 
1023
1074
  # Root cause fixed: Base class doesn't implement queries - raise immediately
1024
- # Subclasses should override this method to provide actual query implementation
1075
+ # Subclasses override this method to provide actual query implementation
1025
1076
  # Priority #4: Performance - Don't load file if operation will fail
1026
1077
  raise NotImplementedError(
1027
1078
  f"Query operations require format-specific implementation for {self.format_name}. "
@@ -1031,7 +1082,7 @@ class ASerialization(ACodec[Any, Union[bytes, str]], ISerialization):
1031
1082
 
1032
1083
  def merge(
1033
1084
  self,
1034
- file_path: Union[str, Path],
1085
+ file_path: str | Path,
1035
1086
  updates: dict[str, Any],
1036
1087
  **options
1037
1088
  ) -> None:
@@ -1115,17 +1166,17 @@ class ASchemaRegistry(ABC):
1115
1166
  """Abstract base class for schema registry implementations."""
1116
1167
 
1117
1168
  @abstractmethod
1118
- async def register_schema(self, subject: str, schema: str, schema_type: str = "AVRO") -> 'SchemaInfo':
1169
+ async def register_schema(self, subject: str, schema: str, schema_type: str = "AVRO") -> SchemaInfo:
1119
1170
  """Register a new schema version."""
1120
1171
  pass
1121
1172
 
1122
1173
  @abstractmethod
1123
- async def get_schema(self, schema_id: int) -> 'SchemaInfo':
1174
+ async def get_schema(self, schema_id: int) -> SchemaInfo:
1124
1175
  """Get schema by ID."""
1125
1176
  pass
1126
1177
 
1127
1178
  @abstractmethod
1128
- async def get_latest_schema(self, subject: str) -> 'SchemaInfo':
1179
+ async def get_latest_schema(self, subject: str) -> SchemaInfo:
1129
1180
  """Get latest schema version for subject."""
1130
1181
  pass
1131
1182
 
@@ -1140,7 +1191,6 @@ class ASchemaRegistry(ABC):
1140
1191
  pass
1141
1192
 
1142
1193
  @abstractmethod
1143
- async def set_compatibility(self, subject: str, level: 'CompatibilityLevel') -> None:
1194
+ async def set_compatibility(self, subject: str, level: CompatibilityLevel) -> None:
1144
1195
  """Set compatibility level for subject."""
1145
1196
  pass
1146
-