Extension for the python package 'construct' that adds typing features
Project description
construct-typing
This project is an extension of the python package construct, which is a powerful declarative and symmetrical parser and builder for binary data. This Repository consists of two packages:
- construct-stubs: Adding .pyi for the whole construct 2.10 package (according to PEP 561 stub-only packages)
- construct_typed: Adding additional classes that help with autocompletion and additional type hints.
Installation
This package comply to PEP 561. So most of the static code analysers will recognise the stubs automatically. The installation only requires:
pip install construct-typing
Tests
The stubs are tested against the pytests of the construct package in a slightly modified form. Since the tests are relatively detailed I think most cases are covered.
The new typed constructs have new written pytests, which also passes all pytests and the static type checkers.
The following static type checkers are fully supported:
- mypy
- pyright
Explanation
Stubs
The construct-stubs package is used for creating type hints for the orignial construct package. In particular the build and parse methods get type hints. So the core of the stubs are the TypeVar's ParsedType and BuildTypes:
Construct.build: converts an object of one of the types defined byBuildTypesto abytesobject.Construct.parse: converts abytesobject to an object of typeParsedType.
For each Construct the stub file defines to which type it parses to and from which it can be build. For example:
| Construct | parses to (ParsedType) | builds from (BuildTypes) |
|---|---|---|
Int16ub |
int |
int |
Bytes |
bytes |
bytes, bytearray or memoryview |
Array(5, Int16ub) |
ListContainer[int] |
typing.List[int] |
Struct("i" / Byte) |
Container[typing.Any] |
typing.Dict[str, typing.Any] or None |
The problem is to describe the more complex constructs like:
Sequence,FocusedSeqwhich has heterogenous subcons in comparison to anArraywith only homogenous subcons.Struct,BitStruct,LazyStruct,Unionwhich has heterogenous and named subcons.
Currently only the very unspecific type typing.Any can be used as type hint (maybe in the future it can be optimised a little, when variadic generics become available). But the biggest disadvantage is that autocompletion for the named subcons is not available.
Note: The stubs are based on construct in Version 2.10.
Typed
!!! EXPERIMENTAL VERSION !!!
To include autocompletion and further enhance the type hints for these complex constructs the construct_typed package is used as an extension to the original construct package. It is mainly a few Adapters with the focus on type hints.
It implements the following new constructs:
DataclassStruct: similar toconstruct.Structbut strictly tied toDataclassMixinand@dataclasses.dataclassDataclassBitStruct: similar toconstruct.BitStructbut strictly tied toDataclassMixinand@dataclasses.dataclassTEnum: similar toconstruct.Enumbut strictly tied to aTEnumBaseclassTFlagsEnum: similar toconstruct.FlagsEnumbut strictly tied to aTFlagsEnumBaseclass
These types are strongly typed, which means that there is no difference between the ParsedType and the BuildTypes. So to build one of the constructs the correct type is enforced. The disadvantage is that the code will be a little bit longer, because you can not for example use a normal dict to build an DataclassStruct. But the big advantage is, that if you use the correct container type instead of a dict, the static code analyses can do its magic and find potential type errors and missing values without running the code itself.
A short example:
import dataclasses
import typing as t
from construct import Array, Byte, Const, Int8ub, this
from construct_typed import DataclassMixin, DataclassStruct, EnumBase, TEnum, csfield
class Orientation(EnumBase):
HORIZONTAL = 0
VERTICAL = 1
@dataclasses.dataclass
class Image(DataclassMixin):
signature: bytes = csfield(Const(b"BMP"))
orientation: Orientation = csfield(TEnum(Int8ub, Orientation))
width: int = csfield(Int8ub)
height: int = csfield(Int8ub)
pixels: t.List[int] = csfield(Array(this.width * this.height, Byte))
format = DataclassStruct(Image)
obj = Image(
orientation=Orientation.VERTICAL,
width=3,
height=2,
pixels=[7, 8, 9, 11, 12, 13],
)
print(format.build(obj))
print(format.parse(b"BMP\x01\x03\x02\x07\x08\t\x0b\x0c\r"))
Output:
b'BMP\x01\x03\x02\x07\x08\t\x0b\x0c\r'
Image:
signature = b'BMP' (total 3)
orientation = Orientation.VERTICAL
width = 3
height = 2
pixels = ListContainer:
7
8
9
11
12
13
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file construct_typing-0.7.0.tar.gz.
File metadata
- Download URL: construct_typing-0.7.0.tar.gz
- Upload date:
- Size: 45.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
71d110dedff39bd3b603c734077032a7065bc597a49db1f5b03a211d05dbac23
|
|
| MD5 |
d33eb3d7f3c5b53b9d612706a2cf3ef7
|
|
| BLAKE2b-256 |
f6ae659fe4866d89ef5a3a65cddbdd7b35882f4feb72db383821965f2fcea934
|
Provenance
The following attestation bundles were made for construct_typing-0.7.0.tar.gz:
Publisher:
python-publish.yml on timrid/construct-typing
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
construct_typing-0.7.0.tar.gz -
Subject digest:
71d110dedff39bd3b603c734077032a7065bc597a49db1f5b03a211d05dbac23 - Sigstore transparency entry: 646080174
- Sigstore integration time:
-
Permalink:
timrid/construct-typing@f3b7bc342ee6ecc1aee4d072972cdfd626666a81 -
Branch / Tag:
refs/tags/v0.7.0 - Owner: https://github.com/timrid
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@f3b7bc342ee6ecc1aee4d072972cdfd626666a81 -
Trigger Event:
release
-
Statement type:
File details
Details for the file construct_typing-0.7.0-py3-none-any.whl.
File metadata
- Download URL: construct_typing-0.7.0-py3-none-any.whl
- Upload date:
- Size: 24.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c92383c6e8e5d07ba25811c8d5163820458d821e73bb1006541f43f89788646c
|
|
| MD5 |
8a06927ed89e1b24229337494eb76455
|
|
| BLAKE2b-256 |
8c0c2db6f7e1ae9795e436c6a0dc0bc38b12b8c8a228cb63203e24190b755b3b
|
Provenance
The following attestation bundles were made for construct_typing-0.7.0-py3-none-any.whl:
Publisher:
python-publish.yml on timrid/construct-typing
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
construct_typing-0.7.0-py3-none-any.whl -
Subject digest:
c92383c6e8e5d07ba25811c8d5163820458d821e73bb1006541f43f89788646c - Sigstore transparency entry: 646080232
- Sigstore integration time:
-
Permalink:
timrid/construct-typing@f3b7bc342ee6ecc1aee4d072972cdfd626666a81 -
Branch / Tag:
refs/tags/v0.7.0 - Owner: https://github.com/timrid
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@f3b7bc342ee6ecc1aee4d072972cdfd626666a81 -
Trigger Event:
release
-
Statement type: