renamed "TContainerBase" to "TContainerMixin"

This commit is contained in:
Tim Rid 2021-03-30 19:34:28 +02:00
parent 7f88357562
commit b336087493
6 changed files with 40 additions and 34 deletions

View file

@ -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])

View file

@ -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",

View file

@ -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):

View file

@ -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")

View file

@ -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
),
)

View file

@ -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)