4.5.3. Bitfield#
Changed in version 2.5.0: New revised concept since v2.5.0.
Each Bitfield instance maintains a sequence of bitfield groups, where each group contains a collection of sized fields. A bitfield group may consist of either multiple entries (i.e., any types that can be converted to an integral type) or a single _StructLike object. For example, consider the following bitfield definition:
@bitfield
class Format:
a1: 1
a2: 1 - boolean
_ : 0
b1: char
c1: uint32
This Bitfield definition will generate three distinct bitfield groups (labeled here as groups a, b, and c). By default, bitfields use 8-bit alignment, leading to the following layout:
Group Pos Bits
a 0x00 8
b 0x01 8
c 0x02 32
Internally, only the first group requires special bit-level parsing. The remaining groups (b and c) are treated as standard structures since they span full bytes or words without sub-byte alignment. This dynamic grouping mechanism allows leveraging full struct-like class definitions within bitfields.
This new approach enables more complex and expressive bitfield definitions. The annotation syntax is therefore extended as follows:
+---------------------------------------------------+--------------------------------------+
1.| <name> : <bits> [ - <field> ] | Standard field with optional type |
+---------------------------------------------------+--------------------------------------+
2.| <name> : 0 | Aligns to the next byte boundary |
+---------------------------------------------------+--------------------------------------+
3.| <name> : <field> | Struct-like field (no bits consumed) |
+---------------------------------------------------+--------------------------------------+
4.| <name> : (<field>,<factory>) | Field with custom type factory |
+---------------------------------------------------+--------------------------------------+
5.| <name> : (<bits>,<factory>[,<options>]) | bits with custom type factory |
| : (<bits>,[<options>]) | and options |
+---------------------------------------------------+--------------------------------------+
4.5.3.1. Main Interface#
- class caterpillar.model.Bitfield(model: type[_VT], order: _EndianLike | None = None, arch: _ArchLike | None = None, options: Iterable[_OptionLike] | None = None, field_options: Iterable[_OptionLike] | None = None, alignment: int | None = None)[source]#
A Bitfield represents a packed structure composed of bit-level fields. This class allows for the declarative definition of compact memory representations where each field can occupy an arbitrary number of bits, not necessarily aligned to byte boundaries.
Core Implementation: - Bitfields are organized into BitfieldGroups, which manage alignment and field aggregation. - Entries can be individual bit widths or wrapped fields with explicit alignment. - Special field options like NewGroup and EndGroup can control group layout. - Supports value factories for type conversion and symbolic runtime actions.
Available global options: -
B_NO_AUTO_BOOL: disables automatically converting 1bit fields to boolean -B_GROUP_KEEP: disables finalizing groups when using the alignment definition syntax- Parameters:
model (Any) – The model for the structure.
order (Optional[str]) – Byte order of the structure.
arch (Optional[str]) – Target architecture.
options (Optional[set]) – Global structure options.
field_options (Optional[set]) – Field-specific options.
alignment (Optional[int]) – Bit alignment size.
Changed in version 2.5.0: Updated concept. See the Bit-field reference for more information.
- class caterpillar.model.BitfieldGroup(bit_count: int)[source]#
A group of one or more bitfield entries. Groups are used to organize fields within a single alignment unit and may represent either packed fields or standalone fields.
- Parameters:
bit_count (int) – The number of bits in the group, or -1 for single field representation.
Changed in version 2.5.0: Renamed from
BitFieldGrouptoBitfieldGroup- is_field() bool[source]#
Determine whether the group contains a single non-bitfield field.
- Returns:
True if the group holds a single struct-like field.
- Return type:
bool
- get_field() Field[source]#
Get the single field from this group.
- Returns:
The field object.
- Return type:
- set_field(field: BitfieldEntry | Field)[source]#
Set the group to hold only the given field and mark it as a standalone field group.
- Parameters:
field (BitfieldEntry) – The field to store in this group.
- align_to(alignment: int)[source]#
Align the bit count of this group to the specified boundary.
- Parameters:
alignment (int) – The number of bits to align to.
- is_empty() bool[source]#
Check if the group contains any entries.
- Returns:
True if the group is empty.
- Return type:
bool
- class caterpillar.model.BitfieldEntry(bit: int, width: int, name: str, factory: BitfieldValueFactory | type[BitfieldValueFactory] | None = None, action: _SupportsActionPack | _SupportsActionUnpack | None = None)[source]#
Represents a single entry in a bitfield, including its bit position, width, name, and conversion behavior.
May also represent a special action or directive instead of a field.
- Parameters:
bit (int) – The starting bit position within its group.
width (int) – The number of bits used by this field.
name (str) – The name of the field.
factory (type or BitfieldValueFactory or None) – A factory for type conversion. Defaults to BitfieldValueFactory.
action (Any) – Optional action object for special handling (e.g., alignment or padding).
Added in version 2.5.0.
- static new_action(action: _SupportsActionPack | _SupportsActionUnpack) BitfieldEntry[source]#
Create a new action-type entry (e.g., padding, control directive).
- Parameters:
action (Any) – The action object to encapsulate.
- Returns:
A BitfieldEntry instance with no bit-width, used for meta instructions.
- Return type:
- caterpillar.model.getbits(obj: object) int[source]#
Retrieve the bit-width of a given object.
This function checks for a
__bits__()attribute on the object. The object must either implement the_SupportsBitsor_ContainsBitsprotocol.>>> class A: ... __bits__ = 3 ... >>> a = A() >>> getbits(a) 3
- Parameters:
obj (Any) – The object for which the bit-width should be determined. It is expected to have an
ATTR_BITSattribute.- Returns:
The number of bits used by the object.
- Return type:
int
- Raises:
AttributeError – If the object does not have an attribute defined by
ATTR_BITS.
- caterpillar.model.issigned(obj: object) bool[source]#
Determine whether a given object represents a signed field.
- Parameters:
obj (Any) – The object for which signedness should be determined.
- Returns:
Trueif the field is marked as signed,Falseotherwise.- Return type:
bool
- caterpillar.model.bitfield(ty: type[_VT] | None = None, /, *, order: _EndianLike | None = None, arch: _ArchLike | None = None, options: Iterable[_OptionLike] | None = None, field_options: Iterable[_OptionLike] | None = None, alignment: int | None = None) type[_VT] | Callable[[type[_VT]], type[_VT]]#
Decorator or direct transformer for creating a
Bitfieldmodel.This method can be used either as:
A decorator:
@bitfield(...)A direct transformer:
MyBitfield = bitfield(MyClass, ...)
It enables defining compact bit-level layouts using standard class syntax while preserving dataclass semantics and static type checking.
>>> from caterpillar.py import bitfield, SetAlignment, uint16 >>> @bitfield ... class Packet: ... version : 3 ... type : (5, SetAlignment(16)) ... length : 10 ... _ : 0 # align to 16bits ... payload : uint16 ... >>> # You can now pack/unpack Packet instances as compact binary bitfields >>> pkt = Packet(version=1, type=2, length=128, payload=0xABCD) >>> packed = pack(pkt) >>> unpacked = unpack(Packet, packed)
- Parameters:
ty (type[_VT] | None, optional) – The user-defined class to transform. If None, a decorator function is returned
order (_EndianLike | None, optional) – Byte order used during serialization, defaults to None
arch (_ArchLike | None, optional) – Architecture configuration inferred by fields, defaults to None
options (Iterable[_OptionLike] | None, optional) – Additional options controlling bitfield behavior, defaults to None
field_options (Iterable[_OptionLike] | None, optional) – Default options applied to bitfield members, defaults to None
alignment (int | None, optional) – Optional bit alignment constraint, defaults to None
- Returns:
The decorated Bitfield model class or a decorator function
- Return type:
type[_VT] | Callable[[type[_VT]], type[_VT]]
Changed in version 2.5.0: Added the
alignmentparameter.
4.5.3.2. Default Factory Classes#
- class caterpillar.model.BitfieldValueFactory(target: Callable[[int], _VT] | None = None)[source]#
A generic factory class responsible for converting values between Python objects and integers for use in bitfield entries.
By default, the factory converts to and from Python’s built-in
inttype, but it can be customized to support any type that accepts an integer in its constructor and implements__int__.- Parameters:
target (type, optional) – The target type to which integer values will be converted., defaults to None
Added in version 2.5.0.
- class caterpillar.model.CharFactory[source]#
A value factory for handling single ASCII/Unicode characters as integers.
This factory allows treating a character field as a one-byte integer and vice versa, automatically converting during packing and unpacking.
Added in version 2.5.0.
- class caterpillar.model.EnumFactory(model: type[_EnumT], strict: bool = False)[source]#
A value factory for enum-like types used in bitfields.
This factory attempts to convert between integers and enumeration instances, using the provided
model(which should support__int__). It can operate in strict or lenient mode:In strict mode, a
ValueErroris raised if conversion fails.In lenient mode, the raw integer is returned if the value is not in the enum.
- Parameters:
model (Type) – The enum model or mapping type to use.
strict (bool) – Whether to raise an error on unknown values.
Example#class Status(enum.IntEnum): OK = 0 ERROR = 1 factory = EnumFactory(Status, strict=True) factory.from_int(0) # -> Status.OK factory.from_int(2) # -> ValueError (strict mode)
Added in version 2.5.0.
4.5.3.3. Default Options#
- caterpillar.model.EndGroup#
Added in version 2.5.0.
Alias for the
B_GROUP_NEWflag, used to indicate that a new bitfield group should be started.
- caterpillar.model.NewGroup#
Alias for the
B_GROUP_ENDflag, used to indicate that the current bitfield group should be finalized.
- class caterpillar.model.SetAlignment(new_alignment: int)[source]#
Instructional flag used to update the current bitfield alignment dynamically during bitfield generation.
This class allows to explicitly set a new alignment boundary (in bits) for subsequent fields or groups in a bitfield definition. This enables finer control over how bitfield groups are organized and aligned.
- Parameters:
new_alignment (int) – The alignment size in bits to be used from this point forward in the bitfield layout.
- static flag(new_alignment: int) Flag[int][source]#
Create a
Flaginstance representing a request to set a new alignment.This method is intended for use where a generic
Flagis expected rather than a fullSetAlignmentobject, e.g. for setting options for aField.>>> field = 5 - uint32 | SetAlignment.flag(32)
- Parameters:
new_alignment (int) – The alignment size in bits.
- Returns:
A Flag object with the key “bitfield.new_alignment” and the specified alignment as its value.
- Return type:
4.5.3.4. Bitfield Mixins#
- class caterpillar.model.BitfieldDefMixin[source]#
Mixin extending
StructDefMixinforBitfield-based models.This mixin behaves identically to
StructDefMixinbut binds the__struct__attribute to aBitfielddefinition instead of a regularStruct. It allows bitfield models to reuse the same convenience API (from_bytes,to_bytes,[]operator, etc.) while operating on compact bit-level layouts.
- class caterpillar.model.bitfield_factory[source]#
Factory for transforming plain classes into
Bitfieldmodels.This factory mirrors the behavior of
struct_factorybut targets bit-level structures. It allows developers to declare compact bitfield layouts using class syntax while retaining full type-checker awareness through@dataclass_transform.- mixin#
alias of
BitfieldDefMixin
- static make_bitfield(ty: type[_VT], /, *, order: _EndianLike | None = None, arch: _ArchLike | None = None, options: Iterable[_OptionLike] | None = None, field_options: Iterable[_OptionLike] | None = None, alignment: int | None = None) type[source]#
Create a
Bitfieldmodel from a class definition.This helper performs the underlying transformation by constructing a
Bitfieldinstance and returning the generated model class.- Parameters:
ty (type[_VT]) – The base class to transform into a Bitfield model
order (_EndianLike | None, optional) – Byte order used during serialization, defaults to None
arch (_ArchLike | None, optional) – Architecture configuration inferred by fields, defaults to None
options (Iterable[_OptionLike] | None, optional) – Additional options controlling bitfield behavior, defaults to None
field_options (Iterable[_OptionLike] | None, optional) – Default options applied to bitfield members, defaults to None
alignment (int | None, optional) – Optional bit alignment constraint, defaults to None
- Returns:
The generated Bitfield model class
- Return type:
type
- static bitfield(ty: type[_VT], /, *, order: _EndianLike | None = None, arch: _ArchLike | None = None, options: Iterable[_OptionLike] | None = None, field_options: Iterable[_OptionLike] | None = None, alignment: int | None = None) type[_VT][source]#
- static bitfield(ty: None = None, /, *, order: _EndianLike | None = None, arch: _ArchLike | None = None, options: Iterable[_OptionLike] | None = None, field_options: Iterable[_OptionLike] | None = None, alignment: int | None = None) Callable[[type[_VT]], type[_VT]]
Decorator or direct transformer for creating a
Bitfieldmodel.This method can be used either as:
A decorator:
@bitfield(...)A direct transformer:
MyBitfield = bitfield(MyClass, ...)
It enables defining compact bit-level layouts using standard class syntax while preserving dataclass semantics and static type checking.
>>> from caterpillar.py import bitfield, SetAlignment, uint16 >>> @bitfield ... class Packet: ... version : 3 ... type : (5, SetAlignment(16)) ... length : 10 ... _ : 0 # align to 16bits ... payload : uint16 ... >>> # You can now pack/unpack Packet instances as compact binary bitfields >>> pkt = Packet(version=1, type=2, length=128, payload=0xABCD) >>> packed = pack(pkt) >>> unpacked = unpack(Packet, packed)
- Parameters:
ty (type[_VT] | None, optional) – The user-defined class to transform. If None, a decorator function is returned
order (_EndianLike | None, optional) – Byte order used during serialization, defaults to None
arch (_ArchLike | None, optional) – Architecture configuration inferred by fields, defaults to None
options (Iterable[_OptionLike] | None, optional) – Additional options controlling bitfield behavior, defaults to None
field_options (Iterable[_OptionLike] | None, optional) – Default options applied to bitfield members, defaults to None
alignment (int | None, optional) – Optional bit alignment constraint, defaults to None
- Returns:
The decorated Bitfield model class or a decorator function
- Return type:
type[_VT] | Callable[[type[_VT]], type[_VT]]