mainsequence 4.1.7__tar.gz → 4.1.8__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 (121) hide show
  1. {mainsequence-4.1.7 → mainsequence-4.1.8}/PKG-INFO +1 -1
  2. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md +55 -14
  3. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md +11 -0
  4. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/meta_tables/data_nodes/data_nodes.py +0 -7
  5. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/meta_tables/pydantic_metadata.py +0 -18
  6. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence.egg-info/PKG-INFO +1 -1
  7. {mainsequence-4.1.7 → mainsequence-4.1.8}/pyproject.toml +1 -1
  8. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_build_operations_hashing.py +0 -40
  9. {mainsequence-4.1.7 → mainsequence-4.1.8}/LICENSE +0 -0
  10. {mainsequence-4.1.7 → mainsequence-4.1.8}/README.md +0 -0
  11. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/AGENTS.md +0 -0
  12. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/skills/a2a_communication/SKILL.md +0 -0
  13. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
  14. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/skills/command_center/adapter_from_api/SKILL.md +0 -0
  15. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/skills/command_center/api_mock_prototyping/SKILL.md +0 -0
  16. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/skills/command_center/app_components/SKILL.md +0 -0
  17. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/skills/command_center/connections/SKILL.md +0 -0
  18. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/skills/command_center/workspace_analysis/SKILL.md +0 -0
  19. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/skills/command_center/workspace_builder/SKILL.md +0 -0
  20. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/skills/command_center/workspace_design/SKILL.md +0 -0
  21. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/skills/dashboards/streamlit/SKILL.md +0 -0
  22. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
  23. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
  24. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/skills/ms-markets/SKILL.md +0 -0
  25. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
  26. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
  27. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/skills/project_builder/SKILL.md +0 -0
  28. {mainsequence-4.1.7 → mainsequence-4.1.8}/agent_scaffold/skills/project_to_agent/SKILL.md +0 -0
  29. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/__init__.py +0 -0
  30. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/__main__.py +0 -0
  31. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/bootstrap.py +0 -0
  32. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/cli/__init__.py +0 -0
  33. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/cli/api.py +0 -0
  34. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/cli/browser_auth.py +0 -0
  35. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/cli/cli.py +0 -0
  36. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/cli/config.py +0 -0
  37. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/cli/docker_utils.py +0 -0
  38. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/cli/doctor.py +0 -0
  39. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/cli/local_ops.py +0 -0
  40. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/cli/model_filters.py +0 -0
  41. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/cli/project_status.py +0 -0
  42. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/cli/pydantic_cli.py +0 -0
  43. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/cli/sdk_utils.py +0 -0
  44. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/cli/ssh_utils.py +0 -0
  45. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/cli/ui.py +0 -0
  46. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/__init__.py +0 -0
  47. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/agent_runtime_models.py +0 -0
  48. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/base.py +0 -0
  49. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/client.py +0 -0
  50. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/command_center/__init__.py +0 -0
  51. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/command_center/app_component.py +0 -0
  52. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/command_center/connections.py +0 -0
  53. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/command_center/data_models.py +0 -0
  54. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/command_center/workspace.py +0 -0
  55. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/command_center/workspace_snapshot.py +0 -0
  56. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/compute_validation.py +0 -0
  57. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
  58. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
  59. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/data_sources_interfaces/local_paths.py +0 -0
  60. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/data_sources_interfaces/sqlite.py +0 -0
  61. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/dtype_codec.py +0 -0
  62. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/exceptions.py +0 -0
  63. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/fastapi/__init__.py +0 -0
  64. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/fastapi/auth.py +0 -0
  65. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/models_foundry.py +0 -0
  66. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/models_helpers.py +0 -0
  67. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/models_metatables.py +0 -0
  68. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/models_user.py +0 -0
  69. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/client/utils.py +0 -0
  70. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/defaults.py +0 -0
  71. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/instrumentation/__init__.py +0 -0
  72. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/instrumentation/utils.py +0 -0
  73. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/logconf.py +0 -0
  74. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/meta_tables/__init__.py +0 -0
  75. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/meta_tables/__main__.py +0 -0
  76. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/meta_tables/compiled_sql/__init__.py +0 -0
  77. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/meta_tables/compiled_sql/v1.py +0 -0
  78. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/meta_tables/data_nodes/__init__.py +0 -0
  79. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/meta_tables/data_nodes/build_operations.py +0 -0
  80. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/meta_tables/data_nodes/models.py +0 -0
  81. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/meta_tables/data_nodes/namespacing.py +0 -0
  82. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/meta_tables/data_nodes/persist_managers.py +0 -0
  83. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/meta_tables/data_nodes/run_operations.py +0 -0
  84. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/meta_tables/data_nodes/utils.py +0 -0
  85. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/meta_tables/future_registry.py +0 -0
  86. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/meta_tables/hashing.py +0 -0
  87. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/meta_tables/sqlalchemy_contracts.py +0 -0
  88. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence/runtime_flags.py +0 -0
  89. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence.egg-info/SOURCES.txt +0 -0
  90. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence.egg-info/dependency_links.txt +0 -0
  91. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence.egg-info/entry_points.txt +0 -0
  92. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence.egg-info/requires.txt +0 -0
  93. {mainsequence-4.1.7 → mainsequence-4.1.8}/mainsequence.egg-info/top_level.txt +0 -0
  94. {mainsequence-4.1.7 → mainsequence-4.1.8}/setup.cfg +0 -0
  95. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_auth_precedence.py +0 -0
  96. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_cli.py +0 -0
  97. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_cli_browser_auth.py +0 -0
  98. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_client.py +0 -0
  99. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_command_center_app_component_models.py +0 -0
  100. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_command_center_data_models.py +0 -0
  101. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_command_center_models.py +0 -0
  102. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_data_access_mixin_dimension_audit.py +0 -0
  103. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_data_node_storage_dimension_queries.py +0 -0
  104. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_data_node_update_flow.py +0 -0
  105. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_dependency_extras.py +0 -0
  106. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_duckdb_interface_dimensions.py +0 -0
  107. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_filter_normalization.py +0 -0
  108. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_logconf.py +0 -0
  109. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_meta_tables_client_models.py +0 -0
  110. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_meta_tables_sqlalchemy_contracts.py +0 -0
  111. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_models_user_request_bound_auth.py +0 -0
  112. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_pod_project_resolution.py +0 -0
  113. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_project_batch_jobs_from_file.py +0 -0
  114. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_run_configuration.py +0 -0
  115. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_secret_client_model.py +0 -0
  116. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_source_table_configuration.py +0 -0
  117. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_sqlite_interface_dimensions.py +0 -0
  118. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_update_runner_uid_runtime.py +0 -0
  119. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_update_statistics.py +0 -0
  120. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_update_uid_guards.py +0 -0
  121. {mainsequence-4.1.7 → mainsequence-4.1.8}/tests/test_workspace_snapshot.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 4.1.7
3
+ Version: 4.1.8
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License: MainSequence GmbH SDK License Agreement
@@ -25,7 +25,7 @@ Canonical workflow:
25
25
  - modify an existing `DataNode` update process
26
26
  - review whether a DataNode change affects update identity or table contract
27
27
  - define or refactor `DataNodeConfiguration`
28
- - classify config fields into update identity and hash-excluded descriptive metadata
28
+ - classify values as hashed config fields or non-config class/runtime values
29
29
  - implement or review:
30
30
  - `dependencies()`
31
31
  - `update()`
@@ -112,6 +112,16 @@ Every storage class must include `__metatable_description__`. The description
112
112
  should explain the table's intention, row grain, and downstream use, not only
113
113
  list columns or schema mechanics.
114
114
 
115
+ Use `__metatable_extra_hash_components__` on storage classes when distinct
116
+ DataNode storage tables could otherwise have the same storage-relevant shape.
117
+ For example, two one-index daily tables with one float column need a stable
118
+ component such as `{"storage_name": "daily_random_number"}` versus
119
+ `{"storage_name": "daily_random_addition"}`.
120
+
121
+ This is storage identity. Changing it creates a different storage table. Do not
122
+ use it for labels, descriptions, runtime options, test isolation, backend UIDs,
123
+ data-source UIDs, or updater scope.
124
+
115
125
  Do not put those concerns in `DataNodeConfiguration`.
116
126
 
117
127
  Minimal pattern:
@@ -132,6 +142,7 @@ class Base(DeclarativeBase):
132
142
  class PricesTable(PlatformTimeIndexMetaData, Base):
133
143
  __metatable_namespace__ = "<domain_namespace>"
134
144
  __metatable_identifier__ = "<table_identifier>"
145
+ __metatable_extra_hash_components__ = {"storage_name": "<stable_storage_name>"}
135
146
  __metatable_description__ = (
136
147
  "Daily close prices keyed by asset unique identifier for portfolio and "
137
148
  "risk analytics."
@@ -183,12 +194,21 @@ Do not accept `test_node`. It has been removed. Use explicit
183
194
  Pattern:
184
195
 
185
196
  ```python
197
+ from typing import ClassVar
198
+
199
+ from pydantic import Field
200
+
186
201
  from mainsequence.meta_tables import DataNode, DataNodeConfiguration
187
202
  from mainsequence.meta_tables import PlatformTimeIndexMetaData
188
203
 
189
204
 
190
205
  class PricesConfig(DataNodeConfiguration):
191
- shard_id: str
206
+ shard_id: str = Field(
207
+ ...,
208
+ description="Stable updater partition for this price job.",
209
+ examples=["us_equities_daily"],
210
+ )
211
+ reference_dimension: ClassVar[str] = "unique_identifier"
192
212
 
193
213
 
194
214
  class PricesUpdate(DataNode):
@@ -216,23 +236,45 @@ class PricesUpdate(DataNode):
216
236
  ### 3. Configuration Is Update-Scoped By Default
217
237
 
218
238
  Every `DataNodeConfiguration` field participates in `update_hash` by default.
239
+ Declare values that change output values, dependencies, source choice, or
240
+ updater scope as normal config fields.
219
241
 
220
- Do not use:
242
+ Every config field must be declared with `Field(...)`. Include a clear
243
+ `description` and add `examples=[...]` whenever a realistic example helps. The
244
+ description must explain what the value means for the update process, not repeat
245
+ the Python type.
221
246
 
222
- - `json_schema_extra={"update_only": True}`
223
- - `json_schema_extra={"runtime_only": True}`
224
- - `json_schema_extra={"ignore_from_storage_hash": True}`
225
- - `_ARGS_IGNORE_IN_STORAGE_HASH`
247
+ Values that must not affect `update_hash` should not be Pydantic config fields.
248
+ Use `ClassVar[...]` for class-level invariants and implementation constants, or
249
+ keep runtime controls in environment/runtime configuration outside the
250
+ DataNode config.
226
251
 
227
- Those are removed. The only supported opt-out is:
252
+ If a value genuinely must remain a Pydantic field while not affecting
253
+ `update_hash`, the only supported field-level opt-out is
254
+ `json_schema_extra={"hash_excluded": True}`:
228
255
 
229
256
  ```python
230
- Field(..., json_schema_extra={"hash_excluded": True})
257
+ from pydantic import Field
258
+
259
+ from mainsequence.meta_tables import DataNodeConfiguration
260
+
261
+
262
+ class PricesConfig(DataNodeConfiguration):
263
+ shard_id: str = Field(
264
+ ...,
265
+ description="Stable updater partition for this price job.",
266
+ examples=["us_equities_daily"],
267
+ )
268
+ display_label: str | None = Field(
269
+ default=None,
270
+ description="Optional human-facing label for UI display only.",
271
+ examples=["US equities daily prices"],
272
+ json_schema_extra={"hash_excluded": True},
273
+ )
231
274
  ```
232
275
 
233
- Use `hash_excluded` only for descriptive metadata that must not affect update
234
- identity. If a field changes output values, dependencies, source choice, or
235
- updater scope, it must remain a normal config field.
276
+ Do not invent other metadata-marker exceptions. Scope, dependency, source, and
277
+ output-affecting fields must remain hashed config fields.
236
278
 
237
279
  ### 4. `hash_namespace` Is Isolation Only
238
280
 
@@ -330,11 +372,10 @@ When reviewing an existing DataNode, look for:
330
372
  - missing `__metatable_description__` on the storage table
331
373
  - dependency storage table passed as an ad hoc constructor argument
332
374
  - schema or published table metadata hidden in DataNode configuration
333
- - `update_only`, `runtime_only`, or `ignore_from_storage_hash`
334
375
  - `test_node=True`
335
376
  - missing explicit `storage_table`
336
377
  - accidental storage registration inside the DataNode
337
- - wrong meaning/scope/hash-excluded split
378
+ - wrong split between hashed config fields and non-config class/runtime values
338
379
  - misuse of `hash_namespace`
339
380
  - non-incremental `update()` behavior
340
381
  - hidden dependency creation inside `update()`
@@ -103,12 +103,23 @@ Always declare `__metatable_description__` on the model. The description must
103
103
  explain the table's business intention, row grain, and expected use, not only
104
104
  the schema. Column-level descriptions stay in `mapped_column(info={...})`.
105
105
 
106
+ Use `__metatable_extra_hash_components__` when two backend-managed tables could
107
+ otherwise produce the same storage hash because their storage-relevant shape is
108
+ identical or intentionally generic. The value must be stable and deterministic,
109
+ usually a small mapping such as `{"storage_name": "account_holdings"}`.
110
+
111
+ This attribute is part of storage identity. Changing it defines a different
112
+ table. Do not use it for labels, descriptions, runtime options, test isolation,
113
+ backend UIDs, data-source UIDs, or updater scope. Use `hash_namespace` for test
114
+ or experiment isolation.
115
+
106
116
  Register through the class API:
107
117
 
108
118
  ```python
109
119
  class Account(PlatformManagedMetaTable, Base):
110
120
  __metatable_namespace__ = "sdk-examples"
111
121
  __metatable_identifier__ = "Account"
122
+ __metatable_extra_hash_components__ = {"storage_name": "account"}
112
123
  __metatable_description__ = (
113
124
  "Customer account master records used to scope balances, holdings, and "
114
125
  "account-level limits."
@@ -420,13 +420,6 @@ class DataNode(DataAccessMixin, ABC):
420
420
  """
421
421
  super().__init_subclass__(**kwargs)
422
422
 
423
- if "_ARGS_IGNORE_IN_STORAGE_HASH" in cls.__dict__:
424
- raise TypeError(
425
- f"{cls.__name__} uses removed class attribute _ARGS_IGNORE_IN_STORAGE_HASH; "
426
- "move those fields into DataNodeConfiguration. Configuration fields "
427
- "participate in update hashing by default."
428
- )
429
-
430
423
  # Get the original __init__ from the new subclass
431
424
  original_init = cls.__init__
432
425
 
@@ -20,24 +20,6 @@ def serialize_pydantic_model(
20
20
 
21
21
  for field_name, field_info in value.__class__.model_fields.items():
22
22
  extra = field_info.json_schema_extra or {}
23
- if "ignore_from_storage_hash" in extra:
24
- raise ValueError(
25
- f"{value.__class__.__name__}.{field_name} uses removed metadata "
26
- "'ignore_from_storage_hash'. All configuration fields participate in "
27
- 'update hashing by default; use json_schema_extra={"hash_excluded": True} '
28
- "only for fields that should not affect update identity."
29
- )
30
- if "update_only" in extra:
31
- raise ValueError(
32
- f"{value.__class__.__name__}.{field_name} uses removed metadata "
33
- "'update_only'. All configuration fields are update-scoped by default."
34
- )
35
- if "runtime_only" in extra:
36
- raise ValueError(
37
- f"{value.__class__.__name__}.{field_name} uses removed metadata "
38
- "'runtime_only'; use json_schema_extra={\"hash_excluded\": True} instead."
39
- )
40
-
41
23
  is_hash_excluded = extra.get("hash_excluded", False)
42
24
  if not isinstance(is_hash_excluded, bool):
43
25
  raise ValueError(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 4.1.7
3
+ Version: 4.1.8
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License: MainSequence GmbH SDK License Agreement
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mainsequence"
7
- version = "4.1.7"
7
+ version = "4.1.8"
8
8
  description = "Main Sequence SDK "
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -101,22 +101,6 @@ def test_normal_config_value_changes_update_hash(monkeypatch):
101
101
  assert storage_hash_a != storage_hash_b
102
102
 
103
103
 
104
- def test_update_only_metadata_is_rejected():
105
- class NodeConfig(BaseModel):
106
- shard_id: str = Field(..., json_schema_extra={"update_only": True})
107
-
108
- with pytest.raises(ValueError, match="update_only"):
109
- build_operations.serialize_argument(NodeConfig(shard_id="desk_a"))
110
-
111
-
112
- def test_runtime_only_metadata_is_rejected():
113
- class NodeConfig(BaseModel):
114
- label: str = Field(..., json_schema_extra={"runtime_only": True})
115
-
116
- with pytest.raises(ValueError, match="runtime_only"):
117
- build_operations.serialize_argument(NodeConfig(label="Close"))
118
-
119
-
120
104
  def test_hash_excluded_metadata_does_not_affect_hashes(monkeypatch):
121
105
  monkeypatch.setattr(build_operations, "POD_PROJECT", None, raising=False)
122
106
 
@@ -264,30 +248,6 @@ def test_plain_dict_with_pydantic_model_import_path_key_is_not_treated_as_wrappe
264
248
  assert build_operations.hash_signature(payload_a) != build_operations.hash_signature(payload_b)
265
249
 
266
250
 
267
- def test_removed_storage_hash_metadata_is_rejected():
268
- class RemovedStorageHashConfig(BaseModel):
269
- shard_id: str = Field(..., json_schema_extra={"ignore_from_storage_hash": True})
270
-
271
- with pytest.raises(ValueError, match="ignore_from_storage_hash"):
272
- build_operations.serialize_argument(RemovedStorageHashConfig(shard_id="desk_a"))
273
-
274
-
275
- def test_removed_storage_hash_class_attribute_is_rejected():
276
- with pytest.raises(TypeError, match="_ARGS_IGNORE_IN_STORAGE_HASH"):
277
-
278
- class RemovedStorageHashDataNode(DataNode):
279
- _ARGS_IGNORE_IN_STORAGE_HASH = ["asset_list"]
280
-
281
- def __init__(self, *args, **kwargs):
282
- super().__init__(*args, **kwargs)
283
-
284
- def dependencies(self):
285
- return {}
286
-
287
- def update(self):
288
- return None
289
-
290
-
291
251
  def test_data_node_configuration_overrides_offset_start():
292
252
  class NodeConfig(DataNodeConfiguration):
293
253
  pass
File without changes
File without changes
File without changes