Install & Compatibility
Where this runs
tested against v3.3.0 · 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
py 3.10
4/12 runs
4/12 runs
py 3.11
4/12 runs
4/12 runs
py 3.12
4/12 runs
4/12 runs
py 3.13
4/12 runs
4/12 runs
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
createParser
✓ from hachoir.parser import createParser
extractMetadata
✓ from hachoir.metadata import extractMetadata
StringInputStream
✓ from hachoir.stream import StringInputStream
FileInputStream
✓ from hachoir.stream import FileInputStream
LITTLE_ENDIAN
✓ from hachoir.stream import LITTLE_ENDIAN
✗ from hachoir.core.endian import LITTLE_ENDIAN
While `hachoir.core.endian` is the source, examples commonly import `LITTLE_ENDIAN` directly from `hachoir.stream`.
This quickstart demonstrates how to define a simple custom parser, create an in-memory `StringInputStream` from binary data, and then parse and access fields using Hachoir. It illustrates the basic workflow of defining field types and accessing their values.
import io
from hachoir.stream import StringInputStream, LITTLE_ENDIAN
from hachoir.field import Root, UInt8, UInt16, Bytes
from hachoir.parser import Parser
# Define a simple custom parser for demonstration
class SimpleBinaryParser(Parser):
PARSER_TAGS = {
"id": "simple_bin",
"category": "misc",
"description": "Simple binary format"
}
endian = LITTLE_ENDIAN # Specify endianness for the parser
def createFields(self):
# A 1-byte header identifier
yield UInt8(self, "header_byte", "Header identifier")
# A 2-byte unsigned integer for length (little endian)
yield UInt16(self, "length", "Length of data section")
# A data payload whose size is determined by the 'length' field
yield Bytes(self, "data", self["length"].value, "Data payload")
# Create a dummy binary string:
# - 0xAA (1 byte) for 'header_byte'
# - 0x05 0x00 (2 bytes, little endian representation of 5) for 'length'
# - "hello" (5 bytes) for 'data'
dummy_data = b"\xAA\x05\x00hello"
# Create a StringInputStream from the dummy data
stream = StringInputStream(dummy_data, "simple_data_stream")
# Instantiate the parser with the stream
parser = SimpleBinaryParser(stream)
# Access and print the parsed field values
print(f"Parsed Header Byte: {parser['header_byte'].value} (0x{parser['header_byte'].value:02X})")
print(f"Parsed Length: {parser['length'].value}")
print(f"Parsed Data: {parser['data'].value.decode('ascii')}")
hachoir-urwid --version
Errors
Common errors & fixes
distutils.errors.DistutilsSetupError: use_2to3 is invalid.
This error occurs when attempting to install `hachoir[urwid]` using a recent version of `setuptools`. The `urwid==1.3.1` dependency, specified by `hachoir[urwid]`, is an old package that uses `use_2to3`, a feature removed in `setuptools` version 58 and newer, as it was for Python 2 to 3 conversion.
fixUpgrade the `urwid` dependency to a newer version that does not rely on `use_2to3`. You can often resolve this by installing `hachoir` and `urwid` separately, or by finding a version of `hachoir-urwid` that specifies a compatible `urwid` version. For example: `pip install hachoir` followed by `pip install urwid` (to get the latest compatible urwid version).
Command "python setup.py egg_info" failed with error code 1 in ...\hachoir-metadata
This installation error typically occurs when trying to install the `hachoir-metadata` package in a Python 3 environment. `hachoir-metadata` is largely a Python 2 package and contains syntax incompatible with Python 3, leading to the setup script failing.
fixThe core `hachoir` library (version 3.x) is Python 3 compatible. If you specifically need `hachoir-metadata` and must use Python 3, consider using a modern alternative or finding a Python 3-compatible fork if available. Otherwise, use a Python 2 environment for `hachoir-metadata` or extract metadata using the `hachoir.metadata` module directly from the Python 3 `hachoir` library. The `hachoir` library itself has `hachoir.metadata` functionalities for Python 3.
from hachoir_core.stream import FileInputStream, StringInputStream
This is a common wrong import pattern that leads to `ModuleNotFoundError` or `ImportError`. Many older examples and tutorials for `hachoir` (especially those written for Python 2 or earlier Python 3 versions) use `hachoir_core` as a direct import path. In recent versions of `hachoir` (like 3.3.0), the submodules are directly under the `hachoir` namespace, not `hachoir_core`.
fixUpdate the import statements to reflect the current package structure by importing directly from `hachoir`. For example: `from hachoir.stream import FileInputStream, StringInputStream`.
hachoir.core.field.field.MissingField: Missing field: /packet[0]/ipv4/src
This error occurs when a specific field path, such as `/packet[0]/ipv4/src`, is requested but `hachoir` cannot find it in the parsed binary stream. This might be due to an incorrect path, the field not existing in the particular file format or at that specific offset, or the parser not correctly identifying the structure.
fixVerify the structure of the binary file you are parsing and confirm the correct field path. You may need to inspect the file's binary structure or consult the documentation/source code of the specific `hachoir` parser for that file type to determine the correct field names and hierarchy. Implement error handling (e.g., `try-except MissingField`) to gracefully manage cases where fields might not be present.
Upgrade
Version history
3.3.0latest on PyPI · released Dec 12, 2023
Audit
Dependencies
python3requiredHachoir 3.x requires Python 3.6 or newer.
urwidoptionalRequired for the 'hachoir-urwid' command-line interface tool, which provides a curses-based UI for binary file exploration.
wxPythonoptionalRequired for the 'hachoir-wx' graphical user interface tool, which provides a GUI for binary file exploration. Installation varies by OS.