diff --git a/construct-stubs/core.pyi b/construct-stubs/core.pyi index 79312c4..573121e 100644 --- a/construct-stubs/core.pyi +++ b/construct-stubs/core.pyi @@ -174,9 +174,9 @@ class Subconstruct( class Adapter( Subconstruct[SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes], ): - def __init__( - self, subcon: Construct[SubconParsedType, SubconBuildTypes] - ) -> None: ... + def __new__( + cls, subcon: Construct[SubconParsedType, SubconBuildTypes] + ) -> Adapter[SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes]: ... def _decode( self, obj: SubconParsedType, context: Context, path: PathType ) -> ParsedType: ... @@ -397,11 +397,11 @@ class FlagsEnum(Adapter[int, int, ParsedType, BuildTypes]): class Mapping(Adapter[SubconParsedType, SubconBuildTypes, t.Any, t.Any]): decmapping: t.Dict[int, str] encmapping: t.Dict[str, int] - def __init__( - self, + def __new__( + cls, subcon: Construct[SubconParsedType, SubconBuildTypes], mapping: t.Dict[t.Any, t.Any], - ) -> None: ... + ) -> Mapping[t.Any, t.Any]: ... # =============================================================================== # structures and sequences @@ -513,7 +513,7 @@ class Const(Subconstruct[SubconParsedType, SubconBuildTypes, ParsedType, BuildTy def __new__( cls, value: bytes, - ) -> Const[None, None, bytes, t.Optional[bytes]]: ... + ) -> Const[None, None, bytes, Bytes[t.ByteString, int]]: ... @t.overload def __new__( cls, @@ -555,9 +555,9 @@ class Default(Subconstruct[SubconParsedType, SubconBuildTypes, ParsedType, Build t.Optional[SubconBuildTypes], ]: ... -class Check(Construct[None, None]): +class Check(Construct[ParsedType, BuildTypes]): func: ConstantOrContextLambda[bool] - def __init__(self, func: ConstantOrContextLambda[bool]) -> None: ... + def __new__(cls, func: ConstantOrContextLambda[bool]) -> Check[None, None]: ... Error: Construct[None, None] @@ -579,19 +579,24 @@ class NamedTuple( Adapter[ SubconParsedType, SubconBuildTypes, - t.Tuple[t.Any, ...], - t.Union[t.Tuple[t.Any, ...], t.List[t.Any], t.Dict[str, t.Any]], + ParsedType, + BuildTypes, ] ): tuplename: str tuplefields: str factory: Construct[SubconParsedType, SubconBuildTypes] - def __init__( - self, + def __new__( + cls, tuplename: str, tuplefields: str, subcon: Construct[SubconParsedType, SubconBuildTypes], - ) -> None: ... + ) -> NamedTuple[ + SubconParsedType, + SubconBuildTypes, + t.Tuple[t.Any, ...], + t.Union[t.Tuple[t.Any, ...], t.List[t.Any], t.Dict[str, t.Any]], + ]: ... if sys.version_info >= (3, 8): MSDOS = t.Literal["msdos"] diff --git a/construct_typed/tenum.py b/construct_typed/tenum.py index d9454c8..bba5e98 100644 --- a/construct_typed/tenum.py +++ b/construct_typed/tenum.py @@ -51,7 +51,7 @@ class TEnum(Adapter[int, int, EnumType, EnumType]): self.enum_type = t.cast(t.Type[EnumType], enum_type) # type: ignore # init adatper - super(TEnum, self).__init__(subcon) + super(TEnum, self).__init__(subcon) # type: ignore def _decode(self, obj: int, context: Context, path: PathType) -> EnumType: return self.enum_type(obj) @@ -89,7 +89,7 @@ class TFlagsEnum(Adapter[int, int, FlagsEnumType, FlagsEnumType]): self.enum_type = t.cast(t.Type[FlagsEnumType], enum_type) # type: ignore # init adatper - super(TFlagsEnum, self).__init__(subcon) + super(TFlagsEnum, self).__init__(subcon) # type: ignore def _decode(self, obj: int, context: Context, path: PathType) -> FlagsEnumType: return self.enum_type(obj) diff --git a/construct_typed/tstruct.py b/construct_typed/tstruct.py index 9c8b0ad..cb2d0b9 100644 --- a/construct_typed/tstruct.py +++ b/construct_typed/tstruct.py @@ -113,7 +113,7 @@ class _TStruct(Adapter[t.Any, t.Any, ContainerType, BuildTypes]): subcon_fields[field.name] = field.metadata["subcon"] # init adatper - super(_TStruct, self).__init__(self._create_subcon(subcon_fields)) + super(_TStruct, self).__init__(self._create_subcon(subcon_fields)) # type: ignore def _create_subcon( self, subcon_fields: t.Dict[str, t.Any] @@ -168,6 +168,14 @@ class TStruct(_TStruct[ContainerType, ContainerType]): Typed struct, based on standard dataclasses. """ + subcon: "cs.Struct[t.Any, t.Any]" + if t.TYPE_CHECKING: + + def __new__( + cls, container_type: t.Type[ContainerType], swapped: bool = False + ) -> "TStruct[ContainerType]": + ... + def _create_subcon( self, subcon_fields: t.Dict[str, t.Any] ) -> Construct[t.Any, t.Any]: @@ -179,6 +187,13 @@ class TBitStruct(_TStruct[ContainerType, ContainerType]): Typed bit struct, based on standard dataclasses. """ + if t.TYPE_CHECKING: + + def __new__( + cls, container_type: t.Type[ContainerType], swapped: bool = False + ) -> "TBitStruct[ContainerType]": + ... + def _create_subcon( self, subcon_fields: t.Dict[str, t.Any] ) -> Construct[t.Any, t.Any]: diff --git a/tests/test_core.py b/tests/test_core.py index 9fa90f4..1056a09 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1687,9 +1687,9 @@ def test_from_issue_362() -> None: "my_tell" / Tell, "my_bits" / Bit[8], ) - for i in range(5): + for _ in range(5): assert FORMAT.parse(b'\x00').my_tell == 0 - for i in range(5): + for _ in range(5): assert BIT_FORMAT.parse(b'\x00').my_tell == 0 @pytest.mark.xfail(raises=AttributeError, reason="can't access Enums inside BitStruct") @@ -2075,7 +2075,7 @@ def test_from_issue_692() -> None: "length" / Int8ul, # The size in bytes of each handle/value pair "datalist" / Array(2, FixedSized(this.length, AttributeHandleValuePair)), ) - assert AttReadByTypeResponse.parse(b"\x04\x01\x02\x03\x04\x01\x02\x03\x04") == Container(length=4,datalist=[dict(handle=0x0201,value=b'\x03\x04'),dict(handle=0x0201,value=b'\x03\x04')]) + assert AttReadByTypeResponse.parse(b"\x04\x01\x02\x03\x04\x01\x02\x03\x04") == Container(length=4,datalist=[{"handle":0x0201,"value":b'\x03\x04'},{"handle": 0x0201,"value": b'\x03\x04'}]) assert AttReadByTypeResponse.sizeof(length=4) == 1+2*4 AttributeHandleValuePair = Struct( @@ -2086,7 +2086,7 @@ def test_from_issue_692() -> None: "length" / Int8ul, # The size in bytes of each handle/value pair "datalist" / AttributeHandleValuePair[2], ) - assert AttReadByTypeResponse.parse(b"\x04\x01\x02\x03\x04\x01\x02\x03\x04") == Container(length=4,datalist=[dict(handle=0x0201,value=b'\x03\x04'),dict(handle=0x0201,value=b'\x03\x04')]) + assert AttReadByTypeResponse.parse(b"\x04\x01\x02\x03\x04\x01\x02\x03\x04") == Container(length=4,datalist=[{"handle": 0x0201,"value": b'\x03\x04'},{"handle": 0x0201,"value": b'\x03\x04'}]) assert AttReadByTypeResponse.sizeof(length=4) == 1+2*(2+4-2) def test_greedyrange_issue_697() -> None: