Registry / serialization / construct

construct

JSON →
library2.10.70pypypi✓ verified 29d ago

construct is a powerful declarative symmetric parser/builder for binary data, supporting Python 3.6+. It allows you to define the structure of binary data using Python objects and then parse or build data according to that structure. The current version is 2.10.70, and it maintains a fairly active release cadence, often releasing minor fixes and improvements.

pip install construct
INSTALL
IMPORT
SIG · CONSTRUCT
C
construct
serializationpythonv2.10.70
Install
1.8s avg
Import
146ms
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.9–3.13
musl
3.9–3.13
Install & Compatibility
Where this runs
tested against v2.10.70 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.156s · 18.4MB
glibc
py 3.10–3.95 runs
installs and imports cleanly · install 1.8s · import 0.136s · 19MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Struct
✓ from construct import Struct
✗ from construct.core import Struct
Old import path for construct versions prior to 2.5/2.6. Modern construct uses top-level imports.
Int8ub
✓ from construct import Int8ub
Bytes
✓ from construct import Bytes
Array
✓ from construct import Array
GreedyRange
✓ from construct import GreedyRange
StreamError
✓ from construct import StreamError

This quickstart demonstrates how to define a `Struct` using various constructors like `Bytes`, `Int8ub`, `Array`, and `GreedyRange`. It shows how to use lambda functions within a structure definition to refer to previously parsed fields (e.g., `ctx.count`). Finally, it illustrates building Python objects into binary data and parsing binary data back into Python objects, including basic error handling.

from construct import Struct, Int8ub, Bytes, Array, GreedyRange, StreamError # Define a simple binary structure # A header, an array of 8-bit unsigned integers, and a variable-length data block packet_struct = Struct( "header" / Bytes(4), # 4-byte header "count" / Int8ub, # 1-byte count of following integers "data" / Array(lambda ctx: ctx.count, Int8ub), # Array of 'count' integers "payload" / GreedyRange(Int8ub) # Remaining bytes as a list of integers ) # Example data to build my_data = { "header": b"\xde\xad\xbe\xef", "count": 3, "data": [10, 20, 30], "payload": [1, 2, 3, 4, 5] } # Build binary data from Python object built_binary = packet_struct.build(my_data) print(f"Built binary: {built_binary.hex()}") # Parse binary data into Python object # Using a different example binary for parsing binary_to_parse = b"\xaa\xbb\xcc\xdd\x02\x01\x02\xff\xee\xdd" try: parsed_object = packet_struct.parse(binary_to_parse) print(f"Parsed object: {parsed_object}") # Accessing fields print(f"Parsed header: {parsed_object.header.hex()}") print(f"Parsed data: {parsed_object.data}") except StreamError as e: print(f"Error parsing data: {e}")
Debug
Known issues
breakingMajor API overhaul occurred between construct 2.0 and 2.5/2.6. This was a near-complete rewrite, deprecating and removing many constructs (e.g., `Buffer`, `BitStruct`), changing import paths (`construct.core`), and modifying core behaviors. Code written for construct 2.0 is highly unlikely to work with 2.5+.
fix
Migrate your code to the modern construct API (2.8+ is recommended). This will likely involve a complete rewrite of your structure definitions and parsing/building logic. Refer to the official construct documentation for the current API.
affects: < 2.5
breakingBreaking changes were introduced in versions 2.8 and 2.9. Notably, `Subconstruct` was removed in 2.8 (use `Construct` directly), `RepeatUntil` was renamed to `GreedyRange`, and `Context.error_when` behavior changed slightly in 2.9.
fix
Review the changelog for versions 2.8 and 2.9. Update `Subconstruct` usage to directly use the base construct, rename `RepeatUntil` to `GreedyRange`, and adjust conditional error handling if `Context.error_when` was used.
affects: >= 2.8
gotchaConstruct objects (e.g., `Struct`, `Array`) are often mutable. If you create an instance of a construct and then modify its internal properties or reuse it in different contexts without care, you might encounter unexpected side effects due to shared state.
fix
If you need to reuse a construct with different parameters or ensure isolation, create a new instance each time, or use `construct.deep_copy` if you're modifying a complex, nested structure and need a true independent copy.
affects: All versions
gotchaThe `this` (or `ctx`) variable, used for accessing context and previously parsed fields within `lambda` functions or methods, can be a source of confusion. Misunderstanding its scope or when certain fields become available can lead to errors.
fix
Thoroughly understand the `Context` object and how `this` (or `ctx`) dynamically refers to the current parsing/building context. Debug with `construct.Probe` to inspect the context at various points in your structure definition. Ensure fields are defined before they are referenced via `this`.
affects: All versions
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'construct'
The 'construct' library is not installed in the Python environment, or the environment where the code is being run does not have access to the installed package.
fix
Install the library using pip: `pip install construct`.
construct.core.StreamError: could not read enough bytes
This error occurs when the parsing operation expects to read a certain number of bytes from the input stream, but the stream ends prematurely or contains fewer bytes than the defined construct requires.
fix
Ensure the input binary data provided to the `parse()` method is complete and matches the structure defined by the construct. You might need to check the source of your binary data or adjust the construct's definition if the data length is variable.
construct.core.ConstError: expected b'VALUE_A' but parsed b'VALUE_B'
A `Const` field in the construct definition enforces that a specific byte sequence (or value) must be present at that point in the stream. This error means the data being parsed does not match the expected constant value.
fix
Verify the binary data being parsed against the expected constant value defined in the `Const` construct. If the data is correct and the `Const` definition is incorrect, update the `Const` value. If the data is faulty, correct the data source.
TypeError: 'bytes' object cannot be interpreted as an integer
This common Python error often arises when working with `construct` because you are attempting to use a `bytes` object (which `construct` frequently returns) in a context where an integer value is expected, or vice-versa, without proper conversion.
fix
Explicitly convert the `bytes` object to an integer using methods like `int.from_bytes(byte_object, byteorder)` with the correct byte order, or access individual bytes as integers (e.g., `byte_object[0]`). Conversely, convert integers to bytes using `int.to_bytes()` when building.
construct.core.SizeofError: SizeofError
This error is raised when the `sizeof()` method of a construct cannot determine its size upfront, often because it depends on a value from the context dictionary that is not available or because the construct has a variable size that cannot be computed statically.
fix
If the size depends on a context value, ensure that the necessary key is present in the context dictionary when calling `sizeof()` or when building. For dynamically sized constructs, `sizeof()` might not be determinable, and you may need to rely on parsing or building to calculate the actual size.
Upgrade
Version history
2.10.70latest on PyPI · released Nov 29, 2023
Audit
Dependencies

No dependency data recorded yet.

Agent activity
27 hits · last 30 days
node
26
Resources
construct — pip install construct · libregistry