4.5.2. Struct#
4.5.2.1. The Struct class#
- class caterpillar.model.Struct(model: type[_ModelT], order: _EndianLike | None = None, arch: _ArchLike | None = None, options: Iterable[_OptionLike] | None = None, field_options: Iterable[_OptionLike] | None = None, kw_only: bool = False, hook_cls: type[UnionHook[_ModelT]] | None = None)[source]#
Represents a structured data model for serialization and deserialization.
- Parameters:
model – The target class used as the base model.
order – Optional byte order for the fields in the structure.
arch – Global architecture definition (will be inferred on all fields).
options – Additional options specifying what to include in the final class.
4.5.2.2. Unions#
- caterpillar.model.union(cls: None = None, /, *, options: Iterable[_OptionLike] | None = None, order: _EndianLike | None = None, arch: _ArchLike | None = None, field_options: Iterable[_OptionLike] | None = None, kw_only: bool = False, hook_cls: type[UnionHook[_ModelT]] | None = None) Callable[[type[_ModelT]], type[_ModelT]][source]#
- caterpillar.model.union(cls: type[_ModelT], /, *, options: Iterable[_OptionLike] | None = None, order: _EndianLike | None = None, arch: _ArchLike | None = None, field_options: Iterable[_OptionLike] | None = None, kw_only: bool = False, hook_cls: type[UnionHook[_ModelT]] | None = None) type[_ModelT]
Decorator to create a Union class.
- Parameters:
cls – The target class used as the base model.
options – Additional options specifying what to include in the final class.
order – Optional configuration value for the byte order of a field.
arch – Global architecture definition (will be inferred on all fields).
- Returns:
The created Union class or a wrapper function if cls is not provided.
- class caterpillar.model.UnionHook(struct_: Struct[_ModelT])[source]#
Implementation of a hook to simulate union types.
It will hook two methods of the target model type:
__init__and__setattr__. Because the constructor calls setattr for each attribute in the model, we have to intercept it before it gets called to set an internal status.Internally, these two methods will be translated into
__model_init__()and__model_setattr__(). Therefore, any class that implements these two methods can be used as a union hook.- max_size: int#
The static (cached) maximum size of the union
4.5.2.3. Standard Interface#
- caterpillar.model.struct(ty: type[_ModelT] | None = None, kw_only: bool = False, options: Iterable[_OptionLike] | None = None, order: _EndianLike | None = None, arch: _ArchLike | None = None, field_options: Iterable[_OptionLike] | None = None) type[_ModelT] | Callable[[_ModelT], type[_ModelT]]#
Decorator or direct constructor for creating a
Structmodel.This method can be used either as:
A decorator:
@struct(...)A direct transformer:
MyStruct = struct(MyClass, ...)
The method configures structure-wide options such as byte order, architecture, and field-level behaviors, and returns a fully initialized model class.
>>> @struct(order=LittleEndian) ... class Format: ... field: f[int, uint32]
- Parameters:
ty (type[_ModelT] | None, optional) – The target class to be transformed into a Struct model. If None, a decorator function is returned
kw_only (bool, optional) – Whether generated dataclass fields should be keyword-only, defaults to False
options (Iterable[_OptionLike] | None, optional) – Additional options controlling structure behavior, defaults to None
order (_EndianLike | None, optional) – Global byte order configuration applied to all fields, defaults to None
arch (_ArchLike | None, optional) – Global architecture configuration inferred by fields, defaults to None
field_options (Iterable[_OptionLike] | None, optional) – Additional options applied at the field level, defaults to None
- Returns:
A transformed Struct model class, or a decorator if
tyis None- Return type:
type[_ModelT] | Callable[[_ModelT], type[_ModelT]]
- caterpillar.model.pack(obj: _ContainsStruct[_IT, _OT], struct: None = None, /, *, use_tempfile: bool = False, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, fill: int | bytes | str | None = None, **kwargs: Any) bytes[source]#
- caterpillar.model.pack(obj: object, struct: None = None, /, *, use_tempfile: bool = False, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, fill: int | bytes | str | None = None, **kwds: Any) bytes
- caterpillar.model.pack(obj: _IT, struct: _SupportsPack[_IT], /, *, use_tempfile: bool = False, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, fill: int | bytes | str | None = None, **kwargs: Any) bytes
- caterpillar.model.pack(obj: _IT, struct: type[_IT], /, *, use_tempfile: bool = False, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, fill: int | bytes | str | None = None, **kwargs: Any) bytes
Pack an object into a bytes buffer using the specified struct.
- Parameters:
obj – The object to pack.
struct – The struct to use for packing.
use_tempfile – Whether to use a temporary file for packing (experimental).
as_field – Whether to wrap the struct in a Field before packing.
fill – pattern to use when filling up space (only applied when fields with offsets are used)
arch – architecture to apply to the struct
order – byte order to apply
kwargs – Additional keyword arguments to pass to the context.
- Returns:
The packed bytes.
Changed in version 2.8.1: Added
fillparameter.
- caterpillar.model.pack_into(obj: _ContainsStruct[_IT, _OT], buffer: IOBase, struct: None = None, /, *, use_tempfile: bool = False, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, fill: int | bytes | str | None = None, **kwds: Any) None[source]#
- caterpillar.model.pack_into(obj: object, buffer: IOBase, struct: None = None, /, *, use_tempfile: bool = False, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, fill: int | bytes | str | None = None, **kwds: Any) None
- caterpillar.model.pack_into(obj: _IT, buffer: IOBase, struct: _SupportsPack[_IT], /, *, use_tempfile: bool = False, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, fill: int | bytes | str | None = None, **kwds: Any) None
- caterpillar.model.pack_into(obj: _IT, buffer: IOBase, struct: type[_IT], /, *, use_tempfile: bool = False, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, fill: int | bytes | str | None = None, **kwds: Any) None
- caterpillar.model.pack_into(obj: _IT, buffer: IOBase, struct: _ContainsStruct[_IT, _OT], /, *, use_tempfile: bool = False, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, fill: int | bytes | str | None = None, **kwds: Any) None
Pack an object into the specified buffer using the specified struct.
This function serializes an object (obj) into a given buffer, using a struct to define how the object should be packed. Optionally, the function can handle temporary files for packing, use a Field wrapper around the struct, and support additional keyword arguments. The packed data is written to the buffer.
Example 1: Packing an object into a bytes buffer
>>> buffer = BytesIO() >>> my_obj = SomeObject() # Assume SomeObject is a valid object to be packed >>> pack_into(my_obj, buffer, struct=SomeStruct()) # Using a specific struct >>> buffer.getvalue() b"..."
Example 2: Packing into a file-like stream (e.g., file)
>>> with open('packed_data.bin', 'wb') as f: ... pack_into(my_obj, f, struct=SomeStruct()) # Pack into a file
Example 3: Using as_field to wrap the struct in a Field before packing
>>> buffer = BytesIO() >>> pack_into(42, buffer, struct=uint8, as_field=True) >>> buffer.getvalue() b"\x2a"
- Parameters:
obj – The object to pack (could be a plain object or a structure-like object).
buffer – The buffer to pack the object into (a writable stream such as BytesIO or a file).
struct – The struct to use for packing. If not specified, will infer from obj.
use_tempfile – Whether to use a temporary file for packing (experimental).
as_field – Whether to wrap the struct in a Field before packing.
fill – pattern to use when filling up space (only applied when fields with offsets are used)
arch – architecture to apply to the struct
order – byte order to apply
kwds – Additional keyword arguments to pass to the context.
- Raises:
TypeError – If no struct is specified and cannot be inferred from the object.
Changed in version 2.8.1: Added
fillparameter.
- caterpillar.model.pack_file(obj: _ContainsStruct[_IT, _OT], filename: str, struct: None = None, /, *, use_tempfile: bool = False, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, fill: int | bytes | str | None = None, **kwds: Any) None[source]#
- caterpillar.model.pack_file(obj: object, filename: str, struct: None = None, /, *, use_tempfile: bool = False, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, fill: int | bytes | str | None = None, **kwds: Any) None
- caterpillar.model.pack_file(obj: _IT, filename: str, struct: _SupportsPack[_IT], /, *, use_tempfile: bool = False, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, fill: int | bytes | str | None = None, **kwds: Any) None
- caterpillar.model.pack_file(obj: _IT, filename: str, struct: type[_IT], /, *, use_tempfile: bool = False, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, fill: int | bytes | str | None = None, **kwds: Any) None
- caterpillar.model.pack_file(obj: _IT, filename: str, struct: _ContainsStruct[_IT, _OT], /, *, use_tempfile: bool = False, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, fill: int | bytes | str | None = None, **kwds: Any) None
Pack an object into a file using the specified struct.
- Parameters:
obj – The object to pack.
filename – The name of the file to write to.
struct – The struct to use for packing.
use_tempfile – Whether to use a temporary file for packing (experimental).
as_field – Whether to wrap the struct in a Field before packing.
fill – pattern to use when filling up space (only applied when fields with offsets are used)
arch – architecture to apply to the struct
order – byte order to apply
kwds – Additional keyword arguments to pass to the context.
- Returns:
None
Changed in version 2.8.1: Added
fillparameter.
- caterpillar.model.unpack(struct: _ContainsStruct[_IT, _OT], buffer: Buffer | IOBase, /, *, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, **kwds: Any) _OT[source]#
- caterpillar.model.unpack(struct: _SupportsUnpack[_OT], buffer: Buffer | IOBase, /, *, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, **kwds: Any) _OT
- caterpillar.model.unpack(struct: type[_OT], buffer: Buffer | IOBase, /, *, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, **kwds: Any) _OT
Unpack an object from a bytes buffer or stream using the specified struct.
This function takes a struct that defines how data should be unpacked, a buffer (either bytes or a stream) containing the serialized data, and returns the unpacked object. If as_field is set to True, the struct is wrapped by a Field. Additional keyword arguments are passed to the root context as attributes.
Example:
>>> buffer = b'\x00\x01\x02\x03' >>> struct = SomeStruct() >>> unpack(struct, buffer) ...
- Parameters:
struct – The struct to use for unpacking (could be a SupportsUnpack or ContainsStruct object).
buffer – The bytes buffer or stream to unpack from.
as_field – Whether to wrap the struct in a Field transformer before unpacking.
kwds – Additional keyword arguments to pass to the unpack function.
- Returns:
The unpacked object, which is the result of calling struct.__unpack__(context).
- Raises:
TypeError – If the struct is not a valid struct instance.
- caterpillar.model.unpack_file(struct: _ContainsStruct[_IT, _OT], filename: str, /, *, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, **kwds: Any) _OT[source]#
- caterpillar.model.unpack_file(struct: _SupportsUnpack[_OT], filename: str, /, *, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, **kwds: Any) _OT
- caterpillar.model.unpack_file(struct: type[_OT], filename: str, /, *, as_field: bool = False, order: _EndianLike | None = None, arch: _ArchLike | None = None, **kwds: Any) _OT
Unpack an object from a file using the specified struct.
- Parameters:
struct – The struct to use for unpacking.
filename – The name of the file to read from.
kwds – Additional keyword arguments to pass to the unpack function.
- Returns:
The unpacked object.
- caterpillar.model.sizeof(obj: _SupportsSize, **kwds: Any) int[source]#
- caterpillar.model.sizeof(obj: _ContainsStruct, **kwds: Any) int
- caterpillar.model.sizeof(obj: type, **kwds: Any) int
Changed in version 2.5.0: Now checks if the provided object implements the
_SupportsSizeprotocol
4.5.2.4. Struct Mixins#
- caterpillar.model.Invisible(*, init: bool = False, default: Any = None) Any[source]#
Create a dataclass field that is hidden from the generated constructor.
This helper returns a
dataclasses.fieldconfigured so that the associated attribute is not exposed as a parameter in the dataclass__init__method. It is primarily intended for use in@structdefinitions where certain fields (e.g., padding, metadata, or internally managed values) should exist in the structure layout but must not be user-provided during instantiation.When used, type checkers and IDEs will treat the field as non-existent from the constructor’s perspective, while the field still participates in the dataclass definition and underlying structure handling.
>>> @struct ... class Format: ... a: uint32_t ... b: f[bytes, b"const value"] = Invisible()
In this example, field
bis part of the structure definition but is not visible as an argument when constructingFormat.- Parameters:
init (bool, optional) – Whether the field should be included in the generated
__init__method. This is typically set toFalseto hide the field, defaults to Falsedefault (Any, optional) – Default value assigned to the field if not explicitly set, defaults to None
- Returns:
A configured
dataclasses.fieldinstance withkw_only=Trueand the specified visibility settings- Return type:
Any
- class caterpillar.model.StructDefMixin[source]#
Mixin providing convenience methods and typing support for
@structmodels.This mixin centralizes common wrapper functionality required by structure definitions so that individual model classes do not need to import or reference low-level packing and unpacking utilities directly.
It provides:
cls[...]support via__class_getitem__for defining repeated fields using the indexing operator.cls.from_bytes(...)for constructing instances from raw binary data.cls.from_file(...)for constructing instances from files.obj.to_bytes(...)for serializing instances back into binary form.
The primary purpose of this mixin is to improve ergonomics and satisfy static type checkers by exposing these behaviors directly on the model class rather than requiring explicit imports of
pack/unpackhelpers.- classmethod from_bytes(data: Buffer | IOBase, *, order: _EndianLike | None = None, arch: _ArchLike | None = None, **kwargs: Any) _ModelT[source]#
Construct an instance from raw binary data or a stream.
This is a convenience wrapper around the underlying
unpackfunction, allowing models to be instantiated directly from bytes without importing parsing utilities.- Parameters:
data (Buffer | _StreamType) – Raw bytes or a readable stream containing serialized data
order (_EndianLike | None, optional) – Endianness override for parsing, defaults to None
arch (_ArchLike | None, optional) – Architecture override for parsing, defaults to None
- Returns:
Parsed model instance
- Return type:
_ModelT
- classmethod from_file(filename: str, *, order: _EndianLike | None = None, arch: _ArchLike | None = None, **kwargs: Any) _ModelT[source]#
Construct an instance from a binary file on disk.
This is a convenience wrapper around
unpack_filefor reading and parsing structured data directly from a file path.- Parameters:
filename (str) – Path to the file containing serialized data
order (_EndianLike | None, optional) – Endianness override for parsing, defaults to None
arch (_ArchLike | None, optional) – Architecture override for parsing, defaults to None
- Returns:
Parsed model instance
- Return type:
_ModelT
- to_bytes(*, fp: IOBase, order: _EndianLike | None = None, arch: _ArchLike | None = None, use_tempfile: bool = False, **kwargs: Any) None[source]#
- to_bytes(*, fp: None = None, order: _EndianLike | None = None, arch: _ArchLike | None = None, use_tempfile: bool = False, **kwargs: Any) bytes
Serialize the instance into its binary representation.
If
fpis provided, the binary data is written directly into the given stream usingpack_into. Otherwise, the binary data is returned as abytesobject usingpack.- Parameters:
fp (_StreamType | None, optional) – Writable stream to receive the serialized data. If None, the serialized bytes are returned, defaults to None
order (_EndianLike | None, optional) – Endianness override for serialization, defaults to None
arch (_ArchLike | None, optional) – Architecture override for serialization, defaults to None
use_tempfile (bool, optional) – Whether to use a temporary file during packing, defaults to False
- Returns:
Serialized bytes if
fpis None, otherwise None- Return type:
bytes | None
- class caterpillar.model.struct_factory[source]#
Factory responsible for converting plain classes into
@structmodels.This factory provides decorator-style and direct-call APIs for transforming a regular class definition into a fully configured
Structmodel. The resulting class gains dataclass semantics and structure metadata.- mixin#
alias of
StructDefMixin
- static new(ty: type[_ModelT], kw_only: Literal[False] = False, options: Iterable[_OptionLike] | None = None, order: _EndianLike | None = None, arch: _ArchLike | None = None, field_options: Iterable[_OptionLike] | None = None) type[_ModelT][source]#
- static new(ty: type[_ModelT], kw_only: Literal[True] = True, options: Iterable[_OptionLike] | None = None, order: _EndianLike | None = None, arch: _ArchLike | None = None, field_options: Iterable[_OptionLike] | None = None) type[_ModelT]
- static new(ty: None = None, kw_only: Literal[False] = False, options: Iterable[_OptionLike] | None = None, order: _EndianLike | None = None, arch: _ArchLike | None = None, field_options: Iterable[_OptionLike] | None = None) Callable[[_ModelT], type[_ModelT]]
- static new(ty: None = None, kw_only: Literal[True] = True, options: Iterable[_OptionLike] | None = None, order: _EndianLike | None = None, arch: _ArchLike | None = None, field_options: Iterable[_OptionLike] | None = None) Callable[[_ModelT], type[_ModelT]]
Decorator or direct constructor for creating a
Structmodel.This method can be used either as:
A decorator:
@struct(...)A direct transformer:
MyStruct = struct(MyClass, ...)
The method configures structure-wide options such as byte order, architecture, and field-level behaviors, and returns a fully initialized model class.
>>> @struct(order=LittleEndian) ... class Format: ... field: f[int, uint32]
- Parameters:
ty (type[_ModelT] | None, optional) – The target class to be transformed into a Struct model. If None, a decorator function is returned
kw_only (bool, optional) – Whether generated dataclass fields should be keyword-only, defaults to False
options (Iterable[_OptionLike] | None, optional) – Additional options controlling structure behavior, defaults to None
order (_EndianLike | None, optional) – Global byte order configuration applied to all fields, defaults to None
arch (_ArchLike | None, optional) – Global architecture configuration inferred by fields, defaults to None
field_options (Iterable[_OptionLike] | None, optional) – Additional options applied at the field level, defaults to None
- Returns:
A transformed Struct model class, or a decorator if
tyis None- Return type:
type[_ModelT] | Callable[[_ModelT], type[_ModelT]]
- static make_struct(ty: type[_ModelT], options: Iterable[_OptionLike] | None = None, order: _EndianLike | None = None, arch: _ArchLike | None = None, field_options: Iterable[_OptionLike] | None = None, kw_only: bool = False, hook_cls: type[UnionHook[_ModelT]] | None = None) type[_ModelT][source]#
Internal helper that performs the actual Struct model creation.
This method instantiates a
Structobject using the provided configuration and returns the generated model class.- Parameters:
ty (type[_ModelT]) – The base class to transform into a Struct model
options (Iterable[_OptionLike] | None, optional) – Additional options controlling structure behavior, defaults to None
order (_EndianLike | None, optional) – Global byte order configuration applied to all fields, defaults to None
arch (_ArchLike | None, optional) – Global architecture configuration inferred by fields, defaults to None
field_options (Iterable[_OptionLike] | None, optional) – Additional options applied at the field level, defaults to None
kw_only (bool, optional) – Whether generated dataclass fields should be keyword-only, defaults to False
hook_cls (type["UnionHook[_ModelT]"] | None, optional) – Optional hook class for union handling, defaults to None
- Returns:
The generated Struct model class
- Return type:
type[_ModelT]