exonware-xwsystem 0.1.0.1__py3-none-any.whl → 0.1.0.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- exonware/__init__.py +2 -1
- exonware/conf.py +2 -2
- exonware/xwsystem/__init__.py +115 -43
- exonware/xwsystem/base.py +30 -0
- exonware/xwsystem/caching/__init__.py +39 -13
- exonware/xwsystem/caching/base.py +24 -6
- exonware/xwsystem/caching/bloom_cache.py +2 -2
- exonware/xwsystem/caching/cache_manager.py +2 -1
- exonware/xwsystem/caching/conditional.py +2 -2
- exonware/xwsystem/caching/contracts.py +85 -139
- exonware/xwsystem/caching/decorators.py +6 -19
- exonware/xwsystem/caching/defs.py +2 -1
- exonware/xwsystem/caching/disk_cache.py +2 -1
- exonware/xwsystem/caching/distributed.py +2 -1
- exonware/xwsystem/caching/errors.py +2 -1
- exonware/xwsystem/caching/events.py +110 -27
- exonware/xwsystem/caching/eviction_strategies.py +2 -2
- exonware/xwsystem/caching/external_caching_python.py +701 -0
- exonware/xwsystem/caching/facade.py +253 -0
- exonware/xwsystem/caching/factory.py +300 -0
- exonware/xwsystem/caching/fluent.py +14 -12
- exonware/xwsystem/caching/integrity.py +21 -6
- exonware/xwsystem/caching/lfu_cache.py +2 -1
- exonware/xwsystem/caching/lfu_optimized.py +18 -6
- exonware/xwsystem/caching/lru_cache.py +7 -4
- exonware/xwsystem/caching/memory_bounded.py +2 -2
- exonware/xwsystem/caching/metrics_exporter.py +2 -2
- exonware/xwsystem/caching/observable_cache.py +2 -2
- exonware/xwsystem/caching/pluggable_cache.py +2 -2
- exonware/xwsystem/caching/rate_limiter.py +2 -2
- exonware/xwsystem/caching/read_through.py +2 -2
- exonware/xwsystem/caching/secure_cache.py +81 -28
- exonware/xwsystem/caching/serializable.py +9 -7
- exonware/xwsystem/caching/stats.py +2 -2
- exonware/xwsystem/caching/tagging.py +2 -2
- exonware/xwsystem/caching/ttl_cache.py +4 -3
- exonware/xwsystem/caching/two_tier_cache.py +6 -3
- exonware/xwsystem/caching/utils.py +30 -12
- exonware/xwsystem/caching/validation.py +2 -2
- exonware/xwsystem/caching/warming.py +6 -3
- exonware/xwsystem/caching/write_behind.py +15 -6
- exonware/xwsystem/config/__init__.py +11 -17
- exonware/xwsystem/config/base.py +5 -5
- exonware/xwsystem/config/contracts.py +93 -153
- exonware/xwsystem/config/defaults.py +3 -2
- exonware/xwsystem/config/defs.py +3 -2
- exonware/xwsystem/config/errors.py +2 -5
- exonware/xwsystem/config/logging.py +12 -8
- exonware/xwsystem/config/logging_setup.py +3 -2
- exonware/xwsystem/config/performance.py +1 -46
- exonware/xwsystem/config/performance_modes.py +9 -8
- exonware/xwsystem/config/version_manager.py +1 -0
- exonware/xwsystem/config.py +27 -0
- exonware/xwsystem/console/__init__.py +53 -0
- exonware/xwsystem/console/base.py +133 -0
- exonware/xwsystem/console/cli/__init__.py +61 -0
- exonware/xwsystem/{cli → console/cli}/args.py +27 -24
- exonware/xwsystem/{cli → console/cli}/base.py +18 -87
- exonware/xwsystem/{cli → console/cli}/colors.py +15 -13
- exonware/xwsystem/console/cli/console.py +98 -0
- exonware/xwsystem/{cli → console/cli}/contracts.py +51 -69
- exonware/xwsystem/console/cli/defs.py +87 -0
- exonware/xwsystem/console/cli/encoding.py +69 -0
- exonware/xwsystem/{cli → console/cli}/errors.py +8 -3
- exonware/xwsystem/console/cli/event_logger.py +166 -0
- exonware/xwsystem/{cli → console/cli}/progress.py +25 -21
- exonware/xwsystem/{cli → console/cli}/prompts.py +3 -2
- exonware/xwsystem/{cli → console/cli}/tables.py +27 -24
- exonware/xwsystem/console/contracts.py +113 -0
- exonware/xwsystem/console/defs.py +154 -0
- exonware/xwsystem/console/errors.py +34 -0
- exonware/xwsystem/console/event_logger.py +385 -0
- exonware/xwsystem/console/writer.py +132 -0
- exonware/xwsystem/contracts.py +28 -0
- exonware/xwsystem/data_structures/__init__.py +23 -0
- exonware/xwsystem/data_structures/trie.py +34 -0
- exonware/xwsystem/data_structures/union_find.py +144 -0
- exonware/xwsystem/defs.py +17 -0
- exonware/xwsystem/errors.py +23 -0
- exonware/xwsystem/facade.py +62 -0
- exonware/xwsystem/http_client/__init__.py +22 -1
- exonware/xwsystem/http_client/advanced_client.py +8 -5
- exonware/xwsystem/http_client/base.py +3 -2
- exonware/xwsystem/http_client/client.py +7 -4
- exonware/xwsystem/http_client/contracts.py +42 -56
- exonware/xwsystem/http_client/defs.py +2 -1
- exonware/xwsystem/http_client/errors.py +2 -1
- exonware/xwsystem/http_client/facade.py +156 -0
- exonware/xwsystem/io/__init__.py +22 -3
- exonware/xwsystem/io/archive/__init__.py +8 -2
- exonware/xwsystem/io/archive/archive.py +1 -1
- exonware/xwsystem/io/archive/archive_files.py +4 -7
- exonware/xwsystem/io/archive/archivers.py +120 -10
- exonware/xwsystem/io/archive/base.py +4 -5
- exonware/xwsystem/io/archive/codec_integration.py +1 -2
- exonware/xwsystem/io/archive/compression.py +1 -2
- exonware/xwsystem/io/archive/facade.py +263 -0
- exonware/xwsystem/io/archive/formats/__init__.py +2 -3
- exonware/xwsystem/io/archive/formats/brotli_format.py +20 -7
- exonware/xwsystem/io/archive/formats/lz4_format.py +20 -7
- exonware/xwsystem/io/archive/formats/rar.py +11 -5
- exonware/xwsystem/io/archive/formats/sevenzip.py +12 -6
- exonware/xwsystem/io/archive/formats/squashfs_format.py +1 -2
- exonware/xwsystem/io/archive/formats/tar.py +52 -7
- exonware/xwsystem/io/archive/formats/wim_format.py +11 -5
- exonware/xwsystem/io/archive/formats/zip.py +1 -2
- exonware/xwsystem/io/archive/formats/zpaq_format.py +1 -2
- exonware/xwsystem/io/archive/formats/zstandard.py +20 -7
- exonware/xwsystem/io/base.py +119 -115
- exonware/xwsystem/io/codec/__init__.py +4 -2
- exonware/xwsystem/io/codec/base.py +19 -13
- exonware/xwsystem/io/codec/contracts.py +59 -2
- exonware/xwsystem/io/codec/registry.py +67 -21
- exonware/xwsystem/io/common/__init__.py +1 -1
- exonware/xwsystem/io/common/atomic.py +29 -16
- exonware/xwsystem/io/common/base.py +11 -10
- exonware/xwsystem/io/common/lock.py +6 -5
- exonware/xwsystem/io/common/path_manager.py +2 -1
- exonware/xwsystem/io/common/watcher.py +1 -2
- exonware/xwsystem/io/contracts.py +301 -433
- exonware/xwsystem/io/contracts_1.py +1180 -0
- exonware/xwsystem/io/data_operations.py +19 -20
- exonware/xwsystem/io/defs.py +4 -3
- exonware/xwsystem/io/errors.py +3 -2
- exonware/xwsystem/io/facade.py +87 -61
- exonware/xwsystem/io/file/__init__.py +1 -1
- exonware/xwsystem/io/file/base.py +8 -9
- exonware/xwsystem/io/file/conversion.py +2 -3
- exonware/xwsystem/io/file/file.py +61 -18
- exonware/xwsystem/io/file/paged_source.py +8 -8
- exonware/xwsystem/io/file/paging/__init__.py +1 -2
- exonware/xwsystem/io/file/paging/byte_paging.py +4 -5
- exonware/xwsystem/io/file/paging/line_paging.py +2 -3
- exonware/xwsystem/io/file/paging/record_paging.py +2 -3
- exonware/xwsystem/io/file/paging/registry.py +1 -2
- exonware/xwsystem/io/file/source.py +13 -17
- exonware/xwsystem/io/filesystem/__init__.py +1 -1
- exonware/xwsystem/io/filesystem/base.py +1 -2
- exonware/xwsystem/io/filesystem/local.py +3 -4
- exonware/xwsystem/io/folder/__init__.py +1 -1
- exonware/xwsystem/io/folder/base.py +1 -2
- exonware/xwsystem/io/folder/folder.py +16 -7
- exonware/xwsystem/io/indexing/__init__.py +14 -0
- exonware/xwsystem/io/indexing/facade.py +443 -0
- exonware/xwsystem/io/path_parser.py +98 -0
- exonware/xwsystem/io/serialization/__init__.py +21 -3
- exonware/xwsystem/io/serialization/auto_serializer.py +146 -20
- exonware/xwsystem/io/serialization/base.py +84 -34
- exonware/xwsystem/io/serialization/contracts.py +50 -73
- exonware/xwsystem/io/serialization/defs.py +2 -1
- exonware/xwsystem/io/serialization/errors.py +2 -1
- exonware/xwsystem/io/serialization/flyweight.py +154 -7
- exonware/xwsystem/io/serialization/format_detector.py +15 -14
- exonware/xwsystem/io/serialization/formats/__init__.py +8 -5
- exonware/xwsystem/io/serialization/formats/binary/bson.py +15 -6
- exonware/xwsystem/io/serialization/formats/binary/cbor.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/marshal.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/msgpack.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/pickle.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/plistlib.py +5 -5
- exonware/xwsystem/io/serialization/formats/database/dbm.py +7 -7
- exonware/xwsystem/io/serialization/formats/database/shelve.py +7 -7
- exonware/xwsystem/io/serialization/formats/database/sqlite3.py +7 -7
- exonware/xwsystem/io/serialization/formats/tabular/__init__.py +27 -0
- exonware/xwsystem/io/serialization/formats/tabular/base.py +89 -0
- exonware/xwsystem/io/serialization/formats/tabular/csv.py +319 -0
- exonware/xwsystem/io/serialization/formats/tabular/df.py +249 -0
- exonware/xwsystem/io/serialization/formats/tabular/excel.py +291 -0
- exonware/xwsystem/io/serialization/formats/tabular/googlesheets.py +374 -0
- exonware/xwsystem/io/serialization/formats/text/__init__.py +1 -1
- exonware/xwsystem/io/serialization/formats/text/append_only_log.py +5 -7
- exonware/xwsystem/io/serialization/formats/text/configparser.py +5 -5
- exonware/xwsystem/io/serialization/formats/text/csv.py +7 -5
- exonware/xwsystem/io/serialization/formats/text/formdata.py +5 -5
- exonware/xwsystem/io/serialization/formats/text/json.py +27 -18
- exonware/xwsystem/io/serialization/formats/text/json5.py +8 -4
- exonware/xwsystem/io/serialization/formats/text/jsonlines.py +18 -14
- exonware/xwsystem/io/serialization/formats/text/multipart.py +5 -5
- exonware/xwsystem/io/serialization/formats/text/toml.py +8 -6
- exonware/xwsystem/io/serialization/formats/text/xml.py +25 -20
- exonware/xwsystem/io/serialization/formats/text/yaml.py +8 -6
- exonware/xwsystem/io/serialization/parsers/__init__.py +3 -2
- exonware/xwsystem/io/serialization/parsers/base.py +6 -5
- exonware/xwsystem/io/serialization/parsers/hybrid_parser.py +7 -6
- exonware/xwsystem/io/serialization/parsers/msgspec_parser.py +10 -7
- exonware/xwsystem/io/serialization/parsers/orjson_direct_parser.py +7 -6
- exonware/xwsystem/io/serialization/parsers/orjson_parser.py +11 -8
- exonware/xwsystem/io/serialization/parsers/pysimdjson_parser.py +13 -9
- exonware/xwsystem/io/serialization/parsers/rapidjson_parser.py +10 -7
- exonware/xwsystem/io/serialization/parsers/registry.py +11 -10
- exonware/xwsystem/io/serialization/parsers/standard.py +7 -6
- exonware/xwsystem/io/serialization/parsers/ujson_parser.py +10 -7
- exonware/xwsystem/io/serialization/registry.py +4 -4
- exonware/xwsystem/io/serialization/serializer.py +168 -79
- exonware/xwsystem/io/serialization/universal_options.py +367 -0
- exonware/xwsystem/io/serialization/utils/__init__.py +1 -2
- exonware/xwsystem/io/serialization/utils/path_ops.py +5 -6
- exonware/xwsystem/io/source_reader.py +223 -0
- exonware/xwsystem/io/stream/__init__.py +1 -1
- exonware/xwsystem/io/stream/async_operations.py +61 -14
- exonware/xwsystem/io/stream/base.py +1 -2
- exonware/xwsystem/io/stream/codec_io.py +6 -7
- exonware/xwsystem/ipc/__init__.py +1 -0
- exonware/xwsystem/ipc/async_fabric.py +4 -4
- exonware/xwsystem/ipc/base.py +6 -5
- exonware/xwsystem/ipc/contracts.py +41 -66
- exonware/xwsystem/ipc/defs.py +2 -1
- exonware/xwsystem/ipc/errors.py +2 -1
- exonware/xwsystem/ipc/message_queue.py +5 -2
- exonware/xwsystem/ipc/pipes.py +70 -34
- exonware/xwsystem/ipc/process_manager.py +7 -5
- exonware/xwsystem/ipc/process_pool.py +6 -5
- exonware/xwsystem/ipc/shared_memory.py +64 -11
- exonware/xwsystem/monitoring/__init__.py +7 -0
- exonware/xwsystem/monitoring/base.py +11 -8
- exonware/xwsystem/monitoring/contracts.py +86 -144
- exonware/xwsystem/monitoring/defs.py +2 -1
- exonware/xwsystem/monitoring/error_recovery.py +16 -3
- exonware/xwsystem/monitoring/errors.py +2 -1
- exonware/xwsystem/monitoring/facade.py +183 -0
- exonware/xwsystem/monitoring/memory_monitor.py +1 -0
- exonware/xwsystem/monitoring/metrics.py +1 -0
- exonware/xwsystem/monitoring/performance_manager_generic.py +7 -7
- exonware/xwsystem/monitoring/performance_monitor.py +1 -0
- exonware/xwsystem/monitoring/performance_validator.py +1 -0
- exonware/xwsystem/monitoring/system_monitor.py +6 -5
- exonware/xwsystem/monitoring/tracing.py +18 -16
- exonware/xwsystem/monitoring/tracker.py +2 -1
- exonware/xwsystem/operations/__init__.py +5 -50
- exonware/xwsystem/operations/base.py +3 -44
- exonware/xwsystem/operations/contracts.py +25 -15
- exonware/xwsystem/operations/defs.py +1 -1
- exonware/xwsystem/operations/diff.py +5 -4
- exonware/xwsystem/operations/errors.py +1 -1
- exonware/xwsystem/operations/merge.py +6 -4
- exonware/xwsystem/operations/patch.py +5 -4
- exonware/xwsystem/patterns/__init__.py +1 -0
- exonware/xwsystem/patterns/base.py +2 -1
- exonware/xwsystem/patterns/context_manager.py +2 -1
- exonware/xwsystem/patterns/contracts.py +215 -256
- exonware/xwsystem/patterns/defs.py +2 -1
- exonware/xwsystem/patterns/dynamic_facade.py +1 -0
- exonware/xwsystem/patterns/errors.py +2 -4
- exonware/xwsystem/patterns/handler_factory.py +2 -3
- exonware/xwsystem/patterns/import_registry.py +1 -0
- exonware/xwsystem/patterns/object_pool.py +1 -0
- exonware/xwsystem/patterns/registry.py +4 -43
- exonware/xwsystem/plugins/__init__.py +2 -1
- exonware/xwsystem/plugins/base.py +6 -5
- exonware/xwsystem/plugins/contracts.py +94 -158
- exonware/xwsystem/plugins/defs.py +2 -1
- exonware/xwsystem/plugins/errors.py +2 -1
- exonware/xwsystem/py.typed +3 -0
- exonware/xwsystem/query/__init__.py +36 -0
- exonware/xwsystem/query/contracts.py +56 -0
- exonware/xwsystem/query/errors.py +22 -0
- exonware/xwsystem/query/registry.py +128 -0
- exonware/xwsystem/runtime/__init__.py +2 -1
- exonware/xwsystem/runtime/base.py +4 -3
- exonware/xwsystem/runtime/contracts.py +39 -60
- exonware/xwsystem/runtime/defs.py +2 -1
- exonware/xwsystem/runtime/env.py +11 -9
- exonware/xwsystem/runtime/errors.py +2 -1
- exonware/xwsystem/runtime/reflection.py +3 -2
- exonware/xwsystem/security/__init__.py +68 -11
- exonware/xwsystem/security/audit.py +167 -0
- exonware/xwsystem/security/base.py +121 -24
- exonware/xwsystem/security/contracts.py +91 -146
- exonware/xwsystem/security/crypto.py +17 -16
- exonware/xwsystem/security/defs.py +2 -1
- exonware/xwsystem/security/errors.py +2 -1
- exonware/xwsystem/security/facade.py +321 -0
- exonware/xwsystem/security/file_security.py +330 -0
- exonware/xwsystem/security/hazmat.py +11 -8
- exonware/xwsystem/security/monitor.py +372 -0
- exonware/xwsystem/security/path_validator.py +140 -18
- exonware/xwsystem/security/policy.py +357 -0
- exonware/xwsystem/security/resource_limits.py +1 -0
- exonware/xwsystem/security/validator.py +455 -0
- exonware/xwsystem/shared/__init__.py +14 -1
- exonware/xwsystem/shared/base.py +285 -2
- exonware/xwsystem/shared/contracts.py +415 -126
- exonware/xwsystem/shared/defs.py +2 -1
- exonware/xwsystem/shared/errors.py +2 -2
- exonware/xwsystem/shared/xwobject.py +316 -0
- exonware/xwsystem/structures/__init__.py +1 -0
- exonware/xwsystem/structures/base.py +3 -2
- exonware/xwsystem/structures/circular_detector.py +15 -14
- exonware/xwsystem/structures/contracts.py +53 -76
- exonware/xwsystem/structures/defs.py +2 -1
- exonware/xwsystem/structures/errors.py +2 -1
- exonware/xwsystem/structures/tree_walker.py +2 -1
- exonware/xwsystem/threading/__init__.py +21 -4
- exonware/xwsystem/threading/async_primitives.py +6 -5
- exonware/xwsystem/threading/base.py +3 -2
- exonware/xwsystem/threading/contracts.py +87 -143
- exonware/xwsystem/threading/defs.py +2 -1
- exonware/xwsystem/threading/errors.py +2 -1
- exonware/xwsystem/threading/facade.py +175 -0
- exonware/xwsystem/threading/locks.py +1 -0
- exonware/xwsystem/threading/safe_factory.py +1 -0
- exonware/xwsystem/utils/__init__.py +40 -0
- exonware/xwsystem/utils/base.py +22 -21
- exonware/xwsystem/utils/contracts.py +50 -73
- exonware/xwsystem/utils/dt/__init__.py +19 -3
- exonware/xwsystem/utils/dt/base.py +5 -4
- exonware/xwsystem/utils/dt/contracts.py +22 -29
- exonware/xwsystem/utils/dt/defs.py +2 -1
- exonware/xwsystem/utils/dt/errors.py +2 -5
- exonware/xwsystem/utils/dt/formatting.py +88 -2
- exonware/xwsystem/utils/dt/humanize.py +10 -9
- exonware/xwsystem/utils/dt/parsing.py +56 -5
- exonware/xwsystem/utils/dt/timezone_utils.py +2 -24
- exonware/xwsystem/utils/errors.py +2 -4
- exonware/xwsystem/utils/paths.py +1 -0
- exonware/xwsystem/utils/string.py +49 -0
- exonware/xwsystem/utils/test_runner.py +185 -0
- exonware/xwsystem/utils/utils_contracts.py +2 -1
- exonware/xwsystem/utils/web.py +110 -0
- exonware/xwsystem/validation/__init__.py +25 -1
- exonware/xwsystem/validation/base.py +6 -5
- exonware/xwsystem/validation/contracts.py +29 -41
- exonware/xwsystem/validation/data_validator.py +1 -0
- exonware/xwsystem/validation/declarative.py +11 -8
- exonware/xwsystem/validation/defs.py +2 -1
- exonware/xwsystem/validation/errors.py +2 -1
- exonware/xwsystem/validation/facade.py +198 -0
- exonware/xwsystem/validation/fluent_validator.py +22 -19
- exonware/xwsystem/validation/schema_discovery.py +210 -0
- exonware/xwsystem/validation/type_safety.py +2 -1
- exonware/xwsystem/version.py +2 -2
- {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/METADATA +71 -4
- exonware_xwsystem-0.1.0.4.dist-info/RECORD +337 -0
- exonware/xwsystem/cli/__init__.py +0 -43
- exonware/xwsystem/cli/console.py +0 -113
- exonware/xwsystem/cli/defs.py +0 -134
- exonware/xwsystem/conf.py +0 -44
- exonware/xwsystem/security/auth.py +0 -484
- exonware_xwsystem-0.1.0.1.dist-info/RECORD +0 -284
- {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/WHEEL +0 -0
- {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/licenses/LICENSE +0 -0
exonware/xwsystem/shared/defs.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
+
#exonware/xwsystem/src/exonware/xwsystem/shared/defs.py
|
|
2
3
|
#exonware/xwsystem/shared/defs.py
|
|
3
4
|
"""
|
|
4
5
|
Company: eXonware.com
|
|
5
6
|
Author: Eng. Muhammad AlShehri
|
|
6
7
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.1.0.
|
|
8
|
+
Version: 0.1.0.4
|
|
8
9
|
Generation Date: 10-Sep-2025
|
|
9
10
|
|
|
10
11
|
Shared types and enums for XWSystem modules.
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/shared/errors.py
|
|
1
2
|
#exonware/xwsystem/shared/errors.py
|
|
2
3
|
"""
|
|
3
4
|
Company: eXonware.com
|
|
4
5
|
Author: Eng. Muhammad AlShehri
|
|
5
6
|
Email: connect@exonware.com
|
|
6
|
-
Version: 0.1.0.
|
|
7
|
+
Version: 0.1.0.4
|
|
7
8
|
Generation Date: September 04, 2025
|
|
8
9
|
|
|
9
10
|
Shared exceptions (merged from the former core module).
|
|
@@ -74,4 +75,3 @@ class CoreOperationError(CoreError):
|
|
|
74
75
|
"""Raised when core operation fails."""
|
|
75
76
|
|
|
76
77
|
pass
|
|
77
|
-
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/shared/xwobject.py
|
|
2
|
+
#exonware/xwsystem/shared/xwobject.py
|
|
3
|
+
"""
|
|
4
|
+
Company: eXonware.com
|
|
5
|
+
Author: Eng. Muhammad AlShehri
|
|
6
|
+
Email: connect@exonware.com
|
|
7
|
+
Version: 0.1.0.4
|
|
8
|
+
Generation Date: September 04, 2025
|
|
9
|
+
|
|
10
|
+
XWObject - Concrete base class for all objects in the eXonware ecosystem.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from typing import Any, Optional
|
|
14
|
+
from datetime import datetime
|
|
15
|
+
import uuid
|
|
16
|
+
|
|
17
|
+
from .base import AObject
|
|
18
|
+
from .contracts import IObject
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class XWObject(AObject):
|
|
22
|
+
"""
|
|
23
|
+
Concrete base class for all objects in the eXonware ecosystem.
|
|
24
|
+
|
|
25
|
+
Provides common functionality shared by objects across xwauth, xwstorage,
|
|
26
|
+
xwentity, and other libraries:
|
|
27
|
+
- Identity management (id property, uid with UUID generation)
|
|
28
|
+
- Timestamp tracking (created_at, updated_at - abstract, must be set by subclasses)
|
|
29
|
+
- Metadata (title, description - optional)
|
|
30
|
+
- Serialization (to_dict, to_native)
|
|
31
|
+
- Storage operations (save, load - abstract, to be implemented by subclasses)
|
|
32
|
+
|
|
33
|
+
Subclasses must implement:
|
|
34
|
+
- id property (returns object identifier)
|
|
35
|
+
- created_at property
|
|
36
|
+
- updated_at property
|
|
37
|
+
- to_dict() method (should include id, uid, created_at, updated_at, title, description)
|
|
38
|
+
- save() method (object-specific storage logic)
|
|
39
|
+
- load() method (object-specific loading logic)
|
|
40
|
+
|
|
41
|
+
Example:
|
|
42
|
+
>>> class MyEntity(XWObject):
|
|
43
|
+
... def __init__(self):
|
|
44
|
+
... super().__init__()
|
|
45
|
+
... self._id = "my_id"
|
|
46
|
+
... self._created_at = datetime.now()
|
|
47
|
+
... self._updated_at = self._created_at
|
|
48
|
+
... self._title = "My Entity"
|
|
49
|
+
... self._description = "Description of my entity"
|
|
50
|
+
...
|
|
51
|
+
... @property
|
|
52
|
+
... def id(self) -> str:
|
|
53
|
+
... return self._id
|
|
54
|
+
...
|
|
55
|
+
... @property
|
|
56
|
+
... def created_at(self) -> datetime:
|
|
57
|
+
... return self._created_at
|
|
58
|
+
...
|
|
59
|
+
... @property
|
|
60
|
+
... def updated_at(self) -> datetime:
|
|
61
|
+
... return self._updated_at
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
def __init__(self, object_id: Optional[str] = None):
|
|
65
|
+
"""
|
|
66
|
+
Initialize XWObject base class.
|
|
67
|
+
|
|
68
|
+
Generates uid (GUID) on creation. Subclasses should call super().__init__()
|
|
69
|
+
and then initialize:
|
|
70
|
+
- self._created_at
|
|
71
|
+
- self._updated_at
|
|
72
|
+
- self._title (optional)
|
|
73
|
+
- self._description (optional)
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
object_id: Optional object identifier (subclasses define their own id property)
|
|
77
|
+
"""
|
|
78
|
+
super().__init__(object_id)
|
|
79
|
+
# Generate uid (GUID) on creation
|
|
80
|
+
self._uid = str(uuid.uuid4())
|
|
81
|
+
# Timestamps are initialized by subclasses
|
|
82
|
+
# Set self._created_at and self._updated_at in __init__
|
|
83
|
+
# Title and description are optional
|
|
84
|
+
self._title: Optional[str] = None
|
|
85
|
+
self._description: Optional[str] = None
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def uid(self) -> str:
|
|
89
|
+
"""
|
|
90
|
+
Get the unique object GUID (universal identifier).
|
|
91
|
+
|
|
92
|
+
This is automatically generated on object creation and provides
|
|
93
|
+
a globally unique identifier for the object.
|
|
94
|
+
"""
|
|
95
|
+
return self._uid
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def title(self) -> Optional[str]:
|
|
99
|
+
"""
|
|
100
|
+
Get the object title.
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
Title string or None if not set
|
|
104
|
+
"""
|
|
105
|
+
return self._title
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def description(self) -> Optional[str]:
|
|
109
|
+
"""
|
|
110
|
+
Get the object description.
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
Description string or None if not set
|
|
114
|
+
"""
|
|
115
|
+
return self._description
|
|
116
|
+
|
|
117
|
+
def _update_timestamp(self) -> None:
|
|
118
|
+
"""
|
|
119
|
+
Update the updated_at timestamp.
|
|
120
|
+
|
|
121
|
+
Subclasses should call this method when modifying the object.
|
|
122
|
+
This is a helper method that subclasses should implement by updating
|
|
123
|
+
self._updated_at. The default implementation does nothing.
|
|
124
|
+
"""
|
|
125
|
+
# Subclasses implement this by updating self._updated_at
|
|
126
|
+
# This is a helper method that can be overridden
|
|
127
|
+
pass
|
|
128
|
+
|
|
129
|
+
def to_native(self) -> Any:
|
|
130
|
+
"""
|
|
131
|
+
Get object as native representation.
|
|
132
|
+
|
|
133
|
+
Default implementation returns to_dict(). Subclasses can override
|
|
134
|
+
if they need a different native representation.
|
|
135
|
+
"""
|
|
136
|
+
return self.to_dict()
|
|
137
|
+
|
|
138
|
+
def __str__(self) -> str:
|
|
139
|
+
"""
|
|
140
|
+
String representation as JSON-like output (reusable by XWSchema, XWData, etc.).
|
|
141
|
+
Uses xwsystem JsonSerializer; to_native() so subclasses get their own content.
|
|
142
|
+
"""
|
|
143
|
+
try:
|
|
144
|
+
from exonware.xwsystem.io.serialization import JsonSerializer
|
|
145
|
+
out = JsonSerializer().encode(
|
|
146
|
+
self.to_native(),
|
|
147
|
+
options={"indent": 2, "ensure_ascii": False, "default": str}
|
|
148
|
+
)
|
|
149
|
+
return out if isinstance(out, str) else out.decode("utf-8")
|
|
150
|
+
except Exception:
|
|
151
|
+
return super().__str__()
|
|
152
|
+
|
|
153
|
+
@classmethod
|
|
154
|
+
def from_string(cls, s: str) -> "IObject":
|
|
155
|
+
"""
|
|
156
|
+
Create instance from JSON string (reusable by subclasses).
|
|
157
|
+
Uses xwsystem JsonSerializer. Default: decode, create instance, call from_native(data).
|
|
158
|
+
Subclasses (e.g. XWSchema) may override to construct from schema/data dict.
|
|
159
|
+
"""
|
|
160
|
+
from exonware.xwsystem.io.serialization import JsonSerializer
|
|
161
|
+
data = JsonSerializer().decode(s)
|
|
162
|
+
obj = cls()
|
|
163
|
+
obj.from_native(data)
|
|
164
|
+
return obj
|
|
165
|
+
|
|
166
|
+
def from_native(self, data: dict[str, Any]) -> "IObject":
|
|
167
|
+
"""
|
|
168
|
+
Populate object from native Python dictionary.
|
|
169
|
+
|
|
170
|
+
This method takes a dictionary and populates the object's properties.
|
|
171
|
+
It handles:
|
|
172
|
+
- uid: Sets _uid if present in dict
|
|
173
|
+
- title: Sets _title if present in dict
|
|
174
|
+
- description: Sets _description if present in dict
|
|
175
|
+
- created_at: Sets _created_at if present (as datetime or ISO string)
|
|
176
|
+
- updated_at: Sets _updated_at if present (as datetime or ISO string)
|
|
177
|
+
- id: Sets _id if present (subclasses may use this)
|
|
178
|
+
- Any other attributes: Sets them directly on the object
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
data: Dictionary containing object data
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
Self (for chaining) - returns IObject to match protocol
|
|
185
|
+
|
|
186
|
+
Example:
|
|
187
|
+
>>> obj = XWObject()
|
|
188
|
+
>>> obj.from_native({
|
|
189
|
+
... "uid": "123e4567-e89b-12d3-a456-426614174000",
|
|
190
|
+
... "title": "My Object",
|
|
191
|
+
... "description": "Description",
|
|
192
|
+
... "created_at": "2025-01-25T10:00:00",
|
|
193
|
+
... "updated_at": "2025-01-25T11:00:00"
|
|
194
|
+
... })
|
|
195
|
+
"""
|
|
196
|
+
if not isinstance(data, dict):
|
|
197
|
+
raise TypeError(f"from_native expects a dict, got {type(data).__name__}")
|
|
198
|
+
|
|
199
|
+
# Handle uid
|
|
200
|
+
if "uid" in data:
|
|
201
|
+
self._uid = str(data["uid"])
|
|
202
|
+
|
|
203
|
+
# Handle title
|
|
204
|
+
if "title" in data:
|
|
205
|
+
self._title = data["title"] if data["title"] is not None else None
|
|
206
|
+
|
|
207
|
+
# Handle description
|
|
208
|
+
if "description" in data:
|
|
209
|
+
self._description = data["description"] if data["description"] is not None else None
|
|
210
|
+
|
|
211
|
+
# Handle created_at (if _created_at attribute exists)
|
|
212
|
+
if "created_at" in data and hasattr(self, "_created_at"):
|
|
213
|
+
created_at_value = data["created_at"]
|
|
214
|
+
if isinstance(created_at_value, str):
|
|
215
|
+
try:
|
|
216
|
+
self._created_at = datetime.fromisoformat(created_at_value.replace("Z", "+00:00"))
|
|
217
|
+
except (ValueError, AttributeError):
|
|
218
|
+
# If parsing fails, try to set as string (subclass may handle it)
|
|
219
|
+
self._created_at = created_at_value
|
|
220
|
+
elif isinstance(created_at_value, datetime):
|
|
221
|
+
self._created_at = created_at_value
|
|
222
|
+
|
|
223
|
+
# Handle updated_at (if _updated_at attribute exists)
|
|
224
|
+
if "updated_at" in data and hasattr(self, "_updated_at"):
|
|
225
|
+
updated_at_value = data["updated_at"]
|
|
226
|
+
if isinstance(updated_at_value, str):
|
|
227
|
+
try:
|
|
228
|
+
self._updated_at = datetime.fromisoformat(updated_at_value.replace("Z", "+00:00"))
|
|
229
|
+
except (ValueError, AttributeError):
|
|
230
|
+
# If parsing fails, try to set as string (subclass may handle it)
|
|
231
|
+
self._updated_at = updated_at_value
|
|
232
|
+
elif isinstance(updated_at_value, datetime):
|
|
233
|
+
self._updated_at = updated_at_value
|
|
234
|
+
|
|
235
|
+
# Handle id (if _id attribute exists - subclasses may use this)
|
|
236
|
+
if "id" in data and hasattr(self, "_id"):
|
|
237
|
+
self._id = str(data["id"])
|
|
238
|
+
|
|
239
|
+
# Handle any other attributes in the dict
|
|
240
|
+
# Set them directly on the object (subclasses may use this)
|
|
241
|
+
for key, value in data.items():
|
|
242
|
+
if key not in ("uid", "title", "description", "created_at", "updated_at", "id"):
|
|
243
|
+
setattr(self, key, value)
|
|
244
|
+
|
|
245
|
+
return self
|
|
246
|
+
|
|
247
|
+
def __getitem__(self, key: str) -> Any:
|
|
248
|
+
"""
|
|
249
|
+
Get object property using dictionary-style access.
|
|
250
|
+
|
|
251
|
+
Supports accessing properties like:
|
|
252
|
+
- obj["uid"] -> returns uid property
|
|
253
|
+
- obj["title"] -> returns title property
|
|
254
|
+
- obj["description"] -> returns description property
|
|
255
|
+
- obj["id"] -> returns id property (if implemented)
|
|
256
|
+
- obj["created_at"] -> returns created_at property (if implemented)
|
|
257
|
+
- obj["updated_at"] -> returns updated_at property (if implemented)
|
|
258
|
+
- obj["property_name"] -> returns any other attribute
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
key: Property name to access
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
Property value
|
|
265
|
+
|
|
266
|
+
Raises:
|
|
267
|
+
KeyError: If property doesn't exist
|
|
268
|
+
|
|
269
|
+
Example:
|
|
270
|
+
>>> obj = XWObject()
|
|
271
|
+
>>> obj._title = "My Title"
|
|
272
|
+
>>> print(obj["title"]) # "My Title"
|
|
273
|
+
>>> print(obj["uid"]) # UUID string
|
|
274
|
+
"""
|
|
275
|
+
# Try to get via property methods first
|
|
276
|
+
if key == "uid":
|
|
277
|
+
return self.uid
|
|
278
|
+
elif key == "title":
|
|
279
|
+
return self.title
|
|
280
|
+
elif key == "description":
|
|
281
|
+
return self.description
|
|
282
|
+
elif key == "id":
|
|
283
|
+
# Try to get id property (may be abstract in some cases)
|
|
284
|
+
try:
|
|
285
|
+
return self.id
|
|
286
|
+
except (AttributeError, NotImplementedError):
|
|
287
|
+
# Fall back to _id attribute if it exists
|
|
288
|
+
if hasattr(self, "_id"):
|
|
289
|
+
return self._id
|
|
290
|
+
raise KeyError(f"Property 'id' not available")
|
|
291
|
+
elif key == "created_at":
|
|
292
|
+
# Try to get created_at property (may be abstract)
|
|
293
|
+
try:
|
|
294
|
+
return self.created_at
|
|
295
|
+
except (AttributeError, NotImplementedError):
|
|
296
|
+
# Fall back to _created_at attribute if it exists
|
|
297
|
+
if hasattr(self, "_created_at"):
|
|
298
|
+
return self._created_at
|
|
299
|
+
raise KeyError(f"Property 'created_at' not available")
|
|
300
|
+
elif key == "updated_at":
|
|
301
|
+
# Try to get updated_at property (may be abstract)
|
|
302
|
+
try:
|
|
303
|
+
return self.updated_at
|
|
304
|
+
except (AttributeError, NotImplementedError):
|
|
305
|
+
# Fall back to _updated_at attribute if it exists
|
|
306
|
+
if hasattr(self, "_updated_at"):
|
|
307
|
+
return self._updated_at
|
|
308
|
+
raise KeyError(f"Property 'updated_at' not available")
|
|
309
|
+
else:
|
|
310
|
+
# Try to get as attribute
|
|
311
|
+
if hasattr(self, key):
|
|
312
|
+
return getattr(self, key)
|
|
313
|
+
# Try with underscore prefix (private attributes)
|
|
314
|
+
if hasattr(self, f"_{key}"):
|
|
315
|
+
return getattr(self, f"_{key}")
|
|
316
|
+
raise KeyError(f"Property '{key}' not found")
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/structures/base.py
|
|
1
2
|
#exonware/xwsystem/structures/base.py
|
|
2
3
|
"""
|
|
3
4
|
Company: eXonware.com
|
|
4
5
|
Author: Eng. Muhammad AlShehri
|
|
5
6
|
Email: connect@exonware.com
|
|
6
|
-
Version: 0.1.0.
|
|
7
|
+
Version: 0.1.0.4
|
|
7
8
|
Generation Date: September 04, 2025
|
|
8
9
|
|
|
9
10
|
Structures module base classes - abstract classes for data structure functionality.
|
|
10
11
|
"""
|
|
11
12
|
|
|
12
13
|
from abc import ABC, abstractmethod
|
|
13
|
-
from typing import Any, Optional,
|
|
14
|
+
from typing import Any, Optional, Iterator
|
|
14
15
|
from .contracts import StructureType, TraversalType, ValidationLevel
|
|
15
16
|
|
|
16
17
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/structures/circular_detector.py
|
|
1
2
|
"""
|
|
2
3
|
Circular reference detection and management utilities.
|
|
3
4
|
"""
|
|
@@ -5,7 +6,7 @@ Circular reference detection and management utilities.
|
|
|
5
6
|
import logging
|
|
6
7
|
import weakref
|
|
7
8
|
from collections import defaultdict
|
|
8
|
-
from typing import Any, Optional
|
|
9
|
+
from typing import Any, Optional
|
|
9
10
|
|
|
10
11
|
logger = logging.getLogger(__name__)
|
|
11
12
|
|
|
@@ -56,6 +57,18 @@ class CircularReferenceDetector:
|
|
|
56
57
|
return True
|
|
57
58
|
finally:
|
|
58
59
|
self.reset()
|
|
60
|
+
|
|
61
|
+
def has_circular_references(self, obj: Any) -> bool:
|
|
62
|
+
"""
|
|
63
|
+
Check if an object has circular references (alias for is_circular).
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
obj: Object to check
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
True if circular references are detected
|
|
70
|
+
"""
|
|
71
|
+
return self.is_circular(obj)
|
|
59
72
|
|
|
60
73
|
def traverse(self, obj: Any, path: list[str]) -> None:
|
|
61
74
|
"""
|
|
@@ -139,7 +152,7 @@ class CircularReferenceDetector:
|
|
|
139
152
|
|
|
140
153
|
self.traverse(value, new_path)
|
|
141
154
|
|
|
142
|
-
def _traverse_sequence(self, obj:
|
|
155
|
+
def _traverse_sequence(self, obj: list | tuple | set, path: list[str]) -> None:
|
|
143
156
|
"""Traverse sequence objects (list, tuple, set)."""
|
|
144
157
|
for i, item in enumerate(obj):
|
|
145
158
|
new_path = path + [f"[{i}]"]
|
|
@@ -298,18 +311,6 @@ def has_circular_references(obj: Any, max_depth: int = 100) -> bool:
|
|
|
298
311
|
"""
|
|
299
312
|
detector = CircularReferenceDetector(max_depth=max_depth)
|
|
300
313
|
return detector.is_circular(obj)
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
class CircularDetector(CircularReferenceDetector):
|
|
304
|
-
"""Alias for CircularReferenceDetector for backward compatibility."""
|
|
305
|
-
|
|
306
|
-
def __init__(self, max_depth: int = 100):
|
|
307
|
-
"""Initialize circular detector."""
|
|
308
|
-
super().__init__(max_depth)
|
|
309
|
-
|
|
310
|
-
def detect(self, obj: Any) -> bool:
|
|
311
|
-
"""Detect circular references (alias for is_circular)."""
|
|
312
|
-
return self.is_circular(obj)
|
|
313
314
|
|
|
314
315
|
def check(self, obj: Any) -> bool:
|
|
315
316
|
"""Check for circular references (alias for is_circular)."""
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/structures/contracts.py
|
|
1
2
|
"""
|
|
2
3
|
Company: eXonware.com
|
|
3
4
|
Author: Eng. Muhammad AlShehri
|
|
4
5
|
Email: connect@exonware.com
|
|
5
|
-
Version: 0.1.0.
|
|
6
|
+
Version: 0.1.0.4
|
|
6
7
|
Generation Date: September 04, 2025
|
|
7
8
|
|
|
8
9
|
Structures module contracts - interfaces and enums for data structure functionality.
|
|
9
10
|
"""
|
|
10
11
|
|
|
11
|
-
from
|
|
12
|
-
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from typing import Any, Optional, Iterator, Callable, Protocol, runtime_checkable
|
|
13
15
|
|
|
14
16
|
# Import enums from types module
|
|
15
17
|
from .defs import (
|
|
@@ -22,177 +24,152 @@ from .defs import (
|
|
|
22
24
|
)
|
|
23
25
|
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
@runtime_checkable
|
|
28
|
+
class ITreeNode(Protocol):
|
|
26
29
|
"""Interface for tree node operations."""
|
|
27
30
|
|
|
28
31
|
@property
|
|
29
|
-
@abstractmethod
|
|
30
32
|
def value(self) -> Any:
|
|
31
33
|
"""Node value."""
|
|
32
|
-
|
|
34
|
+
...
|
|
33
35
|
|
|
34
36
|
@property
|
|
35
|
-
|
|
36
|
-
def children(self) -> list['ITreeNode']:
|
|
37
|
+
def children(self) -> list[ITreeNode]:
|
|
37
38
|
"""Node children."""
|
|
38
|
-
|
|
39
|
+
...
|
|
39
40
|
|
|
40
41
|
@property
|
|
41
|
-
|
|
42
|
-
def parent(self) -> Optional['ITreeNode']:
|
|
42
|
+
def parent(self) -> Optional[ITreeNode]:
|
|
43
43
|
"""Node parent."""
|
|
44
|
-
|
|
44
|
+
...
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
def add_child(self, child: 'ITreeNode') -> None:
|
|
46
|
+
def add_child(self, child: ITreeNode) -> None:
|
|
48
47
|
"""Add child node."""
|
|
49
|
-
|
|
48
|
+
...
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
def remove_child(self, child: 'ITreeNode') -> None:
|
|
50
|
+
def remove_child(self, child: ITreeNode) -> None:
|
|
53
51
|
"""Remove child node."""
|
|
54
|
-
|
|
52
|
+
...
|
|
55
53
|
|
|
56
|
-
@abstractmethod
|
|
57
54
|
def is_leaf(self) -> bool:
|
|
58
55
|
"""Check if node is leaf."""
|
|
59
|
-
|
|
56
|
+
...
|
|
60
57
|
|
|
61
|
-
@abstractmethod
|
|
62
58
|
def get_depth(self) -> int:
|
|
63
59
|
"""Get node depth."""
|
|
64
|
-
|
|
60
|
+
...
|
|
65
61
|
|
|
66
62
|
|
|
67
|
-
|
|
63
|
+
@runtime_checkable
|
|
64
|
+
class ITreeWalker(Protocol):
|
|
68
65
|
"""Interface for tree walking operations."""
|
|
69
66
|
|
|
70
|
-
@abstractmethod
|
|
71
67
|
def walk_preorder(self, root: ITreeNode) -> Iterator[ITreeNode]:
|
|
72
68
|
"""Walk tree in preorder."""
|
|
73
|
-
|
|
69
|
+
...
|
|
74
70
|
|
|
75
|
-
@abstractmethod
|
|
76
71
|
def walk_inorder(self, root: ITreeNode) -> Iterator[ITreeNode]:
|
|
77
72
|
"""Walk tree in inorder."""
|
|
78
|
-
|
|
73
|
+
...
|
|
79
74
|
|
|
80
|
-
@abstractmethod
|
|
81
75
|
def walk_postorder(self, root: ITreeNode) -> Iterator[ITreeNode]:
|
|
82
76
|
"""Walk tree in postorder."""
|
|
83
|
-
|
|
77
|
+
...
|
|
84
78
|
|
|
85
|
-
@abstractmethod
|
|
86
79
|
def walk_level_order(self, root: ITreeNode) -> Iterator[ITreeNode]:
|
|
87
80
|
"""Walk tree in level order."""
|
|
88
|
-
|
|
81
|
+
...
|
|
89
82
|
|
|
90
|
-
@abstractmethod
|
|
91
83
|
def find_nodes(self, root: ITreeNode, predicate: Callable[[ITreeNode], bool]) -> list[ITreeNode]:
|
|
92
84
|
"""Find nodes matching predicate."""
|
|
93
|
-
|
|
85
|
+
...
|
|
94
86
|
|
|
95
87
|
|
|
96
|
-
|
|
88
|
+
@runtime_checkable
|
|
89
|
+
class ICircularDetector(Protocol):
|
|
97
90
|
"""Interface for circular reference detection."""
|
|
98
91
|
|
|
99
|
-
@abstractmethod
|
|
100
92
|
def detect_circular_reference(self, obj: Any) -> bool:
|
|
101
93
|
"""Detect circular reference in object."""
|
|
102
|
-
|
|
94
|
+
...
|
|
103
95
|
|
|
104
|
-
@abstractmethod
|
|
105
96
|
def find_circular_paths(self, obj: Any) -> list[list[Any]]:
|
|
106
97
|
"""Find all circular paths."""
|
|
107
|
-
|
|
98
|
+
...
|
|
108
99
|
|
|
109
|
-
@abstractmethod
|
|
110
100
|
def get_circular_objects(self, obj: Any) -> list[Any]:
|
|
111
101
|
"""Get objects involved in circular references."""
|
|
112
|
-
|
|
102
|
+
...
|
|
113
103
|
|
|
114
|
-
@abstractmethod
|
|
115
104
|
def break_circular_references(self, obj: Any) -> Any:
|
|
116
105
|
"""Break circular references."""
|
|
117
|
-
|
|
106
|
+
...
|
|
118
107
|
|
|
119
108
|
|
|
120
|
-
|
|
109
|
+
@runtime_checkable
|
|
110
|
+
class IGraphNode(Protocol):
|
|
121
111
|
"""Interface for graph node operations."""
|
|
122
112
|
|
|
123
113
|
@property
|
|
124
|
-
@abstractmethod
|
|
125
114
|
def id(self) -> str:
|
|
126
115
|
"""Node ID."""
|
|
127
|
-
|
|
116
|
+
...
|
|
128
117
|
|
|
129
118
|
@property
|
|
130
|
-
@abstractmethod
|
|
131
119
|
def data(self) -> Any:
|
|
132
120
|
"""Node data."""
|
|
133
|
-
|
|
121
|
+
...
|
|
134
122
|
|
|
135
123
|
@property
|
|
136
|
-
|
|
137
|
-
def neighbors(self) -> list['IGraphNode']:
|
|
124
|
+
def neighbors(self) -> list[IGraphNode]:
|
|
138
125
|
"""Node neighbors."""
|
|
139
|
-
|
|
126
|
+
...
|
|
140
127
|
|
|
141
|
-
|
|
142
|
-
def add_neighbor(self, neighbor: 'IGraphNode', weight: Optional[float] = None) -> None:
|
|
128
|
+
def add_neighbor(self, neighbor: IGraphNode, weight: Optional[float] = None) -> None:
|
|
143
129
|
"""Add neighbor node."""
|
|
144
|
-
|
|
130
|
+
...
|
|
145
131
|
|
|
146
|
-
|
|
147
|
-
def remove_neighbor(self, neighbor: 'IGraphNode') -> None:
|
|
132
|
+
def remove_neighbor(self, neighbor: IGraphNode) -> None:
|
|
148
133
|
"""Remove neighbor node."""
|
|
149
|
-
|
|
134
|
+
...
|
|
150
135
|
|
|
151
|
-
|
|
152
|
-
def get_edge_weight(self, neighbor: 'IGraphNode') -> Optional[float]:
|
|
136
|
+
def get_edge_weight(self, neighbor: IGraphNode) -> Optional[float]:
|
|
153
137
|
"""Get edge weight to neighbor."""
|
|
154
|
-
|
|
138
|
+
...
|
|
155
139
|
|
|
156
140
|
|
|
157
|
-
|
|
141
|
+
@runtime_checkable
|
|
142
|
+
class IGraph(Protocol):
|
|
158
143
|
"""Interface for graph operations."""
|
|
159
144
|
|
|
160
|
-
@abstractmethod
|
|
161
145
|
def add_node(self, node: IGraphNode) -> None:
|
|
162
146
|
"""Add node to graph."""
|
|
163
|
-
|
|
147
|
+
...
|
|
164
148
|
|
|
165
|
-
@abstractmethod
|
|
166
149
|
def remove_node(self, node_id: str) -> None:
|
|
167
150
|
"""Remove node from graph."""
|
|
168
|
-
|
|
151
|
+
...
|
|
169
152
|
|
|
170
|
-
@abstractmethod
|
|
171
153
|
def get_node(self, node_id: str) -> Optional[IGraphNode]:
|
|
172
154
|
"""Get node by ID."""
|
|
173
|
-
|
|
155
|
+
...
|
|
174
156
|
|
|
175
|
-
@abstractmethod
|
|
176
157
|
def add_edge(self, from_node: str, to_node: str, weight: Optional[float] = None) -> None:
|
|
177
158
|
"""Add edge between nodes."""
|
|
178
|
-
|
|
159
|
+
...
|
|
179
160
|
|
|
180
|
-
@abstractmethod
|
|
181
161
|
def remove_edge(self, from_node: str, to_node: str) -> None:
|
|
182
162
|
"""Remove edge between nodes."""
|
|
183
|
-
|
|
163
|
+
...
|
|
184
164
|
|
|
185
|
-
@abstractmethod
|
|
186
165
|
def get_all_nodes(self) -> list[IGraphNode]:
|
|
187
166
|
"""Get all nodes."""
|
|
188
|
-
|
|
167
|
+
...
|
|
189
168
|
|
|
190
|
-
@abstractmethod
|
|
191
169
|
def get_all_edges(self) -> list[tuple]:
|
|
192
170
|
"""Get all edges."""
|
|
193
|
-
|
|
171
|
+
...
|
|
194
172
|
|
|
195
|
-
@abstractmethod
|
|
196
173
|
def is_connected(self, from_node: str, to_node: str) -> bool:
|
|
197
174
|
"""Check if nodes are connected."""
|
|
198
|
-
|
|
175
|
+
...
|