GeneralManager 0.82.0__tar.gz → 0.82.2__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.82.0/src/GeneralManager.egg-info → generalmanager-0.82.2}/PKG-INFO +1 -1
- {generalmanager-0.82.0 → generalmanager-0.82.2}/pyproject.toml +1 -1
- {generalmanager-0.82.0 → generalmanager-0.82.2/src/GeneralManager.egg-info}/PKG-INFO +1 -1
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/GeneralManager.egg-info/SOURCES.txt +1 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql.py +18 -1
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql_identifiers.py +43 -1
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql_search.py +10 -1
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/property.py +18 -1
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/cache/dependency_index.py +122 -10
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/cache/signals.py +19 -2
- generalmanager-0.82.2/src/general_manager/cache/transaction_barrier.py +283 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/orm/create_many.py +17 -2
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/utils/testing.py +4 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/LICENSE +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/README.md +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/setup.cfg +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/GeneralManager.egg-info/requires.txt +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/GeneralManager.egg-info/top_level.txt +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/_types/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/_types/api.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/_types/bucket.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/_types/cache.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/_types/dataframes.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/_types/factory.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/_types/general_manager.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/_types/interface.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/_types/manager.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/_types/measurement.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/_types/permission.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/_types/rule.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/_types/search.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/_types/utils.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql_as_of.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql_errors.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql_groups.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql_mutations.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql_ordering.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql_output.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql_prefetch.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql_relations.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql_resolvers.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql_subscription_consumer.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql_subscriptions.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql_type.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql_view.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql_warmup.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql_warmup_registry.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql_warmup_tasks.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/mutation.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/notification_batching.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/registry.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/remote_api.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/remote_invalidation.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/remote_invalidation_client.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/apps.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/as_of.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/bootstrap.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/bucket/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/bucket/_materialized_bucket.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/bucket/_ordering.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/bucket/base_bucket.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/bucket/calculation_bucket.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/bucket/database_bucket.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/bucket/excel_bucket.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/bucket/group_bucket.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/bucket/indexing.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/bucket/projection.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/bucket/request_bucket.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/cache/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/cache/_dependency_graph.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/cache/batch_refresh.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/cache/cache_decorator.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/cache/cache_tracker.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/cache/data_change_context.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/cache/dependency_cache.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/cache/dependency_matching.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/cache/dependency_publish.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/cache/dependency_shards.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/cache/model_dependency_collector.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/cache/run_context.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/cache/run_context_lru.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/audit.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/bootstrap.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/checks.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/consumer.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/context.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/errors.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/__main__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/baseline.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/datasets/basic_queries.yaml +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/datasets/demo_readiness.yaml +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/datasets/edge_cases.yaml +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/datasets/follow_ups.yaml +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/datasets/large_schema.yaml +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/datasets/multi_hop.yaml +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/datasets/planned_orchestration.yaml +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/diagnostics.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/fingerprints.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/fixtures.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/judges/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/judges/answer_quality.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/judges/contract.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/judges/result_accuracy.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/judges/tool_sequence.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/readiness.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/runner.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/evals/traces.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/grounding.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/models.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/planned/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/planned/budget.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/planned/calculations.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/planned/catalog.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/planned/config.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/planned/events.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/planned/evidence.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/planned/models.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/planned/planner.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/planned/provider_calls.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/planned/resolver.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/planned/routing.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/planned/scheduler.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/planned/synthesis.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/planned/validation.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/providers/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/providers/_shared.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/providers/anthropic.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/providers/base.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/providers/google.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/providers/ollama.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/providers/openai.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/rate_limits.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/routing.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/schema_index.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/settings.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/signals.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/system_prompt.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/tool_metadata.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/tools.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/turns.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/chat/views.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/conf.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/dataframes/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/dataframes/measurements.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/factory/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/factory/auto_factory.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/factory/factories.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/factory/factory_methods.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/base_interface.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/bundles/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/bundles/calculation.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/bundles/database.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/bundles/excel.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/bundles/remote_manager.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/bundles/request.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/base.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/builtin.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/calculation/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/calculation/_compat.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/calculation/input_resolution.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/calculation/lifecycle.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/configuration.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/core/observability.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/core/utils.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/excel/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/exceptions.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/existing_model/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/existing_model/_compat.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/existing_model/resolution.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/factory.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/orm/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/orm/_compat.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/orm/bulk.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/orm/history.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/orm/lifecycle.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/orm/mutations.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/orm/support.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/orm_utils/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/orm_utils/django_manager_utils.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/orm_utils/field_descriptors.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/orm_utils/payload_normalizer.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/orm_utils/update_state.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/read_only/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/read_only/_compat.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/read_only/_types.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/read_only/lifecycle.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/read_only/management.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/registry.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/remote_manager.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/capabilities/request/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/excel.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/excel_store.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/excel_workbook.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/infrastructure/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/infrastructure/startup_hooks.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/infrastructure/system_checks.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/interfaces/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/interfaces/calculation.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/interfaces/database.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/interfaces/excel.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/interfaces/existing_model.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/interfaces/read_only.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/interfaces/remote_manager.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/interfaces/request.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/manifests/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/manifests/capability_builder.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/manifests/capability_manifest.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/manifests/capability_models.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/orm_interface.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/requests.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/utils/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/utils/database_interface_protocols.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/utils/errors.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/utils/history.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/interface/utils/models.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/logging.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/management/commands/chat_cleanup.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/management/commands/cleanup_upload_intents.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/management/commands/graphql_warmup.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/management/commands/graphql_warmup_refresh_due.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/management/commands/search_index.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/management/commands/search_reconcile.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/management/commands/seed_manager_landscape.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/management/commands/shell.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/management/commands/workflow_drain_outbox.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/management/commands/workflow_replay_dead_letters.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/manager/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/manager/bulk_create.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/manager/general_manager.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/manager/group_manager.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/manager/input.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/manager/meta.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/measurement/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/measurement/measurement.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/measurement/measurement_field.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/metrics/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/metrics/graphql.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/migrations/0001_initial.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/migrations/0002_workflow_outbox_scaling_indexes.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/migrations/0003_workflow_execution_correlation_constraint.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/migrations/0004_chat_persistence_models.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/migrations/0004_search_index_state.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/migrations/0005_merge_chat_search.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/migrations/0006_chat_pending_confirmation_scoped_ids.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/migrations/0007_upload_intent.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/migrations/0008_upload_finalization_versions.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/migrations/0009_upload_cleanup_state.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/migrations/0010_chat_pending_confirmation_portable_uniqueness.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/migrations/0011_search_index_state_dirty_generation.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/migrations/0012_chat_context_watermarks.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/migrations/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/models.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/permission/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/permission/audit.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/permission/base_permission.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/permission/graphql_capabilities.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/permission/manager_based_permission.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/permission/mutation_permission.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/permission/permission_checks.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/permission/permission_data_manager.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/permission/utils.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/public_api_registry.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/py.typed +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/rule/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/rule/handler.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/rule/rule.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/search/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/search/async_tasks.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/search/backend.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/search/backend_registry.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/search/backends/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/search/backends/dev.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/search/backends/meilisearch.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/search/backends/opensearch.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/search/backends/typesense.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/search/checks.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/search/config.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/search/indexer.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/search/invalidation.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/search/m2m_invalidation.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/search/models.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/search/reconciliation.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/search/registry.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/search/tasks.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/search/utils.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/seeding/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/seeding/manager_landscape.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/uploads/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/uploads/adapters.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/uploads/checks.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/uploads/config.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/uploads/errors.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/uploads/finalization.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/uploads/graphql.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/uploads/graphql_types.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/uploads/metrics.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/uploads/models.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/uploads/public.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/uploads/s3.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/uploads/services.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/uploads/tokens.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/uploads/types.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/uploads/urls.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/uploads/views.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/utils/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/utils/_args_to_kwargs.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/utils/_cache_key_encoder.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/utils/_make_cache_key.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/utils/_none_to_zero.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/utils/filter_parser.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/utils/format_string.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/utils/json_encoder.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/utils/path_mapping.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/utils/public_api.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/utils/type_checks.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/workflow/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/workflow/actions.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/workflow/backend_registry.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/workflow/backends/__init__.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/workflow/backends/celery.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/workflow/backends/local.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/workflow/backends/n8n.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/workflow/config.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/workflow/engine.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/workflow/event_registry.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/workflow/events.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/workflow/models.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/workflow/signal_bridge.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/workflow/tasks.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/workflow/telemetry.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/tests/test_settings.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/tests/test_urls.py +0 -0
- {generalmanager-0.82.0 → generalmanager-0.82.2}/tests/testing_asgi.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GeneralManager
|
|
3
|
-
Version: 0.82.
|
|
3
|
+
Version: 0.82.2
|
|
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.82.
|
|
7
|
+
version = "0.82.2"
|
|
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.82.
|
|
3
|
+
Version: 0.82.2
|
|
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
|
|
@@ -82,6 +82,7 @@ src/general_manager/cache/model_dependency_collector.py
|
|
|
82
82
|
src/general_manager/cache/run_context.py
|
|
83
83
|
src/general_manager/cache/run_context_lru.py
|
|
84
84
|
src/general_manager/cache/signals.py
|
|
85
|
+
src/general_manager/cache/transaction_barrier.py
|
|
85
86
|
src/general_manager/chat/__init__.py
|
|
86
87
|
src/general_manager/chat/audit.py
|
|
87
88
|
src/general_manager/chat/bootstrap.py
|
|
@@ -38,7 +38,10 @@ from django.core.exceptions import ObjectDoesNotExist
|
|
|
38
38
|
from django.db import DEFAULT_DB_ALIAS, models, transaction
|
|
39
39
|
from django.utils.module_loading import import_string
|
|
40
40
|
|
|
41
|
-
from general_manager.api.graphql_identifiers import
|
|
41
|
+
from general_manager.api.graphql_identifiers import (
|
|
42
|
+
build_identification_arguments,
|
|
43
|
+
property_identifier_type,
|
|
44
|
+
)
|
|
42
45
|
from general_manager.bucket.base_bucket import Bucket
|
|
43
46
|
from general_manager.bucket.group_bucket import GroupBucket
|
|
44
47
|
from general_manager.cache.dependency_index import (
|
|
@@ -929,6 +932,20 @@ class GraphQL:
|
|
|
929
932
|
) in generalManagerClass.Interface.get_graph_ql_properties().items():
|
|
930
933
|
raw_hint = attr_value.graphql_type_hint
|
|
931
934
|
|
|
935
|
+
if attr_value.is_identifier:
|
|
936
|
+
native_type, is_collection = property_identifier_type(
|
|
937
|
+
raw_hint,
|
|
938
|
+
owner_name=generalManagerClass.__name__,
|
|
939
|
+
field_name=attr_name,
|
|
940
|
+
)
|
|
941
|
+
fields[attr_name] = (
|
|
942
|
+
graphene.List(graphene.ID) if is_collection else graphene.ID()
|
|
943
|
+
)
|
|
944
|
+
fields[f"resolve_{attr_name}"] = cls._create_resolver(
|
|
945
|
+
attr_name, native_type
|
|
946
|
+
)
|
|
947
|
+
continue
|
|
948
|
+
|
|
932
949
|
if _contains_measurement(raw_hint):
|
|
933
950
|
mapped = map_graphql_output_annotation(
|
|
934
951
|
raw_hint,
|
{generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/api/graphql_identifiers.py
RENAMED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from collections.abc import Mapping
|
|
6
|
-
from
|
|
6
|
+
from types import UnionType
|
|
7
|
+
from typing import Annotated, Union, cast, get_args, get_origin
|
|
8
|
+
from uuid import UUID
|
|
7
9
|
|
|
8
10
|
import graphene
|
|
9
11
|
from django.db import models
|
|
@@ -16,9 +18,49 @@ from general_manager.api.graphql_relations import (
|
|
|
16
18
|
get_graphql_manager_registry,
|
|
17
19
|
resolve_general_manager_type,
|
|
18
20
|
)
|
|
21
|
+
from general_manager.api.graphql_output import GraphQLOutputAnnotationError
|
|
19
22
|
from general_manager.manager.general_manager import GeneralManager
|
|
20
23
|
|
|
21
24
|
|
|
25
|
+
def property_identifier_type(
|
|
26
|
+
annotation: object, *, owner_name: str, field_name: str
|
|
27
|
+
) -> tuple[type, bool]:
|
|
28
|
+
"""Validate an explicit native identity hint and return its type and shape.
|
|
29
|
+
|
|
30
|
+
This shared interpretation lets output and filter builders consume the
|
|
31
|
+
descriptor's public ``is_identifier`` flag without changing its annotation
|
|
32
|
+
or the native resolver value. Optional wrappers do not add non-null output
|
|
33
|
+
constraints to legacy manager properties.
|
|
34
|
+
"""
|
|
35
|
+
original_annotation = annotation
|
|
36
|
+
|
|
37
|
+
def unwrap(hint: object) -> object:
|
|
38
|
+
while get_origin(hint) is Annotated:
|
|
39
|
+
hint = get_args(hint)[0]
|
|
40
|
+
if get_origin(hint) in (Union, UnionType):
|
|
41
|
+
members = get_args(hint)
|
|
42
|
+
if len(members) == 2 and type(None) in members:
|
|
43
|
+
return unwrap(next(t for t in members if t is not type(None)))
|
|
44
|
+
return hint
|
|
45
|
+
|
|
46
|
+
annotation = unwrap(annotation)
|
|
47
|
+
origin = get_origin(annotation)
|
|
48
|
+
is_collection = origin in (list, tuple, set)
|
|
49
|
+
if is_collection:
|
|
50
|
+
elements = get_args(annotation)
|
|
51
|
+
if origin is tuple and len(elements) == 2 and elements[1] is Ellipsis:
|
|
52
|
+
elements = elements[:1]
|
|
53
|
+
if elements and (origin is tuple or len(elements) == 1):
|
|
54
|
+
native_type = unwrap(elements[0])
|
|
55
|
+
if native_type in (int, str, UUID) and all(
|
|
56
|
+
unwrap(element) is native_type for element in elements
|
|
57
|
+
):
|
|
58
|
+
return cast(type, native_type), True
|
|
59
|
+
elif annotation in (int, str, UUID):
|
|
60
|
+
return cast(type, annotation), False
|
|
61
|
+
raise GraphQLOutputAnnotationError(owner_name, field_name, original_annotation)
|
|
62
|
+
|
|
63
|
+
|
|
22
64
|
def is_orm_identifier_input(manager_class: type[GeneralManager], name: str) -> bool:
|
|
23
65
|
"""Identify the ORM constructor alias addressing the actual model PK."""
|
|
24
66
|
model = getattr(manager_class.Interface, "_model", None)
|
|
@@ -25,6 +25,7 @@ from django.core.exceptions import FieldDoesNotExist
|
|
|
25
25
|
from django.db import models
|
|
26
26
|
|
|
27
27
|
from general_manager.conf import get_setting
|
|
28
|
+
from general_manager.api.graphql_identifiers import property_identifier_type
|
|
28
29
|
from general_manager.api.graphql_ordering import (
|
|
29
30
|
GraphQLOrderingInputError,
|
|
30
31
|
create_ordering_types,
|
|
@@ -842,12 +843,20 @@ def create_filter_options(
|
|
|
842
843
|
continue
|
|
843
844
|
hints = [t for t in get_args(prop.graphql_type_hint) if t is not type(None)]
|
|
844
845
|
prop_type = hints[0] if hints else cast(type, prop.graphql_type_hint)
|
|
846
|
+
prop_info: dict[str, object] = {}
|
|
847
|
+
if prop.is_identifier:
|
|
848
|
+
prop_type, _ = property_identifier_type(
|
|
849
|
+
prop.graphql_type_hint,
|
|
850
|
+
owner_name=field_type.__name__,
|
|
851
|
+
field_name=prop_name,
|
|
852
|
+
)
|
|
853
|
+
prop_info["is_identifier"] = True
|
|
845
854
|
filter_fields = {
|
|
846
855
|
**filter_fields,
|
|
847
856
|
**{
|
|
848
857
|
k: v
|
|
849
858
|
for k, v in get_filter_options(
|
|
850
|
-
prop_type, prop_name, map_field_to_graphene_read
|
|
859
|
+
prop_type, prop_name, map_field_to_graphene_read, prop_info
|
|
851
860
|
)
|
|
852
861
|
if v is not None
|
|
853
862
|
},
|
|
@@ -55,7 +55,7 @@ class GraphQLPropertyTimeoutConfigurationError(ValueError):
|
|
|
55
55
|
class GraphQLProperty(property):
|
|
56
56
|
"""Descriptor that exposes a resolver with GraphQL metadata and caching.
|
|
57
57
|
|
|
58
|
-
Stable inspection attributes are `sortable`, `filterable`,
|
|
58
|
+
Stable inspection attributes are `sortable`, `filterable`, `is_identifier`,
|
|
59
59
|
`query_annotation`, `cache`, `timeout`, `warm_up`, and `graphql_type_hint`.
|
|
60
60
|
The descriptor preserves normal `property` behavior such as `fget` and
|
|
61
61
|
`__doc__`, but those values follow Python's property/wraps mechanics rather
|
|
@@ -66,6 +66,7 @@ class GraphQLProperty(property):
|
|
|
66
66
|
|
|
67
67
|
sortable: bool
|
|
68
68
|
filterable: bool
|
|
69
|
+
is_identifier: bool
|
|
69
70
|
warm_up: bool
|
|
70
71
|
query_annotation: object | None
|
|
71
72
|
timeout: int | None
|
|
@@ -77,6 +78,7 @@ class GraphQLProperty(property):
|
|
|
77
78
|
*,
|
|
78
79
|
sortable: bool = False,
|
|
79
80
|
filterable: bool = False,
|
|
81
|
+
is_identifier: bool = False,
|
|
80
82
|
query_annotation: object | None = None,
|
|
81
83
|
cache: GraphQLPropertyCache = "none",
|
|
82
84
|
timeout: int | None = None,
|
|
@@ -101,6 +103,10 @@ class GraphQLProperty(property):
|
|
|
101
103
|
filterable: Whether generated GraphQL fields may expose filtering
|
|
102
104
|
for this property. Stored as supplied; runtime truthiness is not
|
|
103
105
|
coerced or validated.
|
|
106
|
+
is_identifier: Declare native integer, string, or UUID identities,
|
|
107
|
+
either scalar or a homogeneous list, tuple, or set. Generates
|
|
108
|
+
GraphQL ID output without changing Python values. Unsupported
|
|
109
|
+
annotations raise TypeError during schema generation.
|
|
104
110
|
query_annotation: Opaque ORM annotation object or callable consumed
|
|
105
111
|
by database bucket query construction.
|
|
106
112
|
cache: Resolver cache scope. `"none"` evaluates every access,
|
|
@@ -160,6 +166,7 @@ class GraphQLProperty(property):
|
|
|
160
166
|
|
|
161
167
|
self.sortable = sortable
|
|
162
168
|
self.filterable = filterable
|
|
169
|
+
self.is_identifier = is_identifier
|
|
163
170
|
self.query_annotation = query_annotation
|
|
164
171
|
self.cache = cache
|
|
165
172
|
self.timeout = timeout
|
|
@@ -276,6 +283,7 @@ def graph_ql_property(
|
|
|
276
283
|
*,
|
|
277
284
|
sortable: bool = False,
|
|
278
285
|
filterable: bool = False,
|
|
286
|
+
is_identifier: bool = False,
|
|
279
287
|
query_annotation: object | None = None,
|
|
280
288
|
cache: GraphQLPropertyCache = "run",
|
|
281
289
|
timeout: int | None = None,
|
|
@@ -290,6 +298,7 @@ def graph_ql_property(
|
|
|
290
298
|
*,
|
|
291
299
|
sortable: bool = False,
|
|
292
300
|
filterable: bool = False,
|
|
301
|
+
is_identifier: bool = False,
|
|
293
302
|
query_annotation: object | None = None,
|
|
294
303
|
cache: GraphQLPropertyCache = "run",
|
|
295
304
|
timeout: int | None = None,
|
|
@@ -307,6 +316,13 @@ def graph_ql_property(
|
|
|
307
316
|
property.
|
|
308
317
|
filterable: Whether generated GraphQL fields may expose filtering for
|
|
309
318
|
this property.
|
|
319
|
+
is_identifier: Explicitly declare native integer, string, or UUID
|
|
320
|
+
identities. Scalars map to ID and homogeneous list, tuple, or set
|
|
321
|
+
collections to [ID], preserving nullable property output and native
|
|
322
|
+
Python values. Optional annotations and optional elements are
|
|
323
|
+
supported. Manager objects, nested collections, ambiguous unions,
|
|
324
|
+
and other scalar types raise TypeError during schema generation.
|
|
325
|
+
Names and query_annotation never infer this flag. Defaults to False.
|
|
310
326
|
query_annotation: Opaque ORM annotation object or callable consumed by
|
|
311
327
|
database bucket query construction.
|
|
312
328
|
cache: Cache scope. `"run"` is the default and memoizes only within the
|
|
@@ -354,6 +370,7 @@ def graph_ql_property(
|
|
|
354
370
|
sortable=sortable,
|
|
355
371
|
query_annotation=query_annotation,
|
|
356
372
|
filterable=filterable,
|
|
373
|
+
is_identifier=is_identifier,
|
|
357
374
|
cache=cache,
|
|
358
375
|
timeout=timeout,
|
|
359
376
|
warm_up=warm_up,
|
{generalmanager-0.82.0 → generalmanager-0.82.2}/src/general_manager/cache/dependency_index.py
RENAMED
|
@@ -7,7 +7,8 @@ import random
|
|
|
7
7
|
from threading import Event, Thread
|
|
8
8
|
import time
|
|
9
9
|
import uuid
|
|
10
|
-
from collections.abc import Mapping
|
|
10
|
+
from collections.abc import Iterator, Mapping
|
|
11
|
+
from contextlib import contextmanager
|
|
11
12
|
from contextvars import ContextVar
|
|
12
13
|
from datetime import date, datetime
|
|
13
14
|
from time import perf_counter
|
|
@@ -73,6 +74,9 @@ _pending_graphql_rewarm_cache_keys: ContextVar[frozenset[str]] = ContextVar(
|
|
|
73
74
|
"general_manager_pending_graphql_rewarm_cache_keys",
|
|
74
75
|
default=frozenset(),
|
|
75
76
|
)
|
|
77
|
+
_dependency_rewarm_scope_depth: ContextVar[int] = ContextVar(
|
|
78
|
+
"general_manager_dependency_rewarm_scope_depth", default=0
|
|
79
|
+
)
|
|
76
80
|
|
|
77
81
|
|
|
78
82
|
class DependencyLockTimeoutError(TimeoutError):
|
|
@@ -118,6 +122,8 @@ DEPENDENCY_GENERATION_KEY = "dependency_index_generation"
|
|
|
118
122
|
DATA_CHANGE_LOCK_KEY = "dependency_index_data_change_lock"
|
|
119
123
|
DATA_CHANGE_COUNT_KEY = "dependency_index_data_change_count"
|
|
120
124
|
DATA_CHANGE_RECOVERY_KEY = "dependency_index_data_change_recovery"
|
|
125
|
+
DATA_CHANGE_OWNERS_KEY = "dependency_index_data_change_owners"
|
|
126
|
+
COMMITTED_GRAPHQL_REWARM_KEY = "dependency_index_committed_graphql_rewarm"
|
|
121
127
|
LOCK_TIMEOUT = 5 # Lock TTL in seconds
|
|
122
128
|
UNDEFINED = object() # Sentinel for undefined values
|
|
123
129
|
ACTIONS: tuple[Literal["filter"], Literal["exclude"]] = ("filter", "exclude")
|
|
@@ -241,6 +247,15 @@ def _set_dependency_data_change_count(count: int) -> int:
|
|
|
241
247
|
return count
|
|
242
248
|
|
|
243
249
|
|
|
250
|
+
def _get_dependency_data_change_owners() -> frozenset[str]:
|
|
251
|
+
owners = cache.get(DATA_CHANGE_OWNERS_KEY, frozenset())
|
|
252
|
+
if not isinstance(owners, frozenset) or not all(
|
|
253
|
+
isinstance(owner, str) for owner in owners
|
|
254
|
+
):
|
|
255
|
+
raise DependencyBarrierStateError("journal")
|
|
256
|
+
return owners
|
|
257
|
+
|
|
258
|
+
|
|
244
259
|
def _discard_active_context_dependency_cache_state() -> None:
|
|
245
260
|
from general_manager.cache.run_context import current_calculation_run_context
|
|
246
261
|
|
|
@@ -304,10 +319,21 @@ def _clear_data_change_recovery(
|
|
|
304
319
|
|
|
305
320
|
|
|
306
321
|
def _prepare_data_change_recovery(
|
|
307
|
-
token: DependencyLockToken,
|
|
322
|
+
token: DependencyLockToken,
|
|
323
|
+
count: int,
|
|
324
|
+
flag: object,
|
|
325
|
+
owners: frozenset[str],
|
|
326
|
+
generation: int | None = None,
|
|
308
327
|
) -> dict[str, object]:
|
|
309
328
|
_require_data_change_lock_owner(token)
|
|
310
|
-
recovery: dict[str, object] = {
|
|
329
|
+
recovery: dict[str, object] = {
|
|
330
|
+
"owner": token,
|
|
331
|
+
"count": count,
|
|
332
|
+
"flag": flag,
|
|
333
|
+
"owners": owners,
|
|
334
|
+
}
|
|
335
|
+
if generation is not None:
|
|
336
|
+
recovery["generation"] = generation
|
|
311
337
|
cache.set(DATA_CHANGE_RECOVERY_KEY, recovery, None)
|
|
312
338
|
_verify_data_change_cache_value(DATA_CHANGE_RECOVERY_KEY, recovery)
|
|
313
339
|
return recovery
|
|
@@ -321,6 +347,24 @@ def _recover_data_change_barrier(token: DependencyLockToken) -> None:
|
|
|
321
347
|
# previous snapshot never overwrites a later operation's active barrier.
|
|
322
348
|
if not isinstance(recovery, dict) or not isinstance(recovery.get("count"), int):
|
|
323
349
|
raise DependencyBarrierStateError("journal")
|
|
350
|
+
generation = recovery.get("generation")
|
|
351
|
+
if generation is not None:
|
|
352
|
+
if not isinstance(generation, int):
|
|
353
|
+
raise DependencyBarrierStateError("journal")
|
|
354
|
+
_require_data_change_lock_owner(token)
|
|
355
|
+
generation = max(get_dependency_generation(), generation)
|
|
356
|
+
_set_dependency_generation(generation)
|
|
357
|
+
_verify_data_change_cache_value(DEPENDENCY_GENERATION_KEY, generation)
|
|
358
|
+
# Older journals have no owner set. Retain compatibility with #519 recovery.
|
|
359
|
+
if "owners" in recovery:
|
|
360
|
+
owners = recovery["owners"]
|
|
361
|
+
if not isinstance(owners, frozenset) or not all(
|
|
362
|
+
isinstance(owner, str) for owner in owners
|
|
363
|
+
):
|
|
364
|
+
raise DependencyBarrierStateError("journal")
|
|
365
|
+
_require_data_change_lock_owner(token)
|
|
366
|
+
cache.set(DATA_CHANGE_OWNERS_KEY, owners, None)
|
|
367
|
+
_verify_data_change_cache_value(DATA_CHANGE_OWNERS_KEY, owners)
|
|
324
368
|
_require_data_change_lock_owner(token)
|
|
325
369
|
count = recovery["count"]
|
|
326
370
|
_set_dependency_data_change_count(count)
|
|
@@ -359,7 +403,7 @@ def _release_data_change_lock(token: DependencyLockToken) -> None:
|
|
|
359
403
|
logger.exception("dependency data-change mutex release failed")
|
|
360
404
|
|
|
361
405
|
|
|
362
|
-
def begin_dependency_data_change() -> int:
|
|
406
|
+
def begin_dependency_data_change(*, owner: str | None = None) -> int:
|
|
363
407
|
"""Open a publish barrier, preserving a recoverable pre-begin snapshot.
|
|
364
408
|
|
|
365
409
|
Failed starts restore only their own count/flag under the mutex. If cleanup
|
|
@@ -375,8 +419,11 @@ def begin_dependency_data_change() -> int:
|
|
|
375
419
|
_recover_data_change_barrier(lock_token)
|
|
376
420
|
count = _get_dependency_data_change_count()
|
|
377
421
|
flag = cache.get(DATA_CHANGE_LOCK_KEY)
|
|
378
|
-
|
|
379
|
-
|
|
422
|
+
owners = _get_dependency_data_change_owners()
|
|
423
|
+
if owner is not None and owner in owners:
|
|
424
|
+
return get_dependency_generation()
|
|
425
|
+
recovery = {"owner": lock_token, "count": count, "flag": flag, "owners": owners}
|
|
426
|
+
_prepare_data_change_recovery(lock_token, count, flag, owners)
|
|
380
427
|
_require_data_change_lock_owner(lock_token)
|
|
381
428
|
generation = _set_dependency_generation(get_dependency_generation() + 1)
|
|
382
429
|
_verify_data_change_cache_value(DEPENDENCY_GENERATION_KEY, generation)
|
|
@@ -386,6 +433,10 @@ def begin_dependency_data_change() -> int:
|
|
|
386
433
|
_require_data_change_lock_owner(lock_token)
|
|
387
434
|
cache.set(DATA_CHANGE_LOCK_KEY, "1", None)
|
|
388
435
|
_verify_data_change_cache_value(DATA_CHANGE_LOCK_KEY, "1")
|
|
436
|
+
if owner is not None:
|
|
437
|
+
_require_data_change_lock_owner(lock_token)
|
|
438
|
+
cache.set(DATA_CHANGE_OWNERS_KEY, owners | {owner}, None)
|
|
439
|
+
_verify_data_change_cache_value(DATA_CHANGE_OWNERS_KEY, owners | {owner})
|
|
389
440
|
_discard_active_context_dependency_cache_state()
|
|
390
441
|
_clear_data_change_recovery(lock_token, recovery)
|
|
391
442
|
except Exception:
|
|
@@ -400,18 +451,35 @@ def begin_dependency_data_change() -> int:
|
|
|
400
451
|
return generation
|
|
401
452
|
|
|
402
453
|
|
|
403
|
-
def end_dependency_data_change() -> None:
|
|
404
|
-
"""
|
|
454
|
+
def end_dependency_data_change(*, owner: str | None = None) -> None:
|
|
455
|
+
"""Fence in-flight calculations and close one barrier with forward recovery.
|
|
456
|
+
|
|
457
|
+
Owned ends are idempotent, including when cache writes applied then raised.
|
|
458
|
+
A retry completes the journal before checking ownership, so it cannot
|
|
459
|
+
decrement another transaction's barrier.
|
|
460
|
+
"""
|
|
405
461
|
if isinstance(caches["default"], DummyCache):
|
|
406
462
|
return
|
|
407
463
|
lock_token = acquire_lock_with_retry("end_dependency_data_change")
|
|
408
464
|
recovery: dict[str, object] | None = None
|
|
409
465
|
try:
|
|
410
466
|
_recover_data_change_barrier(lock_token)
|
|
467
|
+
owners = _get_dependency_data_change_owners()
|
|
468
|
+
if owner is not None and owner not in owners:
|
|
469
|
+
return
|
|
470
|
+
if owner is not None:
|
|
471
|
+
owners = owners - {owner}
|
|
411
472
|
count = max(_get_dependency_data_change_count() - 1, 0)
|
|
412
473
|
flag = "1" if count else None
|
|
413
|
-
|
|
414
|
-
|
|
474
|
+
generation = get_dependency_generation() + 1
|
|
475
|
+
recovery = {
|
|
476
|
+
"owner": lock_token,
|
|
477
|
+
"count": count,
|
|
478
|
+
"flag": flag,
|
|
479
|
+
"owners": owners,
|
|
480
|
+
"generation": generation,
|
|
481
|
+
}
|
|
482
|
+
_prepare_data_change_recovery(lock_token, count, flag, owners, generation)
|
|
415
483
|
_recover_data_change_barrier(lock_token)
|
|
416
484
|
except Exception:
|
|
417
485
|
if recovery is not None:
|
|
@@ -449,6 +517,50 @@ def drain_invalidated_cache_keys_for_graphql_rewarm() -> tuple[str, ...]:
|
|
|
449
517
|
return cache_keys
|
|
450
518
|
|
|
451
519
|
|
|
520
|
+
def record_committed_graphql_rewarm_keys(cache_keys: Iterable[str]) -> None:
|
|
521
|
+
"""Share committed work with the process that closes the final barrier."""
|
|
522
|
+
keys = frozenset(cache_keys)
|
|
523
|
+
if not keys:
|
|
524
|
+
return
|
|
525
|
+
token = acquire_lock_with_retry("record_committed_graphql_rewarm_keys")
|
|
526
|
+
try:
|
|
527
|
+
existing = cache.get(COMMITTED_GRAPHQL_REWARM_KEY, frozenset())
|
|
528
|
+
cache.set(COMMITTED_GRAPHQL_REWARM_KEY, existing | keys, None)
|
|
529
|
+
finally:
|
|
530
|
+
release_lock(token)
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
def drain_committed_graphql_rewarm_keys() -> tuple[str, ...]:
|
|
534
|
+
"""Claim committed keys only when no writer is pausing publication."""
|
|
535
|
+
if not cache.get(COMMITTED_GRAPHQL_REWARM_KEY):
|
|
536
|
+
return ()
|
|
537
|
+
token = acquire_lock_with_retry("drain_committed_graphql_rewarm_keys")
|
|
538
|
+
try:
|
|
539
|
+
if is_dependency_data_change_active():
|
|
540
|
+
return ()
|
|
541
|
+
keys = tuple(sorted(cache.get(COMMITTED_GRAPHQL_REWARM_KEY, frozenset())))
|
|
542
|
+
cache.delete(COMMITTED_GRAPHQL_REWARM_KEY)
|
|
543
|
+
return keys
|
|
544
|
+
finally:
|
|
545
|
+
release_lock(token)
|
|
546
|
+
|
|
547
|
+
|
|
548
|
+
@contextmanager
|
|
549
|
+
def dependency_rewarm_scope() -> Iterator[None]:
|
|
550
|
+
"""Isolate a mutation's keys from enclosing writes on other connections."""
|
|
551
|
+
depth = _dependency_rewarm_scope_depth.get()
|
|
552
|
+
scope_token = _dependency_rewarm_scope_depth.set(depth + 1)
|
|
553
|
+
token = _pending_graphql_rewarm_cache_keys.set(frozenset()) if depth else None
|
|
554
|
+
try:
|
|
555
|
+
yield
|
|
556
|
+
finally:
|
|
557
|
+
if token is not None:
|
|
558
|
+
remaining = _pending_graphql_rewarm_cache_keys.get()
|
|
559
|
+
_pending_graphql_rewarm_cache_keys.reset(token)
|
|
560
|
+
record_invalidated_cache_keys_for_graphql_rewarm(remaining)
|
|
561
|
+
_dependency_rewarm_scope_depth.reset(scope_token)
|
|
562
|
+
|
|
563
|
+
|
|
452
564
|
def acquire_lock_with_retry(operation: str) -> DependencyLockToken:
|
|
453
565
|
"""
|
|
454
566
|
Acquire the dependency index lock, retrying with exponential backoff.
|
|
@@ -123,6 +123,11 @@ def data_change(
|
|
|
123
123
|
is_dependency_data_change_active,
|
|
124
124
|
)
|
|
125
125
|
from general_manager.cache.run_context import current_calculation_run_context
|
|
126
|
+
from general_manager.cache.transaction_barrier import (
|
|
127
|
+
collect_transaction_rewarm_keys,
|
|
128
|
+
flush_transaction_rewarm_keys,
|
|
129
|
+
hold_dependency_transaction_barrier,
|
|
130
|
+
)
|
|
126
131
|
from general_manager.interface.orm_interface import OrmInterfaceBase
|
|
127
132
|
from general_manager.manager.bulk_create import (
|
|
128
133
|
CreateManyUnsupportedError,
|
|
@@ -179,6 +184,8 @@ def data_change(
|
|
|
179
184
|
transaction_outcome = "rolled_back"
|
|
180
185
|
begin_dependency_data_change()
|
|
181
186
|
try:
|
|
187
|
+
if is_orm_backed:
|
|
188
|
+
hold_dependency_transaction_barrier(database_alias)
|
|
182
189
|
context = current_calculation_run_context()
|
|
183
190
|
if context is not None:
|
|
184
191
|
context.clear_orm_bucket_results()
|
|
@@ -294,6 +301,8 @@ def data_change(
|
|
|
294
301
|
sender=sender,
|
|
295
302
|
**lifecycle_kwargs,
|
|
296
303
|
)
|
|
304
|
+
if is_orm_backed:
|
|
305
|
+
collect_transaction_rewarm_keys(database_alias, completed=True)
|
|
297
306
|
if transaction_scope is not None and transaction_scope.is_outermost:
|
|
298
307
|
transaction_outcome = "committed"
|
|
299
308
|
completed = True
|
|
@@ -333,8 +342,15 @@ def data_change(
|
|
|
333
342
|
raise
|
|
334
343
|
finally:
|
|
335
344
|
try:
|
|
345
|
+
collected = is_orm_backed and collect_transaction_rewarm_keys(
|
|
346
|
+
database_alias, completed=completed
|
|
347
|
+
)
|
|
336
348
|
if not is_dependency_data_change_active():
|
|
337
|
-
|
|
349
|
+
if not collected:
|
|
350
|
+
cache_keys = (
|
|
351
|
+
drain_invalidated_cache_keys_for_graphql_rewarm()
|
|
352
|
+
)
|
|
353
|
+
flush_transaction_rewarm_keys()
|
|
338
354
|
except Exception:
|
|
339
355
|
if primary_exc is not None:
|
|
340
356
|
logger.exception(
|
|
@@ -355,9 +371,10 @@ def data_change(
|
|
|
355
371
|
|
|
356
372
|
@wraps(decorator_source)
|
|
357
373
|
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
|
|
374
|
+
from general_manager.cache.dependency_index import dependency_rewarm_scope
|
|
358
375
|
from general_manager.manager.bulk_create import create_many_signal_scope
|
|
359
376
|
|
|
360
|
-
with create_many_signal_scope():
|
|
377
|
+
with create_many_signal_scope(), dependency_rewarm_scope():
|
|
361
378
|
return perform_change(*args, **kwargs)
|
|
362
379
|
|
|
363
380
|
return wrapper
|