From 270d2776855ffc65a4d55f92e57338952f8434e9 Mon Sep 17 00:00:00 2001 From: timrid <6593626+timrid@users.noreply.github.com> Date: Mon, 20 Jul 2026 11:16:04 +0200 Subject: [PATCH] Use PEP604 union syntax "X | Y" instead of "Union[X, Y]" and "X | None" instead of "Optional[X]" in type hints. We are using Python 3.10+ so we can use the new syntax. --- CHANGELOG.md | 3 + construct-stubs/core.pyi | 234 ++++++++++++---------------- construct-stubs/debug.pyi | 2 +- construct-stubs/expr.pyi | 18 +-- construct-stubs/lib/bitstream.pyi | 18 +-- construct-stubs/lib/containers.pyi | 4 +- construct-stubs/lib/py3compat.pyi | 4 +- construct_typed/dataclass_struct.py | 34 ++-- construct_typed/generic_wrapper.py | 2 +- construct_typed/tenum.py | 8 +- pyproject.toml | 4 +- tests/declarativeunittest.py | 40 ++--- tests/test_typed.py | 4 +- tests/test_typed_pyright.py | 4 +- 14 files changed, 171 insertions(+), 208 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 794842f..2bf66b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,11 @@ - Added `csfield_const` to create dataclass fields that are excluded from constructor and have a constant value. - Added `csfield_default` to create dataclass fields that have a default value. - Added `csfield_noinit` to create dataclass fields that are excluded from constructor. + +**Changes:** - Optimize type stubs for `Computed`, `Default` and `Rebuild` in conjunction with `ty`. - Optimize type stubs for `Checksum`, to represent that it can build from `None`. +- Use PEP604 union syntax "X | Y" instead of "Union[X, Y]" and "X | None" instead of "Optional[X]" in type hints. **Organizational changes:** - Use `uv` as a project management tool and `poe` as a task runner. \ No newline at end of file diff --git a/construct-stubs/core.pyi b/construct-stubs/core.pyi index 710de9e..361c2ab 100644 --- a/construct-stubs/core.pyi +++ b/construct-stubs/core.pyi @@ -33,7 +33,7 @@ from typing_extensions import Buffer, TypeAlias ReadableBuffer: TypeAlias = Buffer StreamType = t.IO[bytes] -FilenameType = t.Union[str, bytes, os.PathLike[str], os.PathLike[bytes]] +FilenameType = str | bytes | os.PathLike[str] | os.PathLike[bytes] PathType = str ContextKWType = t.Any @@ -41,9 +41,9 @@ ContextKWType = t.Any # exceptions # =============================================================================== class ConstructError(Exception): - path: t.Optional[PathType] + path: PathType | None def __init__( - self, message: str = ..., path: t.Optional[PathType] = ... + self, message: str = ..., path: PathType | None = ... ) -> None: ... class SizeofError(ConstructError): ... @@ -78,16 +78,16 @@ class CipherError(ConstructError): ... # used internally # =============================================================================== def stream_read( - stream: StreamType, length: int, path: t.Optional[PathType] + stream: StreamType, length: int, path: PathType | None ) -> bytes: ... -def stream_read_entire(stream: StreamType, path: t.Optional[PathType]) -> bytes: ... +def stream_read_entire(stream: StreamType, path: PathType | None) -> bytes: ... def stream_write( - stream: StreamType, data: bytes, length: int, path: t.Optional[PathType] + stream: StreamType, data: bytes, length: int, path: PathType | None ) -> None: ... def stream_seek( - stream: StreamType, offset: int, whence: int, path: t.Optional[PathType] + stream: StreamType, offset: int, whence: int, path: PathType | None ) -> int: ... -def stream_tell(stream: StreamType, path: t.Optional[PathType]) -> int: ... +def stream_tell(stream: StreamType, path: PathType | None) -> int: ... def stream_size(stream: StreamType) -> int: ... def stream_iseof(stream: StreamType) -> bool: ... def evaluate(param: ConstantOrContextLambda2[T], context: Context) -> T: ... @@ -110,10 +110,10 @@ ParsedType = t.TypeVar("ParsedType", covariant=True) BuildTypes = t.TypeVar("BuildTypes", contravariant=True) class Construct(t.Generic[ParsedType, BuildTypes]): - name: t.Optional[str] + name: str | None docs: str flagbuildnone: bool - parsed: t.Optional[t.Callable[[ParsedType, Context], None]] + parsed: t.Callable[[ParsedType, Context], None] | None def parse(self, data: ReadableBuffer, **contextkw: ContextKWType) -> ParsedType: ... def parse_stream( self, stream: StreamType, **contextkw: ContextKWType @@ -139,21 +139,21 @@ class Construct(t.Generic[ParsedType, BuildTypes]): self, schemaname: str = ..., filename: FilenameType = ... ) -> str: ... def __rtruediv__( - self, name: t.Optional[t.AnyStr] + self, name: t.AnyStr | None ) -> Renamed[ParsedType, BuildTypes]: ... __rdiv__: t.Callable[[str], Construct[ParsedType, BuildTypes]] def __mul__( self, - other: t.Union[str, bytes, t.Callable[[ParsedType, Context], None]], + other: str | bytes | t.Callable[[ParsedType, Context], None], ) -> Renamed[ParsedType, BuildTypes]: ... def __rmul__( self, - other: t.Union[str, bytes, t.Callable[[ParsedType, Context], None]], + other: str | bytes | t.Callable[[ParsedType, Context], None], ) -> Renamed[ParsedType, BuildTypes]: ... def __add__(self, other: Construct[t.Any, t.Any]) -> Struct: ... def __rshift__(self, other: Construct[t.Any, t.Any]) -> Sequence: ... def __getitem__( - self, count: t.Union[int, t.Callable[[Context], int]] + self, count: int | t.Callable[[Context], int] ) -> Array[ ParsedType, BuildTypes, @@ -182,8 +182,8 @@ class Context(Container[t.Any]): _index: int # optional field ValueType = t.TypeVar("ValueType") -ConstantOrContextLambda = t.Union[ValueType, t.Callable[[Context], t.Any]] -ConstantOrContextLambda2 = t.Union[ValueType, t.Callable[[Context], ValueType]] +ConstantOrContextLambda = ValueType | t.Callable[[Context], t.Any] +ConstantOrContextLambda2 = ValueType | t.Callable[[Context], ValueType] SubconParsedType = t.TypeVar("SubconParsedType", covariant=True) SubconBuildTypes = t.TypeVar("SubconBuildTypes", contravariant=True) @@ -238,8 +238,8 @@ class Tunnel( def _encode(self, data: bytes, context: Context, path: PathType) -> bytes: ... class Compiled(Construct[t.Any, t.Any]): - source: t.Optional[str] - defersubcon: t.Optional[Construct[t.Any, t.Any]] + source: str | None + defersubcon: Construct[t.Any, t.Any] | None parsefunc: t.Callable[[StreamType, Context], t.Any] buildfunc: t.Callable[[t.Any, StreamType, Context], t.Any] def __init__( @@ -251,27 +251,21 @@ class Compiled(Construct[t.Any, t.Any]): # =============================================================================== # bytes and bits # =============================================================================== -class Bytes(Construct[bytes, t.Union[bytes, bytearray, int]]): +class Bytes(Construct[bytes, bytes | bytearray | int]): length: ConstantOrContextLambda[int] def __init__( self, length: ConstantOrContextLambda[int], ) -> None: ... -GreedyBytes: Construct[bytes, t.Union[bytes, bytearray]] +GreedyBytes: Construct[bytes, bytes | bytearray] def Bitwise( subcon: Construct[SubconParsedType, SubconBuildTypes], -) -> t.Union[ - Transformed[SubconParsedType, SubconBuildTypes], - Restreamed[SubconParsedType, SubconBuildTypes], -]: ... +) -> Transformed[SubconParsedType, SubconBuildTypes] | Restreamed[SubconParsedType, SubconBuildTypes]: ... def Bytewise( subcon: Construct[SubconParsedType, SubconBuildTypes], -) -> t.Union[ - Transformed[SubconParsedType, SubconBuildTypes], - Restreamed[SubconParsedType, SubconBuildTypes], -]: ... +) -> Transformed[SubconParsedType, SubconBuildTypes] | Restreamed[SubconParsedType, SubconBuildTypes]: ... # =============================================================================== # integers and floats @@ -280,7 +274,7 @@ class FormatField(Construct[ParsedType, BuildTypes]): fmtstr: str length: int if sys.version_info >= (3, 8): - ENDIANITY = t.Union[t.Literal["=", "<", ">"], str] + ENDIANITY = t.Literal["=", "<", ">"] | str FORMAT_INT = t.Literal["B", "H", "L", "Q", "b", "h", "l", "q"] FORMAT_FLOAT = t.Literal["f", "d", "e"] FORMAT_BOOL = t.Literal["?"] @@ -406,7 +400,7 @@ class StringEncoded(Construct[str, str]): ENCODING_1 = t.Literal["ascii", "utf8", "utf_8", "u8"] ENCODING_2 = t.Literal["utf16", "utf_16", "u16", "utf_16_be", "utf_16_le"] ENCODING_4 = t.Literal["utf32", "utf_32", "u32", "utf_32_be", "utf_32_le"] - ENCODING = t.Union[str, ENCODING_1, ENCODING_2, ENCODING_4] + ENCODING = str | ENCODING_1 | ENCODING_2 | ENCODING_4 else: ENCODING = str encoding: ENCODING @@ -437,7 +431,7 @@ class EnumIntegerString(str): def new(intvalue: int, stringvalue: str) -> EnumIntegerString: ... class Enum( - Adapter[int, int, t.Union[EnumInteger, EnumIntegerString], t.Union[int, str]] + Adapter[int, int, EnumInteger | EnumIntegerString, int | str] ): encmapping: t.Dict[str, int] decmapping: t.Dict[int, EnumIntegerString] @@ -445,7 +439,7 @@ class Enum( def __init__( self, subcon: Construct[int, int], - *merge: t.Union[t.Type[enum.IntEnum], t.Type[enum.IntFlag]], + *merge: t.Type[enum.IntEnum] | t.Type[enum.IntFlag], **mapping: int, ) -> None: ... def __getattr__(self, name: str) -> EnumIntegerString: ... @@ -454,14 +448,14 @@ class BitwisableString(str): def __or__(self, other: BitwisableString) -> BitwisableString: ... class FlagsEnum( - Adapter[int, int, Container[bool], t.Union[int, str, t.Dict[str, bool]]] + Adapter[int, int, Container[bool], int | str | t.Dict[str, bool]] ): flags: t.Dict[str, int] reverseflags: t.Dict[int, str] def __init__( self, subcon: Construct[int, int], - *merge: t.Union[t.Type[enum.IntEnum], t.Type[enum.IntFlag]], + *merge: t.Type[enum.IntEnum] | t.Type[enum.IntFlag], **flags: int, ) -> None: ... def __getattr__(self, name: str) -> BitwisableString: ... @@ -479,7 +473,7 @@ class Mapping(Adapter[SubconParsedType, SubconBuildTypes, t.Any, t.Any]): # structures and sequences # =============================================================================== # this can maybe made better when variadic generics are available -class Struct(Construct[Container[t.Any], t.Optional[t.Dict[str, t.Any]]]): +class Struct(Construct[Container[t.Any], t.Dict[str, t.Any] | None]): subcons: t.List[Construct[t.Any, t.Any]] _subcons: t.Dict[str, Construct[t.Any, t.Any]] def __init__( @@ -490,7 +484,7 @@ class Struct(Construct[Container[t.Any], t.Optional[t.Dict[str, t.Any]]]): def __getattr__(self, name: str) -> t.Any: ... # this can maybe made better when variadic generics are available -class Sequence(Construct[ListContainer[t.Any], t.Optional[t.List[t.Any]]]): +class Sequence(Construct[ListContainer[t.Any], t.List[t.Any] | None]): subcons: t.List[Construct[t.Any, t.Any]] _subcons: t.Dict[str, Construct[t.Any, t.Any]] def __init__( @@ -543,19 +537,11 @@ class RepeatUntil( t.List[SubconBuildTypes], # type: ignore ] ): - predicate: t.Union[ - bool, - t.Callable[[SubconParsedType, ListContainer[SubconParsedType], Context], bool], - ] + predicate: bool | t.Callable[[SubconParsedType, ListContainer[SubconParsedType], Context], bool] discard: bool def __init__( self, - predicate: t.Union[ - bool, - t.Callable[ - [SubconParsedType, ListContainer[SubconParsedType], Context], bool - ], - ], + predicate: bool | t.Callable[[SubconParsedType, ListContainer[SubconParsedType], Context], bool], subcon: Construct[SubconParsedType, SubconBuildTypes], discard: bool = ..., ) -> None: ... @@ -569,9 +555,9 @@ class Renamed( def __init__( self, subcon: Construct[SubconParsedType, SubconBuildTypes], - newname: t.Optional[str] = ..., - newdocs: t.Optional[str] = ..., - newparsed: t.Optional[t.Callable[[t.Any, Context], None]] = ..., + newname: str | None = ..., + newdocs: str | None = ..., + newparsed: t.Callable[[t.Any, Context], None] | None = ..., ) -> None: ... # =============================================================================== @@ -581,15 +567,15 @@ class Const(Subconstruct[t.Any, t.Any, ParsedType, BuildTypes]): value: BuildTypes @t.overload def __new__( - cls: "type[Const[bytes, t.Optional[bytes]]]", + cls: "type[Const[bytes, bytes | None]]", value: bytes, - ) -> Const[bytes, t.Optional[bytes]]: ... + ) -> Const[bytes, bytes | None]: ... @t.overload def __new__( - cls: "type[Const[SubconParsedType, t.Optional[SubconBuildTypes]]]", + cls: "type[Const[SubconParsedType, SubconBuildTypes | None]]", value: SubconBuildTypes, subcon: Construct[SubconParsedType, SubconBuildTypes], - ) -> Const[SubconParsedType, t.Optional[SubconBuildTypes]]: ... + ) -> Const[SubconParsedType, SubconBuildTypes | None]: ... class Computed(Construct[ParsedType, None]): func: ConstantOrContextLambda2[ParsedType] @@ -626,7 +612,7 @@ class Default( SubconParsedType, SubconBuildTypes, SubconParsedType, - t.Optional[SubconBuildTypes], + SubconBuildTypes | None, ] ): value: ConstantOrContextLambda2[SubconBuildTypes] @@ -672,7 +658,7 @@ class NamedTuple( SubconParsedType, SubconBuildTypes, t.Tuple[t.Any, ...], - t.Union[t.Tuple[t.Any, ...], t.List[t.Any], t.Dict[str, t.Any]], + t.Tuple[t.Any, ...] | t.List[t.Any] | t.Dict[str, t.Any], ] ): tuplename: str @@ -701,14 +687,14 @@ def Timestamp( @t.overload def Timestamp( subcon: Construct[int, int], - unit: t.Union[int, float], - epoch: t.Union[int, arrow.Arrow], + unit: int | float, + epoch: int | arrow.Arrow, ) -> TimestampAdapter[int, int]: ... @t.overload def Timestamp( subcon: Construct[float, float], - unit: t.Union[int, float], - epoch: t.Union[int, arrow.Arrow], + unit: int | float, + epoch: int | arrow.Arrow, ) -> TimestampAdapter[float, float]: ... K = t.TypeVar("K") @@ -727,10 +713,10 @@ class Hex(Adapter[t.Any, t.Any, ParsedType, BuildTypes]): ) -> Hex[HexDisplayedBytes, BuildTypes]: ... @t.overload def __new__( - cls: "type[Hex[HexDisplayedDict[str, t.Union[int, bytes, SubconParsedType]], BuildTypes,]]", + cls: "type[Hex[HexDisplayedDict[str, int | bytes | SubconParsedType], BuildTypes,]]", subcon: Construct[RawCopyObj[SubconParsedType], BuildTypes], ) -> Hex[ - HexDisplayedDict[str, t.Union[int, bytes, SubconParsedType]], + HexDisplayedDict[str, int | bytes | SubconParsedType], BuildTypes, ]: ... @t.overload @@ -752,10 +738,10 @@ class HexDump(Adapter[t.Any, t.Any, ParsedType, BuildTypes]): ) -> HexDump[HexDumpDisplayedBytes, BuildTypes]: ... @t.overload def __new__( - cls: "type[HexDump[HexDumpDisplayedDict[str, t.Union[int, bytes, SubconParsedType]],BuildTypes,]]", + cls: "type[HexDump[HexDumpDisplayedDict[str, int | bytes | SubconParsedType],BuildTypes,]]", subcon: Construct[RawCopyObj[SubconParsedType], BuildTypes], ) -> HexDump[ - HexDumpDisplayedDict[str, t.Union[int, bytes, SubconParsedType]], + HexDumpDisplayedDict[str, int | bytes | SubconParsedType], BuildTypes, ]: ... @t.overload @@ -774,12 +760,12 @@ class HexDump(Adapter[t.Any, t.Any, ParsedType, BuildTypes]): # =============================================================================== # this can maybe made better when variadic generics are available class Union(Construct[Container[t.Any], t.Dict[str, t.Any]]): - parsefrom: t.Optional[ConstantOrContextLambda[t.Union[int, str]]] + parsefrom: ConstantOrContextLambda[int | str] | None subcons: t.List[Construct[t.Any, t.Any]] _subcons: t.Dict[str, Construct[t.Any, t.Any]] def __init__( self, - parsefrom: t.Optional[ConstantOrContextLambda[t.Union[int, str]]], + parsefrom: ConstantOrContextLambda[int | str] | None, *subcons: Construct[t.Any, t.Any], **subconskw: Construct[t.Any, t.Any], ) -> None: ... @@ -796,7 +782,7 @@ class Select(Construct[t.Any, t.Any]): def Optional( subcon: Construct[SubconParsedType, SubconBuildTypes], -) -> Construct[t.Union[SubconParsedType, None], t.Union[SubconBuildTypes, None]]: ... +) -> Construct[SubconParsedType | None, SubconBuildTypes | None]: ... ThenParsedType = t.TypeVar("ThenParsedType") ThenBuildTypes = t.TypeVar("ThenBuildTypes") @@ -809,11 +795,11 @@ class IfThenElse(Construct[ParsedType, BuildTypes]): elsesubcon: Construct[t.Any, t.Any] @t.overload def __new__( - cls: "type[IfThenElse[t.Union[ThenParsedType, ElseParsedType], t.Union[ThenBuildTypes, ElseBuildTypes]]]", + cls: "type[IfThenElse[ThenParsedType | ElseParsedType, ThenBuildTypes | ElseBuildTypes]]", condfunc: ConstantOrContextLambda[bool], thensubcon: Construct[ThenParsedType, ThenBuildTypes], elsesubcon: Construct[ElseParsedType, ElseBuildTypes], - ) -> "IfThenElse[t.Union[ThenParsedType, ElseParsedType], t.Union[ThenBuildTypes, ElseBuildTypes]]": ... + ) -> "IfThenElse[ThenParsedType | ElseParsedType, ThenBuildTypes | ElseBuildTypes]": ... @t.overload def __new__( cls: "type[IfThenElse[t.Any, t.Any]]", @@ -825,7 +811,7 @@ class IfThenElse(Construct[ParsedType, BuildTypes]): def If( condfunc: ConstantOrContextLambda[bool], subcon: Construct[ThenParsedType, ThenBuildTypes], -) -> IfThenElse[t.Optional[ThenParsedType], t.Optional[ThenBuildTypes]]: ... +) -> IfThenElse[ThenParsedType | None, ThenBuildTypes | None]: ... SwitchType = t.TypeVar("SwitchType") @@ -835,17 +821,17 @@ class Switch(Construct[ParsedType, BuildTypes]): default: Construct[t.Any, t.Any] @t.overload def __new__( - cls: "type[Switch[int, t.Optional[int]]]", + cls: "type[Switch[int, int | None]]", keyfunc: ConstantOrContextLambda[SwitchType], cases: t.Dict[SwitchType, Construct[int, int]], - default: t.Optional[Construct[int, int]] = ..., - ) -> Switch[int, t.Optional[int]]: ... + default: Construct[int, int] | None = ..., + ) -> Switch[int, int | None]: ... @t.overload def __new__( cls: "type[Switch[t.Any, t.Any]]", keyfunc: ConstantOrContextLambda[t.Any], cases: t.Dict[t.Any, Construct[t.Any, t.Any]], - default: t.Optional[Construct[t.Any, t.Any]] = ..., + default: Construct[t.Any, t.Any] | None = ..., ) -> Switch[t.Any, t.Any]: ... class StopIf(Construct[None, None]): @@ -893,10 +879,7 @@ def AlignedStruct( ) -> Struct: ... def BitStruct( *subcons: Construct[t.Any, t.Any], **subconskw: Construct[t.Any, t.Any] -) -> t.Union[ - Transformed[Container[t.Any], t.Dict[str, t.Any]], - Restreamed[Container[t.Any], t.Dict[str, t.Any]], -]: ... +) -> Transformed[Container[t.Any], t.Dict[str, t.Any]] | Restreamed[Container[t.Any], t.Dict[str, t.Any]]: ... # =============================================================================== # stream manipulation @@ -905,12 +888,12 @@ class Pointer( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes] ): offset: ConstantOrContextLambda[int] - stream: t.Optional[t.Callable[[Context], StreamType]] + stream: t.Callable[[Context], StreamType] | None def __init__( self, offset: ConstantOrContextLambda[int], subcon: Construct[SubconParsedType, SubconBuildTypes], - stream: t.Optional[t.Callable[[Context], StreamType]] = ..., + stream: t.Callable[[Context], StreamType] | None = ..., ) -> None: ... class Peek( @@ -918,7 +901,7 @@ class Peek( SubconParsedType, SubconBuildTypes, SubconParsedType, - t.Union[SubconBuildTypes, None], + SubconBuildTypes | None, ] ): def __init__( @@ -969,7 +952,7 @@ class RawCopy( SubconParsedType, SubconBuildTypes, RawCopyObj[SubconParsedType], - t.Optional[t.Dict[str, t.Union[SubconBuildTypes, bytes]]], + t.Dict[str, SubconBuildTypes | bytes] | None, ] ): def __init__( @@ -982,21 +965,18 @@ def ByteSwapped( ) -> Transformed[SubconParsedType, SubconBuildTypes]: ... def BitsSwapped( subcon: Construct[SubconParsedType, SubconBuildTypes], -) -> t.Union[ - Transformed[SubconParsedType, SubconBuildTypes], - Restreamed[SubconParsedType, SubconBuildTypes], -]: ... +) -> Transformed[SubconParsedType, SubconBuildTypes] | Restreamed[SubconParsedType, SubconBuildTypes]: ... class Prefixed( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes] ): lengthfield: Construct[SubconParsedType, SubconBuildTypes] - includelength: t.Optional[bool] + includelength: bool | None def __init__( self, lengthfield: Construct[int, int], subcon: Construct[SubconParsedType, SubconBuildTypes], - includelength: t.Optional[bool] = ..., + includelength: bool | None = ..., ) -> None: ... def PrefixedArray( @@ -1021,16 +1001,16 @@ class NullTerminated( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes] ): term: bytes - include: t.Optional[bool] - consume: t.Optional[bool] - require: t.Optional[bool] + include: bool | None + consume: bool | None + require: bool | None def __init__( self, subcon: Construct[SubconParsedType, SubconBuildTypes], term: bytes = ..., - include: t.Optional[bool] = ..., - consume: t.Optional[bool] = ..., - require: t.Optional[bool] = ..., + include: bool | None = ..., + consume: bool | None = ..., + require: bool | None = ..., ) -> None: ... class NullStripped( @@ -1046,14 +1026,10 @@ class NullStripped( class RestreamData( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, None] ): - datafunc: t.Union[ - bytes, io.BytesIO, Construct[bytes, t.Any], t.Callable[[Context], bytes] - ] + datafunc: bytes | io.BytesIO | Construct[bytes, t.Any] | t.Callable[[Context], bytes] def __init__( self, - datafunc: t.Union[ - bytes, io.BytesIO, Construct[bytes, t.Any], t.Callable[[Context], bytes] - ], + datafunc: bytes | io.BytesIO | Construct[bytes, t.Any] | t.Callable[[Context], bytes], subcon: Construct[SubconParsedType, SubconBuildTypes], ) -> None: ... @@ -1061,16 +1037,16 @@ class Transformed( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes] ): decodefunc: t.Callable[[bytes], bytes] - decodeamount: t.Optional[int] + decodeamount: int | None encodefunc: t.Callable[[bytes], bytes] - encodeamount: t.Optional[int] + encodeamount: int | None def __init__( self, subcon: Construct[SubconParsedType, SubconBuildTypes], decodefunc: t.Callable[[bytes], bytes], - decodeamount: t.Optional[int], + decodeamount: int | None, encodefunc: t.Callable[[bytes], bytes], - encodeamount: t.Optional[int], + encodeamount: int | None, ) -> None: ... class Restreamed( @@ -1094,10 +1070,10 @@ class Restreamed( class ProcessXor( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes] ): - padfunc: ConstantOrContextLambda2[t.Union[int, bytes]] + padfunc: ConstantOrContextLambda2[int | bytes] def __init__( self, - padfunc: ConstantOrContextLambda2[t.Union[int, bytes]], + padfunc: ConstantOrContextLambda2[int | bytes], subcon: Construct[SubconParsedType, SubconBuildTypes], ) -> None: ... @@ -1115,7 +1091,7 @@ class ProcessRotateLeft( T = t.TypeVar("T") -class Checksum(t.Generic[T, ParsedType, BuildTypes], Construct[ParsedType, t.Optional[BuildTypes]]): +class Checksum(t.Generic[T, ParsedType, BuildTypes], Construct[ParsedType, BuildTypes | None]): checksumfield: Construct[ParsedType, BuildTypes] hashfunc: t.Callable[[T], BuildTypes] bytesfunc: t.Callable[[Context], T] @@ -1128,13 +1104,13 @@ class Checksum(t.Generic[T, ParsedType, BuildTypes], Construct[ParsedType, t.Opt class Compressed(Tunnel[SubconParsedType, SubconBuildTypes]): encoding: str - level: t.Optional[int] + level: int | None lib: t.Any def __init__( self, subcon: Construct[SubconParsedType, SubconBuildTypes], encoding: str, - level: t.Optional[int] = ..., + level: int | None = ..., ) -> None: ... class CompressedLZ4(Tunnel[SubconParsedType, SubconBuildTypes]): @@ -1151,7 +1127,7 @@ class Rebuffered( def __init__( self, subcon: Construct[SubconParsedType, SubconBuildTypes], - tailcutoff: t.Optional[int] = ..., + tailcutoff: int | None = ..., ) -> None: ... class EncryptedSym(Tunnel[SubconParsedType, SubconBuildTypes]): @@ -1163,13 +1139,13 @@ class EncryptedSym(Tunnel[SubconParsedType, SubconBuildTypes]): ) -> None: ... class EncryptedSymAead(Tunnel[SubconParsedType, SubconBuildTypes]): - cipher: ConstantOrContextLambda2[t.Union[AESGCM, AESCCM, ChaCha20Poly1305]] + cipher: ConstantOrContextLambda2[AESGCM | AESCCM | ChaCha20Poly1305] nonce: ConstantOrContextLambda2[bytes] associated_data: ConstantOrContextLambda2[bytes] def __init__( self, subcon: Construct[SubconParsedType, SubconBuildTypes], - cipher: ConstantOrContextLambda2[t.Union[AESGCM, AESCCM, ChaCha20Poly1305]], + cipher: ConstantOrContextLambda2[AESGCM | AESCCM | ChaCha20Poly1305], nonce: ConstantOrContextLambda2[bytes], associated_data: ConstantOrContextLambda2[bytes] = ..., ) -> None: ... @@ -1182,7 +1158,7 @@ class Lazy( SubconParsedType, SubconBuildTypes, t.Callable[[], SubconParsedType], - t.Union[t.Callable[[], SubconParsedType], SubconParsedType], + t.Callable[[], SubconParsedType] | SubconParsedType, ] ): def __init__( @@ -1192,12 +1168,12 @@ 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 __getitem__(self, index: str | int) -> 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]]]): +class LazyStruct(Construct[LazyContainer[t.Any], t.Dict[str, t.Any] | None]): subcons: t.List[Construct[t.Any, t.Any]] _subcons: t.Dict[str, Construct[t.Any, t.Any]] _subconsindexes: t.Dict[str, int] @@ -1284,21 +1260,12 @@ class Slicing( ): def __init__( self, - subcon: t.Union[ - Array[ - SubconParsedType, - SubconBuildTypes, - ], - GreedyRange[ - SubconParsedType, - SubconBuildTypes, - ], - ], + subcon: Array[SubconParsedType, SubconBuildTypes] | GreedyRange[SubconParsedType, SubconBuildTypes], count: int, - start: t.Optional[int], - stop: t.Optional[int], + start: int | None, + stop: int | None, step: int = ..., - empty: t.Optional[SubconParsedType] = ..., + empty: SubconParsedType | None = ..., ) -> None: ... class Indexing( @@ -1306,17 +1273,8 @@ class Indexing( ): def __init__( self, - subcon: t.Union[ - Array[ - SubconParsedType, - SubconBuildTypes, - ], - GreedyRange[ - SubconParsedType, - SubconBuildTypes, - ], - ], + subcon: Array[SubconParsedType, SubconBuildTypes] | GreedyRange[SubconParsedType, SubconBuildTypes], count: int, index: int, - empty: t.Optional[SubconParsedType] = ..., + empty: SubconParsedType | None = ..., ) -> None: ... diff --git a/construct-stubs/debug.pyi b/construct-stubs/debug.pyi index 1234663..d840392 100644 --- a/construct-stubs/debug.pyi +++ b/construct-stubs/debug.pyi @@ -6,7 +6,7 @@ ContextLambda = t.Callable[[Context], t.Any] class Probe(Construct[None, None]): def __init__( - self, into: t.Optional[ContextLambda] = ..., lookahead: int = ... + self, into: ContextLambda | None = ..., lookahead: int = ... ) -> None: ... class Debugger(Subconstruct[None, None, None, None]): ... diff --git a/construct-stubs/expr.pyi b/construct-stubs/expr.pyi index 5e37428..ef4c0b1 100644 --- a/construct-stubs/expr.pyi +++ b/construct-stubs/expr.pyi @@ -9,7 +9,7 @@ ReturnType = t.TypeVar("ReturnType") LhsReturnType = t.TypeVar("LhsReturnType") RhsReturnType = t.TypeVar("RhsReturnType") -ConstOrCallable = t.Union[ReturnType, t.Callable[[ReturnType], ReturnType]] +ConstOrCallable = ReturnType | t.Callable[[ReturnType], ReturnType] class ExprMixin(t.Generic[ReturnType], object): # __add__ ########################################################################################################## @@ -767,24 +767,24 @@ class ExprMixin(t.Generic[ReturnType], object): class UniExpr(ExprMixin[ReturnType]): def __init__(self, op: UniOperator, operand: t.Any) -> None: ... def __call__( - self, obj: t.Union[Context, dict[str, t.Any], t.Any], *args: t.Any + self, obj: Context | dict[str, t.Any] | t.Any, *args: t.Any ) -> ReturnType: ... class BinExpr(ExprMixin[ReturnType]): def __init__(self, op: BinOperator, lhs: t.Any, rhs: t.Any) -> None: ... def __call__( - self, obj: t.Union[Context, dict[str, t.Any], t.Any], *args: t.Any + self, obj: Context | dict[str, t.Any] | t.Any, *args: t.Any ) -> ReturnType: ... class Path(ExprMixin[ReturnType]): def __init__( self, name: str, - field: t.Optional[str] = ..., - parent: t.Optional[Path[t.Any]] = ..., + field: str | None = ..., + parent: Path[t.Any] | None = ..., ) -> None: ... def __call__( - self, obj: t.Union[Context, dict[str, t.Any], t.Any], *args: t.Any + self, obj: Context | dict[str, t.Any] | t.Any, *args: t.Any ) -> ReturnType: ... def __getattr__(self, name: str) -> Path[t.Any]: ... def __getitem__(self, name: str) -> Path[t.Any]: ... @@ -793,15 +793,15 @@ class Path2(ExprMixin[ReturnType]): def __init__( self, name: str, - index: t.Optional[int] = ..., - parent: t.Optional[Path2[t.Any]] = ..., + index: int | None = ..., + parent: Path2[t.Any] | None = ..., ) -> None: ... def __call__(self, *args: t.Any) -> ReturnType: ... def __getitem__(self, index: int) -> Path2[t.Any]: ... class FuncPath(ExprMixin[ReturnType]): def __init__( - self, func: t.Callable[[t.Any], ReturnType], operand: t.Optional[t.Any] = ... + self, func: t.Callable[[t.Any], ReturnType], operand: t.Any | None = ... ) -> None: ... def __call__(self, operand: t.Any, *args: t.Any) -> ReturnType: ... diff --git a/construct-stubs/lib/bitstream.pyi b/construct-stubs/lib/bitstream.pyi index 6785ea5..eb41cf0 100644 --- a/construct-stubs/lib/bitstream.pyi +++ b/construct-stubs/lib/bitstream.pyi @@ -2,7 +2,7 @@ import io import typing as t class RestreamedBytesIO(object): - substream: t.Optional[io.BytesIO] + substream: io.BytesIO | None encoder: t.Callable[[bytes], bytes] encoderunit: int decoder: t.Callable[[bytes], bytes] @@ -12,14 +12,14 @@ class RestreamedBytesIO(object): sincereadwritten: int def __init__( self, - substream: t.Optional[io.BytesIO], + substream: io.BytesIO | None, decoder: t.Callable[[bytes], bytes], decoderunit: int, encoder: t.Callable[[bytes], bytes], encoderunit: int, ) -> None: ... - def read(self, count: t.Optional[int] = ...) -> bytes: ... - def write(self, data: t.Union[bytes, bytearray, memoryview]) -> int: ... + def read(self, count: int | None = ...) -> bytes: ... + def write(self, data: bytes | bytearray | memoryview) -> int: ... def close(self) -> None: ... def seek(self, at: int, whence: int = ...) -> int: ... def seekable(self) -> bool: ... @@ -27,16 +27,16 @@ class RestreamedBytesIO(object): def tellable(self) -> bool: ... class RebufferedBytesIO(object): - substream: t.Optional[io.BytesIO] + substream: io.BytesIO | None offset: int rwbuffer: bytes moved: int - tailcutoff: t.Optional[int] + tailcutoff: int | None def __init__( - self, substream: t.Optional[io.BytesIO], tailcutoff: t.Optional[int] = ... + self, substream: io.BytesIO | None, tailcutoff: int | None = ... ) -> None: ... - def read(self, count: t.Optional[int] = ...) -> bytes: ... - def write(self, data: t.Union[bytes, bytearray, memoryview]) -> int: ... + def read(self, count: int | None = ...) -> bytes: ... + def write(self, data: bytes | bytearray | memoryview) -> int: ... def seek(self, at: int, whence: int = ...) -> int: ... def seekable(self) -> bool: ... def tell(self) -> int: ... diff --git a/construct-stubs/lib/containers.pyi b/construct-stubs/lib/containers.pyi index 37efc75..3ceed7d 100644 --- a/construct-stubs/lib/containers.pyi +++ b/construct-stubs/lib/containers.pyi @@ -4,7 +4,7 @@ import typing as t ContainerType = t.TypeVar("ContainerType") ListType = t.TypeVar("ListType") -SearchPattern = t.Union[t.AnyStr, re.Pattern[t.AnyStr]] +SearchPattern = t.AnyStr | re.Pattern[t.AnyStr] globalPrintFullStrings: bool globalPrintFalseFlags: bool @@ -21,7 +21,7 @@ class Container(t.Generic[ContainerType], t.Dict[str, ContainerType]): def __getattr__(self, name: str) -> ContainerType: ... def update( # type: ignore self, - seqordict: t.Union[t.Dict[str, ContainerType], t.Tuple[str, ContainerType]], + seqordict: t.Dict[str, ContainerType] | t.Tuple[str, ContainerType], ) -> None: ... def search(self, pattern: SearchPattern[t.Any]) -> t.Any: ... def search_all(self, pattern: SearchPattern[t.Any]) -> t.Any: ... diff --git a/construct-stubs/lib/py3compat.pyi b/construct-stubs/lib/py3compat.pyi index c86f2f5..c3ebff1 100644 --- a/construct-stubs/lib/py3compat.pyi +++ b/construct-stubs/lib/py3compat.pyi @@ -15,7 +15,7 @@ def int2byte(character: int) -> bytes: ... def byte2int(character: bytes) -> int: ... def str2bytes(string: str) -> bytes: ... def bytes2str(string: bytes) -> str: ... -def reprstring(data: t.Union[bytes, str]) -> str: ... -def trimstring(data: t.Union[bytes, str]) -> str: ... +def reprstring(data: bytes | str) -> str: ... +def trimstring(data: bytes | str) -> str: ... def integers2bytes(ints: t.Iterable[int]) -> bytes: ... def bytes2integers(data: bytes) -> list[int]: ... diff --git a/construct_typed/dataclass_struct.py b/construct_typed/dataclass_struct.py index 0a3951c..8fa07fb 100644 --- a/construct_typed/dataclass_struct.py +++ b/construct_typed/dataclass_struct.py @@ -20,10 +20,11 @@ class DataclassFieldError(Exception): """Exception raised by csfield, csfield_noinit, csfield_const and csfield_default.""" + def _rename_subcon( subcon: Construct[T, t.Any], - doc: t.Optional[str] = None, - parsed: t.Optional[t.Callable[[t.Any, Context], None]] = None, + doc: str | None = None, + parsed: t.Callable[[t.Any, Context], None] | None = None, ) -> Construct[T, t.Any]: """Helper method to rename a subcon if doc or parsed are available.""" if (doc is not None) or (parsed is not None): @@ -35,8 +36,8 @@ def _rename_subcon( def csfield( subcon: Construct[T, t.Any], - doc: t.Optional[str] = None, - parsed: t.Optional[t.Callable[[t.Any, Context], None]] = None, + doc: str | None = None, + parsed: t.Callable[[t.Any, Context], None] | None = None, *, kw_only: bool = False, ) -> T: @@ -71,8 +72,8 @@ def csfield( def csfield_noinit( subcon: Construct[T, None], - doc: t.Optional[str] = None, - parsed: t.Optional[t.Callable[[t.Any, Context], None]] = None, + doc: str | None = None, + parsed: t.Callable[[t.Any, Context], None] | None = None, *, # "init" should not be used by users. It is only for type checkers to see that this field is excluded from __init__. init: t.Literal[False] = False, @@ -92,7 +93,7 @@ def csfield_noinit( raise DataclassFieldError( "csfield_noinit() can only be used with constructs that have flagbuildnone=True (Const, Rebuild, Computed, Padding, Tell, Pass, Terminated)." ) - + subcon = _rename_subcon(subcon, doc, parsed) return t.cast( @@ -108,8 +109,8 @@ def csfield_noinit( def csfield_const( subcon: Construct[T, t.Any], const: T, - doc: t.Optional[str] = None, - parsed: t.Optional[t.Callable[[t.Any, Context], None]] = None, + doc: str | None = None, + parsed: t.Callable[[t.Any, Context], None] | None = None, *, # "init" should not be used by users. It is only for type checkers to see that this field is excluded from __init__. init: t.Literal[False] = False, @@ -126,7 +127,9 @@ def csfield_const( "``cs.Const``, ``cs.Default`` or ``cs.Computed``). Pass the plain, unwrapped subcon instead." ) if callable(const): - raise DataclassFieldError("csfield_const() cannot be used with context lambdas.") + raise DataclassFieldError( + "csfield_const() cannot be used with context lambdas." + ) if isinstance(subcon, cs.Const): raise DataclassFieldError( "csfield_const() cannot be used with a subcon that is already a ``cs.Const``. Pass the plain, unwrapped subcon instead." @@ -135,7 +138,7 @@ def csfield_const( subcon = cs.Const(const, subcon) subcon = _rename_subcon(subcon, doc, parsed) - return t.cast( + return t.cast( T, dataclasses.field( default=const, @@ -147,8 +150,8 @@ def csfield_const( def csfield_default( subcon: Construct[T, t.Any], - doc: t.Optional[str] = None, - parsed: t.Optional[t.Callable[[t.Any, Context], None]] = None, + doc: str | None = None, + parsed: t.Callable[[t.Any, Context], None] | None = None, *, default: T, ) -> T: @@ -363,10 +366,7 @@ def _encode( def DataclassBitStruct( dc_type: t.Type[DataclassType], reverse: bool = False -) -> t.Union[ - "cs.Transformed[DataclassType, DataclassType]", - "cs.Restreamed[DataclassType, DataclassType]", -]: +) -> "cs.Transformed[DataclassType, DataclassType] | cs.Restreamed[DataclassType, DataclassType]": r""" Makes a DataclassStruct inside a Bitwise. diff --git a/construct_typed/generic_wrapper.py b/construct_typed/generic_wrapper.py index 7a055cb..c6f1084 100644 --- a/construct_typed/generic_wrapper.py +++ b/construct_typed/generic_wrapper.py @@ -44,5 +44,5 @@ class Array( ): pass - ConstantOrContextLambda = t.Union[ValueType, t.Callable[[Context], t.Any]] + ConstantOrContextLambda = ValueType | t.Callable[[Context], t.Any] PathType = str diff --git a/construct_typed/tenum.py b/construct_typed/tenum.py index 48f188f..5fb334b 100644 --- a/construct_typed/tenum.py +++ b/construct_typed/tenum.py @@ -12,7 +12,7 @@ class EnumValue: This is a helper class for adding documentation to an enum value. """ - def __init__(self, value: int, doc: t.Optional[str] = None) -> None: + def __init__(self, value: int, doc: str | None = None) -> None: self.value = value self.__doc__ = doc if doc else "" @@ -47,7 +47,7 @@ class EnumBase(enum.IntEnum): 'This is the running state.' """ - def __new__(cls, val: t.Union[EnumValue, int]) -> "Self": + def __new__(cls, val: EnumValue | int) -> "Self": if isinstance(val, EnumValue): obj = int.__new__(cls, val.value) obj._value_ = val.value @@ -62,7 +62,7 @@ def __new__(cls, val: t.Union[EnumValue, int]) -> "Self": # not found in the enum, a new pseudo member is created. # The idea is taken from: https://stackoverflow.com/a/57179436 @classmethod - def _missing_(cls, value: t.Any) -> t.Optional[enum.Enum]: + def _missing_(cls, value: t.Any) -> enum.Enum | None: if isinstance(value, int): pseudo_member = cls._value2member_map_.get(value, None) if pseudo_member is None: @@ -153,7 +153,7 @@ class FlagsEnumBase(enum.IntFlag): 'This is option two.' """ - def __new__(cls, val: t.Union[EnumValue, int]) -> "Self": + def __new__(cls, val: EnumValue | int) -> "Self": if isinstance(val, EnumValue): obj = int.__new__(cls, val.value) obj._value_ = val.value diff --git a/pyproject.toml b/pyproject.toml index 4ba4fe7..31697e1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -148,7 +148,9 @@ output-format = "concise" # "full" | "concise" | "grouped" | "json" | "junit" | [tool.ruff.lint] allowed-confusables = ["×", "–", "‘", "’"] select = [ - "I" + "I", + "UP007", + "UP045" ] [tool.poe.tasks.test] diff --git a/tests/declarativeunittest.py b/tests/declarativeunittest.py index a53fd17..a315126 100644 --- a/tests/declarativeunittest.py +++ b/tests/declarativeunittest.py @@ -25,7 +25,7 @@ skip = pytest.mark.skip skipif = pytest.mark.skipif -Buffer = t.Union[bytes, memoryview, bytearray] +Buffer = bytes | memoryview | bytearray ParsedType = t.TypeVar("ParsedType") BuildTypes = t.TypeVar("BuildTypes") ContainerType = t.TypeVar("ContainerType", bound=cst.TContainerMixin) @@ -35,7 +35,7 @@ class ZeroIO(io.BufferedIOBase): - def read(self, __size: t.Optional[int] = None) -> bytes: + def read(self, __size: int | None = None) -> bytes: if __size is not None: return bytes(__size) else: @@ -54,7 +54,7 @@ def ident(x: IdentType) -> IdentType: def raises( func: t.Callable[..., t.Any], *args: t.Any, **kw: t.Any -) -> t.Union[t.Any, t.Type[Exception]]: +) -> t.Any | t.Type[Exception]: try: return func(*args, **kw) except Exception as e: @@ -65,8 +65,8 @@ def raises( def common( format: cst.TStruct[ContainerType], datasample: Buffer, - objsample: t.Union[ContainerType, t.Dict[str, t.Any]], - sizesample: t.Union[int, t.Type[Exception]] = ..., + objsample: ContainerType | t.Dict[str, t.Any], + sizesample: int | t.Type[Exception] = ..., **kw: t.Any, ) -> None: ... @@ -76,7 +76,7 @@ def common( format: "Construct[ListContainer[ParsedType], t.Any]", datasample: Buffer, objsample: t.List[ParsedType], - sizesample: t.Union[int, t.Type[Exception]] = ..., + sizesample: int | t.Type[Exception] = ..., **kw: t.Any, ) -> None: ... @@ -86,17 +86,17 @@ def common( format: "Construct[Container[t.Any], t.Any]", datasample: Buffer, objsample: t.Dict[str, t.Any], - sizesample: t.Union[int, t.Type[Exception]] = ..., + sizesample: int | t.Type[Exception] = ..., **kw: t.Any, ) -> None: ... @t.overload def common( - format: "Construct[t.Union[EnumInteger, EnumIntegerString], t.Any]", + format: "Construct[EnumInteger | EnumIntegerString, t.Any]", datasample: Buffer, - objsample: t.Union[int, str], - sizesample: t.Union[int, t.Type[Exception]] = ..., + objsample: int | str, + sizesample: int | t.Type[Exception] = ..., **kw: t.Any, ) -> None: ... @@ -105,8 +105,8 @@ def common( def common( format: "Construct[HexDisplayedInteger, t.Any]", datasample: Buffer, - objsample: t.Union[HexDisplayedInteger, int], - sizesample: t.Union[int, t.Type[Exception]] = ..., + objsample: HexDisplayedInteger | int, + sizesample: int | t.Type[Exception] = ..., **kw: t.Any, ) -> None: ... @@ -115,8 +115,8 @@ def common( def common( format: "Construct[HexDisplayedBytes, t.Any]", datasample: Buffer, - objsample: t.Union[HexDisplayedBytes, bytes], - sizesample: t.Union[int, t.Type[Exception]] = ..., + objsample: HexDisplayedBytes | bytes, + sizesample: int | t.Type[Exception] = ..., **kw: t.Any, ) -> None: ... @@ -126,7 +126,7 @@ def common( format: "Construct[HexDisplayedDict[str, t.Any], t.Any]", datasample: Buffer, objsample: t.Dict[str, t.Any], - sizesample: t.Union[int, t.Type[Exception]] = ..., + sizesample: int | t.Type[Exception] = ..., **kw: t.Any, ) -> None: ... @@ -135,8 +135,8 @@ def common( def common( format: "Construct[HexDumpDisplayedBytes, t.Any]", datasample: Buffer, - objsample: t.Union[HexDumpDisplayedBytes, bytes], - sizesample: t.Union[int, t.Type[Exception]] = ..., + objsample: HexDumpDisplayedBytes | bytes, + sizesample: int | t.Type[Exception] = ..., **kw: t.Any, ) -> None: ... @@ -146,7 +146,7 @@ def common( format: "Construct[HexDumpDisplayedDict[str, t.Any], t.Any]", datasample: Buffer, objsample: t.Dict[str, t.Any], - sizesample: t.Union[int, t.Type[Exception]] = ..., + sizesample: int | t.Type[Exception] = ..., **kw: t.Any, ) -> None: ... @@ -156,7 +156,7 @@ def common( format: "Construct[ParsedType, t.Any]", datasample: Buffer, objsample: ParsedType, - sizesample: t.Union[int, t.Type[Exception]] = ..., + sizesample: int | t.Type[Exception] = ..., **kw: t.Any, ) -> None: ... @@ -165,7 +165,7 @@ def common( format: "Construct[t.Any, t.Any]", datasample: Buffer, objsample: t.Any, - sizesample: t.Union[int, t.Type[Exception]] = SizeofError, + sizesample: int | t.Type[Exception] = SizeofError, **kw: t.Any, ) -> None: obj = format.parse(datasample, **kw) diff --git a/tests/test_typed.py b/tests/test_typed.py index 258191f..ca537f0 100644 --- a/tests/test_typed.py +++ b/tests/test_typed.py @@ -202,8 +202,8 @@ class Image(DataclassMixin): 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( + test_if: int | None = csfield(cs.If(False, cs.Int8ub)) + test_ifthenelse: int | None = csfield( cs.IfThenElse(True, cs.Int8ub, cs.Pass) ) diff --git a/tests/test_typed_pyright.py b/tests/test_typed_pyright.py index 0e3db94..e0568ca 100644 --- a/tests/test_typed_pyright.py +++ b/tests/test_typed_pyright.py @@ -43,8 +43,8 @@ class ConstDefaultTest(DataclassMixin): def test_dataclass_padded() -> None: @dataclasses.dataclass class PaddingTest(DataclassMixin): - padding: t.Optional[bytes] = csfield_noinit(cs.Padding(1)) - padded_pass: t.Optional[bytes] = csfield_noinit(cs.Padded(2, cs.Pass)) + padding: bytes | None = csfield_noinit(cs.Padding(1)) + padded_pass: bytes | None = csfield_noinit(cs.Padded(2, cs.Pass)) padded_bytes: bytes = csfield(cs.Padded(7, cs.Bytes(5))) padded_string: str = csfield(cs.PaddedString(4, "utf-8"))