GeneralManager 0.50.0__tar.gz → 0.52.0__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.
- {generalmanager-0.50.0/src/GeneralManager.egg-info → generalmanager-0.52.0}/PKG-INFO +1 -1
- {generalmanager-0.50.0 → generalmanager-0.52.0}/pyproject.toml +1 -1
- {generalmanager-0.50.0 → generalmanager-0.52.0/src/GeneralManager.egg-info}/PKG-INFO +1 -1
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/GeneralManager.egg-info/SOURCES.txt +3 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/_types/bucket.py +12 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/bucket/base_bucket.py +96 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/bucket/calculation_bucket.py +13 -1
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/bucket/database_bucket.py +7 -0
- generalmanager-0.52.0/src/general_manager/bucket/indexing.py +184 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/bucket/request_bucket.py +18 -1
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/cache/dependency_index.py +237 -220
- generalmanager-0.52.0/src/general_manager/cache/dependency_matching.py +242 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/cache/dependency_publish.py +9 -16
- generalmanager-0.52.0/src/general_manager/cache/dependency_shards.py +414 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/cache/run_context.py +63 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/cache/signals.py +1 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/public_api_registry.py +21 -1
- {generalmanager-0.50.0 → generalmanager-0.52.0}/LICENSE +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/README.md +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/setup.cfg +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/GeneralManager.egg-info/requires.txt +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/GeneralManager.egg-info/top_level.txt +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/_types/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/_types/api.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/_types/cache.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/_types/factory.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/_types/general_manager.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/_types/interface.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/_types/manager.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/_types/measurement.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/_types/permission.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/_types/rule.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/_types/search.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/_types/utils.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/api/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/api/graphql.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/api/graphql_errors.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/api/graphql_mutations.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/api/graphql_prefetch.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/api/graphql_resolvers.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/api/graphql_search.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/api/graphql_subscription_consumer.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/api/graphql_subscriptions.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/api/graphql_view.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/api/mutation.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/api/property.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/api/registry.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/api/remote_api.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/api/remote_invalidation.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/api/remote_invalidation_client.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/apps.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/bootstrap.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/bucket/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/bucket/group_bucket.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/cache/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/cache/cache_decorator.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/cache/cache_tracker.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/cache/dependency_cache.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/cache/model_dependency_collector.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/conf.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/factory/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/factory/auto_factory.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/factory/factories.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/factory/factory_methods.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/base_interface.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/bundles/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/bundles/calculation.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/bundles/database.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/bundles/remote_manager.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/bundles/request.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/base.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/builtin.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/calculation/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/calculation/_compat.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/calculation/lifecycle.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/configuration.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/core/observability.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/core/utils.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/exceptions.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/existing_model/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/existing_model/_compat.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/existing_model/resolution.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/factory.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/orm/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/orm/_compat.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/orm/history.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/orm/lifecycle.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/orm/mutations.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/orm/support.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/orm_utils/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/orm_utils/django_manager_utils.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/orm_utils/field_descriptors.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/orm_utils/payload_normalizer.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/read_only/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/read_only/_compat.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/read_only/lifecycle.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/read_only/management.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/registry.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/remote_manager.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/capabilities/request/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/infrastructure/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/infrastructure/startup_hooks.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/infrastructure/system_checks.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/interfaces/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/interfaces/calculation.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/interfaces/database.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/interfaces/existing_model.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/interfaces/read_only.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/interfaces/remote_manager.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/interfaces/request.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/manifests/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/manifests/capability_builder.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/manifests/capability_manifest.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/manifests/capability_models.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/orm_interface.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/requests.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/utils/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/utils/database_interface_protocols.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/utils/errors.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/interface/utils/models.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/logging.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/management/commands/search_index.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/management/commands/seed_manager_landscape.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/management/commands/shell.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/management/commands/workflow_drain_outbox.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/management/commands/workflow_replay_dead_letters.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/manager/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/manager/general_manager.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/manager/group_manager.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/manager/input.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/manager/meta.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/measurement/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/measurement/measurement.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/measurement/measurement_field.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/metrics/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/metrics/graphql.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/migrations/0001_initial.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/migrations/0002_workflow_outbox_scaling_indexes.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/migrations/0003_workflow_execution_correlation_constraint.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/migrations/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/models.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/permission/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/permission/audit.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/permission/base_permission.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/permission/graphql_capabilities.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/permission/manager_based_permission.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/permission/mutation_permission.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/permission/permission_checks.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/permission/permission_data_manager.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/permission/utils.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/py.typed +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/rule/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/rule/handler.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/rule/rule.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/search/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/search/async_tasks.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/search/backend.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/search/backend_registry.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/search/backends/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/search/backends/dev.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/search/backends/meilisearch.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/search/backends/opensearch.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/search/backends/typesense.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/search/config.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/search/indexer.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/search/registry.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/search/utils.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/seeding/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/seeding/manager_landscape.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/utils/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/utils/args_to_kwargs.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/utils/filter_parser.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/utils/format_string.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/utils/json_encoder.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/utils/make_cache_key.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/utils/none_to_zero.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/utils/path_mapping.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/utils/public_api.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/utils/testing.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/utils/type_checks.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/workflow/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/workflow/actions.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/workflow/backend_registry.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/workflow/backends/__init__.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/workflow/backends/celery.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/workflow/backends/local.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/workflow/backends/n8n.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/workflow/config.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/workflow/engine.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/workflow/event_registry.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/workflow/events.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/workflow/models.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/workflow/signal_bridge.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/workflow/tasks.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/workflow/telemetry.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/tests/test_settings.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/tests/test_urls.py +0 -0
- {generalmanager-0.50.0 → generalmanager-0.52.0}/tests/testing_asgi.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GeneralManager
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.52.0
|
|
4
4
|
Summary: Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching.
|
|
5
5
|
Author-email: Tim Kleindick <tkleindick@yahoo.de>
|
|
6
6
|
License: MIT License
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "GeneralManager"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.52.0"
|
|
8
8
|
description = "Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "Tim Kleindick", email = "tkleindick@yahoo.de" }]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GeneralManager
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.52.0
|
|
4
4
|
Summary: Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching.
|
|
5
5
|
Author-email: Tim Kleindick <tkleindick@yahoo.de>
|
|
6
6
|
License: MIT License
|
|
@@ -48,13 +48,16 @@ src/general_manager/bucket/base_bucket.py
|
|
|
48
48
|
src/general_manager/bucket/calculation_bucket.py
|
|
49
49
|
src/general_manager/bucket/database_bucket.py
|
|
50
50
|
src/general_manager/bucket/group_bucket.py
|
|
51
|
+
src/general_manager/bucket/indexing.py
|
|
51
52
|
src/general_manager/bucket/request_bucket.py
|
|
52
53
|
src/general_manager/cache/__init__.py
|
|
53
54
|
src/general_manager/cache/cache_decorator.py
|
|
54
55
|
src/general_manager/cache/cache_tracker.py
|
|
55
56
|
src/general_manager/cache/dependency_cache.py
|
|
56
57
|
src/general_manager/cache/dependency_index.py
|
|
58
|
+
src/general_manager/cache/dependency_matching.py
|
|
57
59
|
src/general_manager/cache/dependency_publish.py
|
|
60
|
+
src/general_manager/cache/dependency_shards.py
|
|
58
61
|
src/general_manager/cache/model_dependency_collector.py
|
|
59
62
|
src/general_manager/cache/run_context.py
|
|
60
63
|
src/general_manager/cache/signals.py
|
|
@@ -4,14 +4,26 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
__all__ = [
|
|
6
6
|
"Bucket",
|
|
7
|
+
"BucketIndexTooLargeError",
|
|
7
8
|
"CalculationBucket",
|
|
8
9
|
"DatabaseBucket",
|
|
10
|
+
"DuplicateBucketIndexKeyError",
|
|
9
11
|
"GroupBucket",
|
|
12
|
+
"MissingBucketIndexKeyError",
|
|
10
13
|
"RequestBucket",
|
|
14
|
+
"UnhashableBucketIndexKeyError",
|
|
15
|
+
"UnsupportedBucketIndexKeySpecError",
|
|
11
16
|
]
|
|
12
17
|
|
|
13
18
|
from general_manager.bucket.base_bucket import Bucket
|
|
14
19
|
from general_manager.bucket.calculation_bucket import CalculationBucket
|
|
15
20
|
from general_manager.bucket.database_bucket import DatabaseBucket
|
|
16
21
|
from general_manager.bucket.group_bucket import GroupBucket
|
|
22
|
+
from general_manager.bucket.indexing import (
|
|
23
|
+
BucketIndexTooLargeError,
|
|
24
|
+
DuplicateBucketIndexKeyError,
|
|
25
|
+
MissingBucketIndexKeyError,
|
|
26
|
+
UnhashableBucketIndexKeyError,
|
|
27
|
+
UnsupportedBucketIndexKeySpecError,
|
|
28
|
+
)
|
|
17
29
|
from general_manager.bucket.request_bucket import RequestBucket
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
from abc import ABC, abstractmethod
|
|
5
|
+
from collections.abc import Hashable
|
|
5
6
|
from typing import (
|
|
6
7
|
Type,
|
|
7
8
|
Generator,
|
|
@@ -11,6 +12,15 @@ from typing import (
|
|
|
11
12
|
TypeVar,
|
|
12
13
|
)
|
|
13
14
|
|
|
15
|
+
from general_manager.bucket.indexing import (
|
|
16
|
+
BucketIndexKeySpec,
|
|
17
|
+
build_multi_bucket_index,
|
|
18
|
+
build_unique_bucket_index,
|
|
19
|
+
normalize_bucket_index_key_spec,
|
|
20
|
+
)
|
|
21
|
+
from general_manager.cache.cache_tracker import DependencyTracker
|
|
22
|
+
from general_manager.cache.run_context import ensure_calculation_run_context
|
|
23
|
+
|
|
14
24
|
GeneralManagerType = TypeVar("GeneralManagerType", bound="GeneralManager")
|
|
15
25
|
|
|
16
26
|
if TYPE_CHECKING:
|
|
@@ -239,6 +249,92 @@ class Bucket(ABC, Generic[GeneralManagerType]):
|
|
|
239
249
|
|
|
240
250
|
return GroupBucket(self._manager_class, group_by_keys, self)
|
|
241
251
|
|
|
252
|
+
def _bucket_index_source_signature(self) -> Hashable:
|
|
253
|
+
"""Return the conservative run-local source signature for bucket indexes."""
|
|
254
|
+
return (
|
|
255
|
+
self.__class__,
|
|
256
|
+
self._manager_class,
|
|
257
|
+
id(self),
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
def index_by(
|
|
261
|
+
self,
|
|
262
|
+
key_spec: BucketIndexKeySpec,
|
|
263
|
+
*,
|
|
264
|
+
max_rows: int | None = 1000,
|
|
265
|
+
) -> dict[Hashable, GeneralManagerType]:
|
|
266
|
+
"""Build or reuse a unique run-scoped index over this bucket.
|
|
267
|
+
|
|
268
|
+
Duplicate frozen keys raise an error because each key must identify one
|
|
269
|
+
row. The result is cached only for the active calculation run.
|
|
270
|
+
"""
|
|
271
|
+
normalized_key_spec = normalize_bucket_index_key_spec(key_spec)
|
|
272
|
+
source_signature = self._bucket_index_source_signature()
|
|
273
|
+
with ensure_calculation_run_context() as context:
|
|
274
|
+
cached = context.get_bucket_index_result(
|
|
275
|
+
source_signature,
|
|
276
|
+
normalized_key_spec,
|
|
277
|
+
False,
|
|
278
|
+
max_rows,
|
|
279
|
+
)
|
|
280
|
+
if cached is not None:
|
|
281
|
+
return cached # type: ignore[return-value]
|
|
282
|
+
|
|
283
|
+
with DependencyTracker() as dependencies:
|
|
284
|
+
index = build_unique_bucket_index(
|
|
285
|
+
self,
|
|
286
|
+
key_spec,
|
|
287
|
+
max_rows=max_rows,
|
|
288
|
+
)
|
|
289
|
+
context.set_bucket_index_result(
|
|
290
|
+
source_signature,
|
|
291
|
+
normalized_key_spec,
|
|
292
|
+
False,
|
|
293
|
+
index,
|
|
294
|
+
dependencies,
|
|
295
|
+
max_rows,
|
|
296
|
+
)
|
|
297
|
+
return index
|
|
298
|
+
|
|
299
|
+
def index_many(
|
|
300
|
+
self,
|
|
301
|
+
key_spec: BucketIndexKeySpec,
|
|
302
|
+
*,
|
|
303
|
+
max_rows: int | None = 1000,
|
|
304
|
+
) -> dict[Hashable, tuple[GeneralManagerType, ...]]:
|
|
305
|
+
"""Build or reuse a run-scoped index that groups rows by key.
|
|
306
|
+
|
|
307
|
+
Values are tuples preserving source iteration order, and the cached
|
|
308
|
+
result is scoped to the active calculation run.
|
|
309
|
+
"""
|
|
310
|
+
normalized_key_spec = normalize_bucket_index_key_spec(key_spec)
|
|
311
|
+
source_signature = self._bucket_index_source_signature()
|
|
312
|
+
with ensure_calculation_run_context() as context:
|
|
313
|
+
cached = context.get_bucket_index_result(
|
|
314
|
+
source_signature,
|
|
315
|
+
normalized_key_spec,
|
|
316
|
+
True,
|
|
317
|
+
max_rows,
|
|
318
|
+
)
|
|
319
|
+
if cached is not None:
|
|
320
|
+
return cached # type: ignore[return-value]
|
|
321
|
+
|
|
322
|
+
with DependencyTracker() as dependencies:
|
|
323
|
+
index = build_multi_bucket_index(
|
|
324
|
+
self,
|
|
325
|
+
key_spec,
|
|
326
|
+
max_rows=max_rows,
|
|
327
|
+
)
|
|
328
|
+
context.set_bucket_index_result(
|
|
329
|
+
source_signature,
|
|
330
|
+
normalized_key_spec,
|
|
331
|
+
True,
|
|
332
|
+
index,
|
|
333
|
+
dependencies,
|
|
334
|
+
max_rows,
|
|
335
|
+
)
|
|
336
|
+
return index
|
|
337
|
+
|
|
242
338
|
def none(self) -> Bucket[GeneralManagerType]:
|
|
243
339
|
"""
|
|
244
340
|
Return an empty bucket instance.
|
{generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/bucket/calculation_bucket.py
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Bucket implementation that enumerates calculation interface combinations."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
|
-
from collections.abc import Iterable
|
|
4
|
+
from collections.abc import Hashable, Iterable
|
|
5
5
|
from types import UnionType
|
|
6
6
|
from typing import (
|
|
7
7
|
Any,
|
|
@@ -22,6 +22,7 @@ from general_manager.interface.base_interface import (
|
|
|
22
22
|
GeneralManagerType,
|
|
23
23
|
)
|
|
24
24
|
from general_manager.bucket.base_bucket import Bucket
|
|
25
|
+
from general_manager.bucket.indexing import freeze_bucket_index_value
|
|
25
26
|
from general_manager.manager.input import Input, InputDomain
|
|
26
27
|
from general_manager.utils.filter_parser import parse_filters
|
|
27
28
|
|
|
@@ -461,6 +462,17 @@ class CalculationBucket(Bucket[GeneralManagerType]):
|
|
|
461
462
|
return (self.sort_key,)
|
|
462
463
|
return self.sort_key
|
|
463
464
|
|
|
465
|
+
def _bucket_index_source_signature(self) -> Hashable:
|
|
466
|
+
"""Return a stable signature for equivalent calculation bucket plans."""
|
|
467
|
+
return (
|
|
468
|
+
"calculation",
|
|
469
|
+
self._manager_class,
|
|
470
|
+
freeze_bucket_index_value(self.filter_definitions),
|
|
471
|
+
freeze_bucket_index_value(self.exclude_definitions),
|
|
472
|
+
self._normalized_sort_key(),
|
|
473
|
+
self.reverse,
|
|
474
|
+
)
|
|
475
|
+
|
|
464
476
|
def _sort_uses_only_inputs(self, sort_key: tuple[str, ...] | None) -> bool:
|
|
465
477
|
"""Return whether a sort can be applied to raw input dictionaries."""
|
|
466
478
|
if sort_key is None:
|
{generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/bucket/database_bucket.py
RENAMED
|
@@ -329,6 +329,13 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
329
329
|
self._sort_reverse,
|
|
330
330
|
)
|
|
331
331
|
|
|
332
|
+
def _bucket_index_source_signature(self) -> Hashable:
|
|
333
|
+
"""Return a queryset signature when safe, otherwise use object identity."""
|
|
334
|
+
query_signature = self._query_signature()
|
|
335
|
+
if query_signature is None:
|
|
336
|
+
return super()._bucket_index_source_signature()
|
|
337
|
+
return ("database", query_signature)
|
|
338
|
+
|
|
332
339
|
def _get_run_scoped_primary_keys(self) -> tuple[Any, ...] | None:
|
|
333
340
|
"""
|
|
334
341
|
Load or reuse a bounded primary-key snapshot for this bucket.
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"""Run-scoped bucket index helpers."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections import defaultdict
|
|
6
|
+
from collections.abc import Hashable, Iterable
|
|
7
|
+
from typing import TypeVar, cast
|
|
8
|
+
|
|
9
|
+
T = TypeVar("T")
|
|
10
|
+
BucketIndexKeySpec = str | tuple[str, ...]
|
|
11
|
+
NormalizedBucketIndexKeySpec = tuple[str, tuple[str, ...], bool]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _frozen_pair_sort_key(pair: tuple[Hashable, Hashable]) -> tuple[str, str]:
|
|
15
|
+
"""Return a string-only sort key for frozen mapping pairs."""
|
|
16
|
+
return (str(pair[0]), str(pair[1]))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class UnsupportedBucketIndexKeySpecError(TypeError):
|
|
20
|
+
"""Raised when a bucket index key spec cannot produce a stable run key."""
|
|
21
|
+
|
|
22
|
+
def __init__(self, key_spec: object) -> None:
|
|
23
|
+
"""Build an error that names the unsupported key specification."""
|
|
24
|
+
super().__init__(
|
|
25
|
+
"Bucket index key specs must be a field name or a non-empty tuple "
|
|
26
|
+
f"of field names; got {key_spec!r}."
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class MissingBucketIndexKeyError(AttributeError):
|
|
31
|
+
"""Raised when an indexed row does not expose a requested key field."""
|
|
32
|
+
|
|
33
|
+
def __init__(self, field_name: str, row: object) -> None:
|
|
34
|
+
"""Build an error that identifies the missing row field."""
|
|
35
|
+
super().__init__(
|
|
36
|
+
f"Cannot build bucket index: {row!r} is missing key field {field_name!r}."
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class DuplicateBucketIndexKeyError(ValueError):
|
|
41
|
+
"""Raised when a unique bucket index sees more than one row for a key."""
|
|
42
|
+
|
|
43
|
+
def __init__(self, key: Hashable) -> None:
|
|
44
|
+
"""Build an error that identifies the duplicated frozen index key."""
|
|
45
|
+
super().__init__(f"Bucket index key {key!r} matched more than one row.")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class BucketIndexTooLargeError(ValueError):
|
|
49
|
+
"""Raised when index construction exceeds the configured row guardrail."""
|
|
50
|
+
|
|
51
|
+
def __init__(self, max_rows: int) -> None:
|
|
52
|
+
"""Build an error that reports the row guardrail that was exceeded."""
|
|
53
|
+
super().__init__(
|
|
54
|
+
f"Bucket index construction exceeded the configured limit of {max_rows} rows."
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class UnhashableBucketIndexKeyError(TypeError):
|
|
59
|
+
"""Raised when a key value cannot be converted to a hashable identity."""
|
|
60
|
+
|
|
61
|
+
def __init__(self, key: object) -> None:
|
|
62
|
+
"""Build an error that reports the unfreezable key value."""
|
|
63
|
+
super().__init__(f"Bucket index key {key!r} is not hashable.")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def normalize_bucket_index_key_spec(
|
|
67
|
+
key_spec: object,
|
|
68
|
+
) -> NormalizedBucketIndexKeySpec:
|
|
69
|
+
"""Return a stable normalized representation for a supported key spec."""
|
|
70
|
+
if isinstance(key_spec, str):
|
|
71
|
+
return ("field", (key_spec,), False)
|
|
72
|
+
if (
|
|
73
|
+
isinstance(key_spec, tuple)
|
|
74
|
+
and len(key_spec) > 0
|
|
75
|
+
and all(isinstance(part, str) for part in key_spec)
|
|
76
|
+
):
|
|
77
|
+
return ("field", key_spec, True)
|
|
78
|
+
raise UnsupportedBucketIndexKeySpecError(key_spec)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def freeze_bucket_index_value(value: object) -> Hashable:
|
|
82
|
+
"""Return a stable hashable identity for values used as index keys.
|
|
83
|
+
|
|
84
|
+
Manager instances are represented by their class and identification, and
|
|
85
|
+
containers are recursively frozen so equivalent values share a run-cache key.
|
|
86
|
+
"""
|
|
87
|
+
from general_manager.manager.general_manager import GeneralManager
|
|
88
|
+
|
|
89
|
+
if isinstance(value, GeneralManager):
|
|
90
|
+
return (
|
|
91
|
+
value.__class__,
|
|
92
|
+
tuple(
|
|
93
|
+
sorted(
|
|
94
|
+
(
|
|
95
|
+
(
|
|
96
|
+
cast(Hashable, freeze_bucket_index_value(key)),
|
|
97
|
+
freeze_bucket_index_value(identifier),
|
|
98
|
+
)
|
|
99
|
+
for key, identifier in value.identification.items()
|
|
100
|
+
),
|
|
101
|
+
key=_frozen_pair_sort_key,
|
|
102
|
+
)
|
|
103
|
+
),
|
|
104
|
+
)
|
|
105
|
+
if isinstance(value, dict):
|
|
106
|
+
return tuple(
|
|
107
|
+
sorted(
|
|
108
|
+
(
|
|
109
|
+
(
|
|
110
|
+
cast(Hashable, freeze_bucket_index_value(key)),
|
|
111
|
+
freeze_bucket_index_value(item),
|
|
112
|
+
)
|
|
113
|
+
for key, item in value.items()
|
|
114
|
+
),
|
|
115
|
+
key=_frozen_pair_sort_key,
|
|
116
|
+
)
|
|
117
|
+
)
|
|
118
|
+
if isinstance(value, (list, tuple)):
|
|
119
|
+
return tuple(freeze_bucket_index_value(item) for item in value)
|
|
120
|
+
if isinstance(value, set):
|
|
121
|
+
return frozenset(freeze_bucket_index_value(item) for item in value)
|
|
122
|
+
try:
|
|
123
|
+
hash(value)
|
|
124
|
+
except TypeError as error:
|
|
125
|
+
raise UnhashableBucketIndexKeyError(value) from error
|
|
126
|
+
return cast(Hashable, value)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def resolve_bucket_index_key(
|
|
130
|
+
row: object,
|
|
131
|
+
key_spec: BucketIndexKeySpec,
|
|
132
|
+
) -> Hashable:
|
|
133
|
+
"""Resolve the requested field value or composite key for one row."""
|
|
134
|
+
_, field_names, composite = normalize_bucket_index_key_spec(key_spec)
|
|
135
|
+
values: list[Hashable] = []
|
|
136
|
+
for field_name in field_names:
|
|
137
|
+
try:
|
|
138
|
+
value = getattr(row, field_name)
|
|
139
|
+
except AttributeError as error:
|
|
140
|
+
raise MissingBucketIndexKeyError(field_name, row) from error
|
|
141
|
+
values.append(freeze_bucket_index_value(value))
|
|
142
|
+
if composite:
|
|
143
|
+
return tuple(values)
|
|
144
|
+
return values[0]
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def _iter_guarded_rows(
|
|
148
|
+
rows: Iterable[T],
|
|
149
|
+
max_rows: int | None,
|
|
150
|
+
) -> Iterable[T]:
|
|
151
|
+
"""Yield rows until max_rows is exceeded, then raise a guardrail error."""
|
|
152
|
+
for index, row in enumerate(rows):
|
|
153
|
+
if max_rows is not None and index >= max_rows:
|
|
154
|
+
raise BucketIndexTooLargeError(max_rows)
|
|
155
|
+
yield row
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def build_unique_bucket_index(
|
|
159
|
+
rows: Iterable[T],
|
|
160
|
+
key_spec: BucketIndexKeySpec,
|
|
161
|
+
*,
|
|
162
|
+
max_rows: int | None,
|
|
163
|
+
) -> dict[Hashable, T]:
|
|
164
|
+
"""Build a unique index and fail when duplicate frozen keys are found."""
|
|
165
|
+
indexed: dict[Hashable, T] = {}
|
|
166
|
+
for row in _iter_guarded_rows(rows, max_rows):
|
|
167
|
+
key = resolve_bucket_index_key(row, key_spec)
|
|
168
|
+
if key in indexed:
|
|
169
|
+
raise DuplicateBucketIndexKeyError(key)
|
|
170
|
+
indexed[key] = row
|
|
171
|
+
return indexed
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def build_multi_bucket_index(
|
|
175
|
+
rows: Iterable[T],
|
|
176
|
+
key_spec: BucketIndexKeySpec,
|
|
177
|
+
*,
|
|
178
|
+
max_rows: int | None,
|
|
179
|
+
) -> dict[Hashable, tuple[T, ...]]:
|
|
180
|
+
"""Build a grouped index that preserves row order for duplicate keys."""
|
|
181
|
+
grouped: defaultdict[Hashable, list[T]] = defaultdict(list)
|
|
182
|
+
for row in _iter_guarded_rows(rows, max_rows):
|
|
183
|
+
grouped[resolve_bucket_index_key(row, key_spec)].append(row)
|
|
184
|
+
return {key: tuple(values) for key, values in grouped.items()}
|
{generalmanager-0.50.0 → generalmanager-0.52.0}/src/general_manager/bucket/request_bucket.py
RENAMED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from collections.abc import Generator, Mapping
|
|
5
|
+
from collections.abc import Generator, Hashable, Mapping
|
|
6
6
|
from typing import TYPE_CHECKING, Any, cast
|
|
7
7
|
|
|
8
8
|
from general_manager.bucket.base_bucket import Bucket, GeneralManagerType
|
|
9
|
+
from general_manager.bucket.indexing import freeze_bucket_index_value
|
|
9
10
|
from general_manager.interface.requests import (
|
|
10
11
|
RequestLocalPredicate,
|
|
11
12
|
RequestLocalPaginationUnsupportedError,
|
|
@@ -172,6 +173,22 @@ class RequestBucket(Bucket[GeneralManagerType]):
|
|
|
172
173
|
item.identification for item in other._ensure_items()
|
|
173
174
|
)
|
|
174
175
|
|
|
176
|
+
def _bucket_index_source_signature(self) -> Hashable:
|
|
177
|
+
"""Return a stable request signature, or object identity for materialized data."""
|
|
178
|
+
if self.request_plan is not None:
|
|
179
|
+
restore_func, restore_args = self.request_plan.__reduce__()
|
|
180
|
+
return (
|
|
181
|
+
"request",
|
|
182
|
+
self._manager_class,
|
|
183
|
+
self._interface_cls,
|
|
184
|
+
self._operation_name,
|
|
185
|
+
restore_func,
|
|
186
|
+
freeze_bucket_index_value(restore_args),
|
|
187
|
+
freeze_bucket_index_value(self.filters),
|
|
188
|
+
freeze_bucket_index_value(self.excludes),
|
|
189
|
+
)
|
|
190
|
+
return super()._bucket_index_source_signature()
|
|
191
|
+
|
|
175
192
|
def __iter__(self) -> Generator[GeneralManagerType, None, None]:
|
|
176
193
|
yield from self._ensure_items()
|
|
177
194
|
|