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.
- 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.3.dist-info}/METADATA +71 -4
- exonware_xwsystem-0.1.0.3.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.3.dist-info}/WHEEL +0 -0
- {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/io/serialization/formats/text/append_only_log.py
|
|
1
2
|
"""Append-only log for fast atomic updates in JSONL files.
|
|
2
3
|
|
|
3
4
|
This module provides an append-only log system that can be used by
|
|
@@ -12,11 +13,8 @@ import time
|
|
|
12
13
|
from pathlib import Path
|
|
13
14
|
from typing import Any, Callable
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
_parser = get_best_available_parser()
|
|
18
|
-
except ImportError:
|
|
19
|
-
import json as _parser
|
|
16
|
+
from exonware.xwsystem.io.serialization.parsers.registry import get_best_available_parser
|
|
17
|
+
_parser = get_best_available_parser()
|
|
20
18
|
|
|
21
19
|
|
|
22
20
|
class AppendOnlyLog:
|
|
@@ -147,7 +145,7 @@ class AppendOnlyLog:
|
|
|
147
145
|
except Exception:
|
|
148
146
|
pass
|
|
149
147
|
|
|
150
|
-
# Not in log, return None (caller
|
|
148
|
+
# Not in log, return None (caller reads from main file)
|
|
151
149
|
return None
|
|
152
150
|
|
|
153
151
|
def _compact_background(self):
|
|
@@ -197,5 +195,5 @@ def atomic_update_with_append_log(
|
|
|
197
195
|
# Fall through to full rewrite
|
|
198
196
|
pass
|
|
199
197
|
|
|
200
|
-
# Fall back to full rewrite (caller
|
|
198
|
+
# Fall back to full rewrite (caller handles this)
|
|
201
199
|
return 0
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/io/serialization/formats/text/configparser.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.3
|
|
6
7
|
Generation Date: November 2, 2025
|
|
7
8
|
|
|
8
9
|
ConfigParser serialization - INI file format.
|
|
@@ -15,7 +16,7 @@ Following I→A pattern:
|
|
|
15
16
|
|
|
16
17
|
import configparser
|
|
17
18
|
import io
|
|
18
|
-
from typing import Any, Optional
|
|
19
|
+
from typing import Any, Optional
|
|
19
20
|
from pathlib import Path
|
|
20
21
|
|
|
21
22
|
from ...base import ASerialization
|
|
@@ -101,7 +102,7 @@ class ConfigParserSerializer(ASerialization):
|
|
|
101
102
|
# CORE ENCODE/DECODE (Using configparser module)
|
|
102
103
|
# ========================================================================
|
|
103
104
|
|
|
104
|
-
def encode(self, value: Any, *, options: Optional[EncodeOptions] = None) ->
|
|
105
|
+
def encode(self, value: Any, *, options: Optional[EncodeOptions] = None) -> bytes | str:
|
|
105
106
|
"""
|
|
106
107
|
Encode data to INI string.
|
|
107
108
|
|
|
@@ -147,7 +148,7 @@ class ConfigParserSerializer(ASerialization):
|
|
|
147
148
|
original_error=e
|
|
148
149
|
)
|
|
149
150
|
|
|
150
|
-
def decode(self, repr:
|
|
151
|
+
def decode(self, repr: bytes | str, *, options: Optional[DecodeOptions] = None) -> Any:
|
|
151
152
|
"""
|
|
152
153
|
Decode INI string to data.
|
|
153
154
|
|
|
@@ -191,4 +192,3 @@ class ConfigParserSerializer(ASerialization):
|
|
|
191
192
|
format_name=self.format_name,
|
|
192
193
|
original_error=e
|
|
193
194
|
)
|
|
194
|
-
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/io/serialization/formats/text/csv.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.3
|
|
6
7
|
Generation Date: November 2, 2025
|
|
7
8
|
|
|
8
9
|
CSV serialization - Comma-separated values format.
|
|
@@ -15,7 +16,7 @@ Following I→A pattern:
|
|
|
15
16
|
|
|
16
17
|
import csv
|
|
17
18
|
import io
|
|
18
|
-
from typing import Any, Optional
|
|
19
|
+
from typing import Any, Optional
|
|
19
20
|
from pathlib import Path
|
|
20
21
|
|
|
21
22
|
from ...base import ASerialization
|
|
@@ -102,7 +103,7 @@ class CsvSerializer(ASerialization):
|
|
|
102
103
|
# CORE ENCODE/DECODE (Using csv module)
|
|
103
104
|
# ========================================================================
|
|
104
105
|
|
|
105
|
-
def encode(self, value: Any, *, options: Optional[EncodeOptions] = None) ->
|
|
106
|
+
def encode(self, value: Any, *, options: Optional[EncodeOptions] = None) -> bytes | str:
|
|
106
107
|
"""
|
|
107
108
|
Encode data to CSV string.
|
|
108
109
|
|
|
@@ -163,7 +164,7 @@ class CsvSerializer(ASerialization):
|
|
|
163
164
|
original_error=e
|
|
164
165
|
)
|
|
165
166
|
|
|
166
|
-
def decode(self, repr:
|
|
167
|
+
def decode(self, repr: bytes | str, *, options: Optional[DecodeOptions] = None) -> Any:
|
|
167
168
|
"""
|
|
168
169
|
Decode CSV string to data.
|
|
169
170
|
|
|
@@ -210,4 +211,5 @@ class CsvSerializer(ASerialization):
|
|
|
210
211
|
format_name=self.format_name,
|
|
211
212
|
original_error=e
|
|
212
213
|
)
|
|
213
|
-
|
|
214
|
+
|
|
215
|
+
# Note: File operations (save_file, load_file) are inherited from ASerialization base class
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/io/serialization/formats/text/formdata.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.3
|
|
6
7
|
Generation Date: November 2, 2025
|
|
7
8
|
|
|
8
9
|
FormData serialization - URL-encoded form data.
|
|
@@ -14,7 +15,7 @@ Following I→A pattern:
|
|
|
14
15
|
"""
|
|
15
16
|
|
|
16
17
|
from urllib.parse import urlencode, parse_qs
|
|
17
|
-
from typing import Any, Optional
|
|
18
|
+
from typing import Any, Optional
|
|
18
19
|
from pathlib import Path
|
|
19
20
|
|
|
20
21
|
from ...base import ASerialization
|
|
@@ -89,7 +90,7 @@ class FormDataSerializer(ASerialization):
|
|
|
89
90
|
# CORE ENCODE/DECODE (Using urllib.parse)
|
|
90
91
|
# ========================================================================
|
|
91
92
|
|
|
92
|
-
def encode(self, value: Any, *, options: Optional[EncodeOptions] = None) ->
|
|
93
|
+
def encode(self, value: Any, *, options: Optional[EncodeOptions] = None) -> bytes | str:
|
|
93
94
|
"""
|
|
94
95
|
Encode data to form-data string.
|
|
95
96
|
|
|
@@ -129,7 +130,7 @@ class FormDataSerializer(ASerialization):
|
|
|
129
130
|
original_error=e
|
|
130
131
|
)
|
|
131
132
|
|
|
132
|
-
def decode(self, repr:
|
|
133
|
+
def decode(self, repr: bytes | str, *, options: Optional[DecodeOptions] = None) -> Any:
|
|
133
134
|
"""
|
|
134
135
|
Decode form-data string to data.
|
|
135
136
|
|
|
@@ -172,4 +173,3 @@ class FormDataSerializer(ASerialization):
|
|
|
172
173
|
format_name=self.format_name,
|
|
173
174
|
original_error=e
|
|
174
175
|
)
|
|
175
|
-
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/io/serialization/formats/text/json.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.3
|
|
6
7
|
Generation Date: November 2, 2025
|
|
7
8
|
|
|
8
9
|
JSON serialization - Universal, human-readable data interchange format.
|
|
@@ -14,12 +15,12 @@ Following I→A pattern:
|
|
|
14
15
|
"""
|
|
15
16
|
|
|
16
17
|
import json
|
|
17
|
-
from typing import Any, Optional
|
|
18
|
+
from typing import Any, Optional
|
|
18
19
|
from pathlib import Path
|
|
19
20
|
|
|
20
21
|
from ...base import ASerialization
|
|
21
22
|
from ...parsers.registry import get_parser
|
|
22
|
-
from ...parsers.base import
|
|
23
|
+
from ...parsers.base import AJsonParser
|
|
23
24
|
from ....contracts import EncodeOptions, DecodeOptions
|
|
24
25
|
from ....defs import CodecCapability
|
|
25
26
|
from ....errors import SerializationError
|
|
@@ -54,15 +55,22 @@ class JsonSerializer(ASerialization):
|
|
|
54
55
|
>>> user = serializer.load_file("user.json")
|
|
55
56
|
"""
|
|
56
57
|
|
|
57
|
-
def __init__(
|
|
58
|
+
def __init__(
|
|
59
|
+
self,
|
|
60
|
+
parser_name: Optional[str] = None,
|
|
61
|
+
max_depth: Optional[int] = None,
|
|
62
|
+
max_size_mb: Optional[float] = None,
|
|
63
|
+
):
|
|
58
64
|
"""
|
|
59
65
|
Initialize JSON serializer with optional parser selection.
|
|
60
66
|
|
|
61
67
|
Args:
|
|
62
68
|
parser_name: Parser name ("standard", "orjson", or None for auto-detect)
|
|
69
|
+
max_depth: Maximum nesting depth allowed (passed to ASerialization / ACodec)
|
|
70
|
+
max_size_mb: Maximum estimated data size in MB (passed to ASerialization / ACodec)
|
|
63
71
|
"""
|
|
64
|
-
super().__init__()
|
|
65
|
-
self._parser:
|
|
72
|
+
super().__init__(max_depth=max_depth, max_size_mb=max_size_mb)
|
|
73
|
+
self._parser: AJsonParser = get_parser(parser_name)
|
|
66
74
|
|
|
67
75
|
# ========================================================================
|
|
68
76
|
# CODEC METADATA
|
|
@@ -137,7 +145,7 @@ class JsonSerializer(ASerialization):
|
|
|
137
145
|
# CORE ENCODE/DECODE (Using official json library)
|
|
138
146
|
# ========================================================================
|
|
139
147
|
|
|
140
|
-
def encode(self, value: Any, *, options: Optional[EncodeOptions] = None) ->
|
|
148
|
+
def encode(self, value: Any, *, options: Optional[EncodeOptions] = None) -> bytes | str:
|
|
141
149
|
"""
|
|
142
150
|
Encode data to JSON string.
|
|
143
151
|
|
|
@@ -188,7 +196,7 @@ class JsonSerializer(ASerialization):
|
|
|
188
196
|
original_error=e
|
|
189
197
|
)
|
|
190
198
|
|
|
191
|
-
def decode(self, repr:
|
|
199
|
+
def decode(self, repr: bytes | str, *, options: Optional[DecodeOptions] = None) -> Any:
|
|
192
200
|
"""
|
|
193
201
|
Decode JSON string to data.
|
|
194
202
|
|
|
@@ -241,7 +249,7 @@ class JsonSerializer(ASerialization):
|
|
|
241
249
|
|
|
242
250
|
def atomic_update_path(
|
|
243
251
|
self,
|
|
244
|
-
file_path:
|
|
252
|
+
file_path: str | Path,
|
|
245
253
|
path: str,
|
|
246
254
|
value: Any,
|
|
247
255
|
**options
|
|
@@ -282,7 +290,7 @@ class JsonSerializer(ASerialization):
|
|
|
282
290
|
|
|
283
291
|
# Load entire file
|
|
284
292
|
# For large files (10GB+), skip size validation to allow atomic operations
|
|
285
|
-
# Root cause: Large files
|
|
293
|
+
# Root cause: Large files use atomic path operations without full validation
|
|
286
294
|
# Solution: Skip size check for atomic operations (depth check still performed)
|
|
287
295
|
large_file_options = {**options, 'skip_size_check': True}
|
|
288
296
|
data = self.load_file(file_path, **large_file_options)
|
|
@@ -297,12 +305,14 @@ class JsonSerializer(ASerialization):
|
|
|
297
305
|
path_obj.parent.mkdir(parents=True, exist_ok=True)
|
|
298
306
|
|
|
299
307
|
backup = options.get('backup', True)
|
|
300
|
-
|
|
308
|
+
encoding = options.get('encoding', 'utf-8')
|
|
309
|
+
# JSON encode returns str, not bytes - write as text
|
|
310
|
+
with AtomicFileWriter(path_obj, mode='w', encoding=encoding, backup=backup) as writer:
|
|
301
311
|
if isinstance(repr_data, bytes):
|
|
302
|
-
|
|
312
|
+
# If somehow we got bytes, decode first
|
|
313
|
+
writer.write(repr_data.decode(encoding))
|
|
303
314
|
else:
|
|
304
|
-
|
|
305
|
-
writer.write(repr_data.encode(encoding))
|
|
315
|
+
writer.write(repr_data)
|
|
306
316
|
|
|
307
317
|
except (FileNotFoundError, ValueError, KeyError, jsonpointer.JsonPointerException) as e:
|
|
308
318
|
raise
|
|
@@ -315,7 +325,7 @@ class JsonSerializer(ASerialization):
|
|
|
315
325
|
|
|
316
326
|
def atomic_read_path(
|
|
317
327
|
self,
|
|
318
|
-
file_path:
|
|
328
|
+
file_path: str | Path,
|
|
319
329
|
path: str,
|
|
320
330
|
**options
|
|
321
331
|
) -> Any:
|
|
@@ -356,7 +366,7 @@ class JsonSerializer(ASerialization):
|
|
|
356
366
|
|
|
357
367
|
# Load entire file
|
|
358
368
|
# For large files (10GB+), skip size validation to allow atomic operations
|
|
359
|
-
# Root cause: Large files
|
|
369
|
+
# Root cause: Large files use atomic path operations without full validation
|
|
360
370
|
# Solution: Skip size check for atomic operations (depth check still performed)
|
|
361
371
|
large_file_options = {**options, 'skip_size_check': True}
|
|
362
372
|
data = self.load_file(file_path, **large_file_options)
|
|
@@ -377,7 +387,7 @@ class JsonSerializer(ASerialization):
|
|
|
377
387
|
|
|
378
388
|
def query(
|
|
379
389
|
self,
|
|
380
|
-
file_path:
|
|
390
|
+
file_path: str | Path,
|
|
381
391
|
query_expr: str,
|
|
382
392
|
**options
|
|
383
393
|
) -> Any:
|
|
@@ -429,4 +439,3 @@ class JsonSerializer(ASerialization):
|
|
|
429
439
|
format_name=self.format_name,
|
|
430
440
|
original_error=e
|
|
431
441
|
) from e
|
|
432
|
-
|
|
@@ -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.
|
|
7
|
+
Version: 0.1.0.3
|
|
8
8
|
Generation Date: 02-Nov-2025
|
|
9
9
|
|
|
10
10
|
JSON5 Serialization - Extended JSON with Comments and Trailing Commas
|
|
@@ -23,7 +23,7 @@ Priority 4 (Performance): Efficient parsing via json5 library
|
|
|
23
23
|
Priority 5 (Extensibility): Compatible with standard JSON
|
|
24
24
|
"""
|
|
25
25
|
|
|
26
|
-
from typing import Any, Optional
|
|
26
|
+
from typing import Any, Optional
|
|
27
27
|
from pathlib import Path
|
|
28
28
|
|
|
29
29
|
# Lazy import for json5 - the lazy hook will automatically handle ImportError
|
|
@@ -85,6 +85,11 @@ class Json5Serializer(JsonSerializer):
|
|
|
85
85
|
"""Alternative names."""
|
|
86
86
|
return ["json5", "JSON5"]
|
|
87
87
|
|
|
88
|
+
@property
|
|
89
|
+
def format_name(self) -> str:
|
|
90
|
+
"""Format name."""
|
|
91
|
+
return "JSON5"
|
|
92
|
+
|
|
88
93
|
@property
|
|
89
94
|
def codec_types(self) -> list[str]:
|
|
90
95
|
"""JSON5 is a serialization and config format (supports comments)."""
|
|
@@ -133,7 +138,7 @@ class Json5Serializer(JsonSerializer):
|
|
|
133
138
|
original_error=e
|
|
134
139
|
)
|
|
135
140
|
|
|
136
|
-
def decode(self, data:
|
|
141
|
+
def decode(self, data: str | bytes, options: Optional[dict[str, Any]] = None) -> Any:
|
|
137
142
|
"""
|
|
138
143
|
Decode JSON5 string to Python data.
|
|
139
144
|
|
|
@@ -191,4 +196,3 @@ class Json5Serializer(JsonSerializer):
|
|
|
191
196
|
format_name=self.format_name,
|
|
192
197
|
original_error=e
|
|
193
198
|
)
|
|
194
|
-
|
|
@@ -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.
|
|
7
|
+
Version: 0.1.0.3
|
|
8
8
|
Generation Date: 02-Nov-2025
|
|
9
9
|
|
|
10
10
|
JSON Lines (JSONL/NDJSON) Serialization - Newline-Delimited JSON
|
|
@@ -22,13 +22,13 @@ Priority 4 (Performance): Memory-efficient streaming
|
|
|
22
22
|
Priority 5 (Extensibility): Compatible with standard JSON
|
|
23
23
|
"""
|
|
24
24
|
|
|
25
|
-
from typing import Any, Optional
|
|
25
|
+
from typing import Any, Optional
|
|
26
26
|
from pathlib import Path
|
|
27
27
|
import json
|
|
28
28
|
|
|
29
29
|
from .json import JsonSerializer
|
|
30
30
|
from ...parsers.registry import get_parser
|
|
31
|
-
from ...parsers.base import
|
|
31
|
+
from ...parsers.base import AJsonParser
|
|
32
32
|
from ....errors import SerializationError
|
|
33
33
|
from ....common.atomic import AtomicFileWriter
|
|
34
34
|
from exonware.xwsystem.config.logging_setup import get_logger
|
|
@@ -55,12 +55,17 @@ class JsonLinesSerializer(JsonSerializer):
|
|
|
55
55
|
"""
|
|
56
56
|
super().__init__(parser_name=parser_name)
|
|
57
57
|
# Get parser instance for direct use in line-by-line operations
|
|
58
|
-
self._parser:
|
|
58
|
+
self._parser: AJsonParser = get_parser(parser_name)
|
|
59
59
|
|
|
60
60
|
@property
|
|
61
61
|
def codec_id(self) -> str:
|
|
62
62
|
"""Codec identifier."""
|
|
63
|
-
return "jsonl"
|
|
63
|
+
return "jsonl" # Primary ID, but "ndjson" also works via aliases
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def format_name(self) -> str:
|
|
67
|
+
"""Format display name."""
|
|
68
|
+
return "JSONL/NDJSON" # Both names prominently displayed
|
|
64
69
|
|
|
65
70
|
@property
|
|
66
71
|
def media_types(self) -> list[str]:
|
|
@@ -74,8 +79,8 @@ class JsonLinesSerializer(JsonSerializer):
|
|
|
74
79
|
|
|
75
80
|
@property
|
|
76
81
|
def aliases(self) -> list[str]:
|
|
77
|
-
"""Alternative names."""
|
|
78
|
-
return ["jsonl", "JSONL", "ndjson", "NDJSON", "jsonlines"]
|
|
82
|
+
"""Alternative names - NDJSON is a first-class alias."""
|
|
83
|
+
return ["jsonl", "JSONL", "ndjson", "NDJSON", "jsonlines", "JSONLines"]
|
|
79
84
|
|
|
80
85
|
@property
|
|
81
86
|
def codec_types(self) -> list[str]:
|
|
@@ -139,7 +144,7 @@ class JsonLinesSerializer(JsonSerializer):
|
|
|
139
144
|
|
|
140
145
|
return "\n".join(lines)
|
|
141
146
|
|
|
142
|
-
def decode(self, data:
|
|
147
|
+
def decode(self, data: str | bytes, *, options: Optional[dict[str, Any]] = None) -> list[Any]:
|
|
143
148
|
"""
|
|
144
149
|
Decode JSON Lines string to list of Python objects.
|
|
145
150
|
|
|
@@ -171,7 +176,7 @@ class JsonLinesSerializer(JsonSerializer):
|
|
|
171
176
|
|
|
172
177
|
def stream_read_record(
|
|
173
178
|
self,
|
|
174
|
-
file_path:
|
|
179
|
+
file_path: str | Path,
|
|
175
180
|
match: callable,
|
|
176
181
|
projection: Optional[list[Any]] = None,
|
|
177
182
|
**options: Any,
|
|
@@ -202,7 +207,7 @@ class JsonLinesSerializer(JsonSerializer):
|
|
|
202
207
|
|
|
203
208
|
def stream_update_record(
|
|
204
209
|
self,
|
|
205
|
-
file_path:
|
|
210
|
+
file_path: str | Path,
|
|
206
211
|
match: callable,
|
|
207
212
|
updater: callable,
|
|
208
213
|
*,
|
|
@@ -222,7 +227,7 @@ class JsonLinesSerializer(JsonSerializer):
|
|
|
222
227
|
if not path.exists():
|
|
223
228
|
raise FileNotFoundError(f"File not found: {path}")
|
|
224
229
|
|
|
225
|
-
# Check if append-only log
|
|
230
|
+
# Check if append-only log is used
|
|
226
231
|
perf_config = get_performance_config()
|
|
227
232
|
use_append_log = options.get("use_append_log", None)
|
|
228
233
|
if use_append_log is None:
|
|
@@ -335,7 +340,7 @@ class JsonLinesSerializer(JsonSerializer):
|
|
|
335
340
|
|
|
336
341
|
def get_record_page(
|
|
337
342
|
self,
|
|
338
|
-
file_path:
|
|
343
|
+
file_path: str | Path,
|
|
339
344
|
page_number: int,
|
|
340
345
|
page_size: int,
|
|
341
346
|
**options: Any,
|
|
@@ -379,7 +384,7 @@ class JsonLinesSerializer(JsonSerializer):
|
|
|
379
384
|
|
|
380
385
|
def get_record_by_id(
|
|
381
386
|
self,
|
|
382
|
-
file_path:
|
|
387
|
+
file_path: str | Path,
|
|
383
388
|
id_value: Any,
|
|
384
389
|
*,
|
|
385
390
|
id_field: str = "id",
|
|
@@ -407,4 +412,3 @@ class JsonLinesSerializer(JsonSerializer):
|
|
|
407
412
|
return record
|
|
408
413
|
|
|
409
414
|
raise KeyError(f"Record with {id_field}={id_value!r} not found")
|
|
410
|
-
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/io/serialization/formats/text/multipart.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.3
|
|
6
7
|
Generation Date: November 2, 2025
|
|
7
8
|
|
|
8
9
|
Multipart serialization - Multipart form data format.
|
|
@@ -20,7 +21,7 @@ from email import encoders
|
|
|
20
21
|
from email.parser import BytesParser
|
|
21
22
|
from email.policy import default
|
|
22
23
|
import io
|
|
23
|
-
from typing import Any, Optional
|
|
24
|
+
from typing import Any, Optional
|
|
24
25
|
from pathlib import Path
|
|
25
26
|
|
|
26
27
|
from ...base import ASerialization
|
|
@@ -97,7 +98,7 @@ class MultipartSerializer(ASerialization):
|
|
|
97
98
|
# CORE ENCODE/DECODE (Using email.mime modules)
|
|
98
99
|
# ========================================================================
|
|
99
100
|
|
|
100
|
-
def encode(self, value: Any, *, options: Optional[EncodeOptions] = None) ->
|
|
101
|
+
def encode(self, value: Any, *, options: Optional[EncodeOptions] = None) -> bytes | str:
|
|
101
102
|
"""
|
|
102
103
|
Encode data to multipart format.
|
|
103
104
|
|
|
@@ -150,7 +151,7 @@ class MultipartSerializer(ASerialization):
|
|
|
150
151
|
original_error=e
|
|
151
152
|
)
|
|
152
153
|
|
|
153
|
-
def decode(self, repr:
|
|
154
|
+
def decode(self, repr: bytes | str, *, options: Optional[DecodeOptions] = None) -> Any:
|
|
154
155
|
"""
|
|
155
156
|
Decode multipart data.
|
|
156
157
|
|
|
@@ -209,4 +210,3 @@ class MultipartSerializer(ASerialization):
|
|
|
209
210
|
format_name=self.format_name,
|
|
210
211
|
original_error=e
|
|
211
212
|
)
|
|
212
|
-
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/io/serialization/formats/text/toml.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.3
|
|
6
7
|
Generation Date: November 2, 2025
|
|
7
8
|
|
|
8
9
|
TOML serialization - Configuration file format.
|
|
@@ -14,7 +15,7 @@ Following I→A pattern:
|
|
|
14
15
|
"""
|
|
15
16
|
|
|
16
17
|
import sys
|
|
17
|
-
from typing import Any, Optional
|
|
18
|
+
from typing import Any, Optional
|
|
18
19
|
from pathlib import Path
|
|
19
20
|
|
|
20
21
|
from ...base import ASerialization
|
|
@@ -158,7 +159,7 @@ class TomlSerializer(ASerialization):
|
|
|
158
159
|
# Primitive values - return as-is (None will be filtered out by caller)
|
|
159
160
|
return data
|
|
160
161
|
|
|
161
|
-
def encode(self, value: Any, *, options: Optional[EncodeOptions] = None) ->
|
|
162
|
+
def encode(self, value: Any, *, options: Optional[EncodeOptions] = None) -> bytes | str:
|
|
162
163
|
"""
|
|
163
164
|
Encode data to TOML string.
|
|
164
165
|
|
|
@@ -195,7 +196,7 @@ class TomlSerializer(ASerialization):
|
|
|
195
196
|
|
|
196
197
|
# Root cause fixed: Remove None values before encoding (TOML doesn't support None).
|
|
197
198
|
# Solution: Recursively remove None values to ensure TOML compatibility.
|
|
198
|
-
# Priority #2: Usability - All data structures
|
|
199
|
+
# Priority #2: Usability - All data structures are serializable.
|
|
199
200
|
cleaned_value = self._remove_none_values(value)
|
|
200
201
|
|
|
201
202
|
# Encode to TOML string
|
|
@@ -213,7 +214,7 @@ class TomlSerializer(ASerialization):
|
|
|
213
214
|
original_error=e
|
|
214
215
|
)
|
|
215
216
|
|
|
216
|
-
def decode(self, repr:
|
|
217
|
+
def decode(self, repr: bytes | str, *, options: Optional[DecodeOptions] = None) -> Any:
|
|
217
218
|
"""
|
|
218
219
|
Decode TOML string to data.
|
|
219
220
|
|
|
@@ -252,4 +253,5 @@ class TomlSerializer(ASerialization):
|
|
|
252
253
|
format_name=self.format_name,
|
|
253
254
|
original_error=e
|
|
254
255
|
)
|
|
255
|
-
|
|
256
|
+
|
|
257
|
+
# Note: File operations (save_file, load_file) are inherited from ASerialization base class
|