exonware-xwsystem 0.1.0.1__py3-none-any.whl → 0.1.0.4__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.
- exonware/__init__.py +2 -1
- exonware/conf.py +2 -2
- exonware/xwsystem/__init__.py +115 -43
- exonware/xwsystem/base.py +30 -0
- exonware/xwsystem/caching/__init__.py +39 -13
- exonware/xwsystem/caching/base.py +24 -6
- exonware/xwsystem/caching/bloom_cache.py +2 -2
- exonware/xwsystem/caching/cache_manager.py +2 -1
- exonware/xwsystem/caching/conditional.py +2 -2
- exonware/xwsystem/caching/contracts.py +85 -139
- exonware/xwsystem/caching/decorators.py +6 -19
- exonware/xwsystem/caching/defs.py +2 -1
- exonware/xwsystem/caching/disk_cache.py +2 -1
- exonware/xwsystem/caching/distributed.py +2 -1
- exonware/xwsystem/caching/errors.py +2 -1
- exonware/xwsystem/caching/events.py +110 -27
- exonware/xwsystem/caching/eviction_strategies.py +2 -2
- exonware/xwsystem/caching/external_caching_python.py +701 -0
- exonware/xwsystem/caching/facade.py +253 -0
- exonware/xwsystem/caching/factory.py +300 -0
- exonware/xwsystem/caching/fluent.py +14 -12
- exonware/xwsystem/caching/integrity.py +21 -6
- exonware/xwsystem/caching/lfu_cache.py +2 -1
- exonware/xwsystem/caching/lfu_optimized.py +18 -6
- exonware/xwsystem/caching/lru_cache.py +7 -4
- exonware/xwsystem/caching/memory_bounded.py +2 -2
- exonware/xwsystem/caching/metrics_exporter.py +2 -2
- exonware/xwsystem/caching/observable_cache.py +2 -2
- exonware/xwsystem/caching/pluggable_cache.py +2 -2
- exonware/xwsystem/caching/rate_limiter.py +2 -2
- exonware/xwsystem/caching/read_through.py +2 -2
- exonware/xwsystem/caching/secure_cache.py +81 -28
- exonware/xwsystem/caching/serializable.py +9 -7
- exonware/xwsystem/caching/stats.py +2 -2
- exonware/xwsystem/caching/tagging.py +2 -2
- exonware/xwsystem/caching/ttl_cache.py +4 -3
- exonware/xwsystem/caching/two_tier_cache.py +6 -3
- exonware/xwsystem/caching/utils.py +30 -12
- exonware/xwsystem/caching/validation.py +2 -2
- exonware/xwsystem/caching/warming.py +6 -3
- exonware/xwsystem/caching/write_behind.py +15 -6
- exonware/xwsystem/config/__init__.py +11 -17
- exonware/xwsystem/config/base.py +5 -5
- exonware/xwsystem/config/contracts.py +93 -153
- exonware/xwsystem/config/defaults.py +3 -2
- exonware/xwsystem/config/defs.py +3 -2
- exonware/xwsystem/config/errors.py +2 -5
- exonware/xwsystem/config/logging.py +12 -8
- exonware/xwsystem/config/logging_setup.py +3 -2
- exonware/xwsystem/config/performance.py +1 -46
- exonware/xwsystem/config/performance_modes.py +9 -8
- exonware/xwsystem/config/version_manager.py +1 -0
- exonware/xwsystem/config.py +27 -0
- exonware/xwsystem/console/__init__.py +53 -0
- exonware/xwsystem/console/base.py +133 -0
- exonware/xwsystem/console/cli/__init__.py +61 -0
- exonware/xwsystem/{cli → console/cli}/args.py +27 -24
- exonware/xwsystem/{cli → console/cli}/base.py +18 -87
- exonware/xwsystem/{cli → console/cli}/colors.py +15 -13
- exonware/xwsystem/console/cli/console.py +98 -0
- exonware/xwsystem/{cli → console/cli}/contracts.py +51 -69
- exonware/xwsystem/console/cli/defs.py +87 -0
- exonware/xwsystem/console/cli/encoding.py +69 -0
- exonware/xwsystem/{cli → console/cli}/errors.py +8 -3
- exonware/xwsystem/console/cli/event_logger.py +166 -0
- exonware/xwsystem/{cli → console/cli}/progress.py +25 -21
- exonware/xwsystem/{cli → console/cli}/prompts.py +3 -2
- exonware/xwsystem/{cli → console/cli}/tables.py +27 -24
- exonware/xwsystem/console/contracts.py +113 -0
- exonware/xwsystem/console/defs.py +154 -0
- exonware/xwsystem/console/errors.py +34 -0
- exonware/xwsystem/console/event_logger.py +385 -0
- exonware/xwsystem/console/writer.py +132 -0
- exonware/xwsystem/contracts.py +28 -0
- exonware/xwsystem/data_structures/__init__.py +23 -0
- exonware/xwsystem/data_structures/trie.py +34 -0
- exonware/xwsystem/data_structures/union_find.py +144 -0
- exonware/xwsystem/defs.py +17 -0
- exonware/xwsystem/errors.py +23 -0
- exonware/xwsystem/facade.py +62 -0
- exonware/xwsystem/http_client/__init__.py +22 -1
- exonware/xwsystem/http_client/advanced_client.py +8 -5
- exonware/xwsystem/http_client/base.py +3 -2
- exonware/xwsystem/http_client/client.py +7 -4
- exonware/xwsystem/http_client/contracts.py +42 -56
- exonware/xwsystem/http_client/defs.py +2 -1
- exonware/xwsystem/http_client/errors.py +2 -1
- exonware/xwsystem/http_client/facade.py +156 -0
- exonware/xwsystem/io/__init__.py +22 -3
- exonware/xwsystem/io/archive/__init__.py +8 -2
- exonware/xwsystem/io/archive/archive.py +1 -1
- exonware/xwsystem/io/archive/archive_files.py +4 -7
- exonware/xwsystem/io/archive/archivers.py +120 -10
- exonware/xwsystem/io/archive/base.py +4 -5
- exonware/xwsystem/io/archive/codec_integration.py +1 -2
- exonware/xwsystem/io/archive/compression.py +1 -2
- exonware/xwsystem/io/archive/facade.py +263 -0
- exonware/xwsystem/io/archive/formats/__init__.py +2 -3
- exonware/xwsystem/io/archive/formats/brotli_format.py +20 -7
- exonware/xwsystem/io/archive/formats/lz4_format.py +20 -7
- exonware/xwsystem/io/archive/formats/rar.py +11 -5
- exonware/xwsystem/io/archive/formats/sevenzip.py +12 -6
- exonware/xwsystem/io/archive/formats/squashfs_format.py +1 -2
- exonware/xwsystem/io/archive/formats/tar.py +52 -7
- exonware/xwsystem/io/archive/formats/wim_format.py +11 -5
- exonware/xwsystem/io/archive/formats/zip.py +1 -2
- exonware/xwsystem/io/archive/formats/zpaq_format.py +1 -2
- exonware/xwsystem/io/archive/formats/zstandard.py +20 -7
- exonware/xwsystem/io/base.py +119 -115
- exonware/xwsystem/io/codec/__init__.py +4 -2
- exonware/xwsystem/io/codec/base.py +19 -13
- exonware/xwsystem/io/codec/contracts.py +59 -2
- exonware/xwsystem/io/codec/registry.py +67 -21
- exonware/xwsystem/io/common/__init__.py +1 -1
- exonware/xwsystem/io/common/atomic.py +29 -16
- exonware/xwsystem/io/common/base.py +11 -10
- exonware/xwsystem/io/common/lock.py +6 -5
- exonware/xwsystem/io/common/path_manager.py +2 -1
- exonware/xwsystem/io/common/watcher.py +1 -2
- exonware/xwsystem/io/contracts.py +301 -433
- exonware/xwsystem/io/contracts_1.py +1180 -0
- exonware/xwsystem/io/data_operations.py +19 -20
- exonware/xwsystem/io/defs.py +4 -3
- exonware/xwsystem/io/errors.py +3 -2
- exonware/xwsystem/io/facade.py +87 -61
- exonware/xwsystem/io/file/__init__.py +1 -1
- exonware/xwsystem/io/file/base.py +8 -9
- exonware/xwsystem/io/file/conversion.py +2 -3
- exonware/xwsystem/io/file/file.py +61 -18
- exonware/xwsystem/io/file/paged_source.py +8 -8
- exonware/xwsystem/io/file/paging/__init__.py +1 -2
- exonware/xwsystem/io/file/paging/byte_paging.py +4 -5
- exonware/xwsystem/io/file/paging/line_paging.py +2 -3
- exonware/xwsystem/io/file/paging/record_paging.py +2 -3
- exonware/xwsystem/io/file/paging/registry.py +1 -2
- exonware/xwsystem/io/file/source.py +13 -17
- exonware/xwsystem/io/filesystem/__init__.py +1 -1
- exonware/xwsystem/io/filesystem/base.py +1 -2
- exonware/xwsystem/io/filesystem/local.py +3 -4
- exonware/xwsystem/io/folder/__init__.py +1 -1
- exonware/xwsystem/io/folder/base.py +1 -2
- exonware/xwsystem/io/folder/folder.py +16 -7
- exonware/xwsystem/io/indexing/__init__.py +14 -0
- exonware/xwsystem/io/indexing/facade.py +443 -0
- exonware/xwsystem/io/path_parser.py +98 -0
- exonware/xwsystem/io/serialization/__init__.py +21 -3
- exonware/xwsystem/io/serialization/auto_serializer.py +146 -20
- exonware/xwsystem/io/serialization/base.py +84 -34
- exonware/xwsystem/io/serialization/contracts.py +50 -73
- exonware/xwsystem/io/serialization/defs.py +2 -1
- exonware/xwsystem/io/serialization/errors.py +2 -1
- exonware/xwsystem/io/serialization/flyweight.py +154 -7
- exonware/xwsystem/io/serialization/format_detector.py +15 -14
- exonware/xwsystem/io/serialization/formats/__init__.py +8 -5
- exonware/xwsystem/io/serialization/formats/binary/bson.py +15 -6
- exonware/xwsystem/io/serialization/formats/binary/cbor.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/marshal.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/msgpack.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/pickle.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/plistlib.py +5 -5
- exonware/xwsystem/io/serialization/formats/database/dbm.py +7 -7
- exonware/xwsystem/io/serialization/formats/database/shelve.py +7 -7
- exonware/xwsystem/io/serialization/formats/database/sqlite3.py +7 -7
- exonware/xwsystem/io/serialization/formats/tabular/__init__.py +27 -0
- exonware/xwsystem/io/serialization/formats/tabular/base.py +89 -0
- exonware/xwsystem/io/serialization/formats/tabular/csv.py +319 -0
- exonware/xwsystem/io/serialization/formats/tabular/df.py +249 -0
- exonware/xwsystem/io/serialization/formats/tabular/excel.py +291 -0
- exonware/xwsystem/io/serialization/formats/tabular/googlesheets.py +374 -0
- exonware/xwsystem/io/serialization/formats/text/__init__.py +1 -1
- exonware/xwsystem/io/serialization/formats/text/append_only_log.py +5 -7
- exonware/xwsystem/io/serialization/formats/text/configparser.py +5 -5
- exonware/xwsystem/io/serialization/formats/text/csv.py +7 -5
- exonware/xwsystem/io/serialization/formats/text/formdata.py +5 -5
- exonware/xwsystem/io/serialization/formats/text/json.py +27 -18
- exonware/xwsystem/io/serialization/formats/text/json5.py +8 -4
- exonware/xwsystem/io/serialization/formats/text/jsonlines.py +18 -14
- exonware/xwsystem/io/serialization/formats/text/multipart.py +5 -5
- exonware/xwsystem/io/serialization/formats/text/toml.py +8 -6
- exonware/xwsystem/io/serialization/formats/text/xml.py +25 -20
- exonware/xwsystem/io/serialization/formats/text/yaml.py +8 -6
- exonware/xwsystem/io/serialization/parsers/__init__.py +3 -2
- exonware/xwsystem/io/serialization/parsers/base.py +6 -5
- exonware/xwsystem/io/serialization/parsers/hybrid_parser.py +7 -6
- exonware/xwsystem/io/serialization/parsers/msgspec_parser.py +10 -7
- exonware/xwsystem/io/serialization/parsers/orjson_direct_parser.py +7 -6
- exonware/xwsystem/io/serialization/parsers/orjson_parser.py +11 -8
- exonware/xwsystem/io/serialization/parsers/pysimdjson_parser.py +13 -9
- exonware/xwsystem/io/serialization/parsers/rapidjson_parser.py +10 -7
- exonware/xwsystem/io/serialization/parsers/registry.py +11 -10
- exonware/xwsystem/io/serialization/parsers/standard.py +7 -6
- exonware/xwsystem/io/serialization/parsers/ujson_parser.py +10 -7
- exonware/xwsystem/io/serialization/registry.py +4 -4
- exonware/xwsystem/io/serialization/serializer.py +168 -79
- exonware/xwsystem/io/serialization/universal_options.py +367 -0
- exonware/xwsystem/io/serialization/utils/__init__.py +1 -2
- exonware/xwsystem/io/serialization/utils/path_ops.py +5 -6
- exonware/xwsystem/io/source_reader.py +223 -0
- exonware/xwsystem/io/stream/__init__.py +1 -1
- exonware/xwsystem/io/stream/async_operations.py +61 -14
- exonware/xwsystem/io/stream/base.py +1 -2
- exonware/xwsystem/io/stream/codec_io.py +6 -7
- exonware/xwsystem/ipc/__init__.py +1 -0
- exonware/xwsystem/ipc/async_fabric.py +4 -4
- exonware/xwsystem/ipc/base.py +6 -5
- exonware/xwsystem/ipc/contracts.py +41 -66
- exonware/xwsystem/ipc/defs.py +2 -1
- exonware/xwsystem/ipc/errors.py +2 -1
- exonware/xwsystem/ipc/message_queue.py +5 -2
- exonware/xwsystem/ipc/pipes.py +70 -34
- exonware/xwsystem/ipc/process_manager.py +7 -5
- exonware/xwsystem/ipc/process_pool.py +6 -5
- exonware/xwsystem/ipc/shared_memory.py +64 -11
- exonware/xwsystem/monitoring/__init__.py +7 -0
- exonware/xwsystem/monitoring/base.py +11 -8
- exonware/xwsystem/monitoring/contracts.py +86 -144
- exonware/xwsystem/monitoring/defs.py +2 -1
- exonware/xwsystem/monitoring/error_recovery.py +16 -3
- exonware/xwsystem/monitoring/errors.py +2 -1
- exonware/xwsystem/monitoring/facade.py +183 -0
- exonware/xwsystem/monitoring/memory_monitor.py +1 -0
- exonware/xwsystem/monitoring/metrics.py +1 -0
- exonware/xwsystem/monitoring/performance_manager_generic.py +7 -7
- exonware/xwsystem/monitoring/performance_monitor.py +1 -0
- exonware/xwsystem/monitoring/performance_validator.py +1 -0
- exonware/xwsystem/monitoring/system_monitor.py +6 -5
- exonware/xwsystem/monitoring/tracing.py +18 -16
- exonware/xwsystem/monitoring/tracker.py +2 -1
- exonware/xwsystem/operations/__init__.py +5 -50
- exonware/xwsystem/operations/base.py +3 -44
- exonware/xwsystem/operations/contracts.py +25 -15
- exonware/xwsystem/operations/defs.py +1 -1
- exonware/xwsystem/operations/diff.py +5 -4
- exonware/xwsystem/operations/errors.py +1 -1
- exonware/xwsystem/operations/merge.py +6 -4
- exonware/xwsystem/operations/patch.py +5 -4
- exonware/xwsystem/patterns/__init__.py +1 -0
- exonware/xwsystem/patterns/base.py +2 -1
- exonware/xwsystem/patterns/context_manager.py +2 -1
- exonware/xwsystem/patterns/contracts.py +215 -256
- exonware/xwsystem/patterns/defs.py +2 -1
- exonware/xwsystem/patterns/dynamic_facade.py +1 -0
- exonware/xwsystem/patterns/errors.py +2 -4
- exonware/xwsystem/patterns/handler_factory.py +2 -3
- exonware/xwsystem/patterns/import_registry.py +1 -0
- exonware/xwsystem/patterns/object_pool.py +1 -0
- exonware/xwsystem/patterns/registry.py +4 -43
- exonware/xwsystem/plugins/__init__.py +2 -1
- exonware/xwsystem/plugins/base.py +6 -5
- exonware/xwsystem/plugins/contracts.py +94 -158
- exonware/xwsystem/plugins/defs.py +2 -1
- exonware/xwsystem/plugins/errors.py +2 -1
- exonware/xwsystem/py.typed +3 -0
- exonware/xwsystem/query/__init__.py +36 -0
- exonware/xwsystem/query/contracts.py +56 -0
- exonware/xwsystem/query/errors.py +22 -0
- exonware/xwsystem/query/registry.py +128 -0
- exonware/xwsystem/runtime/__init__.py +2 -1
- exonware/xwsystem/runtime/base.py +4 -3
- exonware/xwsystem/runtime/contracts.py +39 -60
- exonware/xwsystem/runtime/defs.py +2 -1
- exonware/xwsystem/runtime/env.py +11 -9
- exonware/xwsystem/runtime/errors.py +2 -1
- exonware/xwsystem/runtime/reflection.py +3 -2
- exonware/xwsystem/security/__init__.py +68 -11
- exonware/xwsystem/security/audit.py +167 -0
- exonware/xwsystem/security/base.py +121 -24
- exonware/xwsystem/security/contracts.py +91 -146
- exonware/xwsystem/security/crypto.py +17 -16
- exonware/xwsystem/security/defs.py +2 -1
- exonware/xwsystem/security/errors.py +2 -1
- exonware/xwsystem/security/facade.py +321 -0
- exonware/xwsystem/security/file_security.py +330 -0
- exonware/xwsystem/security/hazmat.py +11 -8
- exonware/xwsystem/security/monitor.py +372 -0
- exonware/xwsystem/security/path_validator.py +140 -18
- exonware/xwsystem/security/policy.py +357 -0
- exonware/xwsystem/security/resource_limits.py +1 -0
- exonware/xwsystem/security/validator.py +455 -0
- exonware/xwsystem/shared/__init__.py +14 -1
- exonware/xwsystem/shared/base.py +285 -2
- exonware/xwsystem/shared/contracts.py +415 -126
- exonware/xwsystem/shared/defs.py +2 -1
- exonware/xwsystem/shared/errors.py +2 -2
- exonware/xwsystem/shared/xwobject.py +316 -0
- exonware/xwsystem/structures/__init__.py +1 -0
- exonware/xwsystem/structures/base.py +3 -2
- exonware/xwsystem/structures/circular_detector.py +15 -14
- exonware/xwsystem/structures/contracts.py +53 -76
- exonware/xwsystem/structures/defs.py +2 -1
- exonware/xwsystem/structures/errors.py +2 -1
- exonware/xwsystem/structures/tree_walker.py +2 -1
- exonware/xwsystem/threading/__init__.py +21 -4
- exonware/xwsystem/threading/async_primitives.py +6 -5
- exonware/xwsystem/threading/base.py +3 -2
- exonware/xwsystem/threading/contracts.py +87 -143
- exonware/xwsystem/threading/defs.py +2 -1
- exonware/xwsystem/threading/errors.py +2 -1
- exonware/xwsystem/threading/facade.py +175 -0
- exonware/xwsystem/threading/locks.py +1 -0
- exonware/xwsystem/threading/safe_factory.py +1 -0
- exonware/xwsystem/utils/__init__.py +40 -0
- exonware/xwsystem/utils/base.py +22 -21
- exonware/xwsystem/utils/contracts.py +50 -73
- exonware/xwsystem/utils/dt/__init__.py +19 -3
- exonware/xwsystem/utils/dt/base.py +5 -4
- exonware/xwsystem/utils/dt/contracts.py +22 -29
- exonware/xwsystem/utils/dt/defs.py +2 -1
- exonware/xwsystem/utils/dt/errors.py +2 -5
- exonware/xwsystem/utils/dt/formatting.py +88 -2
- exonware/xwsystem/utils/dt/humanize.py +10 -9
- exonware/xwsystem/utils/dt/parsing.py +56 -5
- exonware/xwsystem/utils/dt/timezone_utils.py +2 -24
- exonware/xwsystem/utils/errors.py +2 -4
- exonware/xwsystem/utils/paths.py +1 -0
- exonware/xwsystem/utils/string.py +49 -0
- exonware/xwsystem/utils/test_runner.py +185 -0
- exonware/xwsystem/utils/utils_contracts.py +2 -1
- exonware/xwsystem/utils/web.py +110 -0
- exonware/xwsystem/validation/__init__.py +25 -1
- exonware/xwsystem/validation/base.py +6 -5
- exonware/xwsystem/validation/contracts.py +29 -41
- exonware/xwsystem/validation/data_validator.py +1 -0
- exonware/xwsystem/validation/declarative.py +11 -8
- exonware/xwsystem/validation/defs.py +2 -1
- exonware/xwsystem/validation/errors.py +2 -1
- exonware/xwsystem/validation/facade.py +198 -0
- exonware/xwsystem/validation/fluent_validator.py +22 -19
- exonware/xwsystem/validation/schema_discovery.py +210 -0
- exonware/xwsystem/validation/type_safety.py +2 -1
- exonware/xwsystem/version.py +2 -2
- {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/METADATA +71 -4
- exonware_xwsystem-0.1.0.4.dist-info/RECORD +337 -0
- exonware/xwsystem/cli/__init__.py +0 -43
- exonware/xwsystem/cli/console.py +0 -113
- exonware/xwsystem/cli/defs.py +0 -134
- exonware/xwsystem/conf.py +0 -44
- exonware/xwsystem/security/auth.py +0 -484
- exonware_xwsystem-0.1.0.1.dist-info/RECORD +0 -284
- {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/WHEEL +0 -0
- {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/io/serialization/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.
|
|
6
|
+
Version: 0.1.0.4
|
|
6
7
|
Generation Date: November 2, 2025
|
|
7
8
|
|
|
8
9
|
Serialization contracts - ISerialization interface extending ICodec.
|
|
@@ -13,8 +14,7 @@ Following I→A→XW pattern:
|
|
|
13
14
|
- XW: XW{Format}Serializer (concrete implementations)
|
|
14
15
|
"""
|
|
15
16
|
|
|
16
|
-
from
|
|
17
|
-
from typing import Any, Union, Optional, BinaryIO, TextIO, AsyncIterator, Iterator
|
|
17
|
+
from typing import Any, Optional, BinaryIO, TextIO, AsyncIterator, Iterator, Protocol, runtime_checkable
|
|
18
18
|
# Root cause: Migrating to Python 3.12 built-in generic syntax for consistency
|
|
19
19
|
# Priority #3: Maintainability - Modern type annotations improve code clarity
|
|
20
20
|
from pathlib import Path
|
|
@@ -24,15 +24,16 @@ from ..contracts import EncodeOptions, DecodeOptions
|
|
|
24
24
|
from ..defs import CodecCapability
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
@runtime_checkable
|
|
28
|
+
class ISerialization(ICodec[Any, bytes | str], Protocol):
|
|
28
29
|
"""
|
|
29
30
|
Serialization interface extending ICodec.
|
|
30
31
|
|
|
31
32
|
Provides serialization-specific functionality on top of the universal codec interface.
|
|
32
33
|
|
|
33
|
-
Type: ICodec[Any,
|
|
34
|
+
Type: ICodec[Any, bytes | str]
|
|
34
35
|
- T (model type): Any (supports any Python object)
|
|
35
|
-
- R (representation):
|
|
36
|
+
- R (representation): bytes | str (can be text or binary)
|
|
36
37
|
|
|
37
38
|
This interface extends ICodec with:
|
|
38
39
|
- File I/O methods (save_file, load_file)
|
|
@@ -49,63 +50,55 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
49
50
|
# ========================================================================
|
|
50
51
|
|
|
51
52
|
@property
|
|
52
|
-
@abstractmethod
|
|
53
53
|
def format_name(self) -> str:
|
|
54
54
|
"""Get the serialization format name (e.g., 'JSON', 'YAML')."""
|
|
55
|
-
|
|
55
|
+
...
|
|
56
56
|
|
|
57
57
|
@property
|
|
58
|
-
@abstractmethod
|
|
59
58
|
def file_extensions(self) -> list[str]:
|
|
60
59
|
"""Get supported file extensions for this format."""
|
|
61
|
-
|
|
60
|
+
...
|
|
62
61
|
|
|
63
62
|
@property
|
|
64
|
-
@abstractmethod
|
|
65
63
|
def mime_type(self) -> str:
|
|
66
64
|
"""Get the MIME type for this serialization format."""
|
|
67
|
-
|
|
65
|
+
...
|
|
68
66
|
|
|
69
67
|
@property
|
|
70
|
-
@abstractmethod
|
|
71
68
|
def is_binary_format(self) -> bool:
|
|
72
69
|
"""Whether this is a binary or text-based format."""
|
|
73
|
-
|
|
70
|
+
...
|
|
74
71
|
|
|
75
72
|
@property
|
|
76
|
-
@abstractmethod
|
|
77
73
|
def supports_streaming(self) -> bool:
|
|
78
74
|
"""Whether this format supports streaming serialization."""
|
|
79
|
-
|
|
75
|
+
...
|
|
80
76
|
|
|
81
77
|
# ========================================================================
|
|
82
78
|
# CORE CODEC METHODS (from ICodec)
|
|
83
79
|
# ========================================================================
|
|
84
80
|
|
|
85
|
-
|
|
86
|
-
def encode(self, value: Any, *, options: Optional[EncodeOptions] = None) -> Union[bytes, str]:
|
|
81
|
+
def encode(self, value: Any, *, options: Optional[EncodeOptions] = None) -> bytes | str:
|
|
87
82
|
"""
|
|
88
83
|
Encode data to representation (bytes or str).
|
|
89
84
|
|
|
90
85
|
Core codec method - all serializers must implement.
|
|
91
86
|
"""
|
|
92
|
-
|
|
87
|
+
...
|
|
93
88
|
|
|
94
|
-
|
|
95
|
-
def decode(self, repr: Union[bytes, str], *, options: Optional[DecodeOptions] = None) -> Any:
|
|
89
|
+
def decode(self, repr: bytes | str, *, options: Optional[DecodeOptions] = None) -> Any:
|
|
96
90
|
"""
|
|
97
91
|
Decode representation (bytes or str) to data.
|
|
98
92
|
|
|
99
93
|
Core codec method - all serializers must implement.
|
|
100
94
|
"""
|
|
101
|
-
|
|
95
|
+
...
|
|
102
96
|
|
|
103
97
|
# ========================================================================
|
|
104
98
|
# FILE I/O METHODS (Serialization-specific)
|
|
105
99
|
# ========================================================================
|
|
106
100
|
|
|
107
|
-
|
|
108
|
-
def save_file(self, data: Any, file_path: Union[str, Path], **options) -> None:
|
|
101
|
+
def save_file(self, data: Any, file_path: str | Path, **options) -> None:
|
|
109
102
|
"""
|
|
110
103
|
Save data to file with atomic operations.
|
|
111
104
|
|
|
@@ -117,10 +110,9 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
117
110
|
Raises:
|
|
118
111
|
SerializationError: If save fails
|
|
119
112
|
"""
|
|
120
|
-
|
|
113
|
+
...
|
|
121
114
|
|
|
122
|
-
|
|
123
|
-
def load_file(self, file_path: Union[str, Path], **options) -> Any:
|
|
115
|
+
def load_file(self, file_path: str | Path, **options) -> Any:
|
|
124
116
|
"""
|
|
125
117
|
Load data from file.
|
|
126
118
|
|
|
@@ -134,13 +126,12 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
134
126
|
Raises:
|
|
135
127
|
SerializationError: If load fails
|
|
136
128
|
"""
|
|
137
|
-
|
|
129
|
+
...
|
|
138
130
|
|
|
139
131
|
# ========================================================================
|
|
140
132
|
# VALIDATION METHODS
|
|
141
133
|
# ========================================================================
|
|
142
134
|
|
|
143
|
-
@abstractmethod
|
|
144
135
|
def validate_data(self, data: Any) -> bool:
|
|
145
136
|
"""
|
|
146
137
|
Validate data for serialization compatibility.
|
|
@@ -154,14 +145,13 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
154
145
|
Raises:
|
|
155
146
|
SerializationError: If validation fails
|
|
156
147
|
"""
|
|
157
|
-
|
|
148
|
+
...
|
|
158
149
|
|
|
159
150
|
# ========================================================================
|
|
160
151
|
# STREAMING METHODS
|
|
161
152
|
# ========================================================================
|
|
162
153
|
|
|
163
|
-
|
|
164
|
-
def iter_serialize(self, data: Any, chunk_size: int = 8192) -> Iterator[Union[str, bytes]]:
|
|
154
|
+
def iter_serialize(self, data: Any, chunk_size: int = 8192) -> Iterator[str | bytes]:
|
|
165
155
|
"""
|
|
166
156
|
Stream serialize data in chunks.
|
|
167
157
|
|
|
@@ -172,10 +162,9 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
172
162
|
Yields:
|
|
173
163
|
Serialized chunks
|
|
174
164
|
"""
|
|
175
|
-
|
|
165
|
+
...
|
|
176
166
|
|
|
177
|
-
|
|
178
|
-
def iter_deserialize(self, src: Union[TextIO, BinaryIO, Iterator[Union[str, bytes]]]) -> Any:
|
|
167
|
+
def iter_deserialize(self, src: TextIO | BinaryIO | Iterator[str | bytes]) -> Any:
|
|
179
168
|
"""
|
|
180
169
|
Stream deserialize data from chunks.
|
|
181
170
|
|
|
@@ -185,14 +174,13 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
185
174
|
Returns:
|
|
186
175
|
Deserialized data
|
|
187
176
|
"""
|
|
188
|
-
|
|
177
|
+
...
|
|
189
178
|
|
|
190
179
|
# ========================================================================
|
|
191
180
|
# ASYNC METHODS
|
|
192
181
|
# ========================================================================
|
|
193
182
|
|
|
194
|
-
|
|
195
|
-
async def save_file_async(self, data: Any, file_path: Union[str, Path], **options) -> None:
|
|
183
|
+
async def save_file_async(self, data: Any, file_path: str | Path, **options) -> None:
|
|
196
184
|
"""
|
|
197
185
|
Async save data to file.
|
|
198
186
|
|
|
@@ -201,10 +189,9 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
201
189
|
file_path: Path to save file
|
|
202
190
|
**options: Format-specific options
|
|
203
191
|
"""
|
|
204
|
-
|
|
192
|
+
...
|
|
205
193
|
|
|
206
|
-
|
|
207
|
-
async def load_file_async(self, file_path: Union[str, Path], **options) -> Any:
|
|
194
|
+
async def load_file_async(self, file_path: str | Path, **options) -> Any:
|
|
208
195
|
"""
|
|
209
196
|
Async load data from file.
|
|
210
197
|
|
|
@@ -215,10 +202,9 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
215
202
|
Returns:
|
|
216
203
|
Deserialized data
|
|
217
204
|
"""
|
|
218
|
-
|
|
205
|
+
...
|
|
219
206
|
|
|
220
|
-
|
|
221
|
-
async def stream_serialize(self, data: Any, chunk_size: int = 8192) -> AsyncIterator[Union[str, bytes]]:
|
|
207
|
+
async def stream_serialize(self, data: Any, chunk_size: int = 8192) -> AsyncIterator[str | bytes]:
|
|
222
208
|
"""
|
|
223
209
|
Async stream serialize data in chunks.
|
|
224
210
|
|
|
@@ -229,10 +215,9 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
229
215
|
Yields:
|
|
230
216
|
Serialized chunks
|
|
231
217
|
"""
|
|
232
|
-
|
|
218
|
+
...
|
|
233
219
|
|
|
234
|
-
|
|
235
|
-
async def stream_deserialize(self, data_stream: AsyncIterator[Union[str, bytes]]) -> Any:
|
|
220
|
+
async def stream_deserialize(self, data_stream: AsyncIterator[str | bytes]) -> Any:
|
|
236
221
|
"""
|
|
237
222
|
Async stream deserialize data from chunks.
|
|
238
223
|
|
|
@@ -242,16 +227,15 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
242
227
|
Returns:
|
|
243
228
|
Deserialized data
|
|
244
229
|
"""
|
|
245
|
-
|
|
230
|
+
...
|
|
246
231
|
|
|
247
232
|
# ========================================================================
|
|
248
233
|
# ADVANCED FEATURES (Optional - format-specific implementations)
|
|
249
234
|
# ========================================================================
|
|
250
235
|
|
|
251
|
-
@abstractmethod
|
|
252
236
|
def atomic_update_path(
|
|
253
237
|
self,
|
|
254
|
-
file_path:
|
|
238
|
+
file_path: str | Path,
|
|
255
239
|
path: str,
|
|
256
240
|
value: Any,
|
|
257
241
|
**options
|
|
@@ -277,12 +261,11 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
277
261
|
Example:
|
|
278
262
|
>>> serializer.atomic_update_path("config.json", "/database/host", "localhost")
|
|
279
263
|
"""
|
|
280
|
-
|
|
264
|
+
...
|
|
281
265
|
|
|
282
|
-
@abstractmethod
|
|
283
266
|
def atomic_read_path(
|
|
284
267
|
self,
|
|
285
|
-
file_path:
|
|
268
|
+
file_path: str | Path,
|
|
286
269
|
path: str,
|
|
287
270
|
**options
|
|
288
271
|
) -> Any:
|
|
@@ -310,9 +293,8 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
310
293
|
Example:
|
|
311
294
|
>>> host = serializer.atomic_read_path("config.json", "/database/host")
|
|
312
295
|
"""
|
|
313
|
-
|
|
296
|
+
...
|
|
314
297
|
|
|
315
|
-
@abstractmethod
|
|
316
298
|
def validate_with_schema(
|
|
317
299
|
self,
|
|
318
300
|
data: Any,
|
|
@@ -334,13 +316,12 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
334
316
|
NotImplementedError: If this format doesn't support schema validation
|
|
335
317
|
SerializationError: If validation fails
|
|
336
318
|
"""
|
|
337
|
-
|
|
319
|
+
...
|
|
338
320
|
|
|
339
|
-
@abstractmethod
|
|
340
321
|
def incremental_save(
|
|
341
322
|
self,
|
|
342
323
|
items: Iterator[Any],
|
|
343
|
-
file_path:
|
|
324
|
+
file_path: str | Path,
|
|
344
325
|
**options
|
|
345
326
|
) -> None:
|
|
346
327
|
"""
|
|
@@ -358,12 +339,11 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
358
339
|
NotImplementedError: If this format doesn't support incremental streaming
|
|
359
340
|
SerializationError: If save operation fails
|
|
360
341
|
"""
|
|
361
|
-
|
|
342
|
+
...
|
|
362
343
|
|
|
363
|
-
@abstractmethod
|
|
364
344
|
def incremental_load(
|
|
365
345
|
self,
|
|
366
|
-
file_path:
|
|
346
|
+
file_path: str | Path,
|
|
367
347
|
**options
|
|
368
348
|
) -> Iterator[Any]:
|
|
369
349
|
"""
|
|
@@ -383,12 +363,11 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
383
363
|
NotImplementedError: If this format doesn't support incremental streaming
|
|
384
364
|
SerializationError: If load operation fails
|
|
385
365
|
"""
|
|
386
|
-
|
|
366
|
+
...
|
|
387
367
|
|
|
388
|
-
@abstractmethod
|
|
389
368
|
def query(
|
|
390
369
|
self,
|
|
391
|
-
file_path:
|
|
370
|
+
file_path: str | Path,
|
|
392
371
|
query_expr: str,
|
|
393
372
|
**options
|
|
394
373
|
) -> Any:
|
|
@@ -410,12 +389,11 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
410
389
|
SerializationError: If query operation fails
|
|
411
390
|
ValueError: If query expression is invalid
|
|
412
391
|
"""
|
|
413
|
-
|
|
392
|
+
...
|
|
414
393
|
|
|
415
|
-
@abstractmethod
|
|
416
394
|
def merge(
|
|
417
395
|
self,
|
|
418
|
-
file_path:
|
|
396
|
+
file_path: str | Path,
|
|
419
397
|
updates: dict[str, Any],
|
|
420
398
|
**options
|
|
421
399
|
) -> None:
|
|
@@ -433,7 +411,7 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
433
411
|
NotImplementedError: If this format doesn't support merge operations
|
|
434
412
|
SerializationError: If merge operation fails
|
|
435
413
|
"""
|
|
436
|
-
|
|
414
|
+
...
|
|
437
415
|
|
|
438
416
|
# ========================================================================
|
|
439
417
|
# RECORD-LEVEL OPERATIONS (Optional, generic defaults in ASerialization)
|
|
@@ -441,7 +419,7 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
441
419
|
|
|
442
420
|
def stream_read_record(
|
|
443
421
|
self,
|
|
444
|
-
file_path:
|
|
422
|
+
file_path: str | Path,
|
|
445
423
|
match: callable,
|
|
446
424
|
projection: Optional[list[Any]] = None,
|
|
447
425
|
**options: Any,
|
|
@@ -463,7 +441,7 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
463
441
|
|
|
464
442
|
def stream_update_record(
|
|
465
443
|
self,
|
|
466
|
-
file_path:
|
|
444
|
+
file_path: str | Path,
|
|
467
445
|
match: callable,
|
|
468
446
|
updater: callable,
|
|
469
447
|
*,
|
|
@@ -486,7 +464,7 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
486
464
|
|
|
487
465
|
def get_record_page(
|
|
488
466
|
self,
|
|
489
|
-
file_path:
|
|
467
|
+
file_path: str | Path,
|
|
490
468
|
page_number: int,
|
|
491
469
|
page_size: int,
|
|
492
470
|
**options: Any,
|
|
@@ -507,7 +485,7 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
507
485
|
|
|
508
486
|
def get_record_by_id(
|
|
509
487
|
self,
|
|
510
|
-
file_path:
|
|
488
|
+
file_path: str | Path,
|
|
511
489
|
id_value: Any,
|
|
512
490
|
*,
|
|
513
491
|
id_field: str = "id",
|
|
@@ -521,4 +499,3 @@ class ISerialization(ICodec[Any, Union[bytes, str]]):
|
|
|
521
499
|
linear scan over a top-level list.
|
|
522
500
|
"""
|
|
523
501
|
raise NotImplementedError
|
|
524
|
-
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
+
#exonware/xwsystem/src/exonware/xwsystem/io/serialization/defs.py
|
|
2
3
|
#exonware/xwsystem/serialization/types.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.
|
|
8
|
+
Version: 0.1.0.4
|
|
8
9
|
Generation Date: 07-Sep-2025
|
|
9
10
|
|
|
10
11
|
Serialization types and enums for XWSystem.
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/io/serialization/errors.py
|
|
1
2
|
#exonware/xwsystem/serialization/errors.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.
|
|
7
|
+
Version: 0.1.0.4
|
|
7
8
|
Generation Date: September 04, 2025
|
|
8
9
|
|
|
9
10
|
Error classes for XWSystem serialization module.
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/io/serialization/flyweight.py
|
|
1
2
|
#exonware\xwsystem\serialization\flyweight.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.
|
|
7
|
+
Version: 0.1.0.4
|
|
7
8
|
Generation Date: September 05, 2025
|
|
8
9
|
|
|
9
10
|
Flyweight Pattern Implementation for Serializers
|
|
@@ -14,7 +15,7 @@ configuration, which is especially important for high-throughput applications.
|
|
|
14
15
|
"""
|
|
15
16
|
|
|
16
17
|
import threading
|
|
17
|
-
from typing import Any, Hashable, Optional
|
|
18
|
+
from typing import Any, Hashable, Optional
|
|
18
19
|
# Root cause: Migrating to Python 3.12 built-in generic syntax for consistency
|
|
19
20
|
# Priority #3: Maintainability - Modern type annotations improve code clarity
|
|
20
21
|
from weakref import WeakValueDictionary
|
|
@@ -172,7 +173,10 @@ class SerializerFlyweight:
|
|
|
172
173
|
_serializer_flyweight = SerializerFlyweight()
|
|
173
174
|
|
|
174
175
|
|
|
175
|
-
def get_serializer[T: ISerialization](
|
|
176
|
+
def get_serializer[T: ISerialization](
|
|
177
|
+
serializer_class_or_name: type[T] | str,
|
|
178
|
+
**config: Any
|
|
179
|
+
) -> T:
|
|
176
180
|
"""
|
|
177
181
|
Get a serializer instance using the flyweight pattern.
|
|
178
182
|
|
|
@@ -180,22 +184,165 @@ def get_serializer[T: ISerialization](serializer_class: type[T], **config: Any)
|
|
|
180
184
|
automatic memory optimization through instance sharing.
|
|
181
185
|
|
|
182
186
|
Args:
|
|
183
|
-
|
|
187
|
+
serializer_class_or_name: The serializer class to instantiate, or a string
|
|
188
|
+
format name (e.g., "json", "yaml", "toml")
|
|
184
189
|
**config: Configuration parameters for the serializer
|
|
185
190
|
|
|
186
191
|
Returns:
|
|
187
192
|
Shared serializer instance
|
|
188
|
-
|
|
193
|
+
|
|
189
194
|
Example:
|
|
190
195
|
>>> from xwsystem.serialization import JsonSerializer
|
|
191
196
|
>>> # These will return the same instance
|
|
192
197
|
>>> json1 = get_serializer(JsonSerializer, validate_input=True)
|
|
193
198
|
>>> json2 = get_serializer(JsonSerializer, validate_input=True)
|
|
194
199
|
>>> assert json1 is json2 # Same instance
|
|
200
|
+
>>>
|
|
201
|
+
>>> # Can also use string format name
|
|
202
|
+
>>> json3 = get_serializer("json")
|
|
203
|
+
>>> json4 = get_serializer("json")
|
|
204
|
+
>>> assert json3 is json4 # Same instance
|
|
205
|
+
>>> assert json1 is json3 # Same instance (if config matches)
|
|
195
206
|
"""
|
|
207
|
+
# If string format name is provided, resolve to serializer class
|
|
208
|
+
if isinstance(serializer_class_or_name, str):
|
|
209
|
+
serializer_class = _get_serializer_class_from_name(serializer_class_or_name)
|
|
210
|
+
else:
|
|
211
|
+
serializer_class = serializer_class_or_name
|
|
212
|
+
|
|
196
213
|
return _serializer_flyweight.get_serializer(serializer_class, **config)
|
|
197
214
|
|
|
198
215
|
|
|
216
|
+
def _get_serializer_class_from_name(format_name: str) -> type[ISerialization]:
|
|
217
|
+
"""
|
|
218
|
+
Get serializer class from format name string.
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
format_name: Format name (e.g., "json", "yaml", "toml")
|
|
222
|
+
|
|
223
|
+
Returns:
|
|
224
|
+
Serializer class
|
|
225
|
+
|
|
226
|
+
Raises:
|
|
227
|
+
ValueError: If format is not supported
|
|
228
|
+
"""
|
|
229
|
+
# Import here to avoid circular imports
|
|
230
|
+
# Import from formats.text, formats.binary, formats.database packages
|
|
231
|
+
from .formats.text import (
|
|
232
|
+
JsonSerializer, YamlSerializer, TomlSerializer, XmlSerializer,
|
|
233
|
+
CsvSerializer, ConfigParserSerializer, FormDataSerializer,
|
|
234
|
+
MultipartSerializer, Json5Serializer, JsonLinesSerializer
|
|
235
|
+
)
|
|
236
|
+
from .formats.binary import (
|
|
237
|
+
PickleSerializer, MarshalSerializer, BsonSerializer,
|
|
238
|
+
MsgPackSerializer, CborSerializer, PlistSerializer
|
|
239
|
+
)
|
|
240
|
+
from .formats.database import (
|
|
241
|
+
DbmSerializer, ShelveSerializer, Sqlite3Serializer
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
# Core formats (17+ formats)
|
|
245
|
+
format_map = {
|
|
246
|
+
'json': JsonSerializer,
|
|
247
|
+
'yaml': YamlSerializer,
|
|
248
|
+
'toml': TomlSerializer,
|
|
249
|
+
'xml': XmlSerializer,
|
|
250
|
+
'csv': CsvSerializer,
|
|
251
|
+
'ini': ConfigParserSerializer,
|
|
252
|
+
'configparser': ConfigParserSerializer,
|
|
253
|
+
'pickle': PickleSerializer,
|
|
254
|
+
'marshal': MarshalSerializer,
|
|
255
|
+
'bson': BsonSerializer,
|
|
256
|
+
'msgpack': MsgPackSerializer,
|
|
257
|
+
'cbor': CborSerializer,
|
|
258
|
+
'dbm': DbmSerializer,
|
|
259
|
+
'shelve': ShelveSerializer,
|
|
260
|
+
'plist': PlistSerializer,
|
|
261
|
+
'formdata': FormDataSerializer,
|
|
262
|
+
'multipart': MultipartSerializer,
|
|
263
|
+
'json5': Json5Serializer,
|
|
264
|
+
'jsonl': JsonLinesSerializer,
|
|
265
|
+
'jsonlines': JsonLinesSerializer,
|
|
266
|
+
'ndjson': JsonLinesSerializer,
|
|
267
|
+
'sqlite3': Sqlite3Serializer,
|
|
268
|
+
'sqlite': Sqlite3Serializer,
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
# Check for enterprise formats (available in xwformats)
|
|
272
|
+
enterprise_formats = {
|
|
273
|
+
'avro', 'protobuf', 'thrift', 'parquet', 'orc', 'capnproto', 'flatbuffers',
|
|
274
|
+
'hdf5', 'feather', 'zarr', 'netcdf', 'mat',
|
|
275
|
+
'lmdb', 'graphdb', 'leveldb', 'ubjson'
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
format_lower = format_name.lower()
|
|
279
|
+
|
|
280
|
+
if format_lower in enterprise_formats:
|
|
281
|
+
# Try to get from xwformats registry
|
|
282
|
+
from ..codec.registry import get_registry
|
|
283
|
+
registry = get_registry()
|
|
284
|
+
codec = (registry.get_by_id(format_lower) or
|
|
285
|
+
registry.get_by_id(format_name.lower()) or
|
|
286
|
+
registry.get_by_id(format_name.upper()) or
|
|
287
|
+
registry.get_by_alias(format_lower) or
|
|
288
|
+
registry.get_by_alias(format_name.lower()) or
|
|
289
|
+
registry.get_by_alias(format_name.upper()))
|
|
290
|
+
|
|
291
|
+
if codec:
|
|
292
|
+
# Check if codec implements ISerialization (has dumps/loads)
|
|
293
|
+
if hasattr(codec, 'dumps') and hasattr(codec, 'loads'):
|
|
294
|
+
return type(codec)
|
|
295
|
+
else:
|
|
296
|
+
raise ValueError(
|
|
297
|
+
f"Format '{format_name}' found in registry but doesn't implement ISerialization. "
|
|
298
|
+
f"Use the codec directly or ensure it's a full serializer implementation."
|
|
299
|
+
)
|
|
300
|
+
else:
|
|
301
|
+
raise ValueError(
|
|
302
|
+
f"Enterprise format '{format_name}' requires exonware-xwformats.\n"
|
|
303
|
+
f"Install with: pip install exonware-xwformats\n"
|
|
304
|
+
f"Or use lazy install: pip install exonware-xwsystem[lazy]\n"
|
|
305
|
+
f"Then import: from exonware.xwformats import {format_name.capitalize()}Serializer"
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
serializer_class = format_map.get(format_lower)
|
|
309
|
+
if not serializer_class:
|
|
310
|
+
# Check UniversalCodecRegistry for auto-registered formats (like XWJSON)
|
|
311
|
+
# XWJSON and other formats auto-register themselves when their modules are imported
|
|
312
|
+
try:
|
|
313
|
+
from ..codec.registry import get_registry
|
|
314
|
+
registry = get_registry()
|
|
315
|
+
# Try format name as-is, then lowercase, then uppercase, then aliases
|
|
316
|
+
codec = (registry.get_by_id(format_lower) or
|
|
317
|
+
registry.get_by_id(format_name.lower()) or
|
|
318
|
+
registry.get_by_id(format_name.upper()) or
|
|
319
|
+
registry.get_by_alias(format_lower) or
|
|
320
|
+
registry.get_by_alias(format_name.lower()) or
|
|
321
|
+
registry.get_by_alias(format_name.upper()))
|
|
322
|
+
|
|
323
|
+
if codec:
|
|
324
|
+
# Check if codec implements ISerialization (has dumps/loads or load_file/save_file)
|
|
325
|
+
if hasattr(codec, 'load_file') and hasattr(codec, 'save_file'):
|
|
326
|
+
# This is a full ISerialization implementation (like XWJSONSerializer)
|
|
327
|
+
return type(codec)
|
|
328
|
+
elif hasattr(codec, 'dumps') and hasattr(codec, 'loads'):
|
|
329
|
+
# This is a full ISerialization implementation
|
|
330
|
+
return type(codec)
|
|
331
|
+
except Exception:
|
|
332
|
+
# Registry not available or format not found, continue to error
|
|
333
|
+
pass
|
|
334
|
+
|
|
335
|
+
available_formats = list(format_map.keys())
|
|
336
|
+
raise ValueError(
|
|
337
|
+
f"Unsupported format: {format_name}. "
|
|
338
|
+
f"Available core formats: {', '.join(sorted(available_formats))}\n"
|
|
339
|
+
f"Enterprise formats available in exonware-xwformats: {', '.join(sorted(enterprise_formats))}\n"
|
|
340
|
+
f"Auto-registered formats (XWJSON, etc.) should be available via UniversalCodecRegistry"
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
return serializer_class
|
|
344
|
+
|
|
345
|
+
|
|
199
346
|
def get_flyweight_stats() -> dict[str, Any]:
|
|
200
347
|
"""
|
|
201
348
|
Get flyweight usage statistics.
|
|
@@ -334,7 +481,7 @@ def create_serializer(format_name: str, **config: Any) -> ISerialization:
|
|
|
334
481
|
ValueError: If format is not supported
|
|
335
482
|
"""
|
|
336
483
|
# Import here to avoid circular imports
|
|
337
|
-
# Core formats (
|
|
484
|
+
# Core formats (stdlib)
|
|
338
485
|
from . import (
|
|
339
486
|
JsonSerializer, YamlSerializer, TomlSerializer, XmlSerializer,
|
|
340
487
|
CsvSerializer, ConfigParserSerializer, PickleSerializer, MarshalSerializer,
|
|
@@ -344,7 +491,7 @@ def create_serializer(format_name: str, **config: Any) -> ISerialization:
|
|
|
344
491
|
)
|
|
345
492
|
|
|
346
493
|
# NOTE: Enterprise formats moved to exonware-xwformats per DEV_GUIDELINES.md
|
|
347
|
-
# Users
|
|
494
|
+
# Users explicitly import from xwformats:
|
|
348
495
|
# from exonware.xwformats import AvroSerializer, ProtobufSerializer, ...
|
|
349
496
|
# Then use them directly or via registry
|
|
350
497
|
|