sltcodec 2.1.1__tar.gz → 2.3.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.
- {sltcodec-2.1.1 → sltcodec-2.3.0}/PKG-INFO +4 -4
- {sltcodec-2.1.1 → sltcodec-2.3.0}/README_pypi.md +2 -2
- {sltcodec-2.1.1 → sltcodec-2.3.0}/pyproject.toml +2 -2
- {sltcodec-2.1.1 → sltcodec-2.3.0}/src/sltcodec/codec.py +32 -47
- {sltcodec-2.1.1 → sltcodec-2.3.0}/src/sltcodec/types.py +11 -2
- {sltcodec-2.1.1 → sltcodec-2.3.0}/tests/test_codec.py +42 -1
- {sltcodec-2.1.1 → sltcodec-2.3.0}/tests/test_types.py +2 -1
- {sltcodec-2.1.1 → sltcodec-2.3.0}/uv.lock +5 -5
- {sltcodec-2.1.1 → sltcodec-2.3.0}/.github/workflows/publish_to_pypi.yml +0 -0
- {sltcodec-2.1.1 → sltcodec-2.3.0}/.github/workflows/publish_to_testpypi.yml +0 -0
- {sltcodec-2.1.1 → sltcodec-2.3.0}/.gitignore +0 -0
- {sltcodec-2.1.1 → sltcodec-2.3.0}/.python-version +0 -0
- {sltcodec-2.1.1 → sltcodec-2.3.0}/.vscode/launch.json +0 -0
- {sltcodec-2.1.1 → sltcodec-2.3.0}/.vscode/settings.json +0 -0
- {sltcodec-2.1.1 → sltcodec-2.3.0}/LICENSE +0 -0
- {sltcodec-2.1.1 → sltcodec-2.3.0}/README.md +0 -0
- {sltcodec-2.1.1 → sltcodec-2.3.0}/bump_major.ps1 +0 -0
- {sltcodec-2.1.1 → sltcodec-2.3.0}/bump_minor.ps1 +0 -0
- {sltcodec-2.1.1 → sltcodec-2.3.0}/bump_patch.ps1 +0 -0
- {sltcodec-2.1.1 → sltcodec-2.3.0}/src/sltcodec/__init__.py +0 -0
- {sltcodec-2.1.1 → sltcodec-2.3.0}/tests/test_persistence.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: sltcodec
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.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
|
|
@@ -11,7 +11,7 @@ License-Expression: MIT
|
|
|
11
11
|
License-File: LICENSE
|
|
12
12
|
Keywords: byte,deserialization,layout,serialization,struct
|
|
13
13
|
Requires-Python: >=3.12
|
|
14
|
-
Requires-Dist: sltcalc>=
|
|
14
|
+
Requires-Dist: sltcalc>=1.0.0
|
|
15
15
|
Requires-Dist: sltcore>=1.5.0
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
|
|
@@ -77,7 +77,7 @@ The public `PRIMITIVE_TYPES` set contains:
|
|
|
77
77
|
{"bool", "signed int", "int", "unsigned int", "float", "bytearray", "bytes"}
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
-
`FieldDef.type` may also be a nested `StructDef` or an expression string. Expressions can use values from previously processed fields, allowing dynamic types and
|
|
80
|
+
`FieldDef.type` may also be a nested `StructDef` or an expression string. Expressions can use values from previously processed fields, allowing dynamic types, sizes, and repeat counts. Repeated fields, byte swapping, padding, ranges, and enum metadata are supported.
|
|
81
81
|
|
|
82
82
|
## Enums And Named Structures
|
|
83
83
|
|
|
@@ -180,7 +180,7 @@ internal implementation details and are omitted from the public method tables.
|
|
|
180
180
|
| `size` | `InfoSize \| str` | Static size or expression. |
|
|
181
181
|
| `type` | `str \| StructDef` | Primitive, named, or nested field type. |
|
|
182
182
|
| `scale` | `float` | Numeric scale applied to the field. |
|
|
183
|
-
| `repeat` | `int \| None` | Number of repeated field values. |
|
|
183
|
+
| `repeat` | `int \| str \| None` | Number of repeated field values, or an expression that evaluates to the count. |
|
|
184
184
|
| `description` | `str \| None` | Optional field description. |
|
|
185
185
|
| `range_expression` | `str \| None` | Optional value-range expression. |
|
|
186
186
|
| `enum_def_name` | `str \| None` | Name of the associated enum definition. |
|
|
@@ -60,7 +60,7 @@ The public `PRIMITIVE_TYPES` set contains:
|
|
|
60
60
|
{"bool", "signed int", "int", "unsigned int", "float", "bytearray", "bytes"}
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
`FieldDef.type` may also be a nested `StructDef` or an expression string. Expressions can use values from previously processed fields, allowing dynamic types and
|
|
63
|
+
`FieldDef.type` may also be a nested `StructDef` or an expression string. Expressions can use values from previously processed fields, allowing dynamic types, sizes, and repeat counts. Repeated fields, byte swapping, padding, ranges, and enum metadata are supported.
|
|
64
64
|
|
|
65
65
|
## Enums And Named Structures
|
|
66
66
|
|
|
@@ -163,7 +163,7 @@ internal implementation details and are omitted from the public method tables.
|
|
|
163
163
|
| `size` | `InfoSize \| str` | Static size or expression. |
|
|
164
164
|
| `type` | `str \| StructDef` | Primitive, named, or nested field type. |
|
|
165
165
|
| `scale` | `float` | Numeric scale applied to the field. |
|
|
166
|
-
| `repeat` | `int \| None` | Number of repeated field values. |
|
|
166
|
+
| `repeat` | `int \| str \| None` | Number of repeated field values, or an expression that evaluates to the count. |
|
|
167
167
|
| `description` | `str \| None` | Optional field description. |
|
|
168
168
|
| `range_expression` | `str \| None` | Optional value-range expression. |
|
|
169
169
|
| `enum_def_name` | `str \| None` | Name of the associated enum definition. |
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "sltcodec"
|
|
3
|
-
version = "2.
|
|
3
|
+
version = "2.3.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"
|
|
7
7
|
dependencies = [
|
|
8
|
-
"sltcalc>=
|
|
8
|
+
"sltcalc>=1.0.0",
|
|
9
9
|
"sltcore>=1.5.0",
|
|
10
10
|
]
|
|
11
11
|
license = "MIT"
|
|
@@ -136,20 +136,12 @@ def _resolve_info_size(value: InfoSize | str, env: dict[str, Any]) -> InfoSize:
|
|
|
136
136
|
if isinstance(value, str):
|
|
137
137
|
stleval = SltEval(env)
|
|
138
138
|
resolved_byte = stleval.eval(value)
|
|
139
|
+
if isinstance(resolved_byte, InfoSize):
|
|
140
|
+
return resolved_byte
|
|
139
141
|
return InfoSize(resolved_byte, 0)
|
|
140
142
|
return value
|
|
141
143
|
|
|
142
144
|
|
|
143
|
-
def _resolve_offset(field_def: FieldDef, env: dict[str, Any]) -> InfoSize:
|
|
144
|
-
"""Resolve a field offset that can be static or expression-based."""
|
|
145
|
-
return _resolve_info_size(field_def.offset, env)
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
def _resolve_size(field_def: FieldDef, env: dict[str, Any]) -> InfoSize:
|
|
149
|
-
"""Resolve a field size that can be static or expression-based."""
|
|
150
|
-
return _resolve_info_size(field_def.size, env)
|
|
151
|
-
|
|
152
|
-
|
|
153
145
|
def _resolve_byte_swap(field_def: FieldDef, env: dict[str, Any]) -> bool:
|
|
154
146
|
"""Resolve a byte-swap flag that can be static or expression-based."""
|
|
155
147
|
if isinstance(field_def.byte_swap, str):
|
|
@@ -157,9 +149,11 @@ def _resolve_byte_swap(field_def: FieldDef, env: dict[str, Any]) -> bool:
|
|
|
157
149
|
return field_def.byte_swap
|
|
158
150
|
|
|
159
151
|
|
|
160
|
-
def
|
|
161
|
-
"""
|
|
162
|
-
|
|
152
|
+
def _resolve_repeat(value: int | str | None, env: dict[str, Any]) -> int | None:
|
|
153
|
+
"""Resolve a static or expression-based repeat count."""
|
|
154
|
+
if isinstance(value, str):
|
|
155
|
+
return int(SltEval(env).eval(value))
|
|
156
|
+
return value
|
|
163
157
|
|
|
164
158
|
|
|
165
159
|
def _is_padding_field_def(field_def: FieldDef) -> bool:
|
|
@@ -168,16 +162,6 @@ def _is_padding_field_def(field_def: FieldDef) -> bool:
|
|
|
168
162
|
and field_def.type in ["bytes", "bytearray"])
|
|
169
163
|
|
|
170
164
|
|
|
171
|
-
def _info_size_to_bits(info_size: InfoSize) -> int:
|
|
172
|
-
"""Convert InfoSize to an absolute bit count."""
|
|
173
|
-
return info_size.byte * 8 + info_size.bit
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
def _info_size_from_bits(total_bits: int) -> InfoSize:
|
|
177
|
-
"""Create InfoSize from an absolute bit count."""
|
|
178
|
-
return InfoSize(total_bits >> 3, total_bits & 0x7)
|
|
179
|
-
|
|
180
|
-
|
|
181
165
|
def _validate_padding_alignment_bits(padding_alignment_bits: int) -> None:
|
|
182
166
|
"""Validate padding alignment as a positive power-of-two bit size."""
|
|
183
167
|
if (isinstance(padding_alignment_bits, bool)
|
|
@@ -237,8 +221,8 @@ def _prepare_field_info(
|
|
|
237
221
|
padding_alignment_bits: int = _DEFAULT_PADDING_ALIGNMENT_BITS,
|
|
238
222
|
) -> tuple[InfoSize, InfoSize, Info] | None:
|
|
239
223
|
"""Resolve a field definition into an offset, size, and info payload."""
|
|
240
|
-
offset =
|
|
241
|
-
size =
|
|
224
|
+
offset = _resolve_info_size(field_def.offset, env)
|
|
225
|
+
size = _resolve_info_size(field_def.size, env)
|
|
242
226
|
if size.byte == 0 and size.bit == 0:
|
|
243
227
|
return None
|
|
244
228
|
|
|
@@ -305,7 +289,7 @@ def encode_field(
|
|
|
305
289
|
|
|
306
290
|
offset, size, info = prepared
|
|
307
291
|
if _resolve_byte_swap(field_def, env):
|
|
308
|
-
info =
|
|
292
|
+
info = info.byte_swap
|
|
309
293
|
required_bytes = (offset + size).bytes
|
|
310
294
|
if len(buf) < required_bytes:
|
|
311
295
|
buf.extend(b"\x00" * (required_bytes - len(buf)))
|
|
@@ -351,21 +335,22 @@ def encode(
|
|
|
351
335
|
|
|
352
336
|
for field_value in struct_instance.field_instances:
|
|
353
337
|
field_def = field_value.field_def
|
|
338
|
+
repeat = _resolve_repeat(field_def.repeat, env)
|
|
354
339
|
if _is_padding_field_def(field_def):
|
|
355
340
|
has_padding = True
|
|
356
341
|
value = field_value.value
|
|
357
342
|
if _is_padding_field_def(field_def):
|
|
358
|
-
padding_size =
|
|
343
|
+
padding_size = _resolve_info_size(field_def.size, env)
|
|
359
344
|
value = bytearray(padding_size.bytes)
|
|
360
|
-
if
|
|
361
|
-
current_offset =
|
|
345
|
+
if repeat is not None and repeat > 1:
|
|
346
|
+
current_offset = _resolve_info_size(field_def.offset, env)
|
|
362
347
|
values = list(value)
|
|
363
348
|
|
|
364
|
-
for i in range(
|
|
349
|
+
for i in range(repeat):
|
|
365
350
|
field_def_repeat = _repeated_field_def(field_def, i,
|
|
366
351
|
current_offset,
|
|
367
352
|
field_def.size)
|
|
368
|
-
resolved_size =
|
|
353
|
+
resolved_size = _resolve_info_size(field_def_repeat.size, env)
|
|
369
354
|
encode_field(field_def_repeat, values[i], buf, env, type_dict,
|
|
370
355
|
padding_alignment_bits)
|
|
371
356
|
env[field_def_repeat.name] = values[i]
|
|
@@ -410,14 +395,14 @@ def decode_field(
|
|
|
410
395
|
"""
|
|
411
396
|
if env is None:
|
|
412
397
|
env = {}
|
|
413
|
-
offset =
|
|
414
|
-
size =
|
|
398
|
+
offset = _resolve_info_size(field_def.offset, env)
|
|
399
|
+
size = _resolve_info_size(field_def.size, env)
|
|
415
400
|
if size.byte == 0 and size.bit == 0:
|
|
416
401
|
return None
|
|
417
402
|
info = bits_get(data, offset, size, scale=field_def.scale)
|
|
418
403
|
byte_swap = _resolve_byte_swap(field_def, env)
|
|
419
404
|
if byte_swap:
|
|
420
|
-
info =
|
|
405
|
+
info = info.byte_swap
|
|
421
406
|
resolved_type = _resolve_field_type(field_def.type, type_dict, env)
|
|
422
407
|
nested_value = None
|
|
423
408
|
if isinstance(resolved_type, StructDef):
|
|
@@ -526,22 +511,21 @@ def decode(
|
|
|
526
511
|
|
|
527
512
|
def append_padding_until(target_offset: InfoSize) -> None:
|
|
528
513
|
nonlocal current_position, padding_index
|
|
529
|
-
start_bits =
|
|
530
|
-
end_bits =
|
|
514
|
+
start_bits = current_position.bits
|
|
515
|
+
end_bits = target_offset.bits
|
|
531
516
|
if end_bits <= start_bits:
|
|
532
517
|
return
|
|
533
518
|
|
|
534
519
|
chunk_start_bits = start_bits
|
|
535
520
|
while chunk_start_bits < end_bits:
|
|
536
|
-
chunk_start =
|
|
537
|
-
bits_to_boundary =
|
|
538
|
-
chunk_start.align_to(padding_alignment_bits))
|
|
521
|
+
chunk_start = InfoSize(0, chunk_start_bits)
|
|
522
|
+
bits_to_boundary = chunk_start.align_to(padding_alignment_bits).bits
|
|
539
523
|
chunk_size_bits = bits_to_boundary or padding_alignment_bits
|
|
540
524
|
chunk_end_bits = min(end_bits, chunk_start_bits + chunk_size_bits)
|
|
541
525
|
padding_field_def = FieldDef(
|
|
542
526
|
name=f"padding[{padding_index}]",
|
|
543
|
-
offset=
|
|
544
|
-
size=
|
|
527
|
+
offset=InfoSize(0, chunk_start_bits),
|
|
528
|
+
size=InfoSize(0, chunk_end_bits - chunk_start_bits),
|
|
545
529
|
type="bytes",
|
|
546
530
|
description="Auto-generated padding",
|
|
547
531
|
)
|
|
@@ -554,9 +538,10 @@ def decode(
|
|
|
554
538
|
current_position = target_offset
|
|
555
539
|
|
|
556
540
|
for field_def in _as_field_defs(struct_def_obj):
|
|
541
|
+
repeat = _resolve_repeat(field_def.repeat, env)
|
|
557
542
|
# Handle non-repeated fields
|
|
558
|
-
if
|
|
559
|
-
resolved_offset =
|
|
543
|
+
if repeat is None or repeat <= 1:
|
|
544
|
+
resolved_offset = _resolve_info_size(field_def.offset, env)
|
|
560
545
|
append_padding_until(resolved_offset)
|
|
561
546
|
field_instance = decode_field(field_def, data, env, type_dict,
|
|
562
547
|
padding_alignment_bits)
|
|
@@ -564,12 +549,12 @@ def decode(
|
|
|
564
549
|
env[field_instance.field_def.name] = field_instance.value
|
|
565
550
|
result.append_field_instance(field_instance)
|
|
566
551
|
current_position = (resolved_offset +
|
|
567
|
-
|
|
552
|
+
_resolve_info_size(field_def.size, env))
|
|
568
553
|
continue
|
|
569
554
|
# Handle repeated fields
|
|
570
|
-
current_offset =
|
|
555
|
+
current_offset = _resolve_info_size(field_def.offset, env)
|
|
571
556
|
append_padding_until(current_offset)
|
|
572
|
-
for i in range(
|
|
557
|
+
for i in range(repeat):
|
|
573
558
|
field_def_repeat = _repeated_field_def(field_def, i, current_offset,
|
|
574
559
|
field_def.size)
|
|
575
560
|
field_instance = decode_field(field_def_repeat, data, env,
|
|
@@ -579,7 +564,7 @@ def decode(
|
|
|
579
564
|
result.append_field_instance(field_instance)
|
|
580
565
|
actual_size = field_instance.field_def.size
|
|
581
566
|
else:
|
|
582
|
-
actual_size =
|
|
567
|
+
actual_size = _resolve_info_size(field_def_repeat.size, env)
|
|
583
568
|
if isinstance(current_offset, InfoSize) and isinstance(
|
|
584
569
|
actual_size, InfoSize):
|
|
585
570
|
current_offset += actual_size
|
|
@@ -98,7 +98,7 @@ class FieldDef:
|
|
|
98
98
|
metadata={"desc": "The type of the field"})
|
|
99
99
|
scale: float = field(default=1.0,
|
|
100
100
|
metadata={"desc": "The scale of the field"})
|
|
101
|
-
repeat: int | None = field(
|
|
101
|
+
repeat: int | str | None = field(
|
|
102
102
|
default=None, metadata={"desc": "The repeat count of the field"})
|
|
103
103
|
description: str | None = field(
|
|
104
104
|
default=None, metadata={"desc": "The description of the field"})
|
|
@@ -231,7 +231,7 @@ class FieldDef:
|
|
|
231
231
|
self.name,
|
|
232
232
|
self._sortable_type(self.type),
|
|
233
233
|
self.scale,
|
|
234
|
-
|
|
234
|
+
self._sortable_repeat(self.repeat),
|
|
235
235
|
"" if self.description is None else self.description,
|
|
236
236
|
"" if self.range_expression is None else self.range_expression,
|
|
237
237
|
"" if self.enum_def_name is None else self.enum_def_name,
|
|
@@ -245,6 +245,15 @@ class FieldDef:
|
|
|
245
245
|
return (0, value.byte, value.bit)
|
|
246
246
|
return (1, value)
|
|
247
247
|
|
|
248
|
+
@staticmethod
|
|
249
|
+
def _sortable_repeat(value: int | str | None) -> tuple[int, int | str]:
|
|
250
|
+
"""Build a comparable key for static or expression repeat counts."""
|
|
251
|
+
if value is None:
|
|
252
|
+
return 0, -1
|
|
253
|
+
if isinstance(value, int):
|
|
254
|
+
return 1, value
|
|
255
|
+
return 2, value
|
|
256
|
+
|
|
248
257
|
@staticmethod
|
|
249
258
|
def _sortable_type(value: str | "StructDef") -> tuple[Any, ...]:
|
|
250
259
|
"""Build a comparable key for primitive or nested field types."""
|
|
@@ -7,7 +7,7 @@ from sltcore import InfoSize
|
|
|
7
7
|
from sltcodec import (PRIMITIVE_TYPES, EnumDef, FieldDef, FieldInstance,
|
|
8
8
|
StructDef, StructInstance, StructLayout, TypeDict, decode,
|
|
9
9
|
encode)
|
|
10
|
-
from sltcodec.codec import decode_field
|
|
10
|
+
from sltcodec.codec import _resolve_info_size, decode_field
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def layout_for(struct_def):
|
|
@@ -166,6 +166,38 @@ def test_encode_layout_handles_repeat():
|
|
|
166
166
|
]
|
|
167
167
|
|
|
168
168
|
|
|
169
|
+
def test_expression_repeat_uses_previous_field_value():
|
|
170
|
+
"""Test that repeat expressions are evaluated against the field env."""
|
|
171
|
+
seed_field = FieldDef(name="count",
|
|
172
|
+
offset=InfoSize(0, 0),
|
|
173
|
+
size=InfoSize(1, 0),
|
|
174
|
+
type="unsigned int")
|
|
175
|
+
repeated_field = FieldDef(name="value",
|
|
176
|
+
offset=InfoSize(1, 0),
|
|
177
|
+
size=InfoSize(1, 0),
|
|
178
|
+
type="unsigned int",
|
|
179
|
+
repeat="count + 1")
|
|
180
|
+
struct_def = StructDef(fields=[seed_field, repeated_field])
|
|
181
|
+
|
|
182
|
+
encoded = encode(
|
|
183
|
+
layout_for(struct_def),
|
|
184
|
+
StructInstance(
|
|
185
|
+
struct_def=struct_def,
|
|
186
|
+
field_instances=[
|
|
187
|
+
FieldInstance(seed_field, 2),
|
|
188
|
+
FieldInstance(repeated_field, [5, 6, 7]),
|
|
189
|
+
],
|
|
190
|
+
),
|
|
191
|
+
bytearray(),
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
assert encoded == bytearray(b"\x02\x05\x06\x07")
|
|
195
|
+
decoded = decode(layout_for(struct_def), encoded)
|
|
196
|
+
|
|
197
|
+
assert [instance.value
|
|
198
|
+
for instance in decoded.field_instances] == [2, 5, 6, 7]
|
|
199
|
+
|
|
200
|
+
|
|
169
201
|
def test_encode_recurses_for_nested_field_types():
|
|
170
202
|
"""Test that encoding a field with a nested field type works correctly."""
|
|
171
203
|
child_field_defs = [
|
|
@@ -608,6 +640,15 @@ def test_decode_field_sets_actual_size_on_field_instance():
|
|
|
608
640
|
assert decoded.field_def.size == InfoSize(1, 0)
|
|
609
641
|
|
|
610
642
|
|
|
643
|
+
def test_resolve_info_size_returns_expression_info_size_unchanged():
|
|
644
|
+
"""Test that expressions resolving to InfoSize preserve the result."""
|
|
645
|
+
info_size = InfoSize(2, 3)
|
|
646
|
+
|
|
647
|
+
resolved = _resolve_info_size("field_size", {"field_size": info_size})
|
|
648
|
+
|
|
649
|
+
assert resolved is info_size
|
|
650
|
+
|
|
651
|
+
|
|
611
652
|
def test_decode_struct_instance_size_matches_decoded_layout():
|
|
612
653
|
"""Test that decode reports the complete decoded layout size."""
|
|
613
654
|
field_def = FieldDef(name="value",
|
|
@@ -39,7 +39,7 @@ def test_field_def_to_json_from_json_round_trip():
|
|
|
39
39
|
size=InfoSize(1, 0),
|
|
40
40
|
type="unsigned int",
|
|
41
41
|
scale=2.0,
|
|
42
|
-
repeat=
|
|
42
|
+
repeat="count + 1",
|
|
43
43
|
description="A repeated value",
|
|
44
44
|
range_expression="0 <= value <= 255",
|
|
45
45
|
enum_def_name=enum_def.name)
|
|
@@ -48,6 +48,7 @@ def test_field_def_to_json_from_json_round_trip():
|
|
|
48
48
|
restored = FieldDef.from_json(payload)
|
|
49
49
|
|
|
50
50
|
assert restored == field_def
|
|
51
|
+
assert restored.repeat == "count + 1"
|
|
51
52
|
assert restored.range_expression == "0 <= value <= 255"
|
|
52
53
|
assert restored.enum_def_name == enum_def.name
|
|
53
54
|
assert restored.to_dict()["enum_def_name"] == "ValueKind"
|
|
@@ -65,16 +65,16 @@ wheels = [
|
|
|
65
65
|
|
|
66
66
|
[[package]]
|
|
67
67
|
name = "sltcalc"
|
|
68
|
-
version = "
|
|
68
|
+
version = "1.0.0"
|
|
69
69
|
source = { registry = "https://pypi.org/simple" }
|
|
70
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
70
|
+
sdist = { url = "https://files.pythonhosted.org/packages/b5/01/19db81d0e1f1330ab884abf282569b3f05ffe1f2c7b8aff910125295d4be/sltcalc-1.0.0.tar.gz", hash = "sha256:968053bbecc85c30caf5ddfd48962e409c7844ccfc441418d029a4f743030350", size = 10499, upload-time = "2026-08-18T14:38:14.052Z" }
|
|
71
71
|
wheels = [
|
|
72
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
72
|
+
{ url = "https://files.pythonhosted.org/packages/da/77/6d03b5c160ffe42bee2fdabdd46521033794fb02e8975b4da7a1f1c641de/sltcalc-1.0.0-py3-none-any.whl", hash = "sha256:12531fef9633b25e6743c4a41873971c83dffb763590f42e2f1f78accea08088", size = 4824, upload-time = "2026-08-18T14:38:13.247Z" },
|
|
73
73
|
]
|
|
74
74
|
|
|
75
75
|
[[package]]
|
|
76
76
|
name = "sltcodec"
|
|
77
|
-
version = "2.
|
|
77
|
+
version = "2.2.0"
|
|
78
78
|
source = { editable = "." }
|
|
79
79
|
dependencies = [
|
|
80
80
|
{ name = "sltcalc" },
|
|
@@ -88,7 +88,7 @@ dev = [
|
|
|
88
88
|
|
|
89
89
|
[package.metadata]
|
|
90
90
|
requires-dist = [
|
|
91
|
-
{ name = "sltcalc", specifier = ">=
|
|
91
|
+
{ name = "sltcalc", specifier = ">=1.0.0" },
|
|
92
92
|
{ name = "sltcore", specifier = ">=1.5.0" },
|
|
93
93
|
]
|
|
94
94
|
|
|
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
|
|
File without changes
|
|
File without changes
|