GeneralManager 0.60.0__tar.gz → 0.60.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.
Files changed (260) hide show
  1. {generalmanager-0.60.0/src/GeneralManager.egg-info → generalmanager-0.60.2}/PKG-INFO +1 -1
  2. {generalmanager-0.60.0 → generalmanager-0.60.2}/pyproject.toml +1 -1
  3. {generalmanager-0.60.0 → generalmanager-0.60.2/src/GeneralManager.egg-info}/PKG-INFO +1 -1
  4. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/property.py +4 -1
  5. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/bucket/database_bucket.py +267 -20
  6. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/cache_decorator.py +188 -4
  7. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/cache_tracker.py +72 -6
  8. generalmanager-0.60.2/src/general_manager/cache/dependency_cache.py +576 -0
  9. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/dependency_index.py +9 -9
  10. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/dependency_matching.py +128 -5
  11. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/dependency_publish.py +225 -13
  12. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/dependency_shards.py +41 -38
  13. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/run_context.py +218 -4
  14. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/signals.py +7 -0
  15. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/base_interface.py +253 -16
  16. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/calculation/lifecycle.py +1 -7
  17. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/core/utils.py +1 -14
  18. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm/support.py +160 -5
  19. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm_utils/field_descriptors.py +223 -9
  20. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/manager/general_manager.py +197 -45
  21. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/manager/meta.py +126 -5
  22. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/measurement/measurement.py +189 -34
  23. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/json_encoder.py +3 -1
  24. generalmanager-0.60.2/src/general_manager/utils/make_cache_key.py +159 -0
  25. generalmanager-0.60.0/src/general_manager/cache/dependency_cache.py +0 -287
  26. generalmanager-0.60.0/src/general_manager/utils/make_cache_key.py +0 -43
  27. {generalmanager-0.60.0 → generalmanager-0.60.2}/LICENSE +0 -0
  28. {generalmanager-0.60.0 → generalmanager-0.60.2}/README.md +0 -0
  29. {generalmanager-0.60.0 → generalmanager-0.60.2}/setup.cfg +0 -0
  30. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/GeneralManager.egg-info/SOURCES.txt +0 -0
  31. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
  32. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/GeneralManager.egg-info/requires.txt +0 -0
  33. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/GeneralManager.egg-info/top_level.txt +0 -0
  34. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/__init__.py +0 -0
  35. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/__init__.py +0 -0
  36. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/api.py +0 -0
  37. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/bucket.py +0 -0
  38. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/cache.py +0 -0
  39. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/dataframes.py +0 -0
  40. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/factory.py +0 -0
  41. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/general_manager.py +0 -0
  42. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/interface.py +0 -0
  43. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/manager.py +0 -0
  44. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/measurement.py +0 -0
  45. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/permission.py +0 -0
  46. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/rule.py +0 -0
  47. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/search.py +0 -0
  48. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/utils.py +0 -0
  49. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/__init__.py +0 -0
  50. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql.py +0 -0
  51. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_errors.py +0 -0
  52. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_mutations.py +0 -0
  53. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_prefetch.py +0 -0
  54. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_resolvers.py +0 -0
  55. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_search.py +0 -0
  56. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_subscription_consumer.py +0 -0
  57. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_subscriptions.py +0 -0
  58. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_view.py +0 -0
  59. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_warmup.py +0 -0
  60. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_warmup_registry.py +0 -0
  61. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_warmup_tasks.py +0 -0
  62. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/mutation.py +0 -0
  63. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/registry.py +0 -0
  64. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/remote_api.py +0 -0
  65. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/remote_invalidation.py +0 -0
  66. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/remote_invalidation_client.py +0 -0
  67. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/apps.py +0 -0
  68. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/bootstrap.py +0 -0
  69. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/bucket/__init__.py +0 -0
  70. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/bucket/base_bucket.py +0 -0
  71. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/bucket/calculation_bucket.py +0 -0
  72. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/bucket/group_bucket.py +0 -0
  73. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/bucket/indexing.py +0 -0
  74. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/bucket/request_bucket.py +0 -0
  75. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/__init__.py +0 -0
  76. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/model_dependency_collector.py +0 -0
  77. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/__init__.py +0 -0
  78. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/audit.py +0 -0
  79. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/bootstrap.py +0 -0
  80. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/checks.py +0 -0
  81. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/consumer.py +0 -0
  82. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/errors.py +0 -0
  83. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/__init__.py +0 -0
  84. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/__main__.py +0 -0
  85. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/baseline.py +0 -0
  86. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/diagnostics.py +0 -0
  87. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/fingerprints.py +0 -0
  88. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/fixtures.py +0 -0
  89. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/judges/__init__.py +0 -0
  90. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/judges/answer_quality.py +0 -0
  91. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/judges/contract.py +0 -0
  92. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/judges/result_accuracy.py +0 -0
  93. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/judges/tool_sequence.py +0 -0
  94. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/readiness.py +0 -0
  95. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/runner.py +0 -0
  96. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/traces.py +0 -0
  97. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/grounding.py +0 -0
  98. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/models.py +0 -0
  99. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/providers/__init__.py +0 -0
  100. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/providers/_shared.py +0 -0
  101. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/providers/anthropic.py +0 -0
  102. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/providers/base.py +0 -0
  103. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/providers/google.py +0 -0
  104. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/providers/ollama.py +0 -0
  105. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/providers/openai.py +0 -0
  106. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/rate_limits.py +0 -0
  107. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/routing.py +0 -0
  108. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/schema_index.py +0 -0
  109. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/settings.py +0 -0
  110. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/signals.py +0 -0
  111. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/system_prompt.py +0 -0
  112. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/tool_metadata.py +0 -0
  113. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/tools.py +0 -0
  114. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/views.py +0 -0
  115. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/conf.py +0 -0
  116. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/dataframes/__init__.py +0 -0
  117. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/dataframes/measurements.py +0 -0
  118. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/factory/__init__.py +0 -0
  119. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/factory/auto_factory.py +0 -0
  120. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/factory/factories.py +0 -0
  121. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/factory/factory_methods.py +0 -0
  122. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/__init__.py +0 -0
  123. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/bundles/__init__.py +0 -0
  124. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/bundles/calculation.py +0 -0
  125. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/bundles/database.py +0 -0
  126. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/bundles/remote_manager.py +0 -0
  127. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/bundles/request.py +0 -0
  128. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/__init__.py +0 -0
  129. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/base.py +0 -0
  130. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/builtin.py +0 -0
  131. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/calculation/__init__.py +0 -0
  132. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/calculation/_compat.py +0 -0
  133. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/configuration.py +0 -0
  134. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/core/observability.py +0 -0
  135. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/exceptions.py +0 -0
  136. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/existing_model/__init__.py +0 -0
  137. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/existing_model/_compat.py +0 -0
  138. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/existing_model/resolution.py +0 -0
  139. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/factory.py +0 -0
  140. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm/__init__.py +0 -0
  141. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm/_compat.py +0 -0
  142. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm/history.py +0 -0
  143. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm/lifecycle.py +0 -0
  144. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm/mutations.py +0 -0
  145. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm_utils/__init__.py +0 -0
  146. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm_utils/django_manager_utils.py +0 -0
  147. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm_utils/payload_normalizer.py +0 -0
  148. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/read_only/__init__.py +0 -0
  149. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/read_only/_compat.py +0 -0
  150. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/read_only/_types.py +0 -0
  151. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/read_only/lifecycle.py +0 -0
  152. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/read_only/management.py +0 -0
  153. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/registry.py +0 -0
  154. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/remote_manager.py +0 -0
  155. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/request/__init__.py +0 -0
  156. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/infrastructure/__init__.py +0 -0
  157. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/infrastructure/startup_hooks.py +0 -0
  158. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/infrastructure/system_checks.py +0 -0
  159. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/interfaces/__init__.py +0 -0
  160. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/interfaces/calculation.py +0 -0
  161. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/interfaces/database.py +0 -0
  162. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/interfaces/existing_model.py +0 -0
  163. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/interfaces/read_only.py +0 -0
  164. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/interfaces/remote_manager.py +0 -0
  165. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/interfaces/request.py +0 -0
  166. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/manifests/__init__.py +0 -0
  167. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/manifests/capability_builder.py +0 -0
  168. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/manifests/capability_manifest.py +0 -0
  169. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/manifests/capability_models.py +0 -0
  170. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/orm_interface.py +0 -0
  171. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/requests.py +0 -0
  172. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/utils/__init__.py +0 -0
  173. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/utils/database_interface_protocols.py +0 -0
  174. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/utils/errors.py +0 -0
  175. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/utils/models.py +0 -0
  176. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/logging.py +0 -0
  177. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/management/commands/chat_cleanup.py +0 -0
  178. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/management/commands/graphql_warmup.py +0 -0
  179. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/management/commands/graphql_warmup_refresh_due.py +0 -0
  180. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/management/commands/search_index.py +0 -0
  181. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/management/commands/search_reconcile.py +0 -0
  182. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/management/commands/seed_manager_landscape.py +0 -0
  183. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/management/commands/shell.py +0 -0
  184. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/management/commands/workflow_drain_outbox.py +0 -0
  185. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/management/commands/workflow_replay_dead_letters.py +0 -0
  186. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/manager/__init__.py +0 -0
  187. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/manager/group_manager.py +0 -0
  188. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/manager/input.py +0 -0
  189. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/measurement/__init__.py +0 -0
  190. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/measurement/measurement_field.py +0 -0
  191. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/metrics/__init__.py +0 -0
  192. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/metrics/graphql.py +0 -0
  193. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/migrations/0001_initial.py +0 -0
  194. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/migrations/0002_workflow_outbox_scaling_indexes.py +0 -0
  195. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/migrations/0003_workflow_execution_correlation_constraint.py +0 -0
  196. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/migrations/0004_chat_persistence_models.py +0 -0
  197. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/migrations/0004_search_index_state.py +0 -0
  198. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/migrations/0005_merge_chat_search.py +0 -0
  199. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/migrations/0006_chat_pending_confirmation_scoped_ids.py +0 -0
  200. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/migrations/__init__.py +0 -0
  201. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/models.py +0 -0
  202. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/permission/__init__.py +0 -0
  203. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/permission/audit.py +0 -0
  204. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/permission/base_permission.py +0 -0
  205. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/permission/graphql_capabilities.py +0 -0
  206. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/permission/manager_based_permission.py +0 -0
  207. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/permission/mutation_permission.py +0 -0
  208. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/permission/permission_checks.py +0 -0
  209. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/permission/permission_data_manager.py +0 -0
  210. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/permission/utils.py +0 -0
  211. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/public_api_registry.py +0 -0
  212. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/py.typed +0 -0
  213. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/rule/__init__.py +0 -0
  214. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/rule/handler.py +0 -0
  215. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/rule/rule.py +0 -0
  216. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/__init__.py +0 -0
  217. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/async_tasks.py +0 -0
  218. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/backend.py +0 -0
  219. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/backend_registry.py +0 -0
  220. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/backends/__init__.py +0 -0
  221. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/backends/dev.py +0 -0
  222. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/backends/meilisearch.py +0 -0
  223. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/backends/opensearch.py +0 -0
  224. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/backends/typesense.py +0 -0
  225. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/config.py +0 -0
  226. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/indexer.py +0 -0
  227. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/models.py +0 -0
  228. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/reconciliation.py +0 -0
  229. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/registry.py +0 -0
  230. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/tasks.py +0 -0
  231. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/utils.py +0 -0
  232. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/seeding/__init__.py +0 -0
  233. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/seeding/manager_landscape.py +0 -0
  234. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/__init__.py +0 -0
  235. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/args_to_kwargs.py +0 -0
  236. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/filter_parser.py +0 -0
  237. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/format_string.py +0 -0
  238. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/none_to_zero.py +0 -0
  239. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/path_mapping.py +0 -0
  240. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/public_api.py +0 -0
  241. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/testing.py +0 -0
  242. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/type_checks.py +0 -0
  243. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/__init__.py +0 -0
  244. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/actions.py +0 -0
  245. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/backend_registry.py +0 -0
  246. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/backends/__init__.py +0 -0
  247. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/backends/celery.py +0 -0
  248. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/backends/local.py +0 -0
  249. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/backends/n8n.py +0 -0
  250. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/config.py +0 -0
  251. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/engine.py +0 -0
  252. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/event_registry.py +0 -0
  253. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/events.py +0 -0
  254. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/models.py +0 -0
  255. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/signal_bridge.py +0 -0
  256. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/tasks.py +0 -0
  257. {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/telemetry.py +0 -0
  258. {generalmanager-0.60.0 → generalmanager-0.60.2}/tests/test_settings.py +0 -0
  259. {generalmanager-0.60.0 → generalmanager-0.60.2}/tests/test_urls.py +0 -0
  260. {generalmanager-0.60.0 → generalmanager-0.60.2}/tests/testing_asgi.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GeneralManager
3
- Version: 0.60.0
3
+ Version: 0.60.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.60.0"
7
+ version = "0.60.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.60.0
3
+ Version: 0.60.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
@@ -142,7 +142,10 @@ class GraphQLProperty(property):
142
142
  @wraps(fget)
143
143
  def resolver(instance: object) -> object:
144
144
  """Resolve the property through the selected cached wrapper."""
145
- return self._get_cached_fget()(instance)
145
+ cached_fget = self._cached_fget
146
+ if cached_fget is None:
147
+ cached_fget = self._get_cached_fget()
148
+ return cached_fget(instance)
146
149
 
147
150
  super().__init__(resolver, doc=doc)
148
151
  self.is_graphql_resolver = True
@@ -11,7 +11,10 @@ from django.db.models.sql.query import Query
11
11
 
12
12
  from general_manager.bucket.base_bucket import Bucket
13
13
  from general_manager.cache.cache_tracker import DependencyTracker
14
- from general_manager.cache.dependency_index import serialize_dependency_identifier
14
+ from general_manager.cache.dependency_index import (
15
+ Dependency,
16
+ serialize_dependency_identifier,
17
+ )
15
18
  from general_manager.cache.run_context import current_calculation_run_context
16
19
  from general_manager.manager.general_manager import GeneralManager
17
20
  from general_manager.utils.filter_parser import create_filter_function
@@ -27,6 +30,9 @@ QueryAnnotationCallable = Callable[
27
30
  models.QuerySet[models.Model],
28
31
  ]
29
32
  MAX_RUN_SCOPED_BUCKET_RESULT_ROWS = 1000
33
+ _QUERY_SIGNATURE_NOT_COMPUTED = object()
34
+ _FIRST_ROW_CACHE_MISS = object()
35
+ _FIRST_ROW_CACHE_NONE = object()
30
36
 
31
37
 
32
38
  class DatabaseBucketTypeMismatchError(TypeError):
@@ -251,6 +257,79 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
251
257
  self._sort_keys = sort_keys
252
258
  self._sort_reverse = sort_reverse
253
259
  self._run_scoped_cacheable = run_scoped_cacheable
260
+ self._query_signature_cache: tuple[Hashable, ...] | None | object = (
261
+ _QUERY_SIGNATURE_NOT_COMPUTED
262
+ )
263
+ self._trusted_query_signature: Hashable | None = None
264
+
265
+ def _set_trusted_query_signature(self, signature: Hashable | None) -> None:
266
+ """Set an internal non-SQL signature for framework-built querysets."""
267
+ self._trusted_query_signature = signature
268
+ self._query_signature_cache = _QUERY_SIGNATURE_NOT_COMPUTED
269
+
270
+ def _copy_for_run_context_reuse(self) -> DatabaseBucket[GeneralManagerType]:
271
+ """Return an unexposed bucket copy that reuses the same trusted queryset."""
272
+
273
+ bucket = self.__class__(
274
+ self._data,
275
+ self._manager_class,
276
+ self.filters,
277
+ self.excludes,
278
+ search_date=self._search_date,
279
+ sort_keys=self._sort_keys,
280
+ sort_reverse=self._sort_reverse,
281
+ run_scoped_cacheable=self._run_scoped_cacheable,
282
+ )
283
+ bucket._set_trusted_query_signature(self._trusted_query_signature)
284
+ return bucket
285
+
286
+ @staticmethod
287
+ def _freeze_trusted_signature_payload(value: object) -> Hashable:
288
+ if isinstance(value, Mapping):
289
+ return tuple(
290
+ (
291
+ str(key),
292
+ DatabaseBucket._freeze_trusted_signature_payload(item_value),
293
+ )
294
+ for key, item_value in sorted(
295
+ value.items(),
296
+ key=lambda item: str(item[0]),
297
+ )
298
+ )
299
+ if isinstance(value, (list, tuple)):
300
+ return tuple(
301
+ DatabaseBucket._freeze_trusted_signature_payload(item) for item in value
302
+ )
303
+ if isinstance(value, (set, frozenset)):
304
+ return tuple(
305
+ sorted(
306
+ (
307
+ DatabaseBucket._freeze_trusted_signature_payload(item)
308
+ for item in value
309
+ ),
310
+ key=repr,
311
+ )
312
+ )
313
+ if isinstance(value, models.Model):
314
+ return ("model", value.__class__, value.pk)
315
+ try:
316
+ hash(value)
317
+ except TypeError:
318
+ return ("serialized", serialize_dependency_identifier(value))
319
+ return value
320
+
321
+ def _trusted_query_signature_with(
322
+ self,
323
+ operation: str,
324
+ kwargs: Mapping[str, object],
325
+ ) -> Hashable | None:
326
+ if self._trusted_query_signature is None:
327
+ return None
328
+ return (
329
+ self._trusted_query_signature,
330
+ operation,
331
+ self._freeze_trusted_signature_payload(kwargs),
332
+ )
254
333
 
255
334
  def __reduce__(self) -> str | tuple[object, ...]:
256
335
  """
@@ -365,27 +444,50 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
365
444
  tuple[Hashable, ...] | None: Cache key components for equivalent
366
445
  queryset results, or ``None`` when reuse should be bypassed.
367
446
  """
447
+ if self._query_signature_cache is not _QUERY_SIGNATURE_NOT_COMPUTED:
448
+ return cast(tuple[Hashable, ...] | None, self._query_signature_cache)
368
449
  if not self._run_scoped_cacheable:
450
+ self._query_signature_cache = None
369
451
  return None
452
+ if self._trusted_query_signature is not None:
453
+ signature = (
454
+ self._manager_class,
455
+ self._data.model,
456
+ self._data.db,
457
+ "trusted",
458
+ self._trusted_query_signature,
459
+ self._search_date,
460
+ self._sort_keys,
461
+ self._sort_reverse,
462
+ )
463
+ self._query_signature_cache = signature
464
+ return signature
370
465
  query = self._data.query
371
466
  if not isinstance(query, Query):
467
+ self._query_signature_cache = None
372
468
  return None
373
469
  if query.select_for_update:
470
+ self._query_signature_cache = None
374
471
  return None
375
472
  if query.combinator:
473
+ self._query_signature_cache = None
376
474
  return None
377
475
  if query.distinct:
476
+ self._query_signature_cache = None
378
477
  return None
379
478
  if getattr(self._data, "_prefetch_related_lookups", ()):
479
+ self._query_signature_cache = None
380
480
  return None
381
481
  deferred_loading = getattr(query, "deferred_loading", None)
382
482
  if isinstance(deferred_loading, tuple) and deferred_loading[0]:
483
+ self._query_signature_cache = None
383
484
  return None
384
485
  try:
385
486
  sql, params = self._data.query.sql_with_params()
386
487
  except (EmptyResultSet, FieldError, TypeError, ValueError):
488
+ self._query_signature_cache = None
387
489
  return None
388
- return (
490
+ signature = (
389
491
  self._manager_class,
390
492
  self._data.model,
391
493
  self._data.db,
@@ -395,6 +497,8 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
395
497
  self._sort_keys,
396
498
  self._sort_reverse,
397
499
  )
500
+ self._query_signature_cache = signature
501
+ return signature
398
502
 
399
503
  def _bucket_index_source_signature(self) -> Hashable:
400
504
  """Return a queryset signature when safe, otherwise use object identity."""
@@ -501,6 +605,65 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
501
605
  return None
502
606
  return cast(tuple[models.Model, ...], cached)
503
607
 
608
+ def _can_cache_run_scoped_managers(self) -> bool:
609
+ if self._manager_class.__init__ is not GeneralManager.__init__:
610
+ return False
611
+ if not type.__getattribute__(
612
+ self._manager_class,
613
+ "_gm_uses_default_identification_dependency_active",
614
+ ):
615
+ return False
616
+ return callable(
617
+ getattr(self._manager_class.Interface, "_from_trusted_orm_instance", None)
618
+ )
619
+
620
+ def _manager_identification_dependencies(
621
+ self,
622
+ managers: tuple[GeneralManagerType, ...],
623
+ ) -> frozenset[Dependency]:
624
+ manager_name = type.__getattribute__(self._manager_class, "__name__")
625
+ return frozenset(
626
+ (
627
+ manager_name,
628
+ "identification",
629
+ serialize_dependency_identifier(manager.identification),
630
+ )
631
+ for manager in managers
632
+ )
633
+
634
+ def _get_run_scoped_managers(self) -> tuple[GeneralManagerType, ...] | None:
635
+ """Load or reuse manager wrappers for a trusted row snapshot."""
636
+ if not self._can_cache_run_scoped_managers():
637
+ return None
638
+ context = current_calculation_run_context()
639
+ if context is None:
640
+ return None
641
+ signature = self._query_signature()
642
+ if signature is None:
643
+ return None
644
+ cached = context.get_orm_bucket_managers(signature)
645
+ if cached is not None:
646
+ managers = cast(tuple[GeneralManagerType, ...], cached)
647
+ dependencies = context.get_orm_bucket_manager_dependencies(signature)
648
+ if dependencies is not None:
649
+ DependencyTracker._track_many_validated(dependencies)
650
+ else:
651
+ for manager in managers:
652
+ self._manager_class._track_identification_dependency(
653
+ manager.identification
654
+ )
655
+ return managers
656
+ rows = self._get_run_scoped_rows()
657
+ if rows is None:
658
+ return None
659
+ managers = tuple(self._build_manager_from_instance(row) for row in rows)
660
+ context.set_orm_bucket_managers(
661
+ signature,
662
+ managers,
663
+ self._manager_identification_dependencies(managers),
664
+ )
665
+ return managers
666
+
504
667
  @staticmethod
505
668
  def _snapshot_get_primary_key(
506
669
  kwargs: Mapping[str, LookupValue],
@@ -528,21 +691,42 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
528
691
  return kwargs["id"]
529
692
  return None
530
693
 
694
+ def _can_materialize_count_snapshot(self) -> bool:
695
+ """Return whether count/len may populate a bounded run-scoped snapshot."""
696
+ context = current_calculation_run_context()
697
+ if context is None:
698
+ return False
699
+ query = getattr(self._data, "query", None)
700
+ if not isinstance(query, Query):
701
+ return False
702
+ where = getattr(query, "where", None)
703
+ children = getattr(where, "children", None)
704
+ return bool(children)
705
+
531
706
  def _track_effective_dependencies(self) -> None:
532
707
  """Record the bucket's effective filter/exclude state when it is evaluated."""
533
- manager_name = self._manager_class.__name__
534
- normalized_filters = self._normalize_dependency_mapping(self.filters)
535
- normalized_excludes = self._normalize_dependency_mapping(self.excludes)
708
+ manager_name = type.__getattribute__(self._manager_class, "__name__")
709
+ needs_sort_payload = bool(self._sort_keys)
710
+ normalized_filters = (
711
+ self._normalize_dependency_mapping(self.filters)
712
+ if self.filters or needs_sort_payload
713
+ else {}
714
+ )
715
+ normalized_excludes = (
716
+ self._normalize_dependency_mapping(self.excludes)
717
+ if self.excludes or needs_sort_payload
718
+ else {}
719
+ )
536
720
  if self.filters:
537
- DependencyTracker.track(
721
+ DependencyTracker._track_validated(
538
722
  manager_name,
539
723
  "filter",
540
724
  serialize_dependency_identifier(normalized_filters),
541
725
  )
542
726
  else:
543
- DependencyTracker.track(manager_name, "all", "")
727
+ DependencyTracker._track_validated(manager_name, "all", "")
544
728
  if self.excludes:
545
- DependencyTracker.track(
729
+ DependencyTracker._track_validated(
546
730
  manager_name,
547
731
  "exclude",
548
732
  serialize_dependency_identifier(normalized_excludes),
@@ -554,7 +738,7 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
554
738
  "excludes": normalized_excludes,
555
739
  "reverse": self._sort_reverse,
556
740
  }
557
- DependencyTracker.track(
741
+ DependencyTracker._track_validated(
558
742
  manager_name,
559
743
  "filter",
560
744
  serialize_dependency_identifier({f"__sort__{sort_key}": payload}),
@@ -576,6 +760,10 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
576
760
  GeneralManagerType: Manager instance for each primary key in the queryset.
577
761
  """
578
762
  self._track_effective_dependencies()
763
+ managers = self._get_run_scoped_managers()
764
+ if managers is not None:
765
+ yield from managers
766
+ return
579
767
  rows = self._get_run_scoped_rows()
580
768
  if rows is not None:
581
769
  for row in rows:
@@ -782,7 +970,7 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
782
970
  qs = qs.filter(pk__in=ids)
783
971
 
784
972
  merged_filter = self.__merge_filter_definitions(self.filters, **kwargs)
785
- return self.__class__(
973
+ bucket = self.__class__(
786
974
  qs,
787
975
  self._manager_class,
788
976
  merged_filter,
@@ -792,6 +980,11 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
792
980
  sort_reverse=self._sort_reverse,
793
981
  run_scoped_cacheable=self._run_scoped_cacheable,
794
982
  )
983
+ if not annotations and not python_filters:
984
+ bucket._set_trusted_query_signature(
985
+ self._trusted_query_signature_with("filter", orm_kwargs)
986
+ )
987
+ return bucket
795
988
 
796
989
  def exclude(self, **kwargs: LookupValue) -> DatabaseBucket[GeneralManagerType]:
797
990
  """
@@ -843,7 +1036,7 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
843
1036
  qs = qs.exclude(pk__in=ids)
844
1037
 
845
1038
  merged_exclude = self.__merge_filter_definitions(self.excludes, **kwargs)
846
- return self.__class__(
1039
+ bucket = self.__class__(
847
1040
  qs,
848
1041
  self._manager_class,
849
1042
  self.filters,
@@ -853,6 +1046,11 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
853
1046
  sort_reverse=self._sort_reverse,
854
1047
  run_scoped_cacheable=self._run_scoped_cacheable,
855
1048
  )
1049
+ if not annotations and not python_filters:
1050
+ bucket._set_trusted_query_signature(
1051
+ self._trusted_query_signature_with("exclude", orm_kwargs)
1052
+ )
1053
+ return bucket
856
1054
 
857
1055
  def first(self) -> GeneralManagerType | None:
858
1056
  """
@@ -875,7 +1073,23 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
875
1073
  if not primary_keys:
876
1074
  return None
877
1075
  return self._build_manager_from_primary_key(primary_keys[0])
1076
+ context = current_calculation_run_context()
1077
+ signature = self._query_signature() if context is not None else None
1078
+ if context is not None and signature is not None:
1079
+ cached = context.get_orm_bucket_first_row(
1080
+ signature,
1081
+ _FIRST_ROW_CACHE_MISS,
1082
+ )
1083
+ if cached is _FIRST_ROW_CACHE_NONE:
1084
+ return None
1085
+ if cached is not _FIRST_ROW_CACHE_MISS:
1086
+ return self._build_manager_from_instance(cast(models.Model, cached))
878
1087
  first_element = self._data.first()
1088
+ if context is not None and signature is not None:
1089
+ context.set_orm_bucket_first_row(
1090
+ signature,
1091
+ _FIRST_ROW_CACHE_NONE if first_element is None else first_element,
1092
+ )
879
1093
  if first_element is None:
880
1094
  return None
881
1095
  return self._build_manager_from_instance(first_element)
@@ -917,6 +1131,10 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
917
1131
  int: Number of represented rows.
918
1132
  """
919
1133
  self._track_effective_dependencies()
1134
+ if self._can_materialize_count_snapshot():
1135
+ rows = self._get_run_scoped_rows()
1136
+ if rows is not None:
1137
+ return len(rows)
920
1138
  primary_keys = self._peek_run_scoped_primary_keys()
921
1139
  if primary_keys is not None:
922
1140
  return len(primary_keys)
@@ -932,7 +1150,7 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
932
1150
  Returns:
933
1151
  DatabaseBucket[GeneralManagerType]: Bucket encapsulating `self._data.all()`.
934
1152
  """
935
- return self.__class__(
1153
+ bucket = self.__class__(
936
1154
  self._data.all(),
937
1155
  self._manager_class,
938
1156
  self.filters,
@@ -942,6 +1160,8 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
942
1160
  sort_reverse=self._sort_reverse,
943
1161
  run_scoped_cacheable=self._run_scoped_cacheable,
944
1162
  )
1163
+ bucket._set_trusted_query_signature(self._trusted_query_signature)
1164
+ return bucket
945
1165
 
946
1166
  def get(self, **kwargs: LookupValue) -> GeneralManagerType:
947
1167
  """
@@ -1027,21 +1247,43 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
1027
1247
  return self._build_manager_from_primary_key(primary_keys[item])
1028
1248
  return self._build_manager_from_instance(self._data[item])
1029
1249
 
1250
+ def __bool__(self) -> bool:
1251
+ """
1252
+ Return whether the bucket contains at least one row without counting all rows.
1253
+
1254
+ Truthiness is an existence check, not a cardinality request. Reuse any
1255
+ active run-context snapshot first, then cache a queryset ``exists()``
1256
+ result for equivalent trusted querysets in the same calculation run.
1257
+ """
1258
+ self._track_effective_dependencies()
1259
+ rows = self._peek_run_scoped_rows()
1260
+ if rows is not None:
1261
+ return bool(rows)
1262
+ primary_keys = self._peek_run_scoped_primary_keys()
1263
+ if primary_keys is not None:
1264
+ return bool(primary_keys)
1265
+ context = current_calculation_run_context()
1266
+ signature = self._query_signature() if context is not None else None
1267
+ if context is not None and signature is not None:
1268
+ cached = context.get_orm_bucket_exists(signature)
1269
+ if cached is not None:
1270
+ return bool(cached)
1271
+ exists = bool(self._data.exists())
1272
+ if context is not None and signature is not None:
1273
+ context.set_orm_bucket_exists(signature, exists)
1274
+ return exists
1275
+
1030
1276
  def __len__(self) -> int:
1031
1277
  """
1032
1278
  Return the number of rows represented by the bucket.
1033
1279
 
1034
- A safe run-scoped primary-key snapshot is reused when present; otherwise
1035
- this delegates to the queryset count.
1280
+ Delegates to `count()` so dependency tracking, run-scoped snapshots, and
1281
+ queryset fallback behavior stay aligned between both cardinality paths.
1036
1282
 
1037
1283
  Returns:
1038
1284
  int: Number of represented rows.
1039
1285
  """
1040
- self._track_effective_dependencies()
1041
- primary_keys = self._peek_run_scoped_primary_keys()
1042
- if primary_keys is not None:
1043
- return len(primary_keys)
1044
- return int(self._data.count())
1286
+ return self.count()
1045
1287
 
1046
1288
  def __str__(self) -> str:
1047
1289
  """
@@ -1169,7 +1411,7 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
1169
1411
  except (FieldError, TypeError, ValueError) as error:
1170
1412
  raise QuerysetOrderingError(error) from error
1171
1413
 
1172
- return self.__class__(
1414
+ bucket = self.__class__(
1173
1415
  qs,
1174
1416
  self._manager_class,
1175
1417
  self.filters,
@@ -1179,6 +1421,9 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
1179
1421
  sort_reverse=reverse,
1180
1422
  run_scoped_cacheable=self._run_scoped_cacheable,
1181
1423
  )
1424
+ if not annotations and not python_keys:
1425
+ bucket._set_trusted_query_signature(self._trusted_query_signature)
1426
+ return bucket
1182
1427
 
1183
1428
  def none(self) -> DatabaseBucket[GeneralManagerType]:
1184
1429
  """
@@ -1193,4 +1438,6 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
1193
1438
  """
1194
1439
  own = self.all()
1195
1440
  own._data = own._data.none()
1441
+ own._query_signature_cache = _QUERY_SIGNATURE_NOT_COMPUTED
1442
+ own._trusted_query_signature = None
1196
1443
  return own