diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3bdc963..daadc0d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,6 @@ name: CI -on: [push, pull_request] +on: [push, pull_request, workflow_dispatch] jobs: build: @@ -8,7 +8,7 @@ jobs: strategy: matrix: os: ['ubuntu-latest', 'windows-latest'] - python-version: [ '3.7', '3.8', '3.9', '3.10', '3.11' ] + python-version: [ '3.9', '3.10', '3.11', '3.12', '3.13' ] runs-on: ${{ matrix.os }} name: OS ${{ matrix.os }}, Python ${{ matrix.python-version }} @@ -35,6 +35,7 @@ jobs: - name: Install pyright run: | npm install -g pyright + pyright --version # Install this package - name: Install this package diff --git a/construct-stubs/core.pyi b/construct-stubs/core.pyi index 4a28191..36863e6 100644 --- a/construct-stubs/core.pyi +++ b/construct-stubs/core.pyi @@ -169,7 +169,7 @@ class Subconstruct( subcon: Construct[SubconParsedType, SubconBuildTypes], ) -> None: ... @t.overload - def __init__( + def __init__( # type: ignore self, *args: t.Any, **kwargs: t.Any, @@ -221,14 +221,14 @@ class Compiled(Construct[t.Any, t.Any]): # =============================================================================== # bytes and bits # =============================================================================== -class Bytes(Construct[bytes, t.Union[bytes, int]]): +class Bytes(Construct[bytes, t.Union[bytes, bytearray, int]]): length: ConstantOrContextLambda[int] def __init__( self, length: ConstantOrContextLambda[int], ) -> None: ... -GreedyBytes: Construct[bytes, bytes] +GreedyBytes: Construct[bytes, t.Union[bytes, bytearray]] def Bitwise( subcon: Construct[SubconParsedType, SubconBuildTypes] @@ -1110,9 +1110,9 @@ class Lazy( class LazyContainer(t.Generic[ContainerType], t.Dict[str, ContainerType]): def __getattr__(self, name: str) -> ContainerType: ... def __getitem__(self, index: t.Union[str, int]) -> ContainerType: ... - def keys(self) -> t.Iterator[str]: ... - def values(self) -> t.List[ContainerType]: ... - def items(self) -> t.List[t.Tuple[str, ContainerType]]: ... + def keys(self) -> t.Iterator[str]: ... # type: ignore + def values(self) -> t.List[ContainerType]: ... # type: ignore + def items(self) -> t.List[t.Tuple[str, ContainerType]]: ... # type: ignore class LazyStruct(Construct[LazyContainer[t.Any], t.Optional[t.Dict[str, t.Any]]]): subcons: t.List[Construct[t.Any, t.Any]] diff --git a/construct-stubs/expr.pyi b/construct-stubs/expr.pyi index 3d1b032..a7c1a1a 100644 --- a/construct-stubs/expr.pyi +++ b/construct-stubs/expr.pyi @@ -469,7 +469,7 @@ class ExprMixin(t.Generic[ReturnType], object): @t.overload def __eq__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[bool]: ... @t.overload - def __eq__(self, other: t.Any) -> BinExpr[t.Any]: ... + def __eq__(self, other: ConstOrCallable[t.Any]) -> BinExpr[t.Any]: ... # type: ignore # __ne__ ########################################################################################################### @t.overload @@ -487,7 +487,7 @@ class ExprMixin(t.Generic[ReturnType], object): @t.overload def __ne__(self: ExprMixin[float], other: ConstOrCallable[float]) -> BinExpr[bool]: ... @t.overload - def __ne__(self, other: t.Any) -> BinExpr[t.Any]: ... + def __ne__(self, other: t.Any) -> BinExpr[t.Any]: ... # type: ignore # __neg__ ########################################################################################################## @t.overload diff --git a/construct-stubs/lib/containers.pyi b/construct-stubs/lib/containers.pyi index a50033a..37efc75 100644 --- a/construct-stubs/lib/containers.pyi +++ b/construct-stubs/lib/containers.pyi @@ -19,7 +19,7 @@ def recursion_lock( class Container(t.Generic[ContainerType], t.Dict[str, ContainerType]): def __getattr__(self, name: str) -> ContainerType: ... - def update( + def update( # type: ignore self, seqordict: t.Union[t.Dict[str, ContainerType], t.Tuple[str, ContainerType]], ) -> None: ... diff --git a/construct_typed/dataclass_struct.py b/construct_typed/dataclass_struct.py index f276c99..e6ca2e8 100644 --- a/construct_typed/dataclass_struct.py +++ b/construct_typed/dataclass_struct.py @@ -152,13 +152,13 @@ class DataclassStruct(Adapter[t.Any, t.Any, DataclassType, DataclassType]): Image(width=1, height=2, pixels=b'12') """ - subcon: "cs.Struct" + subcon: "cs.Struct" # type: ignore def __init__( self, dc_type: t.Type[DataclassType], reverse: bool = False, ) -> None: - if not issubclass(dc_type, DataclassMixin): + if not issubclass(dc_type, DataclassMixin): # type: ignore raise TypeError(f"'{repr(dc_type)}' has to be a '{repr(DataclassMixin)}'") if not dataclasses.is_dataclass(dc_type): raise TypeError(f"'{repr(dc_type)}' has to be a 'dataclasses.dataclass'") diff --git a/setup.py b/setup.py index aa7b612..cf5ca66 100644 --- a/setup.py +++ b/setup.py @@ -58,11 +58,11 @@ "Topic :: Software Development :: Build Tools", "Topic :: Software Development :: Code Generators", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Programming Language :: Python :: Implementation :: CPython", "Typing :: Typed", ], diff --git a/tests/test_typed.py b/tests/test_typed.py index b85058a..df8cc84 100644 --- a/tests/test_typed.py +++ b/tests/test_typed.py @@ -2,9 +2,11 @@ # pyright: strict import dataclasses import enum +import textwrap import typing as t import construct as cs + import construct_typed as cst from construct_typed import DataclassBitStruct, DataclassMixin, DataclassStruct, csfield @@ -72,16 +74,20 @@ class Image(DataclassMixin): == "Image: \n signature = b'BMP' (total 3)\n width = 3\n height = 2" ) + def test_dataclass_ifthenelse() -> None: @dataclasses.dataclass class IfThenElseTest(DataclassMixin): test_if: t.Optional[int] = csfield(cs.If(False, cs.Int8ub)) - test_ifthenelse: t.Optional[int] = csfield(cs.IfThenElse(True, cs.Int8ub, cs.Pass)) + test_ifthenelse: t.Optional[int] = csfield( + cs.IfThenElse(True, cs.Int8ub, cs.Pass) + ) a = IfThenElseTest(test_if=None, test_ifthenelse=None) assert a.test_if == None assert a.test_ifthenelse == None + def test_dataclass_struct() -> None: @dataclasses.dataclass class Image(DataclassMixin): @@ -395,9 +401,10 @@ class E(enum.Enum): def test_tenum_asdict() -> None: # see: https://github.com/timrid/construct-typing/issues/21 - import construct_typed as cst import dataclasses + import construct_typed as cst + class TestEnum(cst.EnumBase): one = 1 two = 2 @@ -436,9 +443,9 @@ class TestEnum(cst.EnumBase): Value_NoDoc = cst.EnumValue(2) Value_NoDoc2 = 3 - assert ( - TestEnum.__doc__ - == """ + assert TestEnum.__doc__ is not None + assert textwrap.dedent(TestEnum.__doc__) == textwrap.dedent( + """ This is an test enum. """ ) @@ -508,9 +515,10 @@ class TestEnum(cst.FlagsEnumBase): def test_tenum_flags_asdict() -> None: - import construct_typed as cst import dataclasses + import construct_typed as cst + class TestEnum(cst.FlagsEnumBase): one = 1 two = 2 @@ -549,9 +557,9 @@ class TestEnum(cst.FlagsEnumBase): Value_NoDoc = cst.EnumValue(2) Value_NoDoc2 = 4 - assert ( - TestEnum.__doc__ - == """ + assert TestEnum.__doc__ is not None + assert textwrap.dedent(TestEnum.__doc__) == textwrap.dedent( + """ This is an test flags enum. """ )