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
|
@@ -0,0 +1,1180 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/io/contracts_1.py
|
|
2
|
+
"""
|
|
3
|
+
Company: eXonware.com
|
|
4
|
+
Author: Eng. Muhammad AlShehri
|
|
5
|
+
Email: connect@exonware.com
|
|
6
|
+
Version: 0.1.0.3
|
|
7
|
+
Generation Date: September 04, 2025
|
|
8
|
+
|
|
9
|
+
IO module contracts - interfaces and enums for input/output operations.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from typing import (
|
|
15
|
+
Protocol,
|
|
16
|
+
runtime_checkable,
|
|
17
|
+
Any,
|
|
18
|
+
Optional,
|
|
19
|
+
Union,
|
|
20
|
+
BinaryIO,
|
|
21
|
+
TextIO,
|
|
22
|
+
Callable,
|
|
23
|
+
Iterator,
|
|
24
|
+
AsyncGenerator
|
|
25
|
+
)
|
|
26
|
+
from typing_extensions import TypeAlias
|
|
27
|
+
from pathlib import Path
|
|
28
|
+
|
|
29
|
+
# Import enums from types module
|
|
30
|
+
from .defs import (
|
|
31
|
+
FileMode,
|
|
32
|
+
FileType,
|
|
33
|
+
PathType,
|
|
34
|
+
OperationResult,
|
|
35
|
+
LockType,
|
|
36
|
+
CodecCapability,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# ============================================================================
|
|
40
|
+
# BASE CODEC INTERFACES (Moved up for TypeAlias resolution)
|
|
41
|
+
# ============================================================================
|
|
42
|
+
|
|
43
|
+
EncodeOptions: TypeAlias = dict[str, Any]
|
|
44
|
+
DecodeOptions: TypeAlias = dict[str, Any]
|
|
45
|
+
|
|
46
|
+
@runtime_checkable
|
|
47
|
+
class ICodec[T, R](Protocol):
|
|
48
|
+
"""
|
|
49
|
+
Universal codec interface for bidirectional transformation.
|
|
50
|
+
|
|
51
|
+
Type Parameters:
|
|
52
|
+
T: Model type (e.g., dict, AST, dataclass)
|
|
53
|
+
R: Representation type (bytes or str)
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
def encode(self, value: T, *, options: Optional[EncodeOptions] = None) -> R:
|
|
57
|
+
"""Encode a model to its representation."""
|
|
58
|
+
...
|
|
59
|
+
|
|
60
|
+
def decode(self, repr: R, *, options: Optional[DecodeOptions] = None) -> T:
|
|
61
|
+
"""Decode a representation to a model."""
|
|
62
|
+
...
|
|
63
|
+
|
|
64
|
+
@runtime_checkable
|
|
65
|
+
class ICodecMetadata(Protocol):
|
|
66
|
+
"""Metadata protocol for codec discovery and registration."""
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def codec_id(self) -> str:
|
|
70
|
+
"""Unique codec identifier (e.g., 'json', 'sql')."""
|
|
71
|
+
...
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def media_types(self) -> list[str]:
|
|
75
|
+
"""Supported media types / content types (RFC 2046)."""
|
|
76
|
+
...
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def file_extensions(self) -> list[str]:
|
|
80
|
+
"""Supported file extensions (e.g., ['.json'])."""
|
|
81
|
+
...
|
|
82
|
+
|
|
83
|
+
@property
|
|
84
|
+
def aliases(self) -> list[str]:
|
|
85
|
+
"""Alternative names for this codec."""
|
|
86
|
+
...
|
|
87
|
+
|
|
88
|
+
def capabilities(self) -> CodecCapability:
|
|
89
|
+
"""Get capabilities supported by this codec."""
|
|
90
|
+
...
|
|
91
|
+
|
|
92
|
+
# ============================================================================
|
|
93
|
+
# TYPE ALIASES
|
|
94
|
+
# ============================================================================
|
|
95
|
+
|
|
96
|
+
Serializer: TypeAlias = ICodec[Any, bytes]
|
|
97
|
+
Formatter: TypeAlias = ICodec[Any, str]
|
|
98
|
+
|
|
99
|
+
# ============================================================================
|
|
100
|
+
# PATH INTERFACES
|
|
101
|
+
# ============================================================================
|
|
102
|
+
|
|
103
|
+
@runtime_checkable
|
|
104
|
+
class IPath(Protocol):
|
|
105
|
+
"""
|
|
106
|
+
Interface for path operations with both static and instance methods.
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
@staticmethod
|
|
110
|
+
def normalize(path: PathType) -> Path:
|
|
111
|
+
"""Normalize path."""
|
|
112
|
+
...
|
|
113
|
+
|
|
114
|
+
@staticmethod
|
|
115
|
+
def resolve(path: PathType) -> Path:
|
|
116
|
+
"""Resolve path."""
|
|
117
|
+
...
|
|
118
|
+
|
|
119
|
+
@staticmethod
|
|
120
|
+
def absolute(path: PathType) -> Path:
|
|
121
|
+
"""Get absolute path."""
|
|
122
|
+
...
|
|
123
|
+
|
|
124
|
+
@staticmethod
|
|
125
|
+
def relative(path: PathType, start: Optional[PathType] = None) -> Path:
|
|
126
|
+
"""Get relative path."""
|
|
127
|
+
...
|
|
128
|
+
|
|
129
|
+
@staticmethod
|
|
130
|
+
def join(*paths: PathType) -> Path:
|
|
131
|
+
"""Join paths."""
|
|
132
|
+
...
|
|
133
|
+
|
|
134
|
+
@staticmethod
|
|
135
|
+
def split(path: PathType) -> tuple[Path, str]:
|
|
136
|
+
"""Split path into directory and filename."""
|
|
137
|
+
...
|
|
138
|
+
|
|
139
|
+
@staticmethod
|
|
140
|
+
def get_extension(path: PathType) -> str:
|
|
141
|
+
"""Get file extension."""
|
|
142
|
+
...
|
|
143
|
+
|
|
144
|
+
@staticmethod
|
|
145
|
+
def get_stem(path: PathType) -> str:
|
|
146
|
+
"""Get file stem (name without extension)."""
|
|
147
|
+
...
|
|
148
|
+
|
|
149
|
+
@staticmethod
|
|
150
|
+
def get_name(path: PathType) -> str:
|
|
151
|
+
"""Get file/directory name."""
|
|
152
|
+
...
|
|
153
|
+
|
|
154
|
+
@staticmethod
|
|
155
|
+
def get_parent(path: PathType) -> Path:
|
|
156
|
+
"""Get parent directory."""
|
|
157
|
+
...
|
|
158
|
+
|
|
159
|
+
@staticmethod
|
|
160
|
+
def is_absolute(path: PathType) -> bool:
|
|
161
|
+
"""Check if path is absolute."""
|
|
162
|
+
...
|
|
163
|
+
|
|
164
|
+
@staticmethod
|
|
165
|
+
def is_relative(path: PathType) -> bool:
|
|
166
|
+
"""Check if path is relative."""
|
|
167
|
+
...
|
|
168
|
+
|
|
169
|
+
@staticmethod
|
|
170
|
+
def get_parts(path: PathType) -> tuple:
|
|
171
|
+
"""Get path parts."""
|
|
172
|
+
...
|
|
173
|
+
|
|
174
|
+
@staticmethod
|
|
175
|
+
def match(path: PathType, pattern: str) -> bool:
|
|
176
|
+
"""Check if path matches pattern."""
|
|
177
|
+
...
|
|
178
|
+
|
|
179
|
+
@staticmethod
|
|
180
|
+
def with_suffix(path: PathType, suffix: str) -> Path:
|
|
181
|
+
"""Get path with new suffix."""
|
|
182
|
+
...
|
|
183
|
+
|
|
184
|
+
@staticmethod
|
|
185
|
+
def with_name(path: PathType, name: str) -> Path:
|
|
186
|
+
"""Get path with new name."""
|
|
187
|
+
...
|
|
188
|
+
|
|
189
|
+
@runtime_checkable
|
|
190
|
+
class IPathValidator(Protocol):
|
|
191
|
+
"""Interface for path validation and security checks."""
|
|
192
|
+
|
|
193
|
+
def validate_path(self, path: PathType) -> bool:
|
|
194
|
+
"""Validate path safety."""
|
|
195
|
+
...
|
|
196
|
+
|
|
197
|
+
def is_safe_path(self, path: PathType) -> bool:
|
|
198
|
+
"""Check if path is safe to use."""
|
|
199
|
+
...
|
|
200
|
+
|
|
201
|
+
def normalize_path(self, path: PathType) -> Path:
|
|
202
|
+
"""Normalize and resolve path."""
|
|
203
|
+
...
|
|
204
|
+
|
|
205
|
+
# ============================================================================
|
|
206
|
+
# STREAM & ASYNC INTERFACES
|
|
207
|
+
# ============================================================================
|
|
208
|
+
|
|
209
|
+
@runtime_checkable
|
|
210
|
+
class IStream(Protocol):
|
|
211
|
+
"""Interface for stream operations."""
|
|
212
|
+
|
|
213
|
+
# Instance Methods
|
|
214
|
+
def read(self, size: Optional[int] = None) -> str | bytes:
|
|
215
|
+
"""Read from stream."""
|
|
216
|
+
...
|
|
217
|
+
|
|
218
|
+
def write(self, data: str | bytes) -> int:
|
|
219
|
+
"""Write to stream."""
|
|
220
|
+
...
|
|
221
|
+
|
|
222
|
+
def seek(self, position: int, whence: int = 0) -> int:
|
|
223
|
+
"""Seek stream position."""
|
|
224
|
+
...
|
|
225
|
+
|
|
226
|
+
def tell(self) -> int:
|
|
227
|
+
"""Get current stream position."""
|
|
228
|
+
...
|
|
229
|
+
|
|
230
|
+
def flush(self) -> None:
|
|
231
|
+
"""Flush stream buffer."""
|
|
232
|
+
...
|
|
233
|
+
|
|
234
|
+
def close(self) -> None:
|
|
235
|
+
"""Close stream."""
|
|
236
|
+
...
|
|
237
|
+
|
|
238
|
+
# Static Methods
|
|
239
|
+
@staticmethod
|
|
240
|
+
def open_file(path: PathType, mode: str = 'r', encoding: Optional[str] = None) -> TextIO | BinaryIO:
|
|
241
|
+
"""Open file as stream."""
|
|
242
|
+
...
|
|
243
|
+
|
|
244
|
+
@staticmethod
|
|
245
|
+
def is_closed(stream: TextIO | BinaryIO) -> bool:
|
|
246
|
+
"""Check if stream is closed."""
|
|
247
|
+
...
|
|
248
|
+
|
|
249
|
+
@staticmethod
|
|
250
|
+
def readable(stream: TextIO | BinaryIO) -> bool:
|
|
251
|
+
"""Check if stream is readable."""
|
|
252
|
+
...
|
|
253
|
+
|
|
254
|
+
@staticmethod
|
|
255
|
+
def writable(stream: TextIO | BinaryIO) -> bool:
|
|
256
|
+
"""Check if stream is writable."""
|
|
257
|
+
...
|
|
258
|
+
|
|
259
|
+
@staticmethod
|
|
260
|
+
def seekable(stream: TextIO | BinaryIO) -> bool:
|
|
261
|
+
"""Check if stream is seekable."""
|
|
262
|
+
...
|
|
263
|
+
|
|
264
|
+
@runtime_checkable
|
|
265
|
+
class IAsyncIO(Protocol):
|
|
266
|
+
"""Interface for async I/O operations."""
|
|
267
|
+
|
|
268
|
+
# Instance Methods
|
|
269
|
+
async def aread(self, size: Optional[int] = None) -> str | bytes:
|
|
270
|
+
"""Async read operation."""
|
|
271
|
+
...
|
|
272
|
+
|
|
273
|
+
async def awrite(self, data: str | bytes) -> int:
|
|
274
|
+
"""Async write operation."""
|
|
275
|
+
...
|
|
276
|
+
|
|
277
|
+
async def aseek(self, position: int, whence: int = 0) -> int:
|
|
278
|
+
"""Async seek operation."""
|
|
279
|
+
...
|
|
280
|
+
|
|
281
|
+
async def atell(self) -> int:
|
|
282
|
+
"""Async tell operation."""
|
|
283
|
+
...
|
|
284
|
+
|
|
285
|
+
async def aflush(self) -> None:
|
|
286
|
+
"""Async flush operation."""
|
|
287
|
+
...
|
|
288
|
+
|
|
289
|
+
async def aclose(self) -> None:
|
|
290
|
+
"""Async close operation."""
|
|
291
|
+
...
|
|
292
|
+
|
|
293
|
+
# Static Methods
|
|
294
|
+
@staticmethod
|
|
295
|
+
async def aopen_file(path: PathType, mode: str = 'r', encoding: Optional[str] = None) -> Any:
|
|
296
|
+
"""Async open file."""
|
|
297
|
+
...
|
|
298
|
+
|
|
299
|
+
@staticmethod
|
|
300
|
+
async def aread_text(path: PathType, encoding: str = 'utf-8') -> str:
|
|
301
|
+
"""Async read text file."""
|
|
302
|
+
...
|
|
303
|
+
|
|
304
|
+
@staticmethod
|
|
305
|
+
async def aread_bytes(path: PathType) -> bytes:
|
|
306
|
+
"""Async read binary file."""
|
|
307
|
+
...
|
|
308
|
+
|
|
309
|
+
@staticmethod
|
|
310
|
+
async def awrite_text(path: PathType, content: str, encoding: str = 'utf-8') -> bool:
|
|
311
|
+
"""Async write text to file."""
|
|
312
|
+
...
|
|
313
|
+
|
|
314
|
+
@staticmethod
|
|
315
|
+
async def awrite_bytes(path: PathType, content: bytes) -> bool:
|
|
316
|
+
"""Async write bytes to file."""
|
|
317
|
+
...
|
|
318
|
+
|
|
319
|
+
# ============================================================================
|
|
320
|
+
# FILE SYSTEM INTERFACES
|
|
321
|
+
# ============================================================================
|
|
322
|
+
|
|
323
|
+
@runtime_checkable
|
|
324
|
+
class IFile(Protocol):
|
|
325
|
+
"""
|
|
326
|
+
Interface for file operations with both static and instance methods.
|
|
327
|
+
"""
|
|
328
|
+
|
|
329
|
+
# Instance Methods
|
|
330
|
+
def open(self, mode: FileMode = FileMode.READ) -> None:
|
|
331
|
+
"""Open file with specified mode."""
|
|
332
|
+
...
|
|
333
|
+
|
|
334
|
+
def read(self, size: Optional[int] = None) -> str | bytes:
|
|
335
|
+
"""Read from file."""
|
|
336
|
+
...
|
|
337
|
+
|
|
338
|
+
def write(self, data: str | bytes) -> int:
|
|
339
|
+
"""Write to file."""
|
|
340
|
+
...
|
|
341
|
+
|
|
342
|
+
def close(self) -> None:
|
|
343
|
+
"""Close file."""
|
|
344
|
+
...
|
|
345
|
+
|
|
346
|
+
def save(self, data: Any, **kwargs) -> bool:
|
|
347
|
+
"""Save data to file."""
|
|
348
|
+
...
|
|
349
|
+
|
|
350
|
+
def load(self, **kwargs) -> Any:
|
|
351
|
+
"""Load data from file."""
|
|
352
|
+
...
|
|
353
|
+
|
|
354
|
+
def save_as(self, path: PathType, data: Any, **kwargs) -> bool:
|
|
355
|
+
"""Save data to specific path."""
|
|
356
|
+
...
|
|
357
|
+
|
|
358
|
+
def to_file(self, path: PathType, **kwargs) -> bool:
|
|
359
|
+
"""Write current object to file."""
|
|
360
|
+
...
|
|
361
|
+
|
|
362
|
+
def from_file(self, path: PathType, **kwargs) -> IFile:
|
|
363
|
+
"""Load object from file."""
|
|
364
|
+
...
|
|
365
|
+
|
|
366
|
+
# Static Methods
|
|
367
|
+
@staticmethod
|
|
368
|
+
def exists(path: PathType) -> bool:
|
|
369
|
+
"""Check if file exists."""
|
|
370
|
+
...
|
|
371
|
+
|
|
372
|
+
@staticmethod
|
|
373
|
+
def size(path: PathType) -> int:
|
|
374
|
+
"""Get file size."""
|
|
375
|
+
...
|
|
376
|
+
|
|
377
|
+
@staticmethod
|
|
378
|
+
def delete(path: PathType) -> bool:
|
|
379
|
+
"""Delete file."""
|
|
380
|
+
...
|
|
381
|
+
|
|
382
|
+
@staticmethod
|
|
383
|
+
def copy(source: PathType, destination: PathType) -> bool:
|
|
384
|
+
"""Copy file."""
|
|
385
|
+
...
|
|
386
|
+
|
|
387
|
+
@staticmethod
|
|
388
|
+
def move(source: PathType, destination: PathType) -> bool:
|
|
389
|
+
"""Move file."""
|
|
390
|
+
...
|
|
391
|
+
|
|
392
|
+
@staticmethod
|
|
393
|
+
def rename(old_path: PathType, new_path: PathType) -> bool:
|
|
394
|
+
"""Rename file."""
|
|
395
|
+
...
|
|
396
|
+
|
|
397
|
+
@staticmethod
|
|
398
|
+
def get_modified_time(path: PathType) -> float:
|
|
399
|
+
"""Get file modification time."""
|
|
400
|
+
...
|
|
401
|
+
|
|
402
|
+
@staticmethod
|
|
403
|
+
def get_created_time(path: PathType) -> float:
|
|
404
|
+
"""Get file creation time."""
|
|
405
|
+
...
|
|
406
|
+
|
|
407
|
+
@staticmethod
|
|
408
|
+
def get_permissions(path: PathType) -> int:
|
|
409
|
+
"""Get file permissions."""
|
|
410
|
+
...
|
|
411
|
+
|
|
412
|
+
@staticmethod
|
|
413
|
+
def is_readable(path: PathType) -> bool:
|
|
414
|
+
"""Check if file is readable."""
|
|
415
|
+
...
|
|
416
|
+
|
|
417
|
+
@staticmethod
|
|
418
|
+
def is_writable(path: PathType) -> bool:
|
|
419
|
+
"""Check if file is writable."""
|
|
420
|
+
...
|
|
421
|
+
|
|
422
|
+
@staticmethod
|
|
423
|
+
def is_executable(path: PathType) -> bool:
|
|
424
|
+
"""Check if file is executable."""
|
|
425
|
+
...
|
|
426
|
+
|
|
427
|
+
@staticmethod
|
|
428
|
+
def read_text(path: PathType, encoding: str = 'utf-8') -> str:
|
|
429
|
+
"""Read file as text."""
|
|
430
|
+
...
|
|
431
|
+
|
|
432
|
+
@staticmethod
|
|
433
|
+
def read_bytes(path: PathType) -> bytes:
|
|
434
|
+
"""Read file as bytes."""
|
|
435
|
+
...
|
|
436
|
+
|
|
437
|
+
@staticmethod
|
|
438
|
+
def write_text(path: PathType, content: str, encoding: str = 'utf-8') -> bool:
|
|
439
|
+
"""Write text to file."""
|
|
440
|
+
...
|
|
441
|
+
|
|
442
|
+
@staticmethod
|
|
443
|
+
def write_bytes(path: PathType, content: bytes) -> bool:
|
|
444
|
+
"""Write bytes to file."""
|
|
445
|
+
...
|
|
446
|
+
|
|
447
|
+
@staticmethod
|
|
448
|
+
def safe_read_text(path: PathType, encoding: str = 'utf-8') -> Optional[str]:
|
|
449
|
+
"""Safely read text file, returning None on error."""
|
|
450
|
+
...
|
|
451
|
+
|
|
452
|
+
@staticmethod
|
|
453
|
+
def safe_read_bytes(path: PathType) -> Optional[bytes]:
|
|
454
|
+
"""Safely read binary file, returning None on error."""
|
|
455
|
+
...
|
|
456
|
+
|
|
457
|
+
@staticmethod
|
|
458
|
+
def safe_write_text(path: PathType, content: str, encoding: str = 'utf-8') -> bool:
|
|
459
|
+
"""Safely write text to file."""
|
|
460
|
+
...
|
|
461
|
+
|
|
462
|
+
@staticmethod
|
|
463
|
+
def safe_write_bytes(path: PathType, content: bytes) -> bool:
|
|
464
|
+
"""Safely write bytes to file."""
|
|
465
|
+
...
|
|
466
|
+
|
|
467
|
+
# Static Utility Methods (File Manager Features)
|
|
468
|
+
@staticmethod
|
|
469
|
+
def atomic_write(file_path: PathType, data: str | bytes,
|
|
470
|
+
backup: bool = True) -> OperationResult:
|
|
471
|
+
"""Atomically write data to file (static version)."""
|
|
472
|
+
...
|
|
473
|
+
|
|
474
|
+
@staticmethod
|
|
475
|
+
def atomic_copy(source: PathType, destination: PathType) -> OperationResult:
|
|
476
|
+
"""Atomically copy file (static version)."""
|
|
477
|
+
...
|
|
478
|
+
|
|
479
|
+
@staticmethod
|
|
480
|
+
def atomic_move(source: PathType, destination: PathType) -> OperationResult:
|
|
481
|
+
"""Atomically move file (static version)."""
|
|
482
|
+
...
|
|
483
|
+
|
|
484
|
+
@staticmethod
|
|
485
|
+
def atomic_delete(file_path: PathType, backup: bool = True) -> OperationResult:
|
|
486
|
+
"""Atomically delete file (static version)."""
|
|
487
|
+
...
|
|
488
|
+
|
|
489
|
+
@staticmethod
|
|
490
|
+
def create_backup(source: PathType, backup_dir: PathType) -> Optional[Path]:
|
|
491
|
+
"""Create backup of file (static version)."""
|
|
492
|
+
...
|
|
493
|
+
|
|
494
|
+
@staticmethod
|
|
495
|
+
def restore_backup(backup_path: PathType, target: PathType) -> OperationResult:
|
|
496
|
+
"""Restore from backup (static version)."""
|
|
497
|
+
...
|
|
498
|
+
|
|
499
|
+
@staticmethod
|
|
500
|
+
def create_temp_file(suffix: Optional[str] = None, prefix: Optional[str] = None) -> Path:
|
|
501
|
+
"""Create temporary file (static version)."""
|
|
502
|
+
...
|
|
503
|
+
|
|
504
|
+
@staticmethod
|
|
505
|
+
def create_temp_directory(suffix: Optional[str] = None, prefix: Optional[str] = None) -> Path:
|
|
506
|
+
"""Create temporary directory (static version)."""
|
|
507
|
+
...
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
@runtime_checkable
|
|
511
|
+
class IFolder(Protocol):
|
|
512
|
+
"""
|
|
513
|
+
Interface for folder/directory operations.
|
|
514
|
+
"""
|
|
515
|
+
|
|
516
|
+
# Instance Methods
|
|
517
|
+
def create(self, parents: bool = True, exist_ok: bool = True) -> bool:
|
|
518
|
+
"""Create directory."""
|
|
519
|
+
...
|
|
520
|
+
|
|
521
|
+
def delete(self, recursive: bool = False) -> bool:
|
|
522
|
+
"""Delete directory."""
|
|
523
|
+
...
|
|
524
|
+
|
|
525
|
+
def list_files(self, pattern: Optional[str] = None, recursive: bool = False) -> list[Path]:
|
|
526
|
+
"""List files in directory."""
|
|
527
|
+
...
|
|
528
|
+
|
|
529
|
+
def list_directories(self, recursive: bool = False) -> list[Path]:
|
|
530
|
+
"""List subdirectories."""
|
|
531
|
+
...
|
|
532
|
+
|
|
533
|
+
def walk(self) -> list[tuple[Path, list[str], list[str]]]:
|
|
534
|
+
"""Walk directory tree."""
|
|
535
|
+
...
|
|
536
|
+
|
|
537
|
+
def get_size(self) -> int:
|
|
538
|
+
"""Get directory size."""
|
|
539
|
+
...
|
|
540
|
+
|
|
541
|
+
def is_empty(self) -> bool:
|
|
542
|
+
"""Check if directory is empty."""
|
|
543
|
+
...
|
|
544
|
+
|
|
545
|
+
def copy_to(self, destination: PathType) -> bool:
|
|
546
|
+
"""Copy directory to destination."""
|
|
547
|
+
...
|
|
548
|
+
|
|
549
|
+
def move_to(self, destination: PathType) -> bool:
|
|
550
|
+
"""Move directory to destination."""
|
|
551
|
+
...
|
|
552
|
+
|
|
553
|
+
# Static Methods
|
|
554
|
+
@staticmethod
|
|
555
|
+
def exists(path: PathType) -> bool:
|
|
556
|
+
"""Check if directory exists."""
|
|
557
|
+
...
|
|
558
|
+
|
|
559
|
+
@staticmethod
|
|
560
|
+
def create_dir(path: PathType, parents: bool = True, exist_ok: bool = True) -> bool:
|
|
561
|
+
"""Create directory."""
|
|
562
|
+
...
|
|
563
|
+
|
|
564
|
+
@staticmethod
|
|
565
|
+
def delete_dir(path: PathType, recursive: bool = False) -> bool:
|
|
566
|
+
"""Delete directory."""
|
|
567
|
+
...
|
|
568
|
+
|
|
569
|
+
@staticmethod
|
|
570
|
+
def list_files_static(path: PathType, pattern: Optional[str] = None, recursive: bool = False) -> list[Path]:
|
|
571
|
+
"""List files in directory."""
|
|
572
|
+
...
|
|
573
|
+
|
|
574
|
+
@staticmethod
|
|
575
|
+
def list_directories_static(path: PathType, recursive: bool = False) -> list[Path]:
|
|
576
|
+
"""List subdirectories."""
|
|
577
|
+
...
|
|
578
|
+
|
|
579
|
+
@staticmethod
|
|
580
|
+
def walk_static(path: PathType) -> list[tuple[Path, list[str], list[str]]]:
|
|
581
|
+
"""Walk directory tree."""
|
|
582
|
+
...
|
|
583
|
+
|
|
584
|
+
@staticmethod
|
|
585
|
+
def get_size_static(path: PathType) -> int:
|
|
586
|
+
"""Get directory size."""
|
|
587
|
+
...
|
|
588
|
+
|
|
589
|
+
@staticmethod
|
|
590
|
+
def is_empty_static(path: PathType) -> bool:
|
|
591
|
+
"""Check if directory is empty."""
|
|
592
|
+
...
|
|
593
|
+
|
|
594
|
+
@staticmethod
|
|
595
|
+
def copy_dir(source: PathType, destination: PathType) -> bool:
|
|
596
|
+
"""Copy directory."""
|
|
597
|
+
...
|
|
598
|
+
|
|
599
|
+
@staticmethod
|
|
600
|
+
def move_dir(source: PathType, destination: PathType) -> bool:
|
|
601
|
+
"""Move directory."""
|
|
602
|
+
...
|
|
603
|
+
|
|
604
|
+
@staticmethod
|
|
605
|
+
def get_permissions(path: PathType) -> int:
|
|
606
|
+
"""Get directory permissions."""
|
|
607
|
+
...
|
|
608
|
+
|
|
609
|
+
@staticmethod
|
|
610
|
+
def is_readable(path: PathType) -> bool:
|
|
611
|
+
"""Check if directory is readable."""
|
|
612
|
+
...
|
|
613
|
+
|
|
614
|
+
@staticmethod
|
|
615
|
+
def is_writable(path: PathType) -> bool:
|
|
616
|
+
"""Check if directory is writable."""
|
|
617
|
+
...
|
|
618
|
+
|
|
619
|
+
@staticmethod
|
|
620
|
+
def is_executable(path: PathType) -> bool:
|
|
621
|
+
"""Check if directory is executable."""
|
|
622
|
+
...
|
|
623
|
+
|
|
624
|
+
# ============================================================================
|
|
625
|
+
# SYSTEM UTILITY INTERFACES (Watcher, Lock, VirtualFS)
|
|
626
|
+
# ============================================================================
|
|
627
|
+
|
|
628
|
+
@runtime_checkable
|
|
629
|
+
class IFileWatcher(Protocol):
|
|
630
|
+
"""Interface for watching file system changes."""
|
|
631
|
+
|
|
632
|
+
def watch(self, path: PathType) -> None:
|
|
633
|
+
"""Start watching a path."""
|
|
634
|
+
...
|
|
635
|
+
|
|
636
|
+
def stop(self) -> None:
|
|
637
|
+
"""Stop watching."""
|
|
638
|
+
...
|
|
639
|
+
|
|
640
|
+
@runtime_checkable
|
|
641
|
+
class IFileLock(Protocol):
|
|
642
|
+
"""Interface for file locking."""
|
|
643
|
+
|
|
644
|
+
def acquire(self) -> bool:
|
|
645
|
+
"""Acquire the lock."""
|
|
646
|
+
...
|
|
647
|
+
|
|
648
|
+
def release(self) -> None:
|
|
649
|
+
"""Release the lock."""
|
|
650
|
+
...
|
|
651
|
+
|
|
652
|
+
@runtime_checkable
|
|
653
|
+
class IVirtualFS(Protocol):
|
|
654
|
+
"""Interface for virtual filesystem operations."""
|
|
655
|
+
|
|
656
|
+
@property
|
|
657
|
+
def scheme(self) -> str:
|
|
658
|
+
"""URI scheme."""
|
|
659
|
+
...
|
|
660
|
+
|
|
661
|
+
def exists(self, path: str) -> bool:
|
|
662
|
+
"""Check if path exists."""
|
|
663
|
+
...
|
|
664
|
+
|
|
665
|
+
def is_file(self, path: str) -> bool:
|
|
666
|
+
"""Check if path is file."""
|
|
667
|
+
...
|
|
668
|
+
|
|
669
|
+
def read(self, path: str) -> bytes:
|
|
670
|
+
"""Read file contents."""
|
|
671
|
+
...
|
|
672
|
+
|
|
673
|
+
def write(self, path: str, data: bytes) -> None:
|
|
674
|
+
"""Write file contents."""
|
|
675
|
+
...
|
|
676
|
+
|
|
677
|
+
# ============================================================================
|
|
678
|
+
# ADVANCED OPERATION INTERFACES (Atomic, Backup, Temp)
|
|
679
|
+
# ============================================================================
|
|
680
|
+
|
|
681
|
+
@runtime_checkable
|
|
682
|
+
class IAtomicOperations(Protocol):
|
|
683
|
+
"""Interface for atomic operations."""
|
|
684
|
+
|
|
685
|
+
# Instance Methods
|
|
686
|
+
def atomic_write(self, file_path: PathType, data: str | bytes,
|
|
687
|
+
backup: bool = True) -> OperationResult:
|
|
688
|
+
"""Atomically write data to file."""
|
|
689
|
+
...
|
|
690
|
+
|
|
691
|
+
def atomic_copy(self, source: PathType, destination: PathType) -> OperationResult:
|
|
692
|
+
"""Atomically copy file."""
|
|
693
|
+
...
|
|
694
|
+
|
|
695
|
+
def atomic_move(self, source: PathType, destination: PathType) -> OperationResult:
|
|
696
|
+
"""Atomically move file."""
|
|
697
|
+
...
|
|
698
|
+
|
|
699
|
+
def atomic_delete(self, file_path: PathType, backup: bool = True) -> OperationResult:
|
|
700
|
+
"""Atomically delete file."""
|
|
701
|
+
...
|
|
702
|
+
|
|
703
|
+
def atomic_rename(self, old_path: PathType, new_path: PathType) -> OperationResult:
|
|
704
|
+
"""Atomically rename file."""
|
|
705
|
+
...
|
|
706
|
+
|
|
707
|
+
# Static Methods
|
|
708
|
+
@staticmethod
|
|
709
|
+
def atomic_write_static(file_path: PathType, data: str | bytes,
|
|
710
|
+
backup: bool = True) -> OperationResult:
|
|
711
|
+
"""Atomically write data to file."""
|
|
712
|
+
...
|
|
713
|
+
|
|
714
|
+
@staticmethod
|
|
715
|
+
def atomic_copy_static(source: PathType, destination: PathType) -> OperationResult:
|
|
716
|
+
"""Atomically copy file."""
|
|
717
|
+
...
|
|
718
|
+
|
|
719
|
+
@staticmethod
|
|
720
|
+
def atomic_move_static(source: PathType, destination: PathType) -> OperationResult:
|
|
721
|
+
"""Atomically move file."""
|
|
722
|
+
...
|
|
723
|
+
|
|
724
|
+
@staticmethod
|
|
725
|
+
def atomic_delete_static(file_path: PathType, backup: bool = True) -> OperationResult:
|
|
726
|
+
"""Atomically delete file."""
|
|
727
|
+
...
|
|
728
|
+
|
|
729
|
+
@staticmethod
|
|
730
|
+
def atomic_rename_static(old_path: PathType, new_path: PathType) -> OperationResult:
|
|
731
|
+
"""Atomically rename file."""
|
|
732
|
+
...
|
|
733
|
+
|
|
734
|
+
@runtime_checkable
|
|
735
|
+
class IAtomicWriter(Protocol):
|
|
736
|
+
"""Interface for atomic file write context manager."""
|
|
737
|
+
|
|
738
|
+
def write(self, data: bytes) -> int:
|
|
739
|
+
"""Write data atomically."""
|
|
740
|
+
...
|
|
741
|
+
|
|
742
|
+
def __enter__(self) -> IAtomicWriter:
|
|
743
|
+
"""Enter context manager."""
|
|
744
|
+
...
|
|
745
|
+
|
|
746
|
+
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
|
|
747
|
+
"""Exit context manager."""
|
|
748
|
+
...
|
|
749
|
+
|
|
750
|
+
@runtime_checkable
|
|
751
|
+
class IBackupOperations(Protocol):
|
|
752
|
+
"""Interface for backup operations."""
|
|
753
|
+
|
|
754
|
+
# Instance Methods
|
|
755
|
+
def create_backup(self, source: PathType, backup_dir: PathType) -> Optional[Path]:
|
|
756
|
+
"""Create backup of file or directory."""
|
|
757
|
+
...
|
|
758
|
+
|
|
759
|
+
def restore_backup(self, backup_path: PathType, target: PathType) -> OperationResult:
|
|
760
|
+
"""Restore from backup."""
|
|
761
|
+
...
|
|
762
|
+
|
|
763
|
+
def list_backups(self, backup_dir: PathType) -> list[Path]:
|
|
764
|
+
"""List available backups."""
|
|
765
|
+
...
|
|
766
|
+
|
|
767
|
+
def cleanup_backups(self, backup_dir: PathType, max_age_days: int = 30) -> int:
|
|
768
|
+
"""Cleanup old backups."""
|
|
769
|
+
...
|
|
770
|
+
|
|
771
|
+
def verify_backup(self, backup_path: PathType) -> bool:
|
|
772
|
+
"""Verify backup integrity."""
|
|
773
|
+
...
|
|
774
|
+
|
|
775
|
+
# Static Methods
|
|
776
|
+
@staticmethod
|
|
777
|
+
def create_backup_static(source: PathType, backup_dir: PathType) -> Optional[Path]:
|
|
778
|
+
"""Create backup of file or directory."""
|
|
779
|
+
...
|
|
780
|
+
|
|
781
|
+
@staticmethod
|
|
782
|
+
def restore_backup_static(backup_path: PathType, target: PathType) -> OperationResult:
|
|
783
|
+
"""Restore from backup."""
|
|
784
|
+
...
|
|
785
|
+
|
|
786
|
+
@staticmethod
|
|
787
|
+
def list_backups_static(backup_dir: PathType) -> list[Path]:
|
|
788
|
+
"""List available backups."""
|
|
789
|
+
...
|
|
790
|
+
|
|
791
|
+
@staticmethod
|
|
792
|
+
def cleanup_backups_static(backup_dir: PathType, max_age_days: int = 30) -> int:
|
|
793
|
+
"""Cleanup old backups."""
|
|
794
|
+
...
|
|
795
|
+
|
|
796
|
+
@staticmethod
|
|
797
|
+
def verify_backup_static(backup_path: PathType) -> bool:
|
|
798
|
+
"""Verify backup integrity."""
|
|
799
|
+
...
|
|
800
|
+
|
|
801
|
+
@runtime_checkable
|
|
802
|
+
class ITemporaryOperations(Protocol):
|
|
803
|
+
"""Interface for temporary operations."""
|
|
804
|
+
|
|
805
|
+
# Instance Methods
|
|
806
|
+
def create_temp_file(self, suffix: Optional[str] = None, prefix: Optional[str] = None) -> Path:
|
|
807
|
+
"""Create temporary file."""
|
|
808
|
+
...
|
|
809
|
+
|
|
810
|
+
def create_temp_directory(self, suffix: Optional[str] = None, prefix: Optional[str] = None) -> Path:
|
|
811
|
+
"""Create temporary directory."""
|
|
812
|
+
...
|
|
813
|
+
|
|
814
|
+
def cleanup_temp(self, path: PathType) -> bool:
|
|
815
|
+
"""Cleanup temporary file or directory."""
|
|
816
|
+
...
|
|
817
|
+
|
|
818
|
+
def cleanup_all_temp(self) -> int:
|
|
819
|
+
"""Cleanup all temporary files and directories."""
|
|
820
|
+
...
|
|
821
|
+
|
|
822
|
+
# Static Methods
|
|
823
|
+
@staticmethod
|
|
824
|
+
def create_temp_file_static(suffix: Optional[str] = None, prefix: Optional[str] = None) -> Path:
|
|
825
|
+
"""Create temporary file."""
|
|
826
|
+
...
|
|
827
|
+
|
|
828
|
+
@staticmethod
|
|
829
|
+
def create_temp_directory_static(suffix: Optional[str] = None, prefix: Optional[str] = None) -> Path:
|
|
830
|
+
"""Create temporary directory."""
|
|
831
|
+
...
|
|
832
|
+
|
|
833
|
+
@staticmethod
|
|
834
|
+
def cleanup_temp_static(path: PathType) -> bool:
|
|
835
|
+
"""Cleanup temporary file or directory."""
|
|
836
|
+
...
|
|
837
|
+
|
|
838
|
+
@staticmethod
|
|
839
|
+
def get_temp_base_dir() -> Path:
|
|
840
|
+
"""Get temporary base directory."""
|
|
841
|
+
...
|
|
842
|
+
|
|
843
|
+
@staticmethod
|
|
844
|
+
def is_temp(path: PathType) -> bool:
|
|
845
|
+
"""Check if path is temporary."""
|
|
846
|
+
...
|
|
847
|
+
|
|
848
|
+
# ============================================================================
|
|
849
|
+
# ARCHIVE & COMPRESSION INTERFACES
|
|
850
|
+
# ============================================================================
|
|
851
|
+
|
|
852
|
+
@runtime_checkable
|
|
853
|
+
class ICompression(Protocol):
|
|
854
|
+
"""
|
|
855
|
+
Interface for raw compression operations (gzip, bz2, lzma, etc.).
|
|
856
|
+
This operates on bytes, not archive file formats.
|
|
857
|
+
"""
|
|
858
|
+
|
|
859
|
+
@property
|
|
860
|
+
def algorithm_id(self) -> str:
|
|
861
|
+
"""Unique algorithm identifier."""
|
|
862
|
+
...
|
|
863
|
+
|
|
864
|
+
@property
|
|
865
|
+
def file_extensions(self) -> list[str]:
|
|
866
|
+
"""Supported file extensions."""
|
|
867
|
+
...
|
|
868
|
+
|
|
869
|
+
def compress(self, data: bytes, **options) -> bytes:
|
|
870
|
+
"""Compress raw bytes."""
|
|
871
|
+
...
|
|
872
|
+
|
|
873
|
+
def decompress(self, data: bytes, **options) -> bytes:
|
|
874
|
+
"""Decompress raw bytes."""
|
|
875
|
+
...
|
|
876
|
+
|
|
877
|
+
def can_handle(self, data: bytes) -> bool:
|
|
878
|
+
"""Check if this compressor can handle the data."""
|
|
879
|
+
...
|
|
880
|
+
|
|
881
|
+
@runtime_checkable
|
|
882
|
+
class IArchiveFormat(Protocol):
|
|
883
|
+
"""
|
|
884
|
+
Interface for archive format handlers (ZIP, TAR, 7Z, RAR).
|
|
885
|
+
"""
|
|
886
|
+
|
|
887
|
+
@property
|
|
888
|
+
def format_id(self) -> str:
|
|
889
|
+
"""Unique format identifier."""
|
|
890
|
+
...
|
|
891
|
+
|
|
892
|
+
@property
|
|
893
|
+
def file_extensions(self) -> list[str]:
|
|
894
|
+
"""Supported file extensions."""
|
|
895
|
+
...
|
|
896
|
+
|
|
897
|
+
@property
|
|
898
|
+
def mime_types(self) -> list[str]:
|
|
899
|
+
"""Supported MIME types."""
|
|
900
|
+
...
|
|
901
|
+
|
|
902
|
+
def create(self, files: list[Path], output: Path, **opts) -> None:
|
|
903
|
+
"""Create archive from files."""
|
|
904
|
+
...
|
|
905
|
+
|
|
906
|
+
def extract(self, archive: Path, output_dir: Path, members: Optional[list[str]] = None, **opts) -> list[Path]:
|
|
907
|
+
"""Extract archive."""
|
|
908
|
+
...
|
|
909
|
+
|
|
910
|
+
def list_contents(self, archive: Path) -> list[str]:
|
|
911
|
+
"""List archive contents."""
|
|
912
|
+
...
|
|
913
|
+
|
|
914
|
+
def add_file(self, archive: Path, file: Path, arcname: Optional[str] = None) -> None:
|
|
915
|
+
"""Add file to existing archive."""
|
|
916
|
+
...
|
|
917
|
+
|
|
918
|
+
@runtime_checkable
|
|
919
|
+
class IArchiveMetadata(Protocol):
|
|
920
|
+
"""Metadata protocol for self-describing archivers."""
|
|
921
|
+
|
|
922
|
+
@property
|
|
923
|
+
def format_id(self) -> str:
|
|
924
|
+
"""Format identifier."""
|
|
925
|
+
...
|
|
926
|
+
|
|
927
|
+
@property
|
|
928
|
+
def file_extensions(self) -> list[str]:
|
|
929
|
+
"""Supported extensions."""
|
|
930
|
+
...
|
|
931
|
+
|
|
932
|
+
@property
|
|
933
|
+
def mime_types(self) -> list[str]:
|
|
934
|
+
"""MIME types."""
|
|
935
|
+
...
|
|
936
|
+
|
|
937
|
+
@property
|
|
938
|
+
def description(self) -> str:
|
|
939
|
+
"""Human-readable description."""
|
|
940
|
+
...
|
|
941
|
+
|
|
942
|
+
class IArchiver[T](ICodec[T, bytes]):
|
|
943
|
+
"""
|
|
944
|
+
Archive codec interface - operates in MEMORY on ANY data.
|
|
945
|
+
Delegates to encode/decode but provides specific archive terminology.
|
|
946
|
+
"""
|
|
947
|
+
|
|
948
|
+
def compress(self, data: T, **options) -> bytes:
|
|
949
|
+
"""Compress data to archive bytes (delegates to encode)."""
|
|
950
|
+
...
|
|
951
|
+
|
|
952
|
+
def extract(self, archive_bytes: bytes, **options) -> T:
|
|
953
|
+
"""Extract archive bytes to data (delegates to decode)."""
|
|
954
|
+
...
|
|
955
|
+
|
|
956
|
+
class IArchiveFile(IFile):
|
|
957
|
+
"""
|
|
958
|
+
Archive FILE interface - operates on DISK.
|
|
959
|
+
Uses IArchiver internally for composition.
|
|
960
|
+
"""
|
|
961
|
+
|
|
962
|
+
def add_files(self, files: list[Path], **options) -> None:
|
|
963
|
+
"""Add files to archive."""
|
|
964
|
+
...
|
|
965
|
+
|
|
966
|
+
def extract_to(self, dest: Path, **options) -> list[Path]:
|
|
967
|
+
"""Extract archive to destination."""
|
|
968
|
+
...
|
|
969
|
+
|
|
970
|
+
def list_contents(self) -> list[str]:
|
|
971
|
+
"""List files in archive."""
|
|
972
|
+
...
|
|
973
|
+
|
|
974
|
+
def get_archiver(self) -> IArchiver:
|
|
975
|
+
"""Get the underlying archiver codec."""
|
|
976
|
+
...
|
|
977
|
+
|
|
978
|
+
# ============================================================================
|
|
979
|
+
# DATA SOURCE INTERFACES
|
|
980
|
+
# ============================================================================
|
|
981
|
+
|
|
982
|
+
@runtime_checkable
|
|
983
|
+
class IDataSource[T](Protocol):
|
|
984
|
+
"""Universal data source interface."""
|
|
985
|
+
|
|
986
|
+
def read(self) -> T:
|
|
987
|
+
"""Read data from source."""
|
|
988
|
+
...
|
|
989
|
+
|
|
990
|
+
def write(self, data: T) -> None:
|
|
991
|
+
"""Write data to source."""
|
|
992
|
+
...
|
|
993
|
+
|
|
994
|
+
@runtime_checkable
|
|
995
|
+
class IPagedDataSource[T](Protocol):
|
|
996
|
+
"""Paged data source interface for large data sets."""
|
|
997
|
+
|
|
998
|
+
def read_page(self, page_number: int) -> list[T]:
|
|
999
|
+
"""Read a specific page of data."""
|
|
1000
|
+
...
|
|
1001
|
+
|
|
1002
|
+
def get_page_count(self) -> int:
|
|
1003
|
+
"""Get total number of pages."""
|
|
1004
|
+
...
|
|
1005
|
+
|
|
1006
|
+
@runtime_checkable
|
|
1007
|
+
class IFileSource(Protocol):
|
|
1008
|
+
"""Interface for file data sources."""
|
|
1009
|
+
|
|
1010
|
+
@property
|
|
1011
|
+
def uri(self) -> str:
|
|
1012
|
+
"""Source URI."""
|
|
1013
|
+
...
|
|
1014
|
+
|
|
1015
|
+
@property
|
|
1016
|
+
def scheme(self) -> str:
|
|
1017
|
+
"""URI scheme."""
|
|
1018
|
+
...
|
|
1019
|
+
|
|
1020
|
+
def read(self, **options) -> bytes | str:
|
|
1021
|
+
"""Read entire file content."""
|
|
1022
|
+
...
|
|
1023
|
+
|
|
1024
|
+
def write(self, data: bytes | str, **options) -> None:
|
|
1025
|
+
"""Write entire content to file."""
|
|
1026
|
+
...
|
|
1027
|
+
|
|
1028
|
+
def exists(self) -> bool:
|
|
1029
|
+
"""Check if file exists."""
|
|
1030
|
+
...
|
|
1031
|
+
|
|
1032
|
+
def delete(self) -> None:
|
|
1033
|
+
"""Delete file."""
|
|
1034
|
+
...
|
|
1035
|
+
|
|
1036
|
+
@runtime_checkable
|
|
1037
|
+
class IPagedSource(Protocol):
|
|
1038
|
+
"""Interface for paged file sources."""
|
|
1039
|
+
|
|
1040
|
+
@property
|
|
1041
|
+
def total_size(self) -> int:
|
|
1042
|
+
"""Total file size in bytes."""
|
|
1043
|
+
...
|
|
1044
|
+
|
|
1045
|
+
def read_page(self, page: int, page_size: int, **options) -> bytes | str:
|
|
1046
|
+
"""Read specific page."""
|
|
1047
|
+
...
|
|
1048
|
+
|
|
1049
|
+
def read_chunk(self, offset: int, size: int, **options) -> bytes | str:
|
|
1050
|
+
"""Read chunk by byte offset."""
|
|
1051
|
+
...
|
|
1052
|
+
|
|
1053
|
+
def iter_pages(self, page_size: int, **options) -> Iterator[bytes | str]:
|
|
1054
|
+
"""Iterate over pages."""
|
|
1055
|
+
...
|
|
1056
|
+
|
|
1057
|
+
def iter_chunks(self, chunk_size: int, **options) -> Iterator[bytes | str]:
|
|
1058
|
+
"""Iterate over chunks."""
|
|
1059
|
+
...
|
|
1060
|
+
|
|
1061
|
+
@runtime_checkable
|
|
1062
|
+
class IPagingStrategy(Protocol):
|
|
1063
|
+
"""Strategy interface for paging through file data."""
|
|
1064
|
+
|
|
1065
|
+
@property
|
|
1066
|
+
def strategy_id(self) -> str:
|
|
1067
|
+
"""Unique strategy identifier."""
|
|
1068
|
+
...
|
|
1069
|
+
|
|
1070
|
+
def read_page(
|
|
1071
|
+
self,
|
|
1072
|
+
file_path: Path,
|
|
1073
|
+
page: int,
|
|
1074
|
+
page_size: int,
|
|
1075
|
+
mode: str = 'rb',
|
|
1076
|
+
encoding: Optional[str] = None,
|
|
1077
|
+
**options
|
|
1078
|
+
) -> bytes | str:
|
|
1079
|
+
"""Read specific page using this strategy."""
|
|
1080
|
+
...
|
|
1081
|
+
|
|
1082
|
+
def iter_pages(
|
|
1083
|
+
self,
|
|
1084
|
+
file_path: Path,
|
|
1085
|
+
page_size: int,
|
|
1086
|
+
mode: str = 'rb',
|
|
1087
|
+
encoding: Optional[str] = None,
|
|
1088
|
+
**options
|
|
1089
|
+
) -> Iterator[bytes | str]:
|
|
1090
|
+
"""Iterate over pages using this strategy."""
|
|
1091
|
+
...
|
|
1092
|
+
|
|
1093
|
+
@runtime_checkable
|
|
1094
|
+
class IFolderSource(Protocol):
|
|
1095
|
+
"""Interface for folder source operations."""
|
|
1096
|
+
|
|
1097
|
+
def create(self, parents: bool = True, exist_ok: bool = True) -> bool:
|
|
1098
|
+
"""Create directory."""
|
|
1099
|
+
...
|
|
1100
|
+
|
|
1101
|
+
def delete(self, recursive: bool = False) -> bool:
|
|
1102
|
+
"""Delete directory."""
|
|
1103
|
+
...
|
|
1104
|
+
|
|
1105
|
+
def list_files(self, pattern: Optional[str] = None, recursive: bool = False) -> list[Path]:
|
|
1106
|
+
"""List files in directory."""
|
|
1107
|
+
...
|
|
1108
|
+
|
|
1109
|
+
# ============================================================================
|
|
1110
|
+
# CODEC-INTEGRATED IO INTERFACES
|
|
1111
|
+
# ============================================================================
|
|
1112
|
+
|
|
1113
|
+
@runtime_checkable
|
|
1114
|
+
class ICodecIO[T, R](Protocol):
|
|
1115
|
+
"""Codec-integrated IO interface with source type T and result type R."""
|
|
1116
|
+
|
|
1117
|
+
def read_as(self, codec: str):
|
|
1118
|
+
"""Read and decode data using specified codec."""
|
|
1119
|
+
...
|
|
1120
|
+
|
|
1121
|
+
def write_as(self, data, codec: str) -> None:
|
|
1122
|
+
"""Encode and write data using specified codec."""
|
|
1123
|
+
...
|
|
1124
|
+
|
|
1125
|
+
@runtime_checkable
|
|
1126
|
+
class IPagedCodecIO[T, R](ICodecIO[T, R]):
|
|
1127
|
+
"""
|
|
1128
|
+
Interface for paged codec I/O.
|
|
1129
|
+
Inherits read_as/write_as from ICodecIO.
|
|
1130
|
+
"""
|
|
1131
|
+
|
|
1132
|
+
def read_page_as(self, page_number: int, codec: str):
|
|
1133
|
+
"""Read and decode a page using specified codec."""
|
|
1134
|
+
...
|
|
1135
|
+
|
|
1136
|
+
def iter_items(self, page_size: int, **opts):
|
|
1137
|
+
"""Iterate over decoded items."""
|
|
1138
|
+
...
|
|
1139
|
+
|
|
1140
|
+
def load_page(self, page: int, page_size: int, **opts) -> list[T]:
|
|
1141
|
+
"""Load specific page."""
|
|
1142
|
+
...
|
|
1143
|
+
|
|
1144
|
+
# ============================================================================
|
|
1145
|
+
# HIGH-LEVEL COMPOSITE INTERFACES
|
|
1146
|
+
# ============================================================================
|
|
1147
|
+
|
|
1148
|
+
class IUnifiedIO(IFile, IFolder, IPath, IStream, IAsyncIO, IAtomicOperations, IBackupOperations, ITemporaryOperations):
|
|
1149
|
+
"""
|
|
1150
|
+
Unified I/O interface combining all existing I/O capabilities.
|
|
1151
|
+
|
|
1152
|
+
Provides complete I/O functionality for any data source, consolidating:
|
|
1153
|
+
- File/Folder/Path operations
|
|
1154
|
+
- Stream/Async operations
|
|
1155
|
+
- Atomic/Backup/Temporary operations
|
|
1156
|
+
"""
|
|
1157
|
+
pass
|
|
1158
|
+
|
|
1159
|
+
class IFileManager(IFile, IFolder, IPath, IAtomicOperations, IBackupOperations, ITemporaryOperations):
|
|
1160
|
+
"""
|
|
1161
|
+
File Manager interface for comprehensive file operations.
|
|
1162
|
+
|
|
1163
|
+
Specifically designed for managing files on disk with support for:
|
|
1164
|
+
- Universal file type support
|
|
1165
|
+
- Intelligent format detection
|
|
1166
|
+
- Atomic/Backup/Temporary safety features
|
|
1167
|
+
"""
|
|
1168
|
+
pass
|
|
1169
|
+
|
|
1170
|
+
@runtime_checkable
|
|
1171
|
+
class IIOManager(Protocol):
|
|
1172
|
+
"""Generic interface for I/O managers."""
|
|
1173
|
+
|
|
1174
|
+
def open(self, **opts):
|
|
1175
|
+
"""Open resource."""
|
|
1176
|
+
...
|
|
1177
|
+
|
|
1178
|
+
def close(self) -> None:
|
|
1179
|
+
"""Close resource."""
|
|
1180
|
+
...
|