4.8.1. Field Model#
4.8.1.1. Standard Interface#
- class caterpillar.fields.Field(struct: ~caterpillar.abc._StructLike[~caterpillar.abc._IT, ~caterpillar.abc._OT] | ~caterpillar.abc._ContextLambda[~caterpillar.abc._OT] | ~caterpillar.abc._ContainsStruct[~caterpillar.abc._IT, ~caterpillar.abc._OT], order: ~caterpillar.abc._EndianLike | None = None, offset: ~caterpillar.abc._ContextLambda[int] | int = -1, flags: set[~caterpillar.abc._OptionLike] | None = None, amount: int | slice | ~types.EllipsisType | ~caterpillar.abc._ContextLambda[int] | None = None, options: ~caterpillar.abc._SwitchLambda | dict[~typing.Any, ~typing.Any] | None = None, condition: ~caterpillar.abc._ContextLambda[bool] | bool = True, arch: ~caterpillar.abc._ArchLike | None = None, default: object = <object object>, bits: ~caterpillar.abc._ContextLambda[int] | int | None = None)[source]#
Represents a field in a data structure.
- Parameters:
struct – The structure or callable used to define the field’s type.
order – Byte order for the field (default: SysNative).
offset – Field offset or callable (default: -1, meaning no explicit offset).
flags – Optional set of flags associated with the field.
amount – The number of elements if this field is a sequence.
options – A dictionary representing a switch-case mapping.
condition – A boolean or callable determining whether the field is active.
arch – Architecture specification (default: system_arch).
default – The default value (default: INVALID_DEFAULT).
bits – Bit size if the field is bit-packed.
- property struct: _StructLike[_IT, _OT] | _ContextLambda[_OT]#
The internal structure for this field.
- property condition: _ContextLambda[bool] | bool#
The field’s condition expression or value.
- property flags: set[_OptionLike]#
The set of flags associated with this field.
- add_flag(flag: _OptionLike) None[source]#
Adds a flag to this field.
- Parameters:
flag – The flag to add.
Added in version 2.6.0.
- has_flag(flag: _OptionLike[Any]) bool[source]#
Checks whether this field stores the given flag.
- Parameters:
flag (Flag) – the flag to lookup
- Returns:
true if this flag has been found
- Return type:
bool
- remove_flag(flag: _OptionLike) None[source]#
Removes a flag from this field.
- Parameters:
flag – The flag to remove.
Added in version 2.6.0.
- property offset: _ContextLambda[int] | int#
The field’s offset.
- property amount: int | slice | EllipsisType | _ContextLambda[int] | None#
The repetition count for this field.
- property options: _SwitchLambda | dict[Any, Any] | None#
The switch-case options dictionary.
- property order: _EndianLike#
- property arch: _ArchLike#
- _verify_context_value(value: object, expected: type | tuple[type, ...]) None[source]#
Verifies that a value is either of the expected type(s) or is a callable. Used to validate inputs for context-aware fields.
- Parameters:
value – The value to validate.
expected – A type or tuple of valid types.
- Raises:
TypeError – If validation fails.
- is_seq() bool[source]#
Returns whether this field is sequential.
- Returns:
whether this field is sequental
- Return type:
bool
- is_enabled(context: _ContextLike) bool[source]#
Evaluates the condition of this field.
- Parameters:
context (_ContextLike) – the context on which to operate
- Returns:
True, if this field is enabled- Return type:
bool
- length(context: _ContextLike) EllipsisType | slice | int[source]#
Calculates the sequence length of this field.
- Parameters:
context (_ContextLike) – the context on which to operate
- Raises:
DynamicSizeError – if this field has a dynamic size
- Returns:
the number of elements
- Return type:
Union[int, _GreedyType]
- get_struct(value: object, context: _ContextLike) _StructLike[_IT, _OT][source]#
Returns the struct from stored options.
- Parameters:
value (Any) – the unpacked or packed value
context (_ContextLike) – the current context
- Returns:
the struct that packs or unpacks the data
- Return type:
- class caterpillar.fields.FieldMixin[source]#
A simple mixin to support operators used to create
Fieldinstances.
- class caterpillar.fields.FieldStruct[source]#
A mix-in class combining the behavior of _StructLike with additional functionality for packing and unpacking structured data.
- pack_single(obj: _IT, context: _ContextLike) None[source]#
Abstract method to pack a single element.
- Parameters:
obj (Any) – The element to pack.
context (_ContextLike) – The current operation context.
- Raises:
NotImplementedError – This method must be implemented by subclasses.
- unpack_single(context: _ContextLike) _OT[source]#
Abstract method to unpack a single element.
- Parameters:
context (_ContextLike) – The current operation context.
- Raises:
NotImplementedError – This method must be implemented by subclasses.
- Returns:
The unpacked element.
- pack_seq(seq: Collection[_IT], context: _ContextLike) None[source]#
Pack a sequence of elements using the provided context.
- Parameters:
seq (Iterable) – The sequence of elements to pack.
context (_ContextLike) – The current operation context.
- unpack_seq(context: _ContextLike) Collection[_OT][source]#
Unpack a sequence of elements using the provided context.
- Parameters:
context (_ContextLike) – The current operation context.
- Returns:
The list of unpacked elements.
- __pack__(obj: _IT, context: _ContextLike) None[source]#
Pack data based on whether the field is sequential or not.
- Parameters:
obj (Any) – The data to pack.
context (_ContextLike) – The current operation context.
- __unpack__(context: _ContextLike) _OT[source]#
Unpack data based on whether the field is sequential or not.
- Parameters:
context (_ContextLike) – The current operation context.
- Returns:
The unpacked data.
- caterpillar.fields.get_args(args: _ContextLambda[Any] | Any | list[_ContextLambda[Any] | Any], context: _ContextLike) list[Any][source]#
Get arguments for an instance.
- Parameters:
args (Any) – Input arguments.
context (_ContextLike) – The current operation context.
- Returns:
A list of processed arguments.
- Return type:
list
- caterpillar.fields.get_kwargs(kwargs: dict[str, _ContextLambda[Any] | Any], context: _ContextLike) dict[str, Any][source]#
Process a dictionary of keyword arguments, replacing callable values with their results.
- Parameters:
kwargs (dict) – Dictionary of keyword arguments.
context (_ContextLike) – The current operation context.
- Returns:
A new dictionary with processed keyword arguments.
- Return type:
dict
4.8.1.2. Chains and Conditionals#
- class caterpillar.fields.Chain(initial: _StructLike[_ChainHeadT, Any], *structs: _StructLike[Any, Any], tail: _StructLike[bytes, _ChainTailT] | None = None)[source]#
Represents a chain of structures where each structure in the chain is linked to the next one, forming a sequence.
- Parameters:
initial – The initial structure in the chain.
structs – Additional structures to be added to the chain.
The chain allows packing and unpacking data through its elements in sequence.
Note
Unpacking travels from the head to the tail.
Packing travels from the tail to the head.
- __init__(initial: _StructLike[_ChainHeadT, Any], *structs: _StructLike[Any, Any], tail: _StructLike[bytes, _ChainTailT] | None = None) None[source]#
- property head: _StructLike[_ChainHeadT, Any]#
Get the head of the chain, i.e., the first structure.
- Returns:
The head of the chain.
- Return type:
- property tail: _StructLike[Any, _ChainTailT]#
Get the tail of the chain, i.e., the last structure.
- Returns:
The tail of the chain.
- Return type:
- __size__(context: _ContextLike) int[source]#
Calculate the size of the chain in bytes.
- Parameters:
context (_ContextLike) – The context for the calculation.
- Returns:
The size of the chain.
- Return type:
int
- __type__() type | str | None[source]#
Get the type of the tail structure in the chain.
- Returns:
The type of the tail structure.
- Return type:
type
- __and__(other: _StructLike[_IT, _OT]) Chain[_ChainHeadT, _OT][source]#
Concatenate another structure to the end of the chain.
- Parameters:
other (_StructLike) – The structure to concatenate.
- Returns:
The updated chain.
- Return type:
- __rand__(other: _StructLike[_IT, _ChainHeadT]) Chain[_IT, _ChainTailT][source]#
Concatenate another structure to the beginning of the chain.
- Parameters:
other (_StructLike) – The structure to concatenate.
- Returns:
The updated chain.
- Return type:
- unpack_single(context: _ContextLike) _ChainTailT[source]#
Unpack a single data instance from the chain.
- Parameters:
context (_ContextLike) – The context for the unpacking operation.
- Returns:
A memory view representing the unpacked data.
- Return type:
memoryview
- pack_single(obj: _IT, context: _ContextLike) None[source]#
Pack a single data instance into the chain.
- Parameters:
obj (Any) – The data to pack into the chain.
context (_ContextLike) – The context for the packing operation.
- class caterpillar.fields.ConditionalChain(struct: _StructLike, condition: _ContextLambda[bool] | bool)[source]#
Simplistic conditional chain that represents if-else statements.
Using this class we can introduce conditional statements into our class definition. While this class can’t be used in class definitions, it may be used outside of them.
For conditional statements in class definitions, see
If,ElseIforElse.
- class caterpillar.fields.If(condition: _ContextLambda[bool], depth: int = 2)[source]#
If-statement implementation for class definitions.
Changed in version 2.9.0: Python 3.14+ requires explicit conditional annotations using either
with If(condition) as when:withfield: f[type, field, when]for one field, inlineStart(when)/End(when)metadata for a block,field: when[...], or explicit invisible marker fields.@struct class Format: a: uint32 with If(lambda _: GLOBAL_CONSTANT == 33): b: uint8
Python 3.14+ supports type-checker-friendly per-field metadata:
@struct class Format: a: uint32 with If(lambda _: GLOBAL_CONSTANT == 33) as when: b: f[int, uint8, when]
It also supports inline block markers:
@struct class Format: a: uint32 with If(lambda _: GLOBAL_CONSTANT == 33) as when: b: f[int, uint8, Start(when)] c: uint8 d: f[int, uint8, End(when)]
Note that this class will alter the used fields and cover multiple field definitions. In addition, the type annotation will be modified to display the condition as well.
Note
This class is not a struct, but a simple context manager.
- class caterpillar.fields.ElseIf(*args: ConditionContext | _ContextLambda[bool] | bool)[source]#
ElseIf-statement implementation for class definitions.
Python <= 3.13 supports the legacy implicit form:
@struct class Format: a: uint32 with this.a == 32: ... with ElseIf(this.a == 34): ...
Python 3.14+ requires the explicit marker form:
@struct class Format: a: uint32 with If(this.a == 32) as first: one: f[int, uint8, first] with ElseIf(first, this.a == 34) as second: two: f[int, uint8, second]
- caterpillar.fields.Else = <caterpillar.fields.conditional._Else object>#
Else marker factory.
Changed in version 2.9.0: Python <= 3.13 supports
with Else:for legacy condition blocks. Python 3.14+ requireswith Else(previous) as when:withf[..., when]for one field orStart(when)/End(when)metadata for a block.
- class caterpillar.fields.Start(marker: _ConditionalAnnotation | ConditionContext | Start | End)[source]#
Start marker for an inline explicit conditional block.
Use this as metadata on the first real field in a Python 3.14+ conditional block:
with If(this.flag == 1) as when: first: f[int, uint8, Start(when)] second: f[int, uint8] last: f[int, uint8, End(when)]
Unlike the older invisible marker-field spelling, this does not add a synthetic field to the class body.
Added in version 2.9.0.
- class caterpillar.fields.End(marker: _ConditionalAnnotation | ConditionContext | Start | End)[source]#
End marker for an explicit conditional block.
Use this as metadata on the last real field in a Python 3.14+ inline marker block:
with If(this.flag == 1) as when: first: f[int, uint8, Start(when)] second: f[int, uint8] last: f[int, uint8, End(when)]
The older invisible marker-field spelling is still supported:
with If(this.flag == 1) as when: _: f[None, when] = Invisible() value: f[int, uint8] _end: f[None, End(when)] = Invisible()
Invisible marker fields are removed from the final struct model.
- class caterpillar.fields.Branch(*arms: When | Otherwise)[source]#
Conditional field chain for one attribute.
Use this when several conditions should decode or encode the same Python attribute with different field definitions.
@struct class Packet: tag: f[int, uint8] value: f[ int, Branch( When(this.tag == 1, uint8), When(this.tag == 2, uint16), Otherwise(uint8), ), ]
Arm annotations can use
f[...]to carry local options such as byte order.Added in version 2.9.0.
- class caterpillar.fields.When(condition: _ContextLambda[bool] | bool, annotation: str | bytes | type | _SupportsActionPack | _SupportsActionUnpack | _StructLike | Any)[source]#
One conditional arm for
Branch.- Parameters:
condition – Context expression controlling this arm.
annotation – Field annotation or struct selected when the condition evaluates to true.
Added in version 2.9.0.
- class caterpillar.fields.Otherwise(annotation: str | bytes | type | _SupportsActionPack | _SupportsActionUnpack | _StructLike | Any)[source]#
Fallback arm for
Branch.The fallback arm is selected when no earlier
Whencondition matched. A branch can contain at most one fallback arm, and it must appear last.Added in version 2.9.0.