construct-classes 0.1.2__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,7 +11,24 @@ Unreleased
11
11
 
12
12
  Please see all `Unreleased Changes`_ for more information.
13
13
 
14
- .. _Unreleased Changes: https://github.com/matejcik/construct-classes/compare/v0.1.2...HEAD
14
+ .. _Unreleased Changes: https://github.com/matejcik/construct-classes/compare/v0.2.0...HEAD
15
+
16
+
17
+ 0.2.0 - 2025-08-25
18
+ --------------------
19
+
20
+ Added
21
+ ~~~~~
22
+
23
+ - Allow pass-through of dataclass arguments via class attributes.
24
+
25
+ Incompatible changes
26
+ ~~~~~~~~~~~~~~~~~~~~
27
+
28
+ - Subclasses of :code:`Struct` are now :code:`kw_only` by default. This will break
29
+ any constructor invocations using positional arguments. You can explicitly
30
+ set :code:`kw_only=False` on your :code:`Struct` subclass to restore the old
31
+ behavior.
15
32
 
16
33
 
17
34
  0.1.2 - 2022-10-07
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: construct-classes
3
- Version: 0.1.2
3
+ Version: 0.2.0
4
4
  Summary: Parse your binary structs into dataclasses
5
5
  Home-page: https://github.com/matejcik/construct-classes
6
6
  License: MIT
@@ -12,13 +12,17 @@ Classifier: Intended Audience :: Developers
12
12
  Classifier: License :: OSI Approved :: MIT License
13
13
  Classifier: Natural Language :: English
14
14
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.10
16
- Classifier: Programming Language :: Python :: 3.11
17
- Classifier: Programming Language :: Python :: 3.6
18
15
  Classifier: Programming Language :: Python :: 3.7
19
16
  Classifier: Programming Language :: Python :: 3.8
20
17
  Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
23
+ Classifier: Programming Language :: Python :: 3.6
21
24
  Requires-Dist: construct (>=2.10,<3.0)
25
+ Requires-Dist: dataclasses (>=0.8,<0.9) ; python_full_version >= "3.6.0" and python_full_version < "3.7.0"
22
26
  Project-URL: Repository, https://github.com/matejcik/construct-classes
23
27
  Description-Content-Type: text/x-rst
24
28
 
@@ -107,8 +111,21 @@ must match the names of the fields in the Construct struct.
107
111
 
108
112
  Use :code:`dataclasses.field()` to specify attributes on fields that are not subcons.
109
113
 
110
- There are currently no other features. In particular, the resulting class is a Python
111
- dataclass, but you cannot specify its parameters like :code:`frozen` etc.
114
+ By default, subclasses of :code:`Struct` are :code:`kw_only`. This is specifically to
115
+ allow setting default values on any fields regardless of order, so that your attributes
116
+ can be listed in the subcon order.
117
+
118
+ However, you can pass any valid dataclass parameters to the :code:`Struct` class via
119
+ class attributes:
120
+
121
+ .. code-block:: python
122
+
123
+ class MyStruct(Struct, kw_only=False, frozen=True):
124
+ a: int
125
+ b: int
126
+
127
+ my_struct = MyStruct(1, 2) # ok
128
+ my_struct.a = 2 # FrozenInstanceError
112
129
 
113
130
 
114
131
  Installing
@@ -83,8 +83,21 @@ must match the names of the fields in the Construct struct.
83
83
 
84
84
  Use :code:`dataclasses.field()` to specify attributes on fields that are not subcons.
85
85
 
86
- There are currently no other features. In particular, the resulting class is a Python
87
- dataclass, but you cannot specify its parameters like :code:`frozen` etc.
86
+ By default, subclasses of :code:`Struct` are :code:`kw_only`. This is specifically to
87
+ allow setting default values on any fields regardless of order, so that your attributes
88
+ can be listed in the subcon order.
89
+
90
+ However, you can pass any valid dataclass parameters to the :code:`Struct` class via
91
+ class attributes:
92
+
93
+ .. code-block:: python
94
+
95
+ class MyStruct(Struct, kw_only=False, frozen=True):
96
+ a: int
97
+ b: int
98
+
99
+ my_struct = MyStruct(1, 2) # ok
100
+ my_struct.a = 2 # FrozenInstanceError
88
101
 
89
102
 
90
103
  Installing
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "construct-classes"
3
- version = "0.1.2"
3
+ version = "0.2.0"
4
4
  authors = ["matejcik <ja@matejcik.cz>"]
5
5
  classifiers = [
6
6
  "Development Status :: 2 - Pre-Alpha",
@@ -14,17 +14,25 @@ classifiers = [
14
14
  "Programming Language :: Python :: 3.9",
15
15
  "Programming Language :: Python :: 3.10",
16
16
  "Programming Language :: Python :: 3.11",
17
+ "Programming Language :: Python :: 3.12",
18
+ "Programming Language :: Python :: 3.13",
19
+ "Programming Language :: Python :: 3.14",
17
20
  ]
18
21
  description = "Parse your binary structs into dataclasses"
19
22
  homepage = "https://github.com/matejcik/construct-classes"
20
23
  license = "MIT"
21
24
  repository = "https://github.com/matejcik/construct-classes"
22
25
  readme = "README.rst"
23
- include = ["CHANGELOG.rst", "LICENSE", "README.rst"]
26
+ include = [
27
+ { path = "CHANGELOG.rst", format = "sdist" },
28
+ { path = "LICENSE", format = "sdist" },
29
+ { path = "README.rst", format = "sdist" }
30
+ ]
24
31
 
25
32
  [tool.poetry.dependencies]
26
33
  python = ">=3.6.2,<4.0"
27
34
  construct = "^2.10"
35
+ dataclasses = { version = "^0.8", python = "~3.6.0" }
28
36
 
29
37
  [tool.poetry.dev-dependencies]
30
38
  pytest = ">5"
@@ -6,11 +6,14 @@ import construct as c
6
6
  if t.TYPE_CHECKING:
7
7
  from typing_extensions import dataclass_transform
8
8
  else:
9
+
9
10
  def dataclass_transform(**kwargs: t.Any) -> t.Any:
10
11
  def inner(cls: t.Any) -> t.Any:
11
12
  return cls
13
+
12
14
  return inner
13
15
 
16
+
14
17
  # workaround for mypy self type bug
15
18
  Self = t.TypeVar("Self", bound="Struct")
16
19
 
@@ -27,13 +30,23 @@ def subcon(
27
30
  return dataclasses.field(metadata=metadata, **kwargs)
28
31
 
29
32
 
30
- @dataclass_transform(field_specifiers=(subcon,))
33
+ @dataclass_transform(field_specifiers=(subcon,), kw_only_default=True)
31
34
  class _StructMeta(type):
32
35
  def __new__(
33
- cls, name: str, bases: t.Tuple[type, ...], namespace: t.Dict[str, t.Any]
36
+ cls,
37
+ name: str,
38
+ bases: t.Tuple[type, ...],
39
+ namespace: t.Dict[str, t.Any],
40
+ *,
41
+ kw_only: bool = True,
42
+ **kwargs: t.Any,
34
43
  ) -> type:
35
44
  new_cls = super().__new__(cls, name, bases, namespace)
36
- return dataclasses.dataclass()(new_cls) # type: ignore # pyright is bad with metaclasses
45
+ if bases:
46
+ assert bases[0].__name__ == "Struct"
47
+ return dataclasses.dataclass(kw_only=kw_only, **kwargs)(new_cls)
48
+ else:
49
+ return new_cls
37
50
 
38
51
 
39
52
  class Struct(metaclass=_StructMeta):
@@ -1,34 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- from setuptools import setup
3
-
4
- package_dir = \
5
- {'': 'src'}
6
-
7
- packages = \
8
- ['construct_classes']
9
-
10
- package_data = \
11
- {'': ['*']}
12
-
13
- install_requires = \
14
- ['construct>=2.10,<3.0']
15
-
16
- setup_kwargs = {
17
- 'name': 'construct-classes',
18
- 'version': '0.1.2',
19
- 'description': 'Parse your binary structs into dataclasses',
20
- 'long_description': '=================\nconstruct-classes\n=================\n\n.. image:: https://img.shields.io/pypi/v/construct-classes.svg\n :target: https://pypi.python.org/pypi/construct-classes\n\n.. .. image:: https://readthedocs.org/projects/construct-classes/badge/?version=latest\n.. :target: https://construct-classes.readthedocs.io/en/latest/?badge=latest\n.. :alt: Documentation Status\n\n.. image:: https://pyup.io/repos/github/trezor/construct-classes/shield.svg\n :target: https://pyup.io/repos/github/trezor/construct-classes/\n :alt: Updates\n\n\nParse your binary data into dataclasses. Pack your dataclasses into binary data.\n\n:code:`construct-classes` rely on `construct`_ for parsing and packing. The\nprogrammer needs to manually write the Construct expressions. There is also no type\nverification, so it is the programmer\'s responsibility that the dataclass and the\nConstruct expression match.\n\nFor fully type annotated experience, install `construct-typing`_.\n\nThis package typechecks with `mypy`_ and `pyright`_.\n\n.. _construct: https://construct.readthedocs.io/en/latest/\n.. _construct-typing: https://github.com/timrid/construct-typing\n.. _mypy: https://mypy.readthedocs.io/en/stable/\n.. _pyright: https://github.com/microsoft/pyright\n\nUsage\n-----\n\nAny child of :code:`Struct` is a Python dataclass. It expects a Construct :code:`Struct`\nexpression in the :code:`SUBCON` attribute. The names of the attributes of the dataclass\nmust match the names of the fields in the Construct struct.\n\n.. code-block:: python\n\n import construct as c\n from construct_classes import Struct, subcon\n\n class BasicStruct(Struct):\n x: int\n y: int\n description: str\n\n SUBCON = c.Struct(\n "x" / c.Int32ul,\n "y" / c.Int32ul,\n "description" / c.PascalString(c.Int8ul, "utf8"),\n )\n\n\n data = b"\\x01\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x05hello"\n parsed = BasicStruct.parse(data)\n print(parsed) # BasicStruct(x=1, y=2, description=\'hello\')\n\n new_data = BasicStruct(x=100, y=200, description="world")\n print(new_data.build()) # b\'\\x64\\x00\\x00\\x00\\xc8\\x00\\x00\\x00\\x05world\'\n\n\n:code:`construct-classes` support nested structs, but you need to declare them explicitly:\n\n.. code-block:: python\n\n class LargerStruct(Struct):\n # specify the subclass type:\n basic: BasicStruct = subcon(BasicStruct)\n # in case of a list, specify the item type:\n basic_array: List[BasicStruct] = subcon(BasicStruct)\n # the `subcon()` function supports all arguments of `dataclass.field`:\n default_array: List[BasicStruct] = subcon(BasicStruct, default_factory=list)\n\n # to refer to the subcon, use the `SUBCON` class attribute:\n SUBCON = c.Struct(\n "basic" / BasicStruct.SUBCON,\n "basic_array" / c.Array(2, BasicStruct.SUBCON),\n "default_array" / c.PrefixedArray(c.Int8ul, BasicStruct.SUBCON),\n )\n\nUse :code:`dataclasses.field()` to specify attributes on fields that are not subcons.\n\nThere are currently no other features. In particular, the resulting class is a Python\ndataclass, but you cannot specify its parameters like :code:`frozen` etc.\n\n\nInstalling\n----------\n\nInstall using pip:\n\n $ pip install construct-classes\n\n\nChangelog\n~~~~~~~~~\n\nSee `CHANGELOG.rst`_.\n\n.. _CHANGELOG.rst: https://github.com/matejcik/construct-classes/blob/master/CHANGELOG.rst\n\n\nFooter\n------\n\n* Free software: MIT License\n\n.. * Documentation: https://construct-classes.readthedocs.io.\n',
21
- 'author': 'matejcik',
22
- 'author_email': 'ja@matejcik.cz',
23
- 'maintainer': None,
24
- 'maintainer_email': None,
25
- 'url': 'https://github.com/matejcik/construct-classes',
26
- 'package_dir': package_dir,
27
- 'packages': packages,
28
- 'package_data': package_data,
29
- 'install_requires': install_requires,
30
- 'python_requires': '>=3.6.2,<4.0',
31
- }
32
-
33
-
34
- setup(**setup_kwargs)