exonware-xwsystem 0.0.1.409__py3-none-any.whl → 0.0.1.411__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 -2
- exonware/conf.py +10 -20
- exonware/xwsystem/__init__.py +6 -16
- exonware/xwsystem/caching/__init__.py +1 -1
- exonware/xwsystem/caching/base.py +16 -16
- exonware/xwsystem/caching/bloom_cache.py +5 -5
- exonware/xwsystem/caching/cache_manager.py +2 -2
- exonware/xwsystem/caching/conditional.py +4 -4
- exonware/xwsystem/caching/contracts.py +12 -12
- exonware/xwsystem/caching/decorators.py +2 -2
- exonware/xwsystem/caching/defs.py +1 -1
- exonware/xwsystem/caching/disk_cache.py +4 -4
- exonware/xwsystem/caching/distributed.py +1 -1
- exonware/xwsystem/caching/errors.py +1 -1
- exonware/xwsystem/caching/events.py +8 -8
- exonware/xwsystem/caching/eviction_strategies.py +9 -9
- exonware/xwsystem/caching/fluent.py +1 -1
- exonware/xwsystem/caching/integrity.py +1 -1
- exonware/xwsystem/caching/lfu_cache.py +24 -9
- exonware/xwsystem/caching/lfu_optimized.py +21 -21
- exonware/xwsystem/caching/lru_cache.py +14 -7
- exonware/xwsystem/caching/memory_bounded.py +8 -8
- exonware/xwsystem/caching/metrics_exporter.py +6 -6
- exonware/xwsystem/caching/observable_cache.py +1 -1
- exonware/xwsystem/caching/pluggable_cache.py +9 -9
- exonware/xwsystem/caching/rate_limiter.py +1 -1
- exonware/xwsystem/caching/read_through.py +6 -6
- exonware/xwsystem/caching/secure_cache.py +1 -1
- exonware/xwsystem/caching/serializable.py +3 -3
- exonware/xwsystem/caching/stats.py +7 -7
- exonware/xwsystem/caching/tagging.py +11 -11
- exonware/xwsystem/caching/ttl_cache.py +21 -6
- exonware/xwsystem/caching/two_tier_cache.py +5 -5
- exonware/xwsystem/caching/utils.py +3 -3
- exonware/xwsystem/caching/validation.py +1 -1
- exonware/xwsystem/caching/warming.py +9 -9
- exonware/xwsystem/caching/write_behind.py +5 -5
- exonware/xwsystem/cli/__init__.py +1 -1
- exonware/xwsystem/cli/args.py +10 -10
- exonware/xwsystem/cli/base.py +15 -15
- exonware/xwsystem/cli/colors.py +1 -1
- exonware/xwsystem/cli/console.py +1 -1
- exonware/xwsystem/cli/contracts.py +5 -5
- exonware/xwsystem/cli/defs.py +1 -1
- exonware/xwsystem/cli/errors.py +1 -1
- exonware/xwsystem/cli/progress.py +1 -1
- exonware/xwsystem/cli/prompts.py +1 -1
- exonware/xwsystem/cli/tables.py +7 -7
- exonware/xwsystem/config/__init__.py +1 -1
- exonware/xwsystem/config/base.py +14 -14
- exonware/xwsystem/config/contracts.py +22 -22
- exonware/xwsystem/config/defaults.py +2 -2
- exonware/xwsystem/config/defs.py +1 -1
- exonware/xwsystem/config/errors.py +2 -2
- exonware/xwsystem/config/logging.py +1 -1
- exonware/xwsystem/config/logging_setup.py +2 -2
- exonware/xwsystem/config/performance.py +7 -7
- exonware/xwsystem/config/performance_modes.py +20 -20
- exonware/xwsystem/config/version_manager.py +4 -4
- exonware/xwsystem/{http → http_client}/__init__.py +1 -1
- exonware/xwsystem/{http → http_client}/advanced_client.py +20 -20
- exonware/xwsystem/{http → http_client}/base.py +13 -13
- exonware/xwsystem/{http → http_client}/client.py +43 -43
- exonware/xwsystem/{http → http_client}/contracts.py +5 -5
- exonware/xwsystem/{http → http_client}/defs.py +2 -2
- exonware/xwsystem/{http → http_client}/errors.py +2 -2
- exonware/xwsystem/io/__init__.py +1 -1
- exonware/xwsystem/io/archive/__init__.py +1 -1
- exonware/xwsystem/io/archive/archive.py +5 -5
- exonware/xwsystem/io/archive/archive_files.py +8 -8
- exonware/xwsystem/io/archive/archivers.py +3 -3
- exonware/xwsystem/io/archive/base.py +17 -17
- exonware/xwsystem/io/archive/codec_integration.py +1 -1
- exonware/xwsystem/io/archive/compression.py +1 -1
- exonware/xwsystem/io/archive/formats/__init__.py +1 -1
- exonware/xwsystem/io/archive/formats/brotli_format.py +12 -9
- exonware/xwsystem/io/archive/formats/lz4_format.py +12 -9
- exonware/xwsystem/io/archive/formats/rar.py +12 -9
- exonware/xwsystem/io/archive/formats/sevenzip.py +12 -9
- exonware/xwsystem/io/archive/formats/squashfs_format.py +7 -7
- exonware/xwsystem/io/archive/formats/tar.py +8 -8
- exonware/xwsystem/io/archive/formats/wim_format.py +12 -9
- exonware/xwsystem/io/archive/formats/zip.py +8 -8
- exonware/xwsystem/io/archive/formats/zpaq_format.py +7 -7
- exonware/xwsystem/io/archive/formats/zstandard.py +12 -9
- exonware/xwsystem/io/base.py +17 -17
- exonware/xwsystem/io/codec/__init__.py +1 -1
- exonware/xwsystem/io/codec/base.py +261 -14
- exonware/xwsystem/io/codec/contracts.py +3 -6
- exonware/xwsystem/io/codec/registry.py +29 -29
- exonware/xwsystem/io/common/__init__.py +1 -1
- exonware/xwsystem/io/common/atomic.py +2 -2
- exonware/xwsystem/io/common/base.py +1 -1
- exonware/xwsystem/io/common/lock.py +1 -1
- exonware/xwsystem/io/common/watcher.py +4 -4
- exonware/xwsystem/io/contracts.py +34 -39
- exonware/xwsystem/io/data_operations.py +480 -0
- exonware/xwsystem/io/defs.py +2 -2
- exonware/xwsystem/io/errors.py +32 -3
- exonware/xwsystem/io/facade.py +4 -4
- exonware/xwsystem/io/file/__init__.py +1 -1
- exonware/xwsystem/io/file/base.py +2 -2
- exonware/xwsystem/io/file/conversion.py +1 -1
- exonware/xwsystem/io/file/file.py +10 -8
- exonware/xwsystem/io/file/paged_source.py +8 -1
- exonware/xwsystem/io/file/paging/__init__.py +1 -1
- exonware/xwsystem/io/file/paging/byte_paging.py +1 -1
- exonware/xwsystem/io/file/paging/line_paging.py +1 -1
- exonware/xwsystem/io/file/paging/record_paging.py +1 -1
- exonware/xwsystem/io/file/paging/registry.py +5 -5
- exonware/xwsystem/io/file/source.py +22 -11
- exonware/xwsystem/io/filesystem/__init__.py +1 -1
- exonware/xwsystem/io/filesystem/base.py +1 -1
- exonware/xwsystem/io/filesystem/local.py +9 -1
- exonware/xwsystem/io/folder/__init__.py +1 -1
- exonware/xwsystem/io/folder/base.py +2 -2
- exonware/xwsystem/io/folder/folder.py +6 -6
- exonware/xwsystem/io/serialization/__init__.py +1 -1
- exonware/xwsystem/io/serialization/auto_serializer.py +53 -40
- exonware/xwsystem/io/serialization/base.py +248 -35
- exonware/xwsystem/io/serialization/contracts.py +93 -4
- exonware/xwsystem/io/serialization/defs.py +1 -1
- exonware/xwsystem/io/serialization/errors.py +1 -1
- exonware/xwsystem/io/serialization/flyweight.py +22 -22
- exonware/xwsystem/io/serialization/format_detector.py +18 -15
- exonware/xwsystem/io/serialization/formats/__init__.py +1 -1
- exonware/xwsystem/io/serialization/formats/binary/bson.py +1 -1
- exonware/xwsystem/io/serialization/formats/binary/cbor.py +1 -1
- exonware/xwsystem/io/serialization/formats/binary/marshal.py +1 -1
- exonware/xwsystem/io/serialization/formats/binary/msgpack.py +1 -1
- exonware/xwsystem/io/serialization/formats/binary/pickle.py +1 -1
- exonware/xwsystem/io/serialization/formats/binary/plistlib.py +1 -1
- exonware/xwsystem/io/serialization/formats/database/dbm.py +53 -1
- exonware/xwsystem/io/serialization/formats/database/shelve.py +48 -1
- exonware/xwsystem/io/serialization/formats/database/sqlite3.py +85 -1
- exonware/xwsystem/io/serialization/formats/text/configparser.py +2 -2
- exonware/xwsystem/io/serialization/formats/text/csv.py +2 -2
- exonware/xwsystem/io/serialization/formats/text/formdata.py +2 -2
- exonware/xwsystem/io/serialization/formats/text/json.py +23 -5
- exonware/xwsystem/io/serialization/formats/text/json5.py +98 -13
- exonware/xwsystem/io/serialization/formats/text/jsonlines.py +230 -20
- exonware/xwsystem/io/serialization/formats/text/multipart.py +2 -2
- exonware/xwsystem/io/serialization/formats/text/toml.py +65 -4
- exonware/xwsystem/io/serialization/formats/text/xml.py +451 -69
- exonware/xwsystem/io/serialization/formats/text/yaml.py +52 -2
- exonware/xwsystem/io/serialization/registry.py +5 -5
- exonware/xwsystem/io/serialization/serializer.py +184 -12
- exonware/xwsystem/io/serialization/utils/__init__.py +1 -1
- exonware/xwsystem/io/serialization/utils/path_ops.py +3 -3
- exonware/xwsystem/io/stream/__init__.py +1 -1
- exonware/xwsystem/io/stream/async_operations.py +3 -3
- exonware/xwsystem/io/stream/base.py +3 -7
- exonware/xwsystem/io/stream/codec_io.py +4 -7
- exonware/xwsystem/ipc/async_fabric.py +7 -8
- exonware/xwsystem/ipc/base.py +9 -9
- exonware/xwsystem/ipc/contracts.py +5 -5
- exonware/xwsystem/ipc/defs.py +1 -1
- exonware/xwsystem/ipc/errors.py +2 -2
- exonware/xwsystem/ipc/message_queue.py +4 -6
- exonware/xwsystem/ipc/pipes.py +2 -2
- exonware/xwsystem/ipc/process_manager.py +7 -7
- exonware/xwsystem/ipc/process_pool.py +8 -8
- exonware/xwsystem/ipc/shared_memory.py +7 -7
- exonware/xwsystem/monitoring/base.py +33 -33
- exonware/xwsystem/monitoring/contracts.py +27 -27
- exonware/xwsystem/monitoring/defs.py +1 -1
- exonware/xwsystem/monitoring/error_recovery.py +16 -16
- exonware/xwsystem/monitoring/errors.py +2 -2
- exonware/xwsystem/monitoring/memory_monitor.py +12 -12
- exonware/xwsystem/monitoring/metrics.py +8 -8
- exonware/xwsystem/monitoring/performance_manager_generic.py +20 -20
- exonware/xwsystem/monitoring/performance_monitor.py +11 -11
- exonware/xwsystem/monitoring/performance_validator.py +21 -21
- exonware/xwsystem/monitoring/system_monitor.py +17 -17
- exonware/xwsystem/monitoring/tracing.py +20 -20
- exonware/xwsystem/monitoring/tracker.py +7 -7
- exonware/xwsystem/operations/__init__.py +5 -5
- exonware/xwsystem/operations/base.py +3 -3
- exonware/xwsystem/operations/contracts.py +3 -3
- exonware/xwsystem/operations/defs.py +5 -5
- exonware/xwsystem/operations/diff.py +5 -5
- exonware/xwsystem/operations/merge.py +2 -2
- exonware/xwsystem/operations/patch.py +5 -5
- exonware/xwsystem/patterns/base.py +4 -4
- exonware/xwsystem/patterns/context_manager.py +7 -7
- exonware/xwsystem/patterns/contracts.py +29 -31
- exonware/xwsystem/patterns/defs.py +1 -1
- exonware/xwsystem/patterns/dynamic_facade.py +9 -9
- exonware/xwsystem/patterns/errors.py +10 -10
- exonware/xwsystem/patterns/handler_factory.py +15 -14
- exonware/xwsystem/patterns/import_registry.py +22 -22
- exonware/xwsystem/patterns/object_pool.py +14 -13
- exonware/xwsystem/patterns/registry.py +45 -32
- exonware/xwsystem/plugins/__init__.py +1 -1
- exonware/xwsystem/plugins/base.py +25 -25
- exonware/xwsystem/plugins/contracts.py +28 -28
- exonware/xwsystem/plugins/defs.py +1 -1
- exonware/xwsystem/plugins/errors.py +9 -9
- exonware/xwsystem/runtime/__init__.py +1 -1
- exonware/xwsystem/runtime/base.py +42 -42
- exonware/xwsystem/runtime/contracts.py +9 -9
- exonware/xwsystem/runtime/defs.py +1 -1
- exonware/xwsystem/runtime/env.py +9 -9
- exonware/xwsystem/runtime/errors.py +1 -1
- exonware/xwsystem/runtime/reflection.py +15 -15
- exonware/xwsystem/security/auth.py +47 -15
- exonware/xwsystem/security/base.py +17 -17
- exonware/xwsystem/security/contracts.py +30 -30
- exonware/xwsystem/security/crypto.py +8 -8
- exonware/xwsystem/security/defs.py +1 -1
- exonware/xwsystem/security/errors.py +2 -2
- exonware/xwsystem/security/hazmat.py +7 -7
- exonware/xwsystem/security/path_validator.py +1 -1
- exonware/xwsystem/shared/__init__.py +1 -1
- exonware/xwsystem/shared/base.py +14 -14
- exonware/xwsystem/shared/contracts.py +6 -6
- exonware/xwsystem/shared/defs.py +1 -1
- exonware/xwsystem/shared/errors.py +1 -1
- exonware/xwsystem/structures/__init__.py +1 -1
- exonware/xwsystem/structures/base.py +29 -29
- exonware/xwsystem/structures/circular_detector.py +15 -15
- exonware/xwsystem/structures/contracts.py +9 -9
- exonware/xwsystem/structures/defs.py +1 -1
- exonware/xwsystem/structures/errors.py +2 -2
- exonware/xwsystem/structures/tree_walker.py +8 -8
- exonware/xwsystem/threading/async_primitives.py +7 -7
- exonware/xwsystem/threading/base.py +19 -19
- exonware/xwsystem/threading/contracts.py +13 -13
- exonware/xwsystem/threading/defs.py +1 -1
- exonware/xwsystem/threading/errors.py +2 -2
- exonware/xwsystem/threading/safe_factory.py +13 -12
- exonware/xwsystem/utils/base.py +34 -34
- exonware/xwsystem/utils/contracts.py +9 -9
- exonware/xwsystem/utils/dt/__init__.py +1 -1
- exonware/xwsystem/utils/dt/base.py +6 -6
- exonware/xwsystem/utils/dt/contracts.py +2 -2
- exonware/xwsystem/utils/dt/defs.py +1 -1
- exonware/xwsystem/utils/dt/errors.py +2 -2
- exonware/xwsystem/utils/dt/formatting.py +3 -3
- exonware/xwsystem/utils/dt/humanize.py +2 -2
- exonware/xwsystem/utils/dt/parsing.py +2 -2
- exonware/xwsystem/utils/dt/timezone_utils.py +5 -5
- exonware/xwsystem/utils/errors.py +2 -2
- exonware/xwsystem/utils/test_runner.py +6 -6
- exonware/xwsystem/utils/utils_contracts.py +1 -1
- exonware/xwsystem/validation/__init__.py +1 -1
- exonware/xwsystem/validation/base.py +48 -48
- exonware/xwsystem/validation/contracts.py +8 -8
- exonware/xwsystem/validation/data_validator.py +10 -0
- exonware/xwsystem/validation/declarative.py +15 -15
- exonware/xwsystem/validation/defs.py +1 -1
- exonware/xwsystem/validation/errors.py +2 -2
- exonware/xwsystem/validation/fluent_validator.py +10 -10
- exonware/xwsystem/version.py +2 -2
- {exonware_xwsystem-0.0.1.409.dist-info → exonware_xwsystem-0.0.1.411.dist-info}/METADATA +9 -11
- exonware_xwsystem-0.0.1.411.dist-info/RECORD +274 -0
- {exonware_xwsystem-0.0.1.409.dist-info → exonware_xwsystem-0.0.1.411.dist-info}/WHEEL +1 -1
- exonware/xwsystem/lazy_bootstrap.py +0 -79
- exonware_xwsystem-0.0.1.409.dist-info/RECORD +0 -274
- {exonware_xwsystem-0.0.1.409.dist-info → exonware_xwsystem-0.0.1.411.dist-info}/licenses/LICENSE +0 -0
|
@@ -2,27 +2,24 @@
|
|
|
2
2
|
Company: eXonware.com
|
|
3
3
|
Author: Eng. Muhammad AlShehri
|
|
4
4
|
Email: connect@exonware.com
|
|
5
|
-
Version: 0.0.1.
|
|
5
|
+
Version: 0.0.1.411
|
|
6
6
|
Generation Date: September 04, 2025
|
|
7
7
|
|
|
8
8
|
Codec module contracts - interfaces for codec operations.
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
-
from typing import Protocol,
|
|
11
|
+
from typing import Protocol, Optional, runtime_checkable
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
|
|
14
14
|
from ..contracts import EncodeOptions, DecodeOptions, CodecCapability
|
|
15
15
|
|
|
16
|
-
T = TypeVar('T')
|
|
17
|
-
R = TypeVar('R')
|
|
18
|
-
|
|
19
16
|
|
|
20
17
|
# ============================================================================
|
|
21
18
|
# CODEC INTERFACES
|
|
22
19
|
# ============================================================================
|
|
23
20
|
|
|
24
21
|
@runtime_checkable
|
|
25
|
-
class ICodec
|
|
22
|
+
class ICodec[T, R](Protocol):
|
|
26
23
|
"""
|
|
27
24
|
Universal codec interface for bidirectional transformation.
|
|
28
25
|
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
Company: eXonware.com
|
|
3
3
|
Author: Eng. Muhammad AlShehri
|
|
4
4
|
Email: connect@exonware.com
|
|
5
|
-
Version: 0.0.1.
|
|
5
|
+
Version: 0.0.1.411
|
|
6
6
|
Generation Date: November 04, 2025
|
|
7
7
|
|
|
8
8
|
Universal Codec Registry - High-performance registry for all codec types.
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
-
from typing import Optional,
|
|
11
|
+
from typing import Optional, Union, Any, Callable
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
from threading import RLock
|
|
14
14
|
from functools import lru_cache
|
|
@@ -28,9 +28,9 @@ class CompoundExtensionTrie:
|
|
|
28
28
|
|
|
29
29
|
def __init__(self):
|
|
30
30
|
"""Initialize the trie."""
|
|
31
|
-
self.root:
|
|
31
|
+
self.root: dict[str, Any] = {}
|
|
32
32
|
|
|
33
|
-
def insert(self, extensions:
|
|
33
|
+
def insert(self, extensions: list[str], codec_id: str, priority: int = 0) -> None:
|
|
34
34
|
"""
|
|
35
35
|
Insert a compound extension path.
|
|
36
36
|
|
|
@@ -52,7 +52,7 @@ class CompoundExtensionTrie:
|
|
|
52
52
|
# Sort by priority (highest first)
|
|
53
53
|
node['_codecs'].sort(key=lambda x: x[1], reverse=True)
|
|
54
54
|
|
|
55
|
-
def search(self, extensions:
|
|
55
|
+
def search(self, extensions: list[str]) -> list[str]:
|
|
56
56
|
"""
|
|
57
57
|
Search for matching codec IDs.
|
|
58
58
|
|
|
@@ -104,36 +104,36 @@ class UniversalCodecRegistry:
|
|
|
104
104
|
def __init__(self):
|
|
105
105
|
"""Initialize the universal codec registry."""
|
|
106
106
|
# Core mappings (codec_id is always lowercase)
|
|
107
|
-
self._by_id:
|
|
108
|
-
self._by_extension:
|
|
109
|
-
self._by_mime_type:
|
|
110
|
-
self._by_alias:
|
|
111
|
-
self._by_type:
|
|
107
|
+
self._by_id: dict[str, type[ICodec]] = {}
|
|
108
|
+
self._by_extension: dict[str, list[tuple[str, int]]] = {} # ext -> [(codec_id, priority)]
|
|
109
|
+
self._by_mime_type: dict[str, list[tuple[str, int]]] = {} # mime -> [(codec_id, priority)]
|
|
110
|
+
self._by_alias: dict[str, str] = {} # alias -> codec_id (1:1 mapping)
|
|
111
|
+
self._by_type: dict[str, set[str]] = {} # codec_type -> set of codec_ids
|
|
112
112
|
|
|
113
113
|
# Magic bytes support (for content detection)
|
|
114
|
-
self._magic_bytes:
|
|
114
|
+
self._magic_bytes: dict[bytes, list[tuple[str, int]]] = {} # magic -> [(codec_id, priority)]
|
|
115
115
|
|
|
116
116
|
# Compound extension support
|
|
117
117
|
self._compound_trie = CompoundExtensionTrie()
|
|
118
118
|
|
|
119
119
|
# Instance cache
|
|
120
|
-
self._instances:
|
|
120
|
+
self._instances: dict[str, ICodec] = {}
|
|
121
121
|
|
|
122
122
|
# Metadata cache
|
|
123
|
-
self._metadata:
|
|
123
|
+
self._metadata: dict[str, dict[str, Any]] = {}
|
|
124
124
|
|
|
125
125
|
# Priority tracking (codec_id -> priority)
|
|
126
|
-
self._priorities:
|
|
126
|
+
self._priorities: dict[str, int] = {}
|
|
127
127
|
|
|
128
128
|
# Thread safety
|
|
129
129
|
self._lock = RLock()
|
|
130
130
|
|
|
131
131
|
def register(
|
|
132
132
|
self,
|
|
133
|
-
codec_class:
|
|
133
|
+
codec_class: type[ICodec],
|
|
134
134
|
codec_instance: Optional[ICodec] = None,
|
|
135
135
|
priority: int = 0,
|
|
136
|
-
magic_bytes: Optional[
|
|
136
|
+
magic_bytes: Optional[list[bytes]] = None
|
|
137
137
|
) -> None:
|
|
138
138
|
"""
|
|
139
139
|
Register a codec class or instance with optional priority and magic bytes.
|
|
@@ -510,7 +510,7 @@ class UniversalCodecRegistry:
|
|
|
510
510
|
# MULTIPLE RESULT METHODS (All matches)
|
|
511
511
|
# ========================================================================
|
|
512
512
|
|
|
513
|
-
def get_all_by_extension(self, ext: str) ->
|
|
513
|
+
def get_all_by_extension(self, ext: str) -> list[ICodec]:
|
|
514
514
|
"""
|
|
515
515
|
Get all codecs matching an extension (sorted by priority).
|
|
516
516
|
|
|
@@ -528,7 +528,7 @@ class UniversalCodecRegistry:
|
|
|
528
528
|
codec_list = self._by_extension.get(normalized_ext, [])
|
|
529
529
|
return [self.get_by_id(codec_id) for codec_id, _ in codec_list if self.get_by_id(codec_id)]
|
|
530
530
|
|
|
531
|
-
def get_all_by_mime_type(self, mime: str) ->
|
|
531
|
+
def get_all_by_mime_type(self, mime: str) -> list[ICodec]:
|
|
532
532
|
"""
|
|
533
533
|
Get all codecs matching a MIME type (sorted by priority).
|
|
534
534
|
|
|
@@ -542,7 +542,7 @@ class UniversalCodecRegistry:
|
|
|
542
542
|
codec_list = self._by_mime_type.get(mime.lower(), [])
|
|
543
543
|
return [self.get_by_id(codec_id) for codec_id, _ in codec_list if self.get_by_id(codec_id)]
|
|
544
544
|
|
|
545
|
-
def get_all_by_type(self, codec_type: str) ->
|
|
545
|
+
def get_all_by_type(self, codec_type: str) -> list[ICodec]:
|
|
546
546
|
"""
|
|
547
547
|
Get all codecs of a specific type.
|
|
548
548
|
|
|
@@ -556,7 +556,7 @@ class UniversalCodecRegistry:
|
|
|
556
556
|
codec_ids = self._by_type.get(codec_type.lower(), set())
|
|
557
557
|
return [self.get_by_id(codec_id) for codec_id in codec_ids if self.get_by_id(codec_id)]
|
|
558
558
|
|
|
559
|
-
def filter_by_capability(self, cap: CodecCapability) ->
|
|
559
|
+
def filter_by_capability(self, cap: CodecCapability) -> list[ICodec]:
|
|
560
560
|
"""
|
|
561
561
|
Get all codecs with a specific capability.
|
|
562
562
|
|
|
@@ -574,7 +574,7 @@ class UniversalCodecRegistry:
|
|
|
574
574
|
results.append(codec)
|
|
575
575
|
return results
|
|
576
576
|
|
|
577
|
-
def detect_all(self, path: Union[str, Path], codec_type: Optional[str] = None) ->
|
|
577
|
+
def detect_all(self, path: Union[str, Path], codec_type: Optional[str] = None) -> list[ICodec]:
|
|
578
578
|
"""
|
|
579
579
|
Detect all possible codecs for a file path.
|
|
580
580
|
|
|
@@ -624,7 +624,7 @@ class UniversalCodecRegistry:
|
|
|
624
624
|
# METADATA & MANAGEMENT METHODS
|
|
625
625
|
# ========================================================================
|
|
626
626
|
|
|
627
|
-
def get_metadata(self, codec_id: str) -> Optional[
|
|
627
|
+
def get_metadata(self, codec_id: str) -> Optional[dict[str, Any]]:
|
|
628
628
|
"""
|
|
629
629
|
Get full metadata for a codec.
|
|
630
630
|
|
|
@@ -637,7 +637,7 @@ class UniversalCodecRegistry:
|
|
|
637
637
|
with self._lock:
|
|
638
638
|
return self._metadata.get(codec_id.lower())
|
|
639
639
|
|
|
640
|
-
def list_types(self) ->
|
|
640
|
+
def list_types(self) -> list[str]:
|
|
641
641
|
"""
|
|
642
642
|
List all registered codec types.
|
|
643
643
|
|
|
@@ -647,7 +647,7 @@ class UniversalCodecRegistry:
|
|
|
647
647
|
with self._lock:
|
|
648
648
|
return list(self._by_type.keys())
|
|
649
649
|
|
|
650
|
-
def list_codecs(self, codec_type: Optional[str] = None) ->
|
|
650
|
+
def list_codecs(self, codec_type: Optional[str] = None) -> list[str]:
|
|
651
651
|
"""
|
|
652
652
|
List all codec IDs, optionally filtered by type.
|
|
653
653
|
|
|
@@ -663,17 +663,17 @@ class UniversalCodecRegistry:
|
|
|
663
663
|
else:
|
|
664
664
|
return list(self._by_id.keys())
|
|
665
665
|
|
|
666
|
-
def list_extensions(self) ->
|
|
666
|
+
def list_extensions(self) -> list[str]:
|
|
667
667
|
"""List all registered file extensions."""
|
|
668
668
|
with self._lock:
|
|
669
669
|
return list(self._by_extension.keys())
|
|
670
670
|
|
|
671
|
-
def list_mime_types(self) ->
|
|
671
|
+
def list_mime_types(self) -> list[str]:
|
|
672
672
|
"""List all registered MIME types."""
|
|
673
673
|
with self._lock:
|
|
674
674
|
return list(self._by_mime_type.keys())
|
|
675
675
|
|
|
676
|
-
def list_aliases(self) ->
|
|
676
|
+
def list_aliases(self) -> list[str]:
|
|
677
677
|
"""List all registered aliases."""
|
|
678
678
|
with self._lock:
|
|
679
679
|
return list(self._by_alias.keys())
|
|
@@ -702,7 +702,7 @@ class UniversalCodecRegistry:
|
|
|
702
702
|
# BULK OPERATIONS
|
|
703
703
|
# ========================================================================
|
|
704
704
|
|
|
705
|
-
def register_bulk(self, codec_classes:
|
|
705
|
+
def register_bulk(self, codec_classes: list[type[ICodec]], priorities: Optional[list[int]] = None) -> int:
|
|
706
706
|
"""
|
|
707
707
|
Register multiple codecs efficiently.
|
|
708
708
|
|
|
@@ -730,7 +730,7 @@ class UniversalCodecRegistry:
|
|
|
730
730
|
# STATISTICS & INTROSPECTION
|
|
731
731
|
# ========================================================================
|
|
732
732
|
|
|
733
|
-
def get_statistics(self) ->
|
|
733
|
+
def get_statistics(self) -> dict[str, int]:
|
|
734
734
|
"""
|
|
735
735
|
Get registry statistics.
|
|
736
736
|
|
|
@@ -9,7 +9,7 @@ import tempfile
|
|
|
9
9
|
import time
|
|
10
10
|
from contextlib import contextmanager
|
|
11
11
|
from pathlib import Path
|
|
12
|
-
from typing import Any, BinaryIO,
|
|
12
|
+
from typing import Any, BinaryIO, Optional, TextIO, Union
|
|
13
13
|
|
|
14
14
|
logger = logging.getLogger(__name__)
|
|
15
15
|
|
|
@@ -421,7 +421,7 @@ def safe_read_bytes(file_path: Union[str, Path], max_size_mb: float = 100.0) ->
|
|
|
421
421
|
def safe_read_with_fallback(
|
|
422
422
|
file_path: Union[str, Path],
|
|
423
423
|
preferred_encoding: str = "utf-8",
|
|
424
|
-
fallback_encodings: Optional[
|
|
424
|
+
fallback_encodings: Optional[list[str]] = None,
|
|
425
425
|
max_size_mb: float = 100.0,
|
|
426
426
|
) -> str:
|
|
427
427
|
"""
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Company: eXonware.com
|
|
5
5
|
Author: Eng. Muhammad AlShehri
|
|
6
6
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.0.1.
|
|
7
|
+
Version: 0.0.1.411
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
File watching implementation for change monitoring.
|
|
@@ -19,7 +19,7 @@ Priority 5 (Extensibility): Easy to add new event types
|
|
|
19
19
|
import time
|
|
20
20
|
import threading
|
|
21
21
|
from pathlib import Path
|
|
22
|
-
from typing import
|
|
22
|
+
from typing import Any, Optional, Callable
|
|
23
23
|
|
|
24
24
|
from ..contracts import IFileWatcher
|
|
25
25
|
|
|
@@ -56,8 +56,8 @@ class FileWatcher(IFileWatcher):
|
|
|
56
56
|
poll_interval: Polling interval in seconds
|
|
57
57
|
"""
|
|
58
58
|
self._poll_interval = poll_interval
|
|
59
|
-
self._watched:
|
|
60
|
-
self._file_states:
|
|
59
|
+
self._watched: dict[Path, Callable] = {}
|
|
60
|
+
self._file_states: dict[Path, dict[str, Any]] = {}
|
|
61
61
|
self._running = False
|
|
62
62
|
self._thread: Optional[threading.Thread] = None
|
|
63
63
|
|
|
@@ -2,23 +2,22 @@
|
|
|
2
2
|
Company: eXonware.com
|
|
3
3
|
Author: Eng. Muhammad AlShehri
|
|
4
4
|
Email: connect@exonware.com
|
|
5
|
-
Version: 0.0.1.
|
|
5
|
+
Version: 0.0.1.411
|
|
6
6
|
Generation Date: September 04, 2025
|
|
7
7
|
|
|
8
8
|
IO module contracts - interfaces and enums for input/output operations.
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
from abc import ABC, abstractmethod
|
|
12
|
-
from typing import Any,
|
|
12
|
+
from typing import Any, Optional, Union, AsyncGenerator, BinaryIO, TextIO, Protocol, runtime_checkable, Callable, Iterator
|
|
13
13
|
from typing_extensions import TypeAlias
|
|
14
14
|
from pathlib import Path
|
|
15
15
|
|
|
16
|
-
T = TypeVar('T')
|
|
17
|
-
R = TypeVar('R')
|
|
18
|
-
|
|
19
16
|
# Type aliases for codec options
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
# Root cause: Migrating to Python 3.12 built-in generic syntax for consistency
|
|
18
|
+
# Priority #3: Maintainability - Modern type annotations improve code clarity
|
|
19
|
+
EncodeOptions: TypeAlias = dict[str, Any]
|
|
20
|
+
DecodeOptions: TypeAlias = dict[str, Any]
|
|
22
21
|
Serializer: TypeAlias = 'ICodec[Any, bytes]'
|
|
23
22
|
Formatter: TypeAlias = 'ICodec[Any, str]'
|
|
24
23
|
|
|
@@ -305,17 +304,17 @@ class IFolder(ABC):
|
|
|
305
304
|
pass
|
|
306
305
|
|
|
307
306
|
@abstractmethod
|
|
308
|
-
def list_files(self, pattern: Optional[str] = None, recursive: bool = False) ->
|
|
307
|
+
def list_files(self, pattern: Optional[str] = None, recursive: bool = False) -> list[Path]:
|
|
309
308
|
"""List files in directory."""
|
|
310
309
|
pass
|
|
311
310
|
|
|
312
311
|
@abstractmethod
|
|
313
|
-
def list_directories(self, recursive: bool = False) ->
|
|
312
|
+
def list_directories(self, recursive: bool = False) -> list[Path]:
|
|
314
313
|
"""List subdirectories."""
|
|
315
314
|
pass
|
|
316
315
|
|
|
317
316
|
@abstractmethod
|
|
318
|
-
def walk(self) ->
|
|
317
|
+
def walk(self) -> list[tuple[Path, list[str], list[str]]]:
|
|
319
318
|
"""Walk directory tree."""
|
|
320
319
|
pass
|
|
321
320
|
|
|
@@ -363,19 +362,19 @@ class IFolder(ABC):
|
|
|
363
362
|
|
|
364
363
|
@staticmethod
|
|
365
364
|
@abstractmethod
|
|
366
|
-
def list_files_static(path: Union[str, Path], pattern: Optional[str] = None, recursive: bool = False) ->
|
|
365
|
+
def list_files_static(path: Union[str, Path], pattern: Optional[str] = None, recursive: bool = False) -> list[Path]:
|
|
367
366
|
"""List files in directory."""
|
|
368
367
|
pass
|
|
369
368
|
|
|
370
369
|
@staticmethod
|
|
371
370
|
@abstractmethod
|
|
372
|
-
def list_directories_static(path: Union[str, Path], recursive: bool = False) ->
|
|
371
|
+
def list_directories_static(path: Union[str, Path], recursive: bool = False) -> list[Path]:
|
|
373
372
|
"""List subdirectories."""
|
|
374
373
|
pass
|
|
375
374
|
|
|
376
375
|
@staticmethod
|
|
377
376
|
@abstractmethod
|
|
378
|
-
def walk_static(path: Union[str, Path]) ->
|
|
377
|
+
def walk_static(path: Union[str, Path]) -> list[tuple[Path, list[str], list[str]]]:
|
|
379
378
|
"""Walk directory tree."""
|
|
380
379
|
pass
|
|
381
380
|
|
|
@@ -818,7 +817,7 @@ class IBackupOperations(ABC):
|
|
|
818
817
|
pass
|
|
819
818
|
|
|
820
819
|
@abstractmethod
|
|
821
|
-
def list_backups(self, backup_dir: Union[str, Path]) ->
|
|
820
|
+
def list_backups(self, backup_dir: Union[str, Path]) -> list[Path]:
|
|
822
821
|
"""List available backups."""
|
|
823
822
|
pass
|
|
824
823
|
|
|
@@ -850,7 +849,7 @@ class IBackupOperations(ABC):
|
|
|
850
849
|
|
|
851
850
|
@staticmethod
|
|
852
851
|
@abstractmethod
|
|
853
|
-
def list_backups_static(backup_dir: Union[str, Path]) ->
|
|
852
|
+
def list_backups_static(backup_dir: Union[str, Path]) -> list[Path]:
|
|
854
853
|
"""List available backups."""
|
|
855
854
|
pass
|
|
856
855
|
|
|
@@ -1002,7 +1001,7 @@ class IFileManager(IFile, IFolder, IPath, IAtomicOperations, IBackupOperations,
|
|
|
1002
1001
|
# DATA SOURCE INTERFACES (Used by file/, stream/)
|
|
1003
1002
|
# ============================================================================
|
|
1004
1003
|
|
|
1005
|
-
class IDataSource
|
|
1004
|
+
class IDataSource[T](ABC):
|
|
1006
1005
|
"""Universal data source interface for various data sources."""
|
|
1007
1006
|
|
|
1008
1007
|
@abstractmethod
|
|
@@ -1016,11 +1015,11 @@ class IDataSource(ABC, Generic[T]):
|
|
|
1016
1015
|
pass
|
|
1017
1016
|
|
|
1018
1017
|
|
|
1019
|
-
class IPagedDataSource
|
|
1018
|
+
class IPagedDataSource[T](ABC):
|
|
1020
1019
|
"""Paged data source interface for large data sets."""
|
|
1021
1020
|
|
|
1022
1021
|
@abstractmethod
|
|
1023
|
-
def read_page(self, page_number: int) ->
|
|
1022
|
+
def read_page(self, page_number: int) -> list[T]:
|
|
1024
1023
|
"""Read a specific page of data."""
|
|
1025
1024
|
pass
|
|
1026
1025
|
|
|
@@ -1034,7 +1033,7 @@ class IPagedDataSource(ABC, Generic[T]):
|
|
|
1034
1033
|
# CODEC-INTEGRATED IO INTERFACES (Used by stream/)
|
|
1035
1034
|
# ============================================================================
|
|
1036
1035
|
|
|
1037
|
-
class ICodecIO
|
|
1036
|
+
class ICodecIO[T, R](ABC):
|
|
1038
1037
|
"""Codec-integrated IO interface with source type T and result type R."""
|
|
1039
1038
|
|
|
1040
1039
|
@abstractmethod
|
|
@@ -1048,7 +1047,7 @@ class ICodecIO(ABC, Generic[T, R]):
|
|
|
1048
1047
|
pass
|
|
1049
1048
|
|
|
1050
1049
|
|
|
1051
|
-
class IPagedCodecIO
|
|
1050
|
+
class IPagedCodecIO[T, R](ABC):
|
|
1052
1051
|
"""Paged codec-integrated IO interface with source type T and result type R."""
|
|
1053
1052
|
|
|
1054
1053
|
@abstractmethod
|
|
@@ -1134,24 +1133,24 @@ class IArchiveFormat(Protocol):
|
|
|
1134
1133
|
...
|
|
1135
1134
|
|
|
1136
1135
|
@property
|
|
1137
|
-
def file_extensions(self) ->
|
|
1136
|
+
def file_extensions(self) -> list[str]:
|
|
1138
1137
|
"""Supported file extensions."""
|
|
1139
1138
|
...
|
|
1140
1139
|
|
|
1141
1140
|
@property
|
|
1142
|
-
def mime_types(self) ->
|
|
1141
|
+
def mime_types(self) -> list[str]:
|
|
1143
1142
|
"""Supported MIME types."""
|
|
1144
1143
|
...
|
|
1145
1144
|
|
|
1146
|
-
def create(self, files:
|
|
1145
|
+
def create(self, files: list[Path], output: Path, **opts) -> None:
|
|
1147
1146
|
"""Create archive from files."""
|
|
1148
1147
|
...
|
|
1149
1148
|
|
|
1150
|
-
def extract(self, archive: Path, output_dir: Path, members: Optional[
|
|
1149
|
+
def extract(self, archive: Path, output_dir: Path, members: Optional[list[str]] = None, **opts) -> list[Path]:
|
|
1151
1150
|
"""Extract archive."""
|
|
1152
1151
|
...
|
|
1153
1152
|
|
|
1154
|
-
def list_contents(self, archive: Path) ->
|
|
1153
|
+
def list_contents(self, archive: Path) -> list[str]:
|
|
1155
1154
|
"""List archive contents."""
|
|
1156
1155
|
...
|
|
1157
1156
|
|
|
@@ -1173,7 +1172,7 @@ class ICompressor(Protocol):
|
|
|
1173
1172
|
...
|
|
1174
1173
|
|
|
1175
1174
|
@property
|
|
1176
|
-
def file_extensions(self) ->
|
|
1175
|
+
def file_extensions(self) -> list[str]:
|
|
1177
1176
|
"""Supported file extensions."""
|
|
1178
1177
|
...
|
|
1179
1178
|
|
|
@@ -1203,12 +1202,12 @@ class IArchiveMetadata(Protocol):
|
|
|
1203
1202
|
...
|
|
1204
1203
|
|
|
1205
1204
|
@property
|
|
1206
|
-
def file_extensions(self) ->
|
|
1205
|
+
def file_extensions(self) -> list[str]:
|
|
1207
1206
|
"""Supported extensions."""
|
|
1208
1207
|
...
|
|
1209
1208
|
|
|
1210
1209
|
@property
|
|
1211
|
-
def mime_types(self) ->
|
|
1210
|
+
def mime_types(self) -> list[str]:
|
|
1212
1211
|
"""MIME types."""
|
|
1213
1212
|
...
|
|
1214
1213
|
|
|
@@ -1221,7 +1220,7 @@ class IArchiveMetadata(Protocol):
|
|
|
1221
1220
|
# From codec/
|
|
1222
1221
|
|
|
1223
1222
|
@runtime_checkable
|
|
1224
|
-
class ICodec
|
|
1223
|
+
class ICodec[T, R](Protocol):
|
|
1225
1224
|
"""
|
|
1226
1225
|
Universal codec interface for bidirectional transformation.
|
|
1227
1226
|
|
|
@@ -1407,7 +1406,7 @@ class IAtomicWriter(Protocol):
|
|
|
1407
1406
|
# ARCHIVE INTERFACES (Dual Architecture: Codec + File)
|
|
1408
1407
|
# ============================================================================
|
|
1409
1408
|
|
|
1410
|
-
class IArchiver(ICodec[T, bytes]):
|
|
1409
|
+
class IArchiver[T](ICodec[T, bytes]):
|
|
1411
1410
|
"""
|
|
1412
1411
|
Archive codec interface - operates in MEMORY on ANY data.
|
|
1413
1412
|
|
|
@@ -1457,17 +1456,17 @@ class IArchiveFile(IFile):
|
|
|
1457
1456
|
"""
|
|
1458
1457
|
|
|
1459
1458
|
@abstractmethod
|
|
1460
|
-
def add_files(self, files:
|
|
1459
|
+
def add_files(self, files: list[Path], **options) -> None:
|
|
1461
1460
|
"""Add files to archive (uses archiver.compress internally)."""
|
|
1462
1461
|
pass
|
|
1463
1462
|
|
|
1464
1463
|
@abstractmethod
|
|
1465
|
-
def extract_to(self, dest: Path, **options) ->
|
|
1464
|
+
def extract_to(self, dest: Path, **options) -> list[Path]:
|
|
1466
1465
|
"""Extract archive to destination (uses archiver.extract internally)."""
|
|
1467
1466
|
pass
|
|
1468
1467
|
|
|
1469
1468
|
@abstractmethod
|
|
1470
|
-
def list_contents(self) ->
|
|
1469
|
+
def list_contents(self) -> list[str]:
|
|
1471
1470
|
"""List files in archive."""
|
|
1472
1471
|
pass
|
|
1473
1472
|
|
|
@@ -1671,7 +1670,7 @@ class IFolderSource(Protocol):
|
|
|
1671
1670
|
"""Delete directory."""
|
|
1672
1671
|
...
|
|
1673
1672
|
|
|
1674
|
-
def list_files(self, pattern: Optional[str] = None, recursive: bool = False) ->
|
|
1673
|
+
def list_files(self, pattern: Optional[str] = None, recursive: bool = False) -> list[Path]:
|
|
1675
1674
|
"""List files in directory."""
|
|
1676
1675
|
...
|
|
1677
1676
|
|
|
@@ -1694,13 +1693,9 @@ class IIOManager(Protocol):
|
|
|
1694
1693
|
# From stream/
|
|
1695
1694
|
|
|
1696
1695
|
|
|
1697
|
-
class IPagedCodecIO(ICodecIO[T, R]):
|
|
1696
|
+
class IPagedCodecIO[T, R](ICodecIO[T, R]):
|
|
1698
1697
|
"""
|
|
1699
1698
|
Interface for paged codec I/O.
|
|
1700
|
-
|
|
1701
|
-
Root cause fixed: Removed Protocol from class that inherits from ABC.
|
|
1702
|
-
Python 3.12 doesn't allow mixing Protocol with ABC inheritance.
|
|
1703
|
-
ICodecIO is already an ABC, so this class inherits ABC behavior.
|
|
1704
1699
|
"""
|
|
1705
1700
|
|
|
1706
1701
|
@abstractmethod
|