quadkit 0.0.41__tar.gz → 0.0.43__tar.gz
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.
- {quadkit-0.0.41 → quadkit-0.0.43}/PKG-INFO +4 -3
- {quadkit-0.0.41 → quadkit-0.0.43}/README.md +2 -2
- {quadkit-0.0.41 → quadkit-0.0.43}/example.yaml +2 -2
- {quadkit-0.0.41 → quadkit-0.0.43}/pyproject.toml +5 -2
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/config/models.py +6 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/module.py +1 -1
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/codegen/__init__.py +3 -0
- quadkit-0.0.43/src/quadkit/codegen/field_types.py +131 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/container/validation.py +4 -4
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/extensions/discovery.py +1 -1
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/resolution/resolver.py +1 -1
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/domain/unit_of_work.py +1 -1
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/identity/ambient.py +20 -3
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/logging/README.md +36 -8
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/logging/configurator.py +11 -7
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/logging/factory.py +56 -21
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/logging/processors.py +52 -3
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/observability/core.py +1 -1
- quadkit-0.0.43/src/quadkit/observability/di/sub_providers/observability.py +68 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/registry/introspection.py +1 -1
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/hashing/ambient.py +17 -2
- quadkit-0.0.43/tests/integration/test_corrected_patterns_integration.py +254 -0
- quadkit-0.0.43/tests/integration/test_database_integration.py +256 -0
- quadkit-0.0.43/tests/integration/test_monitor_config_integration.py +22 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/security/test_hashing.py +35 -1
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_identity_generators_and_ambient.py +46 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_logging_bridging.py +74 -2
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_logging_factory.py +60 -32
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_observability.py +45 -0
- quadkit-0.0.41/src/quadkit/observability/di/sub_providers/observability.py +0 -52
- {quadkit-0.0.41 → quadkit-0.0.43}/.gitignore +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/LICENSE +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/NOTICE +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/import_error.txt +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/asgi_lifespan.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/base.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/config/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/config/discovery.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/config_validation.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/di/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/di/provider.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/discovery.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/events.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/factory.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/health_probes.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/injectable_provider.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/invoker.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/lifecycle.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/pipeline.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/protocols.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/runner.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/secrets.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/standard.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/app/types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/codegen/base.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/bridges/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/bridges/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/bridges/sync_bridge.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/channels/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/channels/channel.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/channels/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/config.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/di/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/di/provider.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/di/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/executors/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/executors/dispatcher.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/executors/parallel.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/executors/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/executors/task_manager.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/locks/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/locks/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/locks/rwlock.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/module.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/concurrency/task_utils.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/config/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/config/base.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/config/constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/config/di/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/config/di/provider.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/config/exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/config/lib/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/config/lib/merge.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/config/lib/registry.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/config/lib/sources.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/config/lib/validation.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/config/lib/watcher.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/config/main.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/config/protocols.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/config/secrets.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/config/types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/_graph.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/builder.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/config/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/config/models.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/container/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/container/container.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/container/container_introspection.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/container/container_resolution.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/container/container_runtime.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/container/registrar.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/container/resolver.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/container/scope.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/context.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/decorators.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/extensions/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/extensions/aop_interceptors.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/extensions/interceptors.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/extensions/strategies.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/extensions/validator.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/function_provider.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/integration/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/integration/provider.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/markers.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/base.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/compiler/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/compiler/_graph_utils.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/compiler/compiler.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/compiler/context.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/compiler/phases/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/compiler/phases/collect.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/compiler/phases/detect_cycles.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/compiler/phases/expand.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/compiler/phases/order.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/compiler/phases/protocol.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/compiler/phases/validate.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/compiler/phases/visibility.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/decorator.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/dynamic.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/errors.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/graph.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/introspection.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/metadata.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/module/registry.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/orchestrator/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/orchestrator/events.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/orchestrator/health.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/orchestrator/lifecycle.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/orchestrator/orchestrator.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/orchestrator/registry.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/protocols.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/provider.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/provider_utils.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/resolution/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/resolution/context.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/resolution/descriptor.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/resolution/diagnostics.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/resolution/injector.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/resolution/invoker.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/resolution/registry.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/resolution/store.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/resolution/type_hints.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/resolution/validator.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/di/types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/domain/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/domain/constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/domain/exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/domain/models/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/domain/models/aggregate.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/domain/models/base.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/domain/models/coercion.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/domain/models/entity.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/domain/models/factory.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/domain/models/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/domain/models/value_object.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/domain/module.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/domain/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/domain/types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/hooks/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/hooks/ambient.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/hooks/registry.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/hooks/types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/identity/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/identity/config.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/identity/constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/identity/di/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/identity/di/provider.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/identity/generator.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/logging/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/logging/config/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/logging/config/models.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/logging/config/redaction.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/logging/config/sampling.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/logging/constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/logging/debug.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/logging/di/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/logging/di/provider.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/logging/redaction.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/logging/types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/mapping/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/mapping/config.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/mapping/constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/mapping/core/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/mapping/core/mapper.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/mapping/di/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/mapping/di/provider.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/mapping/exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/mapping/module.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/mapping/protocols.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/mapping/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/mapping/types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/middleware/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/middleware/builtins/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/middleware/builtins/caching.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/middleware/builtins/di.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/middleware/builtins/observability.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/middleware/builtins/resilience.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/middleware/builtins/routing.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/middleware/builtins/validation.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/middleware/config.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/middleware/constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/middleware/core/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/middleware/core/chain.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/middleware/core/exception_filters.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/middleware/core/registry.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/middleware/di/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/middleware/di/provider.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/middleware/exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/middleware/module.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/middleware/types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/module.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/observability/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/observability/di/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/observability/di/sub_providers/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/plugins/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/plugins/discovery.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/plugins/engine.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/plugins/exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/plugins/module.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/plugins/state.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/builder.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/clock.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/context.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/context_keys.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/context_registry.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/data.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/di/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/di/provider.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/lazy.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/pipeline.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/protocols.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/registry/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/registry/core.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/trusted_html.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/primitives/typing.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/reactive/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/reactive/core.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/reactive/exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/reactive/operators/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/reactive/operators/control.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/reactive/operators/time_ops.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/reactive/operators/transform.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/reactive/retry.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/reactive/subjects.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/result/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/result/_pipeline.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/result/errors.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/result/types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/result/utils.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/saga/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/saga/base.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/saga/canonical_json.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/saga/content_addressed.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/config.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/decorators.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/encryption/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/encryption/service.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/events.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/guards/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/guards/chain.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/guards/decorator.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/hashing/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/hashing/digest.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/hashing/kdf.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/hooks.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/provider.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/sanitization/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/sanitization/filename.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/sanitization/html.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/sanitization/sanitizer.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/sanitization/url.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/secrets/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/secrets/rotation.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/secrets/store.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/secrets/types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/security/types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/backends/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/backends/json.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/backends/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/config.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/di/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/di/provider.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/di/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/domain/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/domain/domain.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/domain/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/module.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/registry/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/registry/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/registry/registry.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/schema/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/schema/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/schema/schema.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/serialization/types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/validation/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/validation/config.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/validation/constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/validation/decorators.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/validation/engine/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/validation/engine/coercion.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/validation/engine/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/validation/engine/validator.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/validation/exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/validation/module.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/validation/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/validation/rules/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/validation/rules/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/validation/rules/rules.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/validation/schema/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/validation/schema/fields.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/validation/schema/introspection.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/validation/schema/py.typed +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/src/quadkit/validation/types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/conftest.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/integration/di/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/integration/di/module/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/integration/di/module/_fixtures.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/integration/di/module/conftest.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/integration/di/module/test_boot_level.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/integration/di/module/test_cross_method.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/integration/di/module/test_dependency_chain.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/integration/di/module/test_exports.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/integration/di/module/test_importers.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/integration/di/module/test_module_health_integration.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/integration/di/module/test_module_lifecycle_integration.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/integration/di/module/test_name_lookup.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/integration/di/module/test_stub_enforcement_integration.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/integration/di/test_visibility_enforcement_e2e.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/integration/mapping/test_mapping_lifecycle.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/integration/middleware/test_middleware_lifecycle.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/integration/test_full_pipeline.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/test.md +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/test_import_diagnostic.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/aop/test_interceptor_timeout.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/clock/test_clock.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/codegen/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/codegen/test_generator_base.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/codegen/test_staged_generation.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/codegen/test_template_overrides.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/concurrency/conftest.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/concurrency/test_bounded_channel.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/concurrency/test_channel.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/concurrency/test_concurrency_config.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/concurrency/test_concurrency_constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/concurrency/test_concurrency_constants_new.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/concurrency/test_concurrency_exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/concurrency/test_concurrency_parallel.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/concurrency/test_concurrency_provider_config.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/concurrency/test_concurrency_rwlock.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/concurrency/test_config_pool.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/concurrency/test_dispatcher.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/concurrency/test_sync_bridge.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/concurrency/test_task_manager.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/concurrency/test_task_utils.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/config/test_config_constants_new.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/config/test_config_protocols.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/config/test_config_sources.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/config/test_env_interpolation.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/config/test_loader_fail_fast.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/config/test_logging_redaction_config.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/config/test_logging_sampling.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/config/test_profile_overlay.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/config/test_scoping.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/config/test_secrets_validator.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/config/test_strict_bool_env.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/config/test_strict_sections.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/core/test_context_correlation.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/core/test_core_constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/core/test_core_types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/core/test_request_context_di.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/core/test_typing.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/core/validation/test_protocols.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/integration/test_provider.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/module/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/module/conftest.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/module/test_compiler.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/module/test_decorator.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/module/test_dynamic.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/module/test_errors.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/module/test_global.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/module/test_graph_reflection.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/module/test_health_graph.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/module/test_integration.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/module/test_introspection.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/module/test_lifecycle.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/module/test_module_lifecycle.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/module/test_reexport.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/module/test_registry.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/module/test_stub_compiler.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/module/test_stub_decorator.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/module/test_visibility.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_advanced_features.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_container_basics.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_container_builder.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_container_freeze.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_container_hardening.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_container_visibility.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_decorators.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_descriptor.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_di_constants_new.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_di_decorators.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_di_provider_config_wiring.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_diagnostics.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_extensions_discovery.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_extensions_validator.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_function_provider_boot.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_graph_validator.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_interceptor_registry.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_invoker_unit.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_lifecycle_orchestrator.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_module_validation.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_module_visibility_boot.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_module_visibility_enforcement.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_named_binding.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_orchestrator_health.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_provider_basics.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_provider_config_injection.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_provider_conformance.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_provider_orchestration.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_provider_reset_state.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_provider_utils.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_scope_concurrency.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_scope_manager.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_service_store.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_type_hints.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/di/test_validation.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/domain/conftest.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/domain/test_aggregates.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/domain/test_domain.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/domain/test_domain_constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/domain/test_domain_exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/domain/test_domain_init.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/domain/test_domain_model_strict.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/domain/test_domain_module.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/domain/test_models_factory.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/domain/test_value_object.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/identity/test_identity.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/logging/test_logging_constants_new.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/mapping/conftest.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/mapping/test_auto_map.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/mapping/test_exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/mapping/test_mapping_constants_new.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/mapping/test_mapping_exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/mapping/test_mapping_mapper.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/mapping/test_mapping_module.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/mapping/test_mapping_types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/mapping/test_protocol.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/mapping/test_registry.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/middleware/conftest.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/middleware/test_builtins.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/middleware/test_chain.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/middleware/test_config_alignment.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/middleware/test_exception_filters.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/middleware/test_middleware_chain.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/middleware/test_middleware_constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/middleware/test_middleware_constants_new.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/middleware/test_middleware_ep_discovery.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/middleware/test_middleware_exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/middleware/test_middleware_module.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/middleware/test_middleware_routing.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/middleware/test_middleware_types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/middleware/test_p2_retry_traceback.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/middleware/test_registry_defaults.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/middleware/test_registry_with_resilience.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/plugins/test_discovery.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/plugins/test_engine.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/plugins/test_state.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/plugins/test_state_hardening.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/plugins/test_validation.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/primitives/test_primitives_constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/primitives/test_registry_advanced.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/primitives/test_registry_introspection.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/primitives/test_trusted_html.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/reactive/test_control.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/reactive/test_core.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/reactive/test_facade.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/reactive/test_retry.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/reactive/test_subjects.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/reactive/test_time_ops.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/reactive/test_transform.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/security/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/security/test_exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/security/test_guards.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/security/test_package_hooks_p2.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/security/test_secret_rotation_policy.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/security/test_secrets_rotation.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/security/test_secrets_store.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/security/test_security_api.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/security/test_security_components_p2.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/security/test_security_constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/security/test_security_exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/security/test_security_types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/serialization/conftest.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/serialization/test_schema.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/serialization/test_serialization_constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/serialization/test_serialization_di_provider.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/serialization/test_serialization_domain.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/serialization/test_serialization_init.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/serialization/test_serialization_json.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/serialization/test_serialization_registry.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/serialization/test_serialization_types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_app_boot_validation.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_app_config_and_misc.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_app_constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_app_discovery.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_app_health_baseline.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_app_health_config.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_app_runner_and_lifespan.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_app_types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_app_validation_and_misc.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_application.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_application_base.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_application_lifecycle.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_base_and_misc_exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_clock_and_pipeline_primitives.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_codegen.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_compiler_graph_utils.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_component_exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_concurrency_constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_concurrency_exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_config.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_config_constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_config_hardening.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_config_quadkit.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_config_requirements.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_config_sources.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_config_types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_config_watcher.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_container_exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_container_introspection.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_container_override.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_container_resolver_impl.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_container_runtime_mixin.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_context_registry.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_contract_completeness.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_core_builder.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_core_constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_core_lazy.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_core_module.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_core_pipeline.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_dependency_injector.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_di_constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_di_descriptor.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_di_module_constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_domain_constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_domain_exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_domain_model_base.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_dynamic_module.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_events_security_exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_execution_result.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_hatch_build_targets.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_health_probes.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_hook_registry.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_hook_registry_edge_cases.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_hook_registry_introspection.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_hook_registry_scenarios.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_infra_exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_input_sanitizers.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_interceptors.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_json_serialization_backend.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_logging_apply_redaction.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_logging_constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_logging_debug.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_logging_di_provider.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_logging_init.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_logging_redaction.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_logging_redaction_compound.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_logging_types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_m13_m14_verification.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_mapper.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_mapper_enhanced.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_mapping.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_middleware_enhancements.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_middleware_exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_middleware_new.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_module_decorator.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_module_scan_and_provide.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_module_system.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_no_db_imports.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_orchestrator_parallel.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_p2_scope_log_level.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_primitives_context.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_primitives_data.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_primitives_registry.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_provider_boot_enhanced.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_provider_decorator.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_quadkit_constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_quadkit_exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_repr_helpers.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_resilience_exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_result_combinators.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_result_core.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_result_pipeline.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_result_pipeline_and_utils.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_result_types_new.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_result_utils.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_round22_hardening.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_round41_hardening.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_saga_primitives.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_sampling_and_config.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_secret_stores_and_rotation.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_serialization_constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_serialization_exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_service_descriptor.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_structured_logging.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_time_ops.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_validation_coercion.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_validation_exceptions.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_validation_rules.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/test_validation_validator_engine.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/validation/__init__.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/validation/conftest.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/validation/test_async_validator.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/validation/test_coercion.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/validation/test_helpers.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/validation/test_validation.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/validation/test_validation_constants.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/validation/test_validation_constants_new.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/validation/test_validation_fields.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/validation/test_validation_fields_extended.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/validation/test_validation_init.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/validation/test_validation_introspection.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/validation/test_validation_module.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/validation/test_validation_types.py +0 -0
- {quadkit-0.0.41 → quadkit-0.0.43}/tests/unit/validation/test_validator.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: quadkit
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.43
|
|
4
4
|
Summary: Async-first DI/IoC framework for Python — core package
|
|
5
5
|
Project-URL: Homepage, https://dbtinoy-.github.io/quadkit/
|
|
6
6
|
Project-URL: Repository, https://github.com/dbtinoy-/quadkit
|
|
@@ -27,6 +27,7 @@ Classifier: Typing :: Typed
|
|
|
27
27
|
Requires-Python: >=3.11
|
|
28
28
|
Requires-Dist: orjson<4,>=3.0.0
|
|
29
29
|
Requires-Dist: pydantic<3,>=2.10.0
|
|
30
|
+
Requires-Dist: pyyaml<7,>=6.0.0
|
|
30
31
|
Requires-Dist: quadkit-contracts>=0.0.2
|
|
31
32
|
Requires-Dist: structlog<27,>=25.1.0
|
|
32
33
|
Provides-Extra: codegen
|
|
@@ -250,10 +251,10 @@ report vulnerabilities privately per
|
|
|
250
251
|
|
|
251
252
|
## Stability
|
|
252
253
|
|
|
253
|
-
Version `0.0.
|
|
254
|
+
Version `0.0.43` in the `0.x` series, released in lockstep with the
|
|
254
255
|
other four distributions; APIs may change between minor versions until
|
|
255
256
|
1.0 — pin an exact version
|
|
256
|
-
(`quadkit==0.0.
|
|
257
|
+
(`quadkit==0.0.43`) or a tight range (`>=0.0.43,<0.1.0`). Full policy:
|
|
257
258
|
[stability and compatibility](https://dbtinoy-.github.io/quadkit/reference/stability/).
|
|
258
259
|
|
|
259
260
|
## Links
|
|
@@ -199,10 +199,10 @@ report vulnerabilities privately per
|
|
|
199
199
|
|
|
200
200
|
## Stability
|
|
201
201
|
|
|
202
|
-
Version `0.0.
|
|
202
|
+
Version `0.0.43` in the `0.x` series, released in lockstep with the
|
|
203
203
|
other four distributions; APIs may change between minor versions until
|
|
204
204
|
1.0 — pin an exact version
|
|
205
|
-
(`quadkit==0.0.
|
|
205
|
+
(`quadkit==0.0.43`) or a tight range (`>=0.0.43,<0.1.0`). Full policy:
|
|
206
206
|
[stability and compatibility](https://dbtinoy-.github.io/quadkit/reference/stability/).
|
|
207
207
|
|
|
208
208
|
## Links
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# Top-level env var prefix: QK_ (nested delimiter: __)
|
|
6
6
|
#
|
|
7
7
|
# Core fields are declared at the top level of this file.
|
|
8
|
-
# Extension packages (
|
|
8
|
+
# Extension packages (quadkit-cache, quadkit-sql, etc.) each add their own
|
|
9
9
|
# top-level section (e.g. cache:, sql:, ai:) read by their own Config class.
|
|
10
10
|
|
|
11
11
|
# -- Application Identity --------------------------------------------------
|
|
@@ -226,7 +226,7 @@ security:
|
|
|
226
226
|
pbkdf2_iterations: 600000
|
|
227
227
|
|
|
228
228
|
# -- Observability ---------------------------------------------------------
|
|
229
|
-
# NEW -- Core observability hooks. Full OTLP/Prometheus config is in
|
|
229
|
+
# NEW -- Core observability hooks. Full OTLP/Prometheus config is in quadkit-monitor.
|
|
230
230
|
|
|
231
231
|
observability:
|
|
232
232
|
# Master switch. When false, no-op implementations are used unconditionally.
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
# - Structured logging foundation
|
|
11
11
|
#
|
|
12
12
|
# It does NOT contain:
|
|
13
|
+
# - Database code → quadkit-sql
|
|
14
|
+
# - Auth/JWT/crypto → quadkit-auth
|
|
13
15
|
# - HTTP/ASGI/routing → quadkit-web
|
|
14
16
|
# - Any domain-specific feature
|
|
15
17
|
#
|
|
@@ -27,7 +29,7 @@ build-backend = "hatchling.build"
|
|
|
27
29
|
|
|
28
30
|
[project]
|
|
29
31
|
name = "quadkit"
|
|
30
|
-
version = "0.0.
|
|
32
|
+
version = "0.0.43"
|
|
31
33
|
description = "Async-first DI/IoC framework for Python — core package"
|
|
32
34
|
readme = "README.md"
|
|
33
35
|
requires-python = ">=3.11"
|
|
@@ -71,6 +73,7 @@ dependencies = [
|
|
|
71
73
|
"orjson>=3.0.0,<4",
|
|
72
74
|
"structlog>=25.1.0,<27", # Structured logging foundation
|
|
73
75
|
"pydantic>=2.10.0,<3", # Required: used unconditionally by config, validation
|
|
76
|
+
"pyyaml>=6.0.0,<7", # Required: YAML config file parsing
|
|
74
77
|
]
|
|
75
78
|
|
|
76
79
|
# =============================================================================
|
|
@@ -127,7 +130,7 @@ web = [
|
|
|
127
130
|
# events, tasks, monitor, graphql) were removed. Those packages are not
|
|
128
131
|
# published, so the extras resolved against name-reservation placeholders
|
|
129
132
|
# that contain no code: `pip install quadkit[cache]` succeeded and then
|
|
130
|
-
# `import
|
|
133
|
+
# `import quadkit.cache` raised ModuleNotFoundError. Install extension
|
|
131
134
|
# packages directly once they are published.
|
|
132
135
|
|
|
133
136
|
# =============================================================================
|
|
@@ -23,6 +23,12 @@ class AppConfig:
|
|
|
23
23
|
# ``name`` is the canonical YAML key under ``app:``; ``app_name`` remains
|
|
24
24
|
# supported for compatibility with the original flat configuration.
|
|
25
25
|
name: str | None = None
|
|
26
|
+
# ``version`` is the canonical YAML key under ``app:`` (application
|
|
27
|
+
# version string). Declared so apps that pin ``app.version`` in
|
|
28
|
+
# application.yaml bind cleanly — unknown keys raise ConfigSourceError
|
|
29
|
+
# from Application.stop()/get_section().
|
|
30
|
+
version: str = "0.0.0"
|
|
31
|
+
# consumed by: Application — version surfaced in health/telemetry
|
|
26
32
|
# consumed by: OTEL resource attribute, logger context, AppProvider
|
|
27
33
|
debug: bool | str = False
|
|
28
34
|
# consumed by: Application — verbose startup/teardown logging
|
|
@@ -15,7 +15,7 @@ Kernel providers (boot order governed by provider ``priority`` and ``dependencie
|
|
|
15
15
|
For a batteries-included bundle that also provides serialization and
|
|
16
16
|
concurrency, use :class:`~quadkit.app.standard.StandardModule` instead.
|
|
17
17
|
|
|
18
|
-
Extension packages (``
|
|
18
|
+
Extension packages (``quadkit-cache``, ``quadkit-auth``, ``quadkit-web``,
|
|
19
19
|
etc.) register their own providers via ``app.add_provider()`` or
|
|
20
20
|
``app.add_module()``. ``CoreModule`` intentionally imports **only** from
|
|
21
21
|
``quadkit-contracts`` and the ``quadkit`` core package — zero cross-package
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from quadkit.codegen.base import GeneratorBase
|
|
2
|
+
from quadkit.codegen.field_types import annotation_for, import_lines
|
|
2
3
|
from quadkit.contracts.cli.generators import GenerationResult
|
|
3
4
|
from quadkit.contracts.cli.parsers import FieldSpec, parse_fields
|
|
4
5
|
|
|
@@ -6,5 +7,7 @@ __all__ = [
|
|
|
6
7
|
"FieldSpec",
|
|
7
8
|
"GenerationResult",
|
|
8
9
|
"GeneratorBase",
|
|
10
|
+
"annotation_for",
|
|
11
|
+
"import_lines",
|
|
9
12
|
"parse_fields",
|
|
10
13
|
]
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"""Field-type vocabulary for the CLI code generators.
|
|
2
|
+
|
|
3
|
+
Field types arrive as free-form identifiers from ``--fields`` strings
|
|
4
|
+
(``order_id:uuid,total:decimal,payload:json``) and generators render them
|
|
5
|
+
straight into annotations -- dataclass fields, Pydantic model fields, function
|
|
6
|
+
signatures. Rendering the token verbatim only
|
|
7
|
+
works while the token happens to be a builtin: ``float`` and ``str`` are fine,
|
|
8
|
+
but ``uuid``, ``datetime``, ``date``, ``time`` and ``json`` are *not* names in
|
|
9
|
+
the generated module, so a payload carrying any of them produced a file that
|
|
10
|
+
raised ``NameError`` on import — the module could not even be collected by
|
|
11
|
+
pytest.
|
|
12
|
+
|
|
13
|
+
Two things have to agree for a field to render correctly, so they live
|
|
14
|
+
together here: the annotation for a token, and the import that annotation
|
|
15
|
+
needs. ``date`` is a ``datetime`` name, ``UUID`` is a ``uuid`` name, and
|
|
16
|
+
``dict[str, Any]`` needs ``Any`` — an annotation vocabulary without its import
|
|
17
|
+
list is how the original bug happened.
|
|
18
|
+
|
|
19
|
+
Unknown tokens fall back to themselves, matching the SQL vocabulary's stance
|
|
20
|
+
that a typo degrades rather than blocks generation; the difference is that a
|
|
21
|
+
*known* token now always renders a name that exists.
|
|
22
|
+
|
|
23
|
+
This lives in ``quadkit.codegen`` because every generator that renders a field
|
|
24
|
+
already imports from here (``parse_fields`` is the other half of the same
|
|
25
|
+
contract): the vocabulary and the parser that produces its input belong
|
|
26
|
+
together, and a second copy is how the two halves drift apart again.
|
|
27
|
+
|
|
28
|
+
``quadkit-sql`` keeps its own table: SQLAlchemy columns need a second mapping
|
|
29
|
+
(``String(length=255)``, ``Text``) that has no meaning for a payload.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
from __future__ import annotations
|
|
33
|
+
|
|
34
|
+
from collections.abc import Iterable
|
|
35
|
+
import re
|
|
36
|
+
|
|
37
|
+
#: Field type → Python annotation for a dataclass field or signature.
|
|
38
|
+
PY_TYPES: dict[str, str] = {
|
|
39
|
+
# Text — an event payload carries values, so URL-ish tokens stay strings:
|
|
40
|
+
# a domain event is a frozen dataclass, not a validated Pydantic model,
|
|
41
|
+
# and importing a validator type for one field would point the dependency
|
|
42
|
+
# the wrong way.
|
|
43
|
+
"str": "str",
|
|
44
|
+
"string": "str",
|
|
45
|
+
"text": "str",
|
|
46
|
+
"slug": "str",
|
|
47
|
+
"char": "str",
|
|
48
|
+
"email": "str",
|
|
49
|
+
"phone": "str",
|
|
50
|
+
"filename": "str",
|
|
51
|
+
"filepath": "str",
|
|
52
|
+
"enum": "str",
|
|
53
|
+
"url": "str",
|
|
54
|
+
"uri": "str",
|
|
55
|
+
"ipv4": "str",
|
|
56
|
+
"ipv6": "str",
|
|
57
|
+
"ip": "str",
|
|
58
|
+
# Numeric
|
|
59
|
+
"int": "int",
|
|
60
|
+
"integer": "int",
|
|
61
|
+
"bigint": "int",
|
|
62
|
+
"smallint": "int",
|
|
63
|
+
"float": "float",
|
|
64
|
+
"double": "float",
|
|
65
|
+
"number": "float",
|
|
66
|
+
"decimal": "float",
|
|
67
|
+
"numeric": "float",
|
|
68
|
+
"money": "float",
|
|
69
|
+
# Boolean and temporal
|
|
70
|
+
"bool": "bool",
|
|
71
|
+
"boolean": "bool",
|
|
72
|
+
"datetime": "datetime",
|
|
73
|
+
"timestamp": "datetime",
|
|
74
|
+
"date": "date",
|
|
75
|
+
"time": "time",
|
|
76
|
+
# Identifiers and structured data
|
|
77
|
+
"uuid": "UUID",
|
|
78
|
+
"json": "dict[str, Any]",
|
|
79
|
+
"jsonb": "dict[str, Any]",
|
|
80
|
+
"dict": "dict[str, Any]",
|
|
81
|
+
"object": "dict[str, Any]",
|
|
82
|
+
"bytes": "bytes",
|
|
83
|
+
"blob": "bytes",
|
|
84
|
+
"binary": "bytes",
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
#: Annotation → the module and name that provide it.
|
|
88
|
+
ANNOTATION_SOURCES: dict[str, tuple[str, str]] = {
|
|
89
|
+
"UUID": ("uuid", "UUID"),
|
|
90
|
+
"datetime": ("datetime", "datetime"),
|
|
91
|
+
"date": ("datetime", "date"),
|
|
92
|
+
"time": ("datetime", "time"),
|
|
93
|
+
"Any": ("typing", "Any"),
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def annotation_for(field_type: str) -> str:
|
|
98
|
+
"""The Python annotation for a field-spec type token."""
|
|
99
|
+
return PY_TYPES.get(field_type.strip().lower(), field_type.strip())
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def import_lines(
|
|
103
|
+
field_types: Iterable[str], *, always: Iterable[str] = ()
|
|
104
|
+
) -> list[str]:
|
|
105
|
+
"""One import line per module needed by the rendered annotations.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
field_types: Raw field-spec tokens from the ``--fields`` string.
|
|
109
|
+
always: Annotations the template renders outside the payload — the
|
|
110
|
+
event template's ``aggregate_id: UUID``, the command and query
|
|
111
|
+
templates' ``Any`` — so they are imported whether or not a field
|
|
112
|
+
happens to ask for them. Templates have no import machinery of
|
|
113
|
+
their own; this is it.
|
|
114
|
+
"""
|
|
115
|
+
per_module: dict[str, set[str]] = {}
|
|
116
|
+
for field_type in [*field_types, *always]:
|
|
117
|
+
rendered = annotation_for(field_type)
|
|
118
|
+
# Scan the *rendered annotation* rather than looking the token up in a
|
|
119
|
+
# second table: a composite annotation carries more than one name
|
|
120
|
+
# (``dict[str, Any]`` needs ``Any``), and the names are what the file
|
|
121
|
+
# has to import.
|
|
122
|
+
for name, (module, _) in ANNOTATION_SOURCES.items():
|
|
123
|
+
if re.search(rf"\b{name}\b", rendered):
|
|
124
|
+
per_module.setdefault(module, set()).add(name)
|
|
125
|
+
return [
|
|
126
|
+
f"from {module} import {', '.join(sorted(names))}"
|
|
127
|
+
for module, names in sorted(per_module.items())
|
|
128
|
+
]
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
__all__ = ["ANNOTATION_SOURCES", "PY_TYPES", "annotation_for", "import_lines"]
|
|
@@ -70,7 +70,7 @@ class ContainerValidator:
|
|
|
70
70
|
# not something the user can fix with annotations.
|
|
71
71
|
logger.warning(
|
|
72
72
|
"validate.scope_check_unhashable_hint",
|
|
73
|
-
|
|
73
|
+
service_type=service_name,
|
|
74
74
|
error=str(e),
|
|
75
75
|
)
|
|
76
76
|
else:
|
|
@@ -85,13 +85,13 @@ class ContainerValidator:
|
|
|
85
85
|
except AttributeError as e:
|
|
86
86
|
logger.warning(
|
|
87
87
|
"validate.scope_check_attribute_error",
|
|
88
|
-
|
|
88
|
+
service_type=service_name,
|
|
89
89
|
error=str(e),
|
|
90
90
|
)
|
|
91
91
|
except (KeyError, ValueError) as e:
|
|
92
92
|
logger.warning(
|
|
93
93
|
"validate.scope_check_resolution_error",
|
|
94
|
-
|
|
94
|
+
service_type=service_name,
|
|
95
95
|
error=str(e),
|
|
96
96
|
)
|
|
97
97
|
|
|
@@ -123,7 +123,7 @@ class ContainerValidator:
|
|
|
123
123
|
except (AttributeError, TypeError, KeyError, ValueError) as e:
|
|
124
124
|
logger.debug(
|
|
125
125
|
"validate_no_orphans.dep_resolution_error",
|
|
126
|
-
|
|
126
|
+
service_type=getattr(service_type, "__name__", str(service_type)),
|
|
127
127
|
error=str(e),
|
|
128
128
|
)
|
|
129
129
|
continue
|
|
@@ -127,7 +127,7 @@ class ProviderScanner:
|
|
|
127
127
|
def import_string(dotted_path: str) -> Any:
|
|
128
128
|
"""Import a dotted module path and return the attribute at the end.
|
|
129
129
|
|
|
130
|
-
E.g. '
|
|
130
|
+
E.g. 'quadkit.sql.DatabaseService' imports 'quadkit.sql' and returns
|
|
131
131
|
the 'DatabaseService' attribute.
|
|
132
132
|
"""
|
|
133
133
|
try:
|
|
@@ -79,7 +79,7 @@ class ServiceResolver:
|
|
|
79
79
|
if self._debug_resolution:
|
|
80
80
|
logger.debug(
|
|
81
81
|
"di.resolution.resolved",
|
|
82
|
-
|
|
82
|
+
service_type=getattr(service_type, "__name__", repr(service_type)),
|
|
83
83
|
)
|
|
84
84
|
return instance
|
|
85
85
|
|
|
@@ -8,7 +8,7 @@ This base is deliberately storage-agnostic -- it imports no database driver --
|
|
|
8
8
|
so in-memory and SQL implementations can share it:
|
|
9
9
|
|
|
10
10
|
- ``quadkit.testing.memory.uow.InMemoryUnitOfWork`` supplies a no-op flush.
|
|
11
|
-
- ``
|
|
11
|
+
- ``quadkit-sql``'s ``SQLUnitOfWork`` flushes through the active session.
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
14
|
from __future__ import annotations
|
|
@@ -7,7 +7,8 @@ Example:
|
|
|
7
7
|
from quadkit import identity
|
|
8
8
|
|
|
9
9
|
id = identity.generate_for("user") # ULID/UUID based on config
|
|
10
|
-
|
|
10
|
+
opaque = identity.new_uuid() # the configured strategy, not
|
|
11
|
+
# necessarily a UUID — see below
|
|
11
12
|
|
|
12
13
|
For tests:
|
|
13
14
|
from quadkit import identity
|
|
@@ -78,10 +79,26 @@ def generate_for(entity_type: str) -> str:
|
|
|
78
79
|
|
|
79
80
|
|
|
80
81
|
def new_uuid() -> str:
|
|
81
|
-
"""Generate
|
|
82
|
+
"""Generate an id with the ambient generator, whatever it is.
|
|
83
|
+
|
|
84
|
+
**The name is narrower than the behaviour.** This delegates to the
|
|
85
|
+
installed ``IdGeneratorProtocol``, so the result follows
|
|
86
|
+
``IdentityConfig.strategy``: UUID4 by default, but a 36-char UUID7, a
|
|
87
|
+
26-char Crockford base32 ULID, or a prefixed ULID (``usr_01H…``) when
|
|
88
|
+
the application configures one — and whatever a test installs through
|
|
89
|
+
``use()``.
|
|
90
|
+
|
|
91
|
+
Two consequences worth stating, because the name hides both:
|
|
92
|
+
|
|
93
|
+
- **Shape is not guaranteed.** Do not feed the result to a ``UUID``
|
|
94
|
+
column or ``uuid.UUID()`` unless the strategy is pinned to UUID4/7.
|
|
95
|
+
- **Randomness is not guaranteed.** UUID7 and ULID are time-ordered:
|
|
96
|
+
the leading bits are a millisecond timestamp. For a value that must
|
|
97
|
+
be unguessable — a reset token, a session id, a webhook secret — use
|
|
98
|
+
``secrets.token_urlsafe()``, not this.
|
|
82
99
|
|
|
83
100
|
Returns:
|
|
84
|
-
|
|
101
|
+
An id string from the ambient generator.
|
|
85
102
|
"""
|
|
86
103
|
return _ambient.get().generate()
|
|
87
104
|
|
|
@@ -43,15 +43,15 @@ Each log line is a single JSON object emitted by
|
|
|
43
43
|
{
|
|
44
44
|
"timestamp": "2026-08-19 10:15:30",
|
|
45
45
|
"level": "INFO",
|
|
46
|
-
"logger": "quadkit.web.controller",
|
|
47
46
|
"event": "user_created",
|
|
48
47
|
"service": "my-app",
|
|
49
48
|
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
|
|
50
49
|
"span_id": "00f067aa0ba902b7",
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
50
|
+
"_logger_name": "quadkit.web.controller",
|
|
51
|
+
"_filename": "controller.py",
|
|
52
|
+
"_lineno": 42,
|
|
53
|
+
"_module": "controller",
|
|
54
|
+
"_func_name": "create_user",
|
|
55
55
|
"user_id": "usr_123"
|
|
56
56
|
}
|
|
57
57
|
```
|
|
@@ -60,16 +60,44 @@ Each log line is a single JSON object emitted by
|
|
|
60
60
|
|-------------|---------------------------------------------------------------|
|
|
61
61
|
| `timestamp` | `TimeStamper(fmt="%Y-%m-%d %H:%M:%S")` |
|
|
62
62
|
| `level` | `structlog.stdlib.add_log_level` |
|
|
63
|
-
| `logger` | `_add_logger_name` — auto-prefixed with `quadkit.` |
|
|
64
63
|
| `event` | Message passed to `logger.info("...")` |
|
|
65
64
|
| `service` | Injected by `configure_logging(service_name=...)` / `Application.name`; overridable via `bind(service=...)` |
|
|
66
65
|
| `trace_id` / `span_id` | `_otel_processor` — only when an OTEL trace context is active |
|
|
67
|
-
| `
|
|
66
|
+
| `_logger_name` | `get_logger()` / `_add_logger_name` — auto-prefixed with `quadkit.` |
|
|
67
|
+
| `_filename` / `_lineno` / `_module` / `_func_name` | `CallsiteParameterAdder`, wrapped by `_NamespacedCallsiteAdder` |
|
|
68
68
|
| `exception` | Formatted traceback, present on `logger.exception(...)` / `exc_info=True` |
|
|
69
69
|
|
|
70
70
|
Key-value arguments passed to a log call are appended verbatim as top-level
|
|
71
71
|
fields (`logger.info("user_created", user_id=usr.id)` → `"user_id"`).
|
|
72
72
|
|
|
73
|
+
## Field names: what the envelope owns, and what you own
|
|
74
|
+
|
|
75
|
+
Two namespaces, so a caller's field and the pipeline's metadata can never
|
|
76
|
+
be the same key:
|
|
77
|
+
|
|
78
|
+
- **`_`-prefixed keys belong to the framework** — `_logger_name`,
|
|
79
|
+
`_filename`, `_lineno`, `_module`, `_func_name`. Do not pass them.
|
|
80
|
+
- **Every other plain name belongs to the caller.** `module=`, `filename=`,
|
|
81
|
+
`name=`, `msg=` are ordinary fields; `logger.info("module_booted",
|
|
82
|
+
module=self.name)` renders the value you passed.
|
|
83
|
+
- **Five envelope names are reserved**: `event`, `level`, `timestamp`,
|
|
84
|
+
`service` and `exception`. `service` is deliberately overridable via
|
|
85
|
+
`bind(service=...)`; the other four are not yours to set.
|
|
86
|
+
`dev/checks/reserved_log_fields.py` fails the build on a call site that
|
|
87
|
+
passes one.
|
|
88
|
+
|
|
89
|
+
`event` is the sharp one: it is structlog's parameter for the *message*, so
|
|
90
|
+
`logger.warning("emit_failed", event=type(evt).__name__)` raises
|
|
91
|
+
`TypeError` — inside the `except` block that was reporting the failure.
|
|
92
|
+
Because a diagnostic must never raise, `_NamedLogger` moves such a field to
|
|
93
|
+
`event_field` rather than letting the call blow up; the gate is what makes
|
|
94
|
+
you rename it properly (`event_type`, `webhook_event`).
|
|
95
|
+
|
|
96
|
+
Callsite metadata reports *your* frame, not the framework's: the adder is
|
|
97
|
+
configured with `additional_ignores=["quadkit.logging"]`, without which
|
|
98
|
+
`_NamedLogger.info` in `logging/factory.py` is the nearest non-structlog
|
|
99
|
+
frame and every line in the process is stamped with it.
|
|
100
|
+
|
|
73
101
|
## Behavior guarantees
|
|
74
102
|
|
|
75
103
|
- **Levels**: `DEBUG < INFO < WARNING < ERROR < CRITICAL`. A global
|
|
@@ -94,5 +122,5 @@ fields (`logger.info("user_created", user_id=usr.id)` → `"user_id"`).
|
|
|
94
122
|
- Never `print()`; never log secret material (redaction is a safety net,
|
|
95
123
|
not a substitute for not logging secrets).
|
|
96
124
|
- For error tracking, forward `level >= ERROR` events with `event`,
|
|
97
|
-
`exception`, `
|
|
125
|
+
`exception`, `_logger_name`, and `trace_id` fields — correlation IDs make
|
|
98
126
|
distributed debugging possible.
|
|
@@ -21,6 +21,7 @@ from quadkit.logging.processors import (
|
|
|
21
21
|
_add_logger_name,
|
|
22
22
|
_context_processor,
|
|
23
23
|
_level_filter_processor,
|
|
24
|
+
_NamespacedCallsiteAdder,
|
|
24
25
|
_otel_processor,
|
|
25
26
|
_redact_processor,
|
|
26
27
|
_sampling_processor,
|
|
@@ -101,13 +102,16 @@ def configure_logging(
|
|
|
101
102
|
_service_processor,
|
|
102
103
|
_otel_processor,
|
|
103
104
|
_redact_processor,
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
105
|
+
_NamespacedCallsiteAdder(
|
|
106
|
+
structlog.processors.CallsiteParameterAdder(
|
|
107
|
+
{
|
|
108
|
+
structlog.processors.CallsiteParameter.FILENAME,
|
|
109
|
+
structlog.processors.CallsiteParameter.LINENO,
|
|
110
|
+
structlog.processors.CallsiteParameter.MODULE,
|
|
111
|
+
structlog.processors.CallsiteParameter.FUNC_NAME,
|
|
112
|
+
},
|
|
113
|
+
additional_ignores=["quadkit.logging"],
|
|
114
|
+
),
|
|
111
115
|
),
|
|
112
116
|
structlog.processors.StackInfoRenderer(),
|
|
113
117
|
]
|
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
Provides ``get_logger()`` for obtaining structlog bound-loggers with a
|
|
4
4
|
``.name`` attribute, and ``LoggerFactoryImpl`` which implements the
|
|
5
5
|
``LoggerFactoryProtocol`` protocol.
|
|
6
|
+
|
|
7
|
+
A logging call must never raise. structlog names the message parameter
|
|
8
|
+
``event``, so ``logger.info("task_finished", event=evt.name)`` is a
|
|
9
|
+
``TypeError`` — raised from inside the ``except`` block that was trying to
|
|
10
|
+
report a failure. ``_deconflict()`` moves such a field to ``event_field``
|
|
11
|
+
instead of letting the diagnostic take down the path it was diagnosing;
|
|
12
|
+
``dev/checks/reserved_log_fields.py`` fails the build on the call site so
|
|
13
|
+
the remap stays a safety net rather than an interface.
|
|
6
14
|
"""
|
|
7
15
|
|
|
8
16
|
from __future__ import annotations
|
|
@@ -16,6 +24,25 @@ if TYPE_CHECKING:
|
|
|
16
24
|
from quadkit.logging.config.models import LoggingConfig
|
|
17
25
|
|
|
18
26
|
|
|
27
|
+
def _deconflict(kwargs: dict[str, Any]) -> dict[str, Any]:
|
|
28
|
+
"""Move a caller field named ``event`` out of structlog's way.
|
|
29
|
+
|
|
30
|
+
``event`` is structlog's parameter for the log message, so passing it as
|
|
31
|
+
a field raises ``TypeError``. The field is preserved under
|
|
32
|
+
``event_field`` (``event_field_``, ``event_field__``, … if the caller
|
|
33
|
+
already used that name) rather than dropped: a log call is a diagnostic
|
|
34
|
+
and must not raise.
|
|
35
|
+
"""
|
|
36
|
+
if "event" not in kwargs:
|
|
37
|
+
return kwargs
|
|
38
|
+
safe = dict(kwargs)
|
|
39
|
+
key = "event_field"
|
|
40
|
+
while key in safe:
|
|
41
|
+
key += "_"
|
|
42
|
+
safe[key] = safe.pop("event")
|
|
43
|
+
return safe
|
|
44
|
+
|
|
45
|
+
|
|
19
46
|
class _NamedLogger:
|
|
20
47
|
"""Thin wrapper that adds ``.name`` to a structlog bound logger.
|
|
21
48
|
|
|
@@ -34,26 +61,31 @@ class _NamedLogger:
|
|
|
34
61
|
# These exist so ``hasattr(_NamedLogger, 'debug')`` etc. return True for
|
|
35
62
|
# the DI validator. At runtime the call is forwarded via __getattr__.
|
|
36
63
|
|
|
37
|
-
|
|
38
|
-
|
|
64
|
+
# ``msg`` is positional-only: without the ``/`` this wrapper would add a
|
|
65
|
+
# reserved word of its own making, and ``logger.info("x", msg=body)``
|
|
66
|
+
# would fail with "got multiple values for argument 'msg'" even though
|
|
67
|
+
# the underlying structlog logger has no such parameter.
|
|
68
|
+
|
|
69
|
+
def debug(self, msg: str, /, *args: Any, **kwargs: Any) -> None:
|
|
70
|
+
self._inner.debug(msg, *args, **_deconflict(kwargs))
|
|
39
71
|
|
|
40
|
-
def info(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
|
41
|
-
self._inner.info(msg, *args, **kwargs)
|
|
72
|
+
def info(self, msg: str, /, *args: Any, **kwargs: Any) -> None:
|
|
73
|
+
self._inner.info(msg, *args, **_deconflict(kwargs))
|
|
42
74
|
|
|
43
|
-
def warning(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
|
44
|
-
self._inner.warning(msg, *args, **kwargs)
|
|
75
|
+
def warning(self, msg: str, /, *args: Any, **kwargs: Any) -> None:
|
|
76
|
+
self._inner.warning(msg, *args, **_deconflict(kwargs))
|
|
45
77
|
|
|
46
|
-
def error(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
|
47
|
-
self._inner.error(msg, *args, **kwargs)
|
|
78
|
+
def error(self, msg: str, /, *args: Any, **kwargs: Any) -> None:
|
|
79
|
+
self._inner.error(msg, *args, **_deconflict(kwargs))
|
|
48
80
|
|
|
49
|
-
def critical(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
|
50
|
-
self._inner.critical(msg, *args, **kwargs)
|
|
81
|
+
def critical(self, msg: str, /, *args: Any, **kwargs: Any) -> None:
|
|
82
|
+
self._inner.critical(msg, *args, **_deconflict(kwargs))
|
|
51
83
|
|
|
52
|
-
def exception(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
|
53
|
-
self._inner.exception(msg, *args, **kwargs)
|
|
84
|
+
def exception(self, msg: str, /, *args: Any, **kwargs: Any) -> None:
|
|
85
|
+
self._inner.exception(msg, *args, **_deconflict(kwargs))
|
|
54
86
|
|
|
55
87
|
def bind(self, **kwargs: Any) -> _NamedLogger:
|
|
56
|
-
result = self._inner.bind(**kwargs)
|
|
88
|
+
result = self._inner.bind(**_deconflict(kwargs))
|
|
57
89
|
return self if result is self._inner else _NamedLogger(result, self.name)
|
|
58
90
|
|
|
59
91
|
def unbind(self, *keys: str) -> _NamedLogger:
|
|
@@ -122,18 +154,21 @@ class LoggerFactoryImpl:
|
|
|
122
154
|
self._config = config
|
|
123
155
|
|
|
124
156
|
def get_logger(self, name: str | None = None) -> LoggerProtocol:
|
|
125
|
-
"""Get or create a logger
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
157
|
+
"""Get or create a logger.
|
|
158
|
+
|
|
159
|
+
This used to ``bind(service=name)``. ``service`` is the envelope
|
|
160
|
+
field identifying the *application* (set by ``configure_logging()``
|
|
161
|
+
and used for log routing), and ``_service_processor`` yields to a
|
|
162
|
+
bound value — so every DI-resolved logger relabelled the service as
|
|
163
|
+
whichever component had asked for it. The logger name already
|
|
164
|
+
travels in ``_logger_name``.
|
|
165
|
+
"""
|
|
166
|
+
return cast("LoggerProtocol", get_logger(name))
|
|
133
167
|
|
|
134
168
|
|
|
135
169
|
__all__ = [
|
|
136
170
|
"LoggerFactoryImpl",
|
|
137
171
|
"_NamedLogger",
|
|
172
|
+
"_deconflict",
|
|
138
173
|
"get_logger",
|
|
139
174
|
]
|