objectstate 2.1.1__tar.gz → 3.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. {objectstate-2.1.1 → objectstate-3.0.0}/PKG-INFO +1 -1
  2. {objectstate-2.1.1 → objectstate-3.0.0}/docs/provenance.rst +28 -11
  3. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/__init__.py +5 -7
  4. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/context_manager.py +182 -446
  5. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/docs/context_system.rst +26 -71
  6. objectstate-3.0.0/src/objectstate/dual_axis_resolver.py +221 -0
  7. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/lazy_factory.py +67 -194
  8. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/live_context_resolver.py +48 -24
  9. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/object_state.py +29 -17
  10. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/object_state_registry.py +108 -79
  11. objectstate-3.0.0/tests/test_atomic_block_context.py +139 -0
  12. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_callable_baseline.py +0 -3
  13. objectstate-3.0.0/tests/test_context_failures_surface.py +130 -0
  14. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_context_manager.py +7 -12
  15. objectstate-3.0.0/tests/test_lazy_counterpart_registry.py +171 -0
  16. objectstate-3.0.0/tests/test_live_context_resolver_answers.py +106 -0
  17. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_object_state_metadata_contracts.py +0 -3
  18. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_object_state_update_instance.py +0 -3
  19. objectstate-3.0.0/tests/test_one_field_resolution.py +301 -0
  20. objectstate-3.0.0/tests/test_scopeless_state_resolution.py +109 -0
  21. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_undo_redo_cascade.py +1 -6
  22. objectstate-2.1.1/src/objectstate/dual_axis_resolver.py +0 -383
  23. {objectstate-2.1.1 → objectstate-3.0.0}/.github/badges/coverage.svg +0 -0
  24. {objectstate-2.1.1 → objectstate-3.0.0}/.github/workflows/ci.yml +0 -0
  25. {objectstate-2.1.1 → objectstate-3.0.0}/.github/workflows/coverage-pages.yml +0 -0
  26. {objectstate-2.1.1 → objectstate-3.0.0}/.github/workflows/publish.yml +0 -0
  27. {objectstate-2.1.1 → objectstate-3.0.0}/.gitignore +0 -0
  28. {objectstate-2.1.1 → objectstate-3.0.0}/.readthedocs.yaml +0 -0
  29. {objectstate-2.1.1 → objectstate-3.0.0}/BADGE_SETUP.md +0 -0
  30. {objectstate-2.1.1 → objectstate-3.0.0}/LICENSE +0 -0
  31. {objectstate-2.1.1 → objectstate-3.0.0}/README.md +0 -0
  32. {objectstate-2.1.1 → objectstate-3.0.0}/docs/.gitignore +0 -0
  33. {objectstate-2.1.1 → objectstate-3.0.0}/docs/Makefile +0 -0
  34. {objectstate-2.1.1 → objectstate-3.0.0}/docs/api/modules.rst +0 -0
  35. {objectstate-2.1.1 → objectstate-3.0.0}/docs/architectural_fixes.rst +0 -0
  36. {objectstate-2.1.1 → objectstate-3.0.0}/docs/architecture.rst +0 -0
  37. {objectstate-2.1.1 → objectstate-3.0.0}/docs/archive/DOCUMENTATION_AUDIT.md +0 -0
  38. {objectstate-2.1.1 → objectstate-3.0.0}/docs/archive/DOCUMENTATION_FIXES.md +0 -0
  39. {objectstate-2.1.1 → objectstate-3.0.0}/docs/archive/README.md +0 -0
  40. {objectstate-2.1.1 → objectstate-3.0.0}/docs/conf.py +0 -0
  41. {objectstate-2.1.1 → objectstate-3.0.0}/docs/examples/atomic_operations.rst +0 -0
  42. {objectstate-2.1.1 → objectstate-3.0.0}/docs/examples/basic.rst +0 -0
  43. {objectstate-2.1.1 → objectstate-3.0.0}/docs/examples/dual_axis.rst +0 -0
  44. {objectstate-2.1.1 → objectstate-3.0.0}/docs/examples/index.rst +0 -0
  45. {objectstate-2.1.1 → objectstate-3.0.0}/docs/examples/ui.rst +0 -0
  46. {objectstate-2.1.1 → objectstate-3.0.0}/docs/index.rst +0 -0
  47. {objectstate-2.1.1 → objectstate-3.0.0}/docs/make.bat +0 -0
  48. {objectstate-2.1.1 → objectstate-3.0.0}/docs/performance/canonical-context-type-resolution-20261005.json +0 -0
  49. {objectstate-2.1.1 → objectstate-3.0.0}/docs/quickstart.rst +0 -0
  50. {objectstate-2.1.1 → objectstate-3.0.0}/docs/state_management.rst +0 -0
  51. {objectstate-2.1.1 → objectstate-3.0.0}/docs/state_propagation.rst +0 -0
  52. {objectstate-2.1.1 → objectstate-3.0.0}/docs/undo_redo.rst +0 -0
  53. {objectstate-2.1.1 → objectstate-3.0.0}/paper.bib +0 -0
  54. {objectstate-2.1.1 → objectstate-3.0.0}/paper.md +0 -0
  55. {objectstate-2.1.1 → objectstate-3.0.0}/plans/n_dimensional_inheritance.md +0 -0
  56. {objectstate-2.1.1 → objectstate-3.0.0}/pyproject.toml +0 -0
  57. {objectstate-2.1.1 → objectstate-3.0.0}/scripts/check_ruff_added_lines.py +0 -0
  58. {objectstate-2.1.1 → objectstate-3.0.0}/scripts/release.py +0 -0
  59. {objectstate-2.1.1 → objectstate-3.0.0}/scripts/update_and_release.py +0 -0
  60. {objectstate-2.1.1 → objectstate-3.0.0}/scripts/update_version.py +0 -0
  61. {objectstate-2.1.1 → objectstate-3.0.0}/scripts/verify_release_ready.py +0 -0
  62. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/codegen.py +0 -0
  63. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/collection_containers.py +0 -0
  64. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/config.py +0 -0
  65. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/construction_binding.py +0 -0
  66. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/docs/configuration_framework.rst +0 -0
  67. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/docs/object_state_lifecycle.rst +0 -0
  68. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/edit_session.py +0 -0
  69. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/field_access.py +0 -0
  70. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/global_config.py +0 -0
  71. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/inspection.py +0 -0
  72. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/object_state_metadata.py +0 -0
  73. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/parameter_owner.py +0 -0
  74. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/parameter_structure.py +0 -0
  75. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/parametric_axes.py +0 -0
  76. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/placeholder.py +0 -0
  77. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/reified_generics.py +0 -0
  78. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/scope_key.py +0 -0
  79. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/snapshot_model.py +0 -0
  80. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/subfield_semantics.py +0 -0
  81. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/time_travel_profile.py +0 -0
  82. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/token_cache.py +0 -0
  83. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/transaction_checkpoint.py +0 -0
  84. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/ui_visibility.py +0 -0
  85. {objectstate-2.1.1 → objectstate-3.0.0}/src/objectstate/value_semantics.py +0 -0
  86. {objectstate-2.1.1 → objectstate-3.0.0}/tests/__init__.py +0 -0
  87. {objectstate-2.1.1 → objectstate-3.0.0}/tests/conftest.py +0 -0
  88. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_authored_paths.py +0 -0
  89. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_codegen.py +0 -0
  90. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_config.py +0 -0
  91. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_construction_history.py +0 -0
  92. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_field_access.py +0 -0
  93. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_global_config.py +0 -0
  94. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_history_persistence.py +0 -0
  95. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_inspection.py +0 -0
  96. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_integration.py +0 -0
  97. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_lazy_factory.py +0 -0
  98. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_object_state_restore.py +0 -0
  99. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_parameter_owner.py +0 -0
  100. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_parametric_axes.py +0 -0
  101. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_placeholder.py +0 -0
  102. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_registry_subscription.py +0 -0
  103. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_reified_generics.py +0 -0
  104. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_release_readiness.py +0 -0
  105. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_resolved_change_notifications.py +0 -0
  106. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_scope_key.py +0 -0
  107. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_subfield_semantics.py +0 -0
  108. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_timeline_projection.py +0 -0
  109. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_transaction_checkpoint.py +0 -0
  110. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_ui_visible_field_projection.py +0 -0
  111. {objectstate-2.1.1 → objectstate-3.0.0}/tests/test_value_semantics.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: objectstate
3
- Version: 2.1.1
3
+ Version: 3.0.0
4
4
  Summary: Generic lazy dataclass configuration framework with dual-axis inheritance and contextvars-based resolution
5
5
  Project-URL: Homepage, https://github.com/OpenHCSDev/objectstate
6
6
  Project-URL: Documentation, https://objectstate.readthedocs.io
@@ -77,6 +77,11 @@ Get the source scope_id and type for an inherited field value:
77
77
  else:
78
78
  print("partition_filter is explicitly set on this object")
79
79
 
80
+ When another config of the same object supplies the value, the source scope is the
81
+ state's own ``scope_id``. For a state created without a scope id that is ``None``, so
82
+ ``(None, source_type)`` means "this object, through ``source_type``". ``None`` alone
83
+ still means the value is set on the field itself.
84
+
80
85
  **Returns:**
81
86
  * ``Tuple[str, type]`` if the value is inherited
82
87
  * ``None`` if the value is explicitly set on the current object
@@ -86,7 +91,8 @@ Get the source scope_id and type for an inherited field value:
86
91
  resolve_with_provenance()
87
92
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~
88
93
 
89
- Resolve a field value AND find its provenance source in ONE walk:
94
+ Resolve a field in the active context. This is the one resolution: attribute access on a
95
+ lazy config returns its ``value``, and ``ObjectState`` stores all three parts.
90
96
 
91
97
  .. code-block:: python
92
98
 
@@ -109,11 +115,21 @@ Resolve a field value AND find its provenance source in ONE walk:
109
115
 
110
116
  **Returns:**
111
117
 
118
+ A ``ResolvedField`` named tuple:
119
+
112
120
  * ``value``: The resolved field value (may be ``None``)
113
- * ``source_scope``: The scope_id where the value was found (or ``None``)
114
- * ``source_type``: The type that provided the value (or ``None``)
121
+ * ``source_scope``: The scope id of the layer that supplied the value. ``None`` for a layer
122
+ entered with ``config_context(obj)`` without a ``scope_id``.
123
+ * ``source_type``: The type the value was read from: the container type or one of its bases.
124
+
125
+ When no layer holds a value, ``value`` is the declared default and the source names the
126
+ outermost layer holding the nearest type in the MRO (``None`` when no layer holds one).
115
127
 
116
- **Performance:** Single walk instead of separate resolve + provenance calls.
128
+ Raises ``NoActiveContextError`` when no context is active.
129
+
130
+ **Caching:** the answer is kept on the layer stack it was computed from
131
+ (``ContextLayerStack.resolved_fields``) and is dropped with that stack. Entering or leaving a
132
+ context, in this thread or another, never clears another context's answers.
117
133
 
118
134
  get_field_provenance()
119
135
  ~~~~~~~~~~~~~~~~~~~~~~~
@@ -142,13 +158,14 @@ The provenance system uses the context layer stack for tracking:
142
158
 
143
159
  from objectstate.context_manager import get_context_layer_stack
144
160
 
145
- # Get the current layer stack for provenance tracking
146
- layers = get_context_layer_stack()
147
- # Returns: [(scope_id, obj), ...] tuples
148
-
149
- # Used by get_field_provenance() to determine which scope provided a resolved value
161
+ stack = get_context_layer_stack()
162
+ for layer in stack.layers: # outermost first
163
+ print(layer.scope_id, layer.obj)
150
164
 
151
- The context layer stack tracks ``(scope_id, obj)`` tuples for provenance tracking, parallel to the merged config. It preserves hierarchy for inheritance source lookup.
165
+ The stack holds one ``ContextLayer`` for every object entered with ``config_context()``, with or
166
+ without a scope id, above the global config the context started from (scope ``""``). It is the
167
+ value ``resolve_with_provenance()`` reads. A layer entered with ``mask_with_none=True`` hides the
168
+ layers outside it.
152
169
 
153
170
  Usage Examples
154
171
  --------------
@@ -285,7 +302,7 @@ How Provenance Works
285
302
 
286
303
  The provenance system works through these mechanisms:
287
304
 
288
- 1. **Context Layer Stack**: The ``config_context()`` manager tracks ``(scope_id, obj)`` tuples as contexts are pushed.
305
+ 1. **Context Layer Stack**: The ``config_context()`` manager adds a ``ContextLayer`` for every object entered.
289
306
 
290
307
  2. **Dual-Axis Resolution with Provenance**: When resolving inherited fields, ``resolve_with_provenance()`` walks both the MRO and context hierarchy, returning the first concrete value found along with its source information.
291
308
 
@@ -78,15 +78,14 @@ from objectstate.lazy_factory import (
78
78
 
79
79
  # Resolver
80
80
  from objectstate.dual_axis_resolver import (
81
- resolve_field_inheritance,
82
- _has_concrete_field_override,
81
+ ResolvedField,
82
+ resolve_with_provenance,
83
83
  )
84
84
 
85
85
  # Context
86
86
  from objectstate.context_manager import (
87
87
  config_context,
88
88
  get_current_temp_global,
89
- set_current_temp_global,
90
89
  clear_current_temp_global,
91
90
  merge_configs,
92
91
  extract_all_configs,
@@ -168,12 +167,11 @@ __all__ = [
168
167
  'is_global_config_type',
169
168
  'is_global_config_instance',
170
169
  # Resolver
171
- 'resolve_field_inheritance',
172
- '_has_concrete_field_override',
170
+ 'ResolvedField',
171
+ 'resolve_with_provenance',
173
172
  # Context
174
173
  'config_context',
175
174
  'get_current_temp_global',
176
- 'set_current_temp_global',
177
175
  'clear_current_temp_global',
178
176
  'merge_configs',
179
177
  'extract_all_configs',
@@ -212,7 +210,7 @@ __all__ = [
212
210
  'ObjectStateEditSession',
213
211
  ]
214
212
 
215
- __version__ = "2.1.1"
213
+ __version__ = "3.0.0"
216
214
  __author__ = 'OpenHCS Team'
217
215
  __description__ = 'Generic configuration framework for lazy dataclass resolution'
218
216