sltcodec 2.0.0__tar.gz → 2.1.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: sltcodec
3
- Version: 2.0.0
3
+ Version: 2.1.0
4
4
  Summary: Decode and encode bytearrays according to struct layout definitions using sltcore.
5
5
  Project-URL: Homepage, https://github.com/fangface-hub/StructLayoutToolkitCodec
6
6
  Project-URL: Documentation, https://readthedocs.org
@@ -205,6 +205,7 @@ internal implementation details and are omitted from the public method tables.
205
205
  | --- | --- |
206
206
  | `range_check(env=None)` | Evaluate the field's range expression. |
207
207
  | `from_value(field_def, value, type_dict=None, is_padding=False)` | Create an instance and resolve matching enum metadata. |
208
+ | `with_value(value, type_dict=None)` | Return a new instance with the given value; keeps `field_def` and `is_padding` and recomputes `enum_item`. |
208
209
  | `__lt__(other)` | Compare field instances using field-definition order. |
209
210
 
210
211
  #### `StructDef`
@@ -61,6 +61,19 @@ Layout persistence uses the explicit names `save_struct_layout` and
61
61
  `load_struct_layout`. The former `save_type_dict` and `load_type_dict` API is
62
62
  not part of the current public interface.
63
63
 
64
+ `FieldInstance` stays frozen. To change a decoded value, use
65
+ `FieldInstance.with_value(value, type_dict=None)`, which returns a new
66
+ instance instead of mutating the original. It keeps `field_def` and
67
+ `is_padding`, and recomputes `enum_item` from the new value and `type_dict`
68
+ by delegating to `FieldInstance.from_value`.
69
+
70
+ ```python
71
+ updated_field = field_instance.with_value(
72
+ new_value,
73
+ struct_layout.type_dict,
74
+ )
75
+ ```
76
+
64
77
  ## Versioning And Release
65
78
 
66
79
  Version bump scripts are provided for patch, minor, and major releases:
@@ -188,6 +188,7 @@ internal implementation details and are omitted from the public method tables.
188
188
  | --- | --- |
189
189
  | `range_check(env=None)` | Evaluate the field's range expression. |
190
190
  | `from_value(field_def, value, type_dict=None, is_padding=False)` | Create an instance and resolve matching enum metadata. |
191
+ | `with_value(value, type_dict=None)` | Return a new instance with the given value; keeps `field_def` and `is_padding` and recomputes `enum_item`. |
191
192
  | `__lt__(other)` | Compare field instances using field-definition order. |
192
193
 
193
194
  #### `StructDef`
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sltcodec"
3
- version = "2.0.0"
3
+ version = "2.1.0"
4
4
  description = "Decode and encode bytearrays according to struct layout definitions using sltcore."
5
5
  readme = "README_pypi.md"
6
6
  requires-python = ">=3.12"
@@ -347,6 +347,15 @@ class FieldInstance:
347
347
  enum_item=enum_item,
348
348
  is_padding=is_padding)
349
349
 
350
+ def with_value(self,
351
+ value: Any,
352
+ type_dict: "TypeDict | None" = None) -> "FieldInstance":
353
+ """Return a new FieldInstance with the given value applied."""
354
+ return type(self).from_value(field_def=self.field_def,
355
+ value=value,
356
+ type_dict=type_dict,
357
+ is_padding=self.is_padding)
358
+
350
359
  @staticmethod
351
360
  def _resolve_enum_def(field_def: FieldDef,
352
361
  type_dict: "TypeDict | None") -> EnumDef | None:
@@ -169,6 +169,89 @@ def test_field_instance_from_value_sets_enum_item_from_field_enum_def():
169
169
  assert field_instance.enum_item == ("MANUAL", 1)
170
170
 
171
171
 
172
+ def _mode_enum_fixture() -> tuple[EnumDef, FieldDef, TypeDict]:
173
+ """Build an enum-backed field definition and its type dictionary."""
174
+ enum_def = EnumDef(name="Mode", values={"AUTO": 0, "MANUAL": 1})
175
+ field_def = FieldDef(name="mode",
176
+ offset=InfoSize(0, 0),
177
+ size=InfoSize(1, 0),
178
+ type="unsigned int",
179
+ enum_def_name=enum_def.name)
180
+ type_dict = TypeDict(enum_dict={enum_def.name: enum_def})
181
+ return enum_def, field_def, type_dict
182
+
183
+
184
+ def test_field_instance_with_value_keeps_original_unchanged():
185
+ """Test FieldInstance.with_value does not mutate the original."""
186
+ _, field_def, type_dict = _mode_enum_fixture()
187
+ original = FieldInstance.from_value(field_def, 0, type_dict=type_dict)
188
+
189
+ original.with_value(1, type_dict)
190
+
191
+ assert original.value == 0
192
+ assert original.enum_item == ("AUTO", 0)
193
+
194
+
195
+ def test_field_instance_with_value_returns_new_instance():
196
+ """Test FieldInstance.with_value returns a new instance with the value."""
197
+ _, field_def, type_dict = _mode_enum_fixture()
198
+ original = FieldInstance.from_value(field_def, 0, type_dict=type_dict)
199
+
200
+ updated = original.with_value(1, type_dict)
201
+
202
+ assert updated is not original
203
+ assert updated.value == 1
204
+
205
+
206
+ def test_field_instance_with_value_preserves_field_def_and_padding():
207
+ """Test FieldInstance.with_value preserves field_def and is_padding."""
208
+ _, field_def, type_dict = _mode_enum_fixture()
209
+ original = FieldInstance.from_value(field_def,
210
+ 0,
211
+ type_dict=type_dict,
212
+ is_padding=True)
213
+
214
+ updated = original.with_value(1, type_dict)
215
+
216
+ assert updated.field_def is original.field_def
217
+ assert updated.is_padding is True
218
+
219
+
220
+ def test_field_instance_with_value_updates_enum_item():
221
+ """Test FieldInstance.with_value recomputes a matching enum_item."""
222
+ _, field_def, type_dict = _mode_enum_fixture()
223
+ original = FieldInstance.from_value(field_def, 0, type_dict=type_dict)
224
+
225
+ updated = original.with_value(1, type_dict)
226
+
227
+ assert updated.enum_item == ("MANUAL", 1)
228
+
229
+
230
+ def test_field_instance_with_value_clears_unmatched_enum_item():
231
+ """Test FieldInstance.with_value clears enum_item when unmatched."""
232
+ _, field_def, type_dict = _mode_enum_fixture()
233
+ original = FieldInstance.from_value(field_def, 0, type_dict=type_dict)
234
+
235
+ updated = original.with_value(7, type_dict)
236
+
237
+ assert updated.enum_item is None
238
+
239
+
240
+ def test_field_instance_with_value_without_type_dict():
241
+ """Test FieldInstance.with_value works for plain fields."""
242
+ field_def = FieldDef(name="count",
243
+ offset=InfoSize(0, 0),
244
+ size=InfoSize(1, 0),
245
+ type="unsigned int")
246
+ original = FieldInstance.from_value(field_def, 1)
247
+
248
+ updated = original.with_value(2)
249
+
250
+ assert updated.value == 2
251
+ assert updated.enum_item is None
252
+ assert original.value == 1
253
+
254
+
172
255
  def test_struct_def_metadata_json_round_trip():
173
256
  """Test that StructDef name/description are preserved in JSON."""
174
257
  child = FieldDef(name="value",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes