From b3360874930e88a12b56ef6eb1bcd1d2ceb852c7 Mon Sep 17 00:00:00 2001 From: Tim Rid <6593626+timrid@users.noreply.github.com> Date: Tue, 30 Mar 2021 19:34:28 +0200 Subject: [PATCH] renamed "TContainerBase" to "TContainerMixin" --- README.md | 15 ++++++++------- construct_typed/__init__.py | 3 ++- construct_typed/tstruct.py | 16 ++++++++++------ tests/declarativeunittest.pyi | 2 +- tests/test_core.py | 2 +- tests/test_typed.py | 36 +++++++++++++++++------------------ 6 files changed, 40 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 12f5692..d9a2467 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ Note: The stubs are based on *construct* in Version 2.10. 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 bunch of Adapters for the original constructs with the focus on type hints. It implements the following new constructs: -- `TStruct`, `TBitStruct`: similar to `construct.Struct` but strictly tied to `TContainerBase` and `@dataclasses.dataclass` +- `TStruct`, `TBitStruct`: similar to `construct.Struct` but strictly tied to `TContainerMixin` and `@dataclasses.dataclass` - `TEnum`: similar to `construct.Enum` but strictly tied to a `TEnumBase` class - `TFlagsEnum`: similar to `construct.FlagsEnum` but strictly tied to a `TFlagsEnumBase` class @@ -67,18 +67,19 @@ A short example: import dataclasses import construct as cs import construct_typed as cst +import typing as t class Orientation(cst.EnumBase): HORIZONTAL = 0 VERTICAL = 1 @dataclasses.dataclass -class Image(cst.TContainerBase): - signature: cst.Opt[bytes] = cst.sfield(cs.Const(b"BMP")) - orientation: Orientation = cst.sfield(cst.TEnum(cs.Int8ub, Orientation)) - width: int = cst.sfield(cs.Int8ub) - height: int = cst.sfield(cs.Int8ub) - pixels: cst.List[int] = cst.sfield(cs.Array(cs.this.width * cs.this.height, cs.Byte)) +class Image(cst.TContainerMixin): + signature: t.Optional[bytes] = cst.TStructField(cs.Const(b"BMP")) + orientation: Orientation = cst.TStructField(cst.TEnum(cs.Int8ub, Orientation)) + width: int = cst.TStructField(cs.Int8ub) + height: int = cst.TStructField(cs.Int8ub) + pixels: t.List[int] = cst.TStructField(cs.Array(cs.this.width * cs.this.height, cs.Byte)) format = cst.TStruct(Image) obj = Image(orientation=Orientation.VERTICAL, width=3, height=2, pixels=[7, 8, 9, 11, 12, 13]) diff --git a/construct_typed/__init__.py b/construct_typed/__init__.py index d667d31..017a86f 100644 --- a/construct_typed/__init__.py +++ b/construct_typed/__init__.py @@ -7,7 +7,7 @@ from .generic_wrapper import ( PathType, ) from .tenum import EnumBase, FlagsEnumBase, TEnum, TFlagsEnum -from .tstruct import TBitStruct, TStruct, sfield, TStructField, TContainerBase +from .tstruct import TBitStruct, TStruct, sfield, TStructField, TContainerMixin, TContainerBase from .tunion import TUnion, ufield, TUnionField __all__ = [ @@ -24,6 +24,7 @@ __all__ = [ "Adapter", "ListContainer", "TContainerBase", + "TContainerMixin", "Context", "ConstantOrContextLambda", "PathType", diff --git a/construct_typed/tstruct.py b/construct_typed/tstruct.py index 4f25d88..d818b74 100644 --- a/construct_typed/tstruct.py +++ b/construct_typed/tstruct.py @@ -15,17 +15,17 @@ from .generic_wrapper import ( if t.TYPE_CHECKING: - class _TContainerBase(cs.Container[t.Any]): + class _TContainerMixin(cs.Container[t.Any]): ... else: - class _TContainerBase(cs.Container): + class _TContainerMixin(cs.Container): pass -class TContainerBase(_TContainerBase): +class TContainerMixin(_TContainerMixin): """ Base class for a Container of a TStruct and a TBitStruct. @@ -50,6 +50,9 @@ class TContainerBase(_TContainerBase): self.move_to_end(field.name) +TContainerBase = TContainerMixin # also support legacy name + + def sfield( subcon: Construct[ParsedType, t.Any], doc: t.Optional[str] = None, @@ -76,9 +79,10 @@ def sfield( return field # type: ignore + TStructField = sfield # also support legacy name -ContainerType = t.TypeVar("ContainerType", bound=TContainerBase) +ContainerType = t.TypeVar("ContainerType", bound=TContainerMixin) class _TStruct(Adapter[t.Any, t.Any, ContainerType, BuildTypes]): @@ -92,10 +96,10 @@ class _TStruct(Adapter[t.Any, t.Any, ContainerType, BuildTypes]): swapped: bool = False, add_offsets: bool = False, ) -> None: - if not issubclass(container_type, TContainerBase): + if not issubclass(container_type, TContainerMixin): raise TypeError( "'{}' has to be a '{}'".format( - repr(container_type), repr(TContainerBase) + repr(container_type), repr(TContainerMixin) ) ) if not dataclasses.is_dataclass(container_type): diff --git a/tests/declarativeunittest.pyi b/tests/declarativeunittest.pyi index 336b003..985cd0a 100644 --- a/tests/declarativeunittest.pyi +++ b/tests/declarativeunittest.pyi @@ -6,7 +6,7 @@ import construct_typed as cst Buffer = t.Union[bytes, memoryview, bytearray] ParsedType = t.TypeVar("ParsedType") BuildTypes = t.TypeVar("BuildTypes") -ContainerType = t.TypeVar("ContainerType", bound=cst.TContainerBase) +ContainerType = t.TypeVar("ContainerType", bound=cst.TContainerMixin) T = t.TypeVar("T") IdentType = t.TypeVar("IdentType") diff --git a/tests/test_core.py b/tests/test_core.py index 78c6740..66d9305 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1705,7 +1705,7 @@ def test_from_issue_324() -> None: )), "checksum" / Checksum( Byte, - lambda data: sum(iterateints(data)) & 0xFF, + lambda data: sum(data) & 0xFF, this.vals.data ), ) diff --git a/tests/test_typed.py b/tests/test_typed.py index 5964553..acff21d 100644 --- a/tests/test_typed.py +++ b/tests/test_typed.py @@ -18,7 +18,7 @@ def test_tcontainer_compare_with_dataclass() -> None: b: int = cst.sfield(cs.Int8ub) @dataclasses.dataclass - class TestTContainer(cst.TContainerBase): + class TestTContainer(cst.TContainerMixin): a: t.Optional[int] = cst.sfield(cs.Const(1, cs.Byte)) b: int = cst.sfield(cs.Int8ub) @@ -66,7 +66,7 @@ def test_tcontainer_compare_with_dataclass() -> None: def test_tcontainer_order() -> None: @dataclasses.dataclass - class Image(cst.TContainerBase): + class Image(cst.TContainerMixin): signature: t.Optional[bytes] = cst.sfield(cs.Const(b"BMP")) width: int = cst.sfield(cs.Int8ub) height: int = cst.sfield(cs.Int8ub) @@ -85,7 +85,7 @@ def test_tcontainer_order() -> None: def test_tstruct() -> None: @dataclasses.dataclass - class TestContainer(cst.TContainerBase): + class TestContainer(cst.TContainerMixin): a: int = cst.sfield(cs.Int16ub) b: int = cst.sfield(cs.Int8ub) @@ -101,7 +101,7 @@ def test_tstruct() -> None: def test_tstruct_swapped() -> None: @dataclasses.dataclass - class TestContainer(cst.TContainerBase): + class TestContainer(cst.TContainerMixin): a: int = cst.sfield(cs.Int16ub) b: int = cst.sfield(cs.Int8ub) @@ -118,7 +118,7 @@ def test_tstruct_swapped() -> None: def test_tstruct_add_offsets() -> None: @dataclasses.dataclass - class TestContainer(cst.TContainerBase): + class TestContainer(cst.TContainerMixin): a: int = cst.sfield(cs.Int16ub) b: int = cst.sfield(cs.Int8ub) @@ -138,9 +138,9 @@ def test_tstruct_add_offsets() -> None: def test_tstruct_nested() -> None: @dataclasses.dataclass - class TestContainer(cst.TContainerBase): + class TestContainer(cst.TContainerMixin): @dataclasses.dataclass - class InnerDataclass(cst.TContainerBase): + class InnerDataclass(cst.TContainerMixin): b: int = cst.sfield(cs.Byte) a: InnerDataclass = cst.sfield(cst.TStruct(InnerDataclass)) @@ -155,7 +155,7 @@ def test_tstruct_nested() -> None: def test_tstruct_default_field() -> None: @dataclasses.dataclass - class Image(cst.TContainerBase): + class Image(cst.TContainerMixin): width: int = cst.sfield(cs.Int8ub) height: int = cst.sfield(cs.Int8ub) pixels: t.Optional[bytes] = cst.sfield( @@ -175,7 +175,7 @@ def test_tstruct_default_field() -> None: def test_tstruct_const_field() -> None: @dataclasses.dataclass - class TestContainer(cst.TContainerBase): + class TestContainer(cst.TContainerMixin): const_field: t.Optional[bytes] = cst.sfield(cs.Const(b"\x00")) common( @@ -195,7 +195,7 @@ def test_tstruct_const_field() -> None: def test_tstruct_array_field() -> None: @dataclasses.dataclass - class TestContainer(cst.TContainerBase): + class TestContainer(cst.TContainerMixin): array_field: t.List[int] = cst.sfield(cs.Array(5, cs.Int8ub)) common( @@ -208,7 +208,7 @@ def test_tstruct_array_field() -> None: def test_tstruct_anonymus_fields_1() -> None: @dataclasses.dataclass - class TestContainer(cst.TContainerBase): + class TestContainer(cst.TContainerMixin): _1: t.Optional[bytes] = cst.sfield(cs.Const(b"\x00")) _2: None = cst.sfield(cs.Padding(1)) _3: None = cst.sfield(cs.Pass) @@ -224,7 +224,7 @@ def test_tstruct_anonymus_fields_1() -> None: def test_tstruct_anonymus_fields_2() -> None: @dataclasses.dataclass - class TestContainer(cst.TContainerBase): + class TestContainer(cst.TContainerMixin): _1: int = cst.sfield(cs.Computed(7)) _2: t.Optional[bytes] = cst.sfield(cs.Const(b"JPEG")) _3: None = cst.sfield(cs.Pass) @@ -235,14 +235,14 @@ def test_tstruct_anonymus_fields_2() -> None: def test_tstruct_no_dataclass() -> None: - class TestContainer(cst.TContainerBase): + class TestContainer(cst.TContainerMixin): a: int = cst.sfield(cs.Int16ub) b: int = cst.sfield(cs.Int8ub) assert raises(lambda: cst.TStruct(TestContainer)) == TypeError -def test_tstruct_no_tcontainerbase() -> None: +def test_tstruct_no_TContainerMixin() -> None: @dataclasses.dataclass class TestContainer: a: int = cst.sfield(cs.Int16ub) @@ -253,12 +253,12 @@ def test_tstruct_no_tcontainerbase() -> None: def test_tstruct_wrong_container() -> None: @dataclasses.dataclass - class TestContainer1(cst.TContainerBase): + class TestContainer1(cst.TContainerMixin): a: int = cst.sfield(cs.Int16ub) b: int = cst.sfield(cs.Int8ub) @dataclasses.dataclass - class TestContainer2(cst.TContainerBase): + class TestContainer2(cst.TContainerMixin): a: int = cst.sfield(cs.Int16ub) b: int = cst.sfield(cs.Int8ub) @@ -269,7 +269,7 @@ def test_tstruct_wrong_container() -> None: def test_tstruct_doc() -> None: @dataclasses.dataclass - class TestContainer(cst.TContainerBase): + class TestContainer(cst.TContainerMixin): a: int = cst.sfield(cs.Int16ub, "This is the documentation of a") b: int = cst.sfield( cs.Int8ub, doc="This is the documentation of b\nwhich is multiline" @@ -344,7 +344,7 @@ def test_tenum_in_tstruct() -> None: b = 2 @dataclasses.dataclass - class TestContainer(cst.TContainerBase): + class TestContainer(cst.TContainerMixin): a: TestEnum = cst.sfield(cst.TEnum(cs.Int8ub, TestEnum)) b: int = cst.sfield(cs.Int8ub)