Core API: Miscellaneous

construct.Const(subcon, value=None)

Field enforcing a constant value. It is used for file signatures, to validate that the given pattern exists. When parsed, the value must match.

Usually a member of a Struct, where it can be anonymous (so it does not appear in parsed dictionary for simplicity).

Note that a variable length subcon may still provide positive verification. Const does not consume a precomputed amount of bytes (and hence does NOT require a fixed sized lenghtfield), but depends on the subcon to read the appropriate amount (eg. VarInt is acceptable).

Parameters:
  • subcon – the subcon used to build value from, or a bytes value
  • value – optional, the expected value
Raises:

ConstError – when parsed data does not match specified value, or building from wrong value

Example:

>>> d = Const(b"IHDR")
>>> d.build(None)
b'IHDR'
>>> d.parse(b"JPEG")
construct.core.ConstError: expected b'IHDR' but parsed b'JPEG'

>>> d = Const(Int32ul, 16)
>>> d.build(None)
b'\x10\x00\x00\x00'
construct.Computed(func)

Field computing a value. Underlying byte stream is unaffected. When parsing, the context function provides the value. Constant literal value can also be provided.

Building does not require a value, the value gets computed from context, the same as during parsing.

Size is defined as 0 because parsing and building does not consume or produce bytes.

Parameters:func – a context function or a constant value
Example::
>>> d = Struct(
...     "width" / Byte,
...     "height" / Byte,
...     "total" / Computed(this.width * this.height),
... )
>>> d.build(dict(width=4,height=5))
b'\x04\x05'
>>> d.parse(b"12")
Container(width=49)(height=50)(total=2450)
>>> d = Computed(lambda ctx: 7)
>>> d.parse(b"")
7
>>> import os
>>> d = Computed(lambda ctx: os.urandom(10))
>>> d.parse(b"")
b'\x98\xc2\xec\x10\x07\xf5\x8e\x98\xc2\xec'
construct.Rebuild(subcon, func)

Parses the field like normal, but computes the value used for building from a context function. Constant value can also be used instead.

Building does not require a value, because the value gets recomputed anyway.

Size is the same as subcon size.

See also

Useful for length and count fields when Prefixed and PrefixedArray cannot be used.

Example:

>>> d = Struct(
...     "count" / Rebuild(Byte, len_(this.items)),
...     "items" / Byte[this.count],
... )
>>> d.build(dict(items=[1,2,3]))
b'\x03\x01\x02\x03'
construct.Default(subcon, value)

Allows to make a field have a default value, which comes handly when building a Struct from a dict with missing keys.

Building does not require a value, but can accept one.

Size is the same as subcon size.

Example:

>>> d = Struct(
...     "a" / Default(Byte, 0),
... )
>>> d.build(dict(a=1))
b'\x01'
>>> d.build(dict())
b'\x00'
construct.Check(func)

Checks for a condition, and raises ValidationError if the check fails.

Parameters:func – a context function returning a bool (or truthy value)
Raises:ValidationError – when condition fails

Example:

Check(lambda ctx: len(ctx.payload.data) == ctx.payload_len)
Check(len_(this.payload.data) == this.payload_len)
construct.Error()

Raises an exception when triggered by parse or build. Can be used as a sentinel that blows a whistle when a conditional branch goes the wrong way, or to raise an error explicitly the declarative way.

Raises:ExplicitError – when parsed or build

Example:

>>> d = ("x"/Byte >> IfThenElse(this.x > 0, Byte, Error))
>>> d.parse(b"\xff\x05")
construct.core.ExplicitError: Error field was activated during parsing
construct.FocusedSeq(parsebuildfrom, *subcons, **kw)

Parses and builds a sequence where only one subcon value is returned from parsing or taken into building, other fields are parsed and discarded or built from nothing.

Parameters:
  • parsebuildfrom – which subcon to use, an integer index or string name, or a context lambda returning either
  • *subcons – a list of members
  • **kw – a list of members (works ONLY on python 3.6)

Excample:

>>> d = FocusedSeq(1 or "num", Const(b"MZ"), "num"/Byte, Terminated)
>>> d.parse(b"MZ\xff")
255
>>> d.build(255)
b'MZ\xff'
construct.Numpy()

Preserves numpy arrays (both shape, dtype and values).

Raises:ImportError – when numpy cannot be imported during init

Example:

>>> import numpy
>>> a = numpy.asarray([1,2,3])
>>> Numpy.build(a)
b"\x93NUMPY\x01\x00F\x00"...
>>> Numpy.parse(_)
array([1, 2, 3])
construct.NamedTuple(tuplename, tuplefields, subcon)

Both arrays, structs, and sequences can be mapped to a namedtuple from collections module. To create a named tuple, you need to provide a name and a sequence of fields, either a string with space-separated names or a list of string names. Just like the standard namedtuple.

Raises:AdaptationError – when subcon is not either Struct Sequence Range

Example:

>>> d = NamedTuple("coord", "x y z", Byte[3])
>>> d = NamedTuple("coord", "x y z", Byte >> Byte >> Byte)
>>> d = NamedTuple("coord", "x y z", "x"/Byte + "y"/Byte + "z"/Byte)
>>> d.parse(b"123")
coord(x=49, y=50, z=51)