Add declarative syntax#161
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #161 +/- ##
======================================
Coverage 0.00% 0.00%
======================================
Files 22 23 +1
Lines 2773 2999 +226
======================================
- Misses 2773 2999 +226
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Merging this PR will improve performance by 12.19%
Performance Changes
Tip Curious why this is faster? Comment Comparing |
There was a problem hiding this comment.
Pull request overview
Adds an optional “declarative” API for defining cstruct Structure/Union types using Python class syntax + type annotations, while keeping parity with existing cstruct behavior and allowing either auto-created or user-supplied cstruct instances.
Changes:
- Introduces
dissect.cstruct.declarativewithStruct/Unionbases, unbound type references (e.g.uint32,uint8[4]), pointer/array helpers, andfield(...)specs (includingtyping.Annotatedsupport). - Extends array subscripting (
Type[...]) to accept string expressions (converted toExpression) for declarative string parsing. - Adds comprehensive tests for the declarative feature and updates Ruff per-file ignores for the new test module.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
dissect/cstruct/declarative.py |
New declarative structure/union definition layer built on annotations + metaclasses. |
dissect/cstruct/types/base.py |
Allows __getitem__ array sizes to be provided as str expressions (parsed as Expression). |
dissect/cstruct/__init__.py |
Exposes declarative Struct and field in the public package API. |
tests/test_declarative.py |
Adds test coverage for declarative structs/unions, forward refs, pointers, arrays, Annotated, alignment, etc. |
pyproject.toml |
Adds Ruff per-file ignores needed for declarative syntax test coverage. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
310e4a0 to
23a40d8
Compare
Miauwkeru
left a comment
There was a problem hiding this comment.
Some remarks when trying out to use this declarative version.
Currently the Struct instance will fail when you try to use dumps, print or initializing the structure.
Using the Header struct from the example, using it like this. it complains about the endianess of the attached cstruct instance, which doesn't exist.
E.g:
Header().dumps()Header(b"heey0102")
Adding a cstruct instance in the class definition class Header(..., cs=cs): ... it cannot find the __fields__ attribute of the Struct.
Another thing I noticed is with an empty Struct instance, (e.g. Header()) where it creates an attribute error with the magic and version attributes.
Trying to print this Header instance will result into another error where it cannot find the fields attribute.
|
|
||
| A structure may reference itself through a pointer (``next: pointer["Node"]`` or ``next: "Node*"``); | ||
| directly embedding a structure in itself is an error. Subclassing a concrete structure extends it: | ||
| the subclass inherits the fields of its parent, followed by its own. |
There was a problem hiding this comment.
shouldn't there also be a note like in https://github.com/fox-it/flow.record/blob/d50435feffc7e13eb3a636e995a27e3e3418eeda/flow/record/declarative.py#L43 for ruff not put the Annotation and field things underneath TYPE_CHECKING?
This adds an optional declarative syntax for structure definitions, for when you want to write structures in a more Pythonic syntax.
Or to bring-your-own-cstruct:
The resulting classes are proper subclasses of
Structureand have all the same behavior as regular cstruct structures.