Skip to content

Commit 37bd976

Browse files
cleanup
1 parent 7c28f1e commit 37bd976

11 files changed

Lines changed: 48 additions & 96 deletions

File tree

demo/DemoMessage.1.0.dsdl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
# DemoMessage.1.0.dsdl
2-
# Self-contained demo type for serialization/deserialization demonstration
1+
# A simple demo type.
32

43
bool flag
54
uint32 counter
65
float64 temperature
76
float32[4] numeric_data
87
uint8[<=256] text_data # UTF-8 encoded text data
9-
uint8[<=64] binary_data # Raw binary data
8+
byte[<=64] binary_data # Raw binary data
109

1110
@extent 1024 * 8

demo/demo_serdes.py

100644100755
Lines changed: 16 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,59 @@
11
#!/usr/bin/env python3
22
"""
3-
Self-contained demo of pydsdl serialization and deserialization.
4-
5-
Demonstrates the complete workflow:
6-
1. Load a custom DSDL type using read_files()
7-
2. Create an object using the representation convention (dict, list, str, bytes, primitives)
8-
3. Serialize the object to bytes
9-
4. Deserialize the bytes back to an object
10-
5. Verify roundtrip equality
3+
Self-contained demo of PyDSDL serialization.
114
"""
125

136
import pydsdl
147
from pathlib import Path
158

9+
SCRIPT_DIR = Path(__file__).parent
10+
DSDL_FILE = SCRIPT_DIR / "DemoMessage.1.0.dsdl"
1611

17-
def main() -> None:
18-
SCRIPT_DIR = Path(__file__).parent
19-
DSDL_FILE = SCRIPT_DIR / "DemoMessage.1.0.dsdl"
20-
21-
print("=" * 70)
22-
print("PyDSDL Serialization/Deserialization Demo")
23-
print("=" * 70)
2412

25-
print("\n[Step 1] Loading DSDL type from:", DSDL_FILE.name)
26-
13+
def main() -> None:
14+
print("Loading DSDL type from:", DSDL_FILE.name)
2715
types, _ = pydsdl.read_files(
2816
dsdl_files=DSDL_FILE,
2917
root_namespace_directories_or_names=SCRIPT_DIR,
30-
lookup_directories=[]
18+
lookup_directories=[],
3119
)
32-
3320
schema = types[0]
3421
print(f"✓ Loaded type: {schema.full_name} v{schema.version.major}.{schema.version.minor}")
3522
print(f" Fields: {[f.name for f in schema.fields_except_padding]}")
3623

37-
print("\n[Step 2] Creating example object")
38-
print(" Representation convention: dict→struct, list→array, primitives as-is")
24+
print("Creating example object:")
3925
obj = {
4026
"flag": True,
4127
"counter": 42,
4228
"temperature": 23.5,
43-
"numeric_data": [1.0, 2.0, 3.0, 4.0],
44-
"text_data": list("Hello, SerDes!".encode("utf-8")),
45-
"binary_data": [0x00, 0x01, 0x02, 0x03]
29+
"numeric_data": [1.0, 2.0, 3, 4],
30+
"text_data": "Hello, SerDes!",
31+
"binary_data": b"\x00\x01\x02\x03",
4632
}
47-
48-
print(" Object structure:")
4933
for key, value in obj.items():
5034
value_repr = repr(value)
5135
if len(value_repr) > 50:
5236
value_repr = value_repr[:47] + "..."
5337
print(f" {key:15} = {value_repr} ({type(value).__name__})")
5438

55-
print("\n[Step 3] Serializing object to bytes")
39+
print("Serializing object to bytes")
5640
serialized_data = pydsdl.serialize(schema, obj)
57-
print(f"✓ Serialized to {len(serialized_data)} bytes")
58-
print(f" Hex: {serialized_data.hex()}")
41+
print(f"✓ Serialized to {len(serialized_data)} bytes:")
42+
print(f" {serialized_data.hex()}")
5943

60-
print("\n[Step 4] Deserializing bytes back to object")
44+
print("Deserializing bytes back to object")
6145
deserialized = pydsdl.deserialize(schema, serialized_data)
62-
print("✓ Deserialized successfully")
63-
print(" Deserialized structure:")
46+
print("✓ Deserialized successfully:")
6447
for key, value in deserialized.items():
6548
value_repr = repr(value)
6649
if len(value_repr) > 50:
6750
value_repr = value_repr[:47] + "..."
6851
print(f" {key:15} = {value_repr} ({type(value).__name__})")
6952

70-
print("\n[Step 5] Verifying roundtrip equality")
53+
print("Verifying roundtrip equality")
7154
assert obj == deserialized, "Roundtrip failed! Objects don't match."
7255
print("✓ Roundtrip verification passed: Original == Deserialized")
7356

74-
print("\n" + "=" * 70)
75-
print("Demo completed successfully!")
76-
print("=" * 70)
77-
7857

7958
if __name__ == "__main__":
8059
main()

docs/pages/pydsdl.rst

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,44 +15,18 @@ You can find a practical usage example in the Nunavut code generation library th
1515
The main functions
1616
++++++++++++++++++
1717

18+
DSDL parsing frint-end:
19+
1820
.. autofunction:: pydsdl.read_namespace
1921
.. autofunction:: pydsdl.read_files
2022

21-
22-
Serialization
23-
+++++++++++++
24-
25-
PyDSDL provides built-in serialization and deserialization functions for binary encoding/decoding
26-
of DSDL types without code generation.
23+
Data (de)serialization:
2724

2825
.. autofunction:: pydsdl.serialize
2926
.. autofunction:: pydsdl.deserialize
3027

31-
Object Representation Convention
32-
---------------------------------
33-
34-
Deserialized objects use Python primitives:
35-
36-
- **Composites (StructureType)**: ``dict[str, Any]`` with field names as keys
37-
- **Unions (UnionType)**: ``dict`` with exactly one key (the active variant)
38-
- **Arrays (Fixed/Variable)**: ``list``
39-
- **UTF-8 arrays**: ``str``
40-
- **Byte arrays**: ``bytes``
41-
- **Primitives**: ``bool``, ``int``, ``float``
42-
- **Void**: ``None`` (skipped in output)
43-
44-
Example::
45-
46-
obj = {"flag": True, "values": [1, 2, 3], "text": "hello"}
47-
data = pydsdl.serialize(schema, obj)
48-
reconstructed = pydsdl.deserialize(schema, data)
49-
assert obj == reconstructed
50-
5128
See ``demo/demo_serdes.py`` for a complete working example.
5229

53-
.. autoexception:: pydsdl.SerDesError
54-
:show-inheritance:
55-
5630

5731
Type model
5832
++++++++++
@@ -88,6 +62,12 @@ Exceptions
8862
:show-inheritance:
8963
:special-members:
9064

65+
.. autoexception:: pydsdl.SerDesError
66+
:undoc-members:
67+
:no-inherited-members:
68+
:show-inheritance:
69+
:special-members:
70+
9171
.. autoexception:: pydsdl.InternalError
9272
:undoc-members:
9373
:no-inherited-members:

pydsdl/__init__.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@
3131

3232
# Error model.
3333
from ._error import Error as Error
34-
from ._error import FrontendError as FrontendError
3534
from ._error import InvalidDefinitionError as InvalidDefinitionError
3635
from ._error import InternalError as InternalError
3736

37+
# Deprecated compatibility alias, to be removed.
38+
FrontendError = Error
39+
3840
# Data type model - meta types.
3941
from ._serializable import SerializableType as SerializableType
4042
from ._serializable import PrimitiveType as PrimitiveType
@@ -80,9 +82,5 @@
8082
from ._serdes import serialize as serialize
8183
from ._serdes import deserialize as deserialize
8284
from ._serdes import SerDesError as SerDesError
83-
from ._serdes import ArrayLengthError as ArrayLengthError
84-
from ._serdes import UnionFieldError as UnionFieldError
85-
from ._serdes import UnionTagError as UnionTagError
86-
from ._serdes import DelimiterHeaderError as DelimiterHeaderError
8785

8886
_sys.path = _original_sys_path

pydsdl/_dsdl_definition.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from . import _parser
1212
from ._data_type_builder import DataTypeBuilder, UndefinedDataTypeError
1313
from ._dsdl import DefinitionVisitor, ReadableDSDLFile
14-
from ._error import FrontendError, InternalError, InvalidDefinitionError
14+
from ._error import Error, InternalError, InvalidDefinitionError
1515
from ._serializable import CompositeType, Version
1616

1717
_logger = logging.getLogger(__name__)
@@ -275,7 +275,7 @@ def read(
275275
self._cached_type.fixed_port_id,
276276
)
277277
return self._cached_type
278-
except FrontendError as ex: # pragma: no cover
278+
except Error as ex: # pragma: no cover
279279
ex.set_error_location_if_unknown(path=self.file_path)
280280
raise ex
281281
except (MemoryError, SystemError): # pragma: no cover

pydsdl/_error.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,6 @@ def __repr__(self) -> str:
7171
return self.__class__.__name__ + ": " + repr(self.__str__())
7272

7373

74-
# Backward compatibility alias
75-
FrontendError = Error
76-
77-
7874
class InternalError(Error):
7975
"""
8076
This exception is used to report internal errors in the front end itself that prevented it from
@@ -138,7 +134,7 @@ def _unittest_error() -> None:
138134
def _unittest_internal_error_github_reporting() -> None:
139135
try:
140136
raise InternalError(path=Path("FILE_PATH"), line=42)
141-
except FrontendError as ex:
137+
except Error as ex:
142138
assert ex.path == Path("FILE_PATH")
143139
assert ex.line == 42
144140
assert str(ex) == "FILE_PATH:42: "
@@ -147,13 +143,13 @@ def _unittest_internal_error_github_reporting() -> None:
147143
try:
148144
try: # TRY HARDER
149145
raise InternalError(text="BASE TEXT", culprit=Exception("ERROR TEXT"))
150-
except FrontendError as ex:
146+
except Error as ex:
151147
ex.set_error_location_if_unknown(path=Path("FILE_PATH"))
152148
raise
153-
except FrontendError as ex:
149+
except Error as ex:
154150
ex.set_error_location_if_unknown(line=42)
155151
raise
156-
except FrontendError as ex:
152+
except Error as ex:
157153
print(ex)
158154
assert ex.path == Path("FILE_PATH")
159155
assert ex.line == 42
@@ -168,5 +164,5 @@ def _unittest_internal_error_github_reporting() -> None:
168164

169165
try:
170166
raise InternalError(text="BASE TEXT", path=Path("FILE_PATH"))
171-
except FrontendError as ex:
167+
except Error as ex:
172168
assert str(ex) == "FILE_PATH: BASE TEXT"

pydsdl/_namespace.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ def read_namespace(
112112
version (newest version first). The ordering guarantee allows the caller to always find the newest version
113113
simply by picking the first matching occurrence.
114114
115-
:raises: :class:`pydsdl.FrontendError`, :class:`MemoryError`, :class:`SystemError`,
115+
:raises: :class:`pydsdl.Error`, :class:`MemoryError`, :class:`SystemError`,
116116
:class:`OSError` if directories do not exist or inaccessible,
117117
:class:`ValueError`/:class:`TypeError` if the arguments are invalid.
118118
"""
@@ -250,7 +250,7 @@ def read_files(
250250
fields that provide links back to the filesystem where the dsdl files were located when parsing the type;
251251
``source_file_path`` and ``source_file_path_to_root``.
252252
253-
:raises: :class:`pydsdl.FrontendError`, :class:`MemoryError`, :class:`SystemError`,
253+
:raises: :class:`pydsdl.Error`, :class:`MemoryError`, :class:`SystemError`,
254254
:class:`OSError` if directories do not exist or inaccessible,
255255
:class:`ValueError`/:class:`TypeError` if the arguments are invalid.
256256
"""
@@ -366,7 +366,7 @@ def _construct_lookup_directories_path_list(
366366
367367
:return: A list of lookup directories as paths.
368368
369-
:raises: :class:`pydsdl.FrontendError`, :class:`MemoryError`, :class:`SystemError`,
369+
:raises: :class:`pydsdl.Error`, :class:`MemoryError`, :class:`SystemError`,
370370
:class:`OSError` if directories do not exist or inaccessible,
371371
:class:`ValueError`/:class:`TypeError` if the arguments are invalid.
372372
"""

pydsdl/_namespace_reader.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
from ._dsdl import DefinitionVisitor, DSDLFile, ReadableDSDLFile, PrintOutputHandler, SortedFileList
1313
from ._dsdl import file_sort as dsdl_file_sort
14-
from ._error import FrontendError, InternalError
14+
from ._error import Error, InternalError
1515
from ._serializable._composite import CompositeType
1616

1717

@@ -69,7 +69,7 @@ def print_handler(file: Path, line: int, message: str) -> None:
6969
functools.partial(print_handler, target_definition.file_path),
7070
allow_unregulated_fixed_port_id,
7171
)
72-
except FrontendError as ex: # pragma: no cover
72+
except Error as ex: # pragma: no cover
7373
ex.set_error_location_if_unknown(path=target_definition.file_path)
7474
raise ex
7575
except Exception as ex: # pragma: no cover

pydsdl/_parser.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def parse(text: str, statement_stream_processor: "StatementStreamProcessor", *,
2929
pr = _ParseTreeProcessor(statement_stream_processor, strict=strict)
3030
try:
3131
pr.visit(_get_grammar().parse(text)) # type: ignore
32-
except _error.FrontendError as ex:
32+
except _error.Error as ex:
3333
# Inject error location. If this exception is being propagated from a recursive instance, it already has
3434
# its error location populated, so nothing will happen here.
3535
ex.set_error_location_if_unknown(line=pr.current_line_number)
@@ -132,7 +132,7 @@ class _ParseTreeProcessor(parsimonious.NodeVisitor):
132132

133133
# Intentional exceptions that shall not be treated as parse errors.
134134
# Beware that those might be propagated from recursive parser instances!
135-
unwrapped_exceptions = (_error.FrontendError, SystemError, MemoryError, SystemExit) # type: ignore
135+
unwrapped_exceptions = (_error.Error, SystemError, MemoryError, SystemExit) # type: ignore
136136

137137
def __init__(self, statement_stream_processor: StatementStreamProcessor, *, strict: bool):
138138
assert isinstance(statement_stream_processor, StatementStreamProcessor)

pydsdl/_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,7 @@ def standalone(rel_path: str, definition: str, allow_unregulated: bool = False)
656656
"""
657657
),
658658
)
659-
except _error.FrontendError as ex:
659+
except _error.Error as ex:
660660
assert ex.path and ex.path.parts[-3:] == ("vendor", "types", "A.1.0.dsdl")
661661
assert ex.line and ex.line == 4
662662
else: # pragma: no cover

0 commit comments

Comments
 (0)