import enum import io import sys import typing as t import arrow from construct.lib import ( Container, ContainerType, HexDisplayedBytes, HexDisplayedDict, HexDisplayedInteger, HexDumpDisplayedBytes, HexDumpDisplayedDict, ListContainer, ListType, RebufferedBytesIO, ) # unfortunately, there are a few duplications with "typing", e.g. Union and Optional, which is why the t. prefix must be used everywhere # Some of the Constructs can be optimised when the following typing optimisations are available: # - Variadic Generics: https://mail.python.org/archives/list/typing-sig@python.org/thread/SQVTQYWIOI4TIO7NNBTFFWFMSMS2TA4J/ # - Higher Kinded Types: https://github.com/python/typing/issues/548 # - Higher Kinded Types: https://sobolevn.me/2020/10/higher-kinded-types-in-python StreamType = t.BinaryIO PathType = str ContextKWType = t.Any # =============================================================================== # exceptions # =============================================================================== class ConstructError(Exception): path: t.Optional[PathType] def __init__( self, message: str = ..., path: t.Optional[PathType] = ... ) -> None: ... class SizeofError(ConstructError): ... class AdaptationError(ConstructError): ... class ValidationError(ConstructError): ... class StreamError(ConstructError): ... class FormatFieldError(ConstructError): ... class IntegerError(ConstructError): ... class StringError(ConstructError): ... class MappingError(ConstructError): ... class RangeError(ConstructError): ... class RepeatError(ConstructError): ... class ConstError(ConstructError): ... class IndexFieldError(ConstructError): ... class CheckError(ConstructError): ... class ExplicitError(ConstructError): ... class NamedTupleError(ConstructError): ... class TimestampError(ConstructError): ... class UnionError(ConstructError): ... class SelectError(ConstructError): ... class SwitchError(ConstructError): ... class StopFieldError(ConstructError): ... class PaddingError(ConstructError): ... class TerminatedError(ConstructError): ... class RawCopyError(ConstructError): ... class RotationError(ConstructError): ... class ChecksumError(ConstructError): ... class CancelParsing(ConstructError): ... # =============================================================================== # used internally # =============================================================================== def stream_read( stream: t.BinaryIO, length: int, path: t.Optional[PathType] ) -> bytes: ... def stream_read_entire(stream: t.BinaryIO, path: t.Optional[PathType]) -> bytes: ... def stream_write( stream: t.BinaryIO, data: bytes, length: int, path: t.Optional[PathType] ) -> None: ... def stream_seek( stream: t.BinaryIO, offset: int, whence: int, path: t.Optional[PathType] ) -> int: ... def stream_tell(stream: t.BinaryIO, path: t.Optional[PathType]) -> int: ... def stream_size(stream: t.BinaryIO) -> int: ... def stream_iseof(stream: t.BinaryIO) -> bool: ... def evaluate(param: ConstantOrContextLambda2[T], context: Context) -> T: ... # =============================================================================== # abstract constructs # =============================================================================== ParsedType = t.TypeVar("ParsedType", covariant=True) BuildTypes = t.TypeVar("BuildTypes", contravariant=True) class Construct(t.Generic[ParsedType, BuildTypes]): name: t.Optional[str] docs: str flagbuildnone: bool parsed: t.Optional[t.Callable[[ParsedType, Context], None]] def parse(self, data: bytes, **contextkw: ContextKWType) -> ParsedType: ... def parse_stream( self, stream: StreamType, **contextkw: ContextKWType ) -> ParsedType: ... def parse_file(self, filename: str, **contextkw: ContextKWType) -> ParsedType: ... def build(self, obj: BuildTypes, **contextkw: ContextKWType) -> bytes: ... def build_stream( self, obj: BuildTypes, stream: StreamType, **contextkw: ContextKWType ) -> bytes: ... def build_file( self, obj: BuildTypes, filename: str, **contextkw: ContextKWType ) -> bytes: ... def sizeof(self, **contextkw: ContextKWType) -> int: ... def compile(self, filename: str = ...) -> Construct[ParsedType, BuildTypes]: ... def benchmark(self, sampledata: bytes, filename: str = ...) -> str: ... def export_ksy(self, schemaname: str = ..., filename: str = ...) -> str: ... def __rtruediv__( self, name: t.Optional[t.AnyStr] ) -> Renamed[ParsedType, BuildTypes]: ... __rdiv__: t.Callable[[str], Construct[ParsedType, BuildTypes]] def __mul__( self, other: t.Union[str, bytes, t.Callable[[ParsedType, Context], None]], ) -> Renamed[ParsedType, BuildTypes]: ... def __rmul__( self, other: t.Union[str, bytes, t.Callable[[ParsedType, Context], None]], ) -> Renamed[ParsedType, BuildTypes]: ... def __add__( self, other: Construct[t.Any, t.Any] ) -> Struct[Container[t.Any], t.Optional[t.Dict[str, t.Any]]]: ... def __rshift__( self, other: Construct[t.Any, t.Any] ) -> Sequence[ListContainer[t.Any], t.Optional[t.List[t.Any]]]: ... def __getitem__( self, count: t.Union[int, t.Callable[[Context], int]] ) -> Array[ ParsedType, BuildTypes, ListContainer[ParsedType], t.List[BuildTypes], ]: ... @t.type_check_only class Context(Container[t.Any]): _: Context # optional field _params: Context # optional field _root: Context # optional field _parsing: bool _building: bool _sizing: bool _subcons: Container[Construct[t.Any, t.Any]] _io: StreamType # optional field _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]] SubconParsedType = t.TypeVar("SubconParsedType", covariant=True) SubconBuildTypes = t.TypeVar("SubconBuildTypes", contravariant=True) class Subconstruct( t.Generic[SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes], Construct[ParsedType, BuildTypes], ): subcon: Construct[SubconParsedType, SubconBuildTypes] @t.overload def __new__( cls, subcon: Construct[SubconParsedType, SubconBuildTypes] ) -> Subconstruct[ SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes ]: ... @t.overload def __new__( cls, *args: t.Any, **kwargs: t.Any ) -> Subconstruct[SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes]: ... class Adapter( Subconstruct[SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes], ): def __new__( cls, subcon: Construct[SubconParsedType, SubconBuildTypes] ) -> Adapter[SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes]: ... def _decode( self, obj: SubconBuildTypes, context: Context, path: PathType ) -> ParsedType: ... def _encode( self, obj: BuildTypes, context: Context, path: PathType ) -> SubconBuildTypes: ... class SymmetricAdapter( Adapter[SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes] ): ... class Validator( SymmetricAdapter[ SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes ] ): def _validate( self, obj: SubconBuildTypes, context: Context, path: PathType ) -> bool: ... class Tunnel( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes] ): def _decode(self, data: bytes, context: Context, path: PathType) -> bytes: ... def _encode(self, data: bytes, context: Context, path: PathType) -> bytes: ... # TODO: Compiled # =============================================================================== # bytes and bits # =============================================================================== class Bytes(Construct[ParsedType, BuildTypes]): length: ConstantOrContextLambda[int] def __new__( cls, length: ConstantOrContextLambda[int] ) -> Bytes[bytes, t.Union[bytes, int]]: ... GreedyBytes: Construct[bytes, bytes] def Bitwise( subcon: Construct[SubconParsedType, SubconBuildTypes] ) -> t.Union[ Transformed[SubconParsedType, SubconBuildTypes], Restreamed[SubconParsedType, SubconBuildTypes], ]: ... def Bytewise( subcon: Construct[SubconParsedType, SubconBuildTypes] ) -> t.Union[ Transformed[SubconParsedType, SubconBuildTypes], Restreamed[SubconParsedType, SubconBuildTypes], ]: ... # =============================================================================== # integers and floats # =============================================================================== class FormatField(Construct[ParsedType, BuildTypes]): fmtstr: str length: int if sys.version_info >= (3, 8): ENDIANITY = t.Union[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["?"] @t.overload def __new__( cls, endianity: str, format: FORMAT_INT ) -> FormatField[int, int]: ... @t.overload def __new__( cls, endianity: str, format: FORMAT_FLOAT ) -> FormatField[float, float]: ... @t.overload def __new__( cls, endianity: str, format: FORMAT_BOOL ) -> FormatField[bool, bool]: ... @t.overload def __new__(cls, endianity: str, format: str) -> FormatField[t.Any, t.Any]: ... else: def __new__(cls, endianity: str, format: str) -> FormatField[t.Any, t.Any]: ... class BytesInteger(Construct[ParsedType, BuildTypes]): length: ConstantOrContextLambda[int] signed: bool swapped: ConstantOrContextLambda[bool] def __new__( cls, length: ConstantOrContextLambda[int], signed: bool = ..., swapped: ConstantOrContextLambda[bool] = ..., ) -> BytesInteger[int, int]: ... class BitsInteger(Construct[ParsedType, BuildTypes]): length: ConstantOrContextLambda[int] signed: bool swapped: ConstantOrContextLambda[bool] def __new__( cls, length: ConstantOrContextLambda[int], signed: bool = ..., swapped: ConstantOrContextLambda[bool] = ..., ) -> BitsInteger[int, int]: ... Bit: BitsInteger[int, int] Nibble: BitsInteger[int, int] Octet: BitsInteger[int, int] Int8ub: FormatField[int, int] Int16ub: FormatField[int, int] Int32ub: FormatField[int, int] Int64ub: FormatField[int, int] Int8sb: FormatField[int, int] Int16sb: FormatField[int, int] Int32sb: FormatField[int, int] Int64sb: FormatField[int, int] Int8ul: FormatField[int, int] Int16ul: FormatField[int, int] Int32ul: FormatField[int, int] Int64ul: FormatField[int, int] Int8sl: FormatField[int, int] Int16sl: FormatField[int, int] Int32sl: FormatField[int, int] Int64sl: FormatField[int, int] Int8un: FormatField[int, int] Int16un: FormatField[int, int] Int32un: FormatField[int, int] Int64un: FormatField[int, int] Int8sn: FormatField[int, int] Int16sn: FormatField[int, int] Int32sn: FormatField[int, int] Int64sn: FormatField[int, int] Byte: FormatField[int, int] Short: FormatField[int, int] Int: FormatField[int, int] Long: FormatField[int, int] Float16b: FormatField[float, float] Float16l: FormatField[float, float] Float16n: FormatField[float, float] Float32b: FormatField[float, float] Float32l: FormatField[float, float] Float32n: FormatField[float, float] Float64b: FormatField[float, float] Float64l: FormatField[float, float] Float64n: FormatField[float, float] Half: FormatField[float, float] Single: FormatField[float, float] Double: FormatField[float, float] Int24ub: BytesInteger[int, int] Int24ul: BytesInteger[int, int] Int24un: BytesInteger[int, int] Int24sb: BytesInteger[int, int] Int24sl: BytesInteger[int, int] Int24sn: BytesInteger[int, int] VarInt: Construct[int, int] ZigZag: Construct[int, int] # =============================================================================== # strings # =============================================================================== class StringEncoded(Construct[ParsedType, BuildTypes]): if sys.version_info >= (3, 8): 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] else: ENCODING = str encoding: ENCODING def __new__( cls, subcon: Construct[ParsedType, BuildTypes], encoding: ENCODING ) -> StringEncoded[str, str]: ... def PaddedString( length: ConstantOrContextLambda[int], encoding: StringEncoded.ENCODING ) -> StringEncoded[str, str]: ... def PascalString( lengthfield: Construct[int, int], encoding: StringEncoded.ENCODING ) -> StringEncoded[str, str]: ... def CString(encoding: StringEncoded.ENCODING) -> StringEncoded[str, str]: ... def GreedyString(encoding: StringEncoded.ENCODING) -> StringEncoded[str, str]: ... # =============================================================================== # mappings # =============================================================================== Flag: Construct[bool, bool] class EnumInteger(int): ... class EnumIntegerString(str): @staticmethod def new(intvalue: int, stringvalue: str) -> EnumIntegerString: ... class Enum(Adapter[int, int, ParsedType, BuildTypes]): encmapping: t.Dict[str, int] decmapping: t.Dict[int, EnumIntegerString] ksymapping: t.Dict[int, str] def __new__( cls, subcon: Construct[int, int], *merge: t.Union[t.Type[enum.IntEnum], t.Type[enum.IntFlag]], **mapping: int ) -> Enum[t.Union[EnumInteger, EnumIntegerString], t.Union[int, str]]: ... def __getattr__(self, name: str) -> EnumIntegerString: ... class BitwisableString(str): def __or__(self, other: BitwisableString) -> BitwisableString: ... class FlagsEnum(Adapter[int, int, ParsedType, BuildTypes]): flags: t.Dict[str, int] reverseflags: t.Dict[int, str] def __new__( cls, subcon: Construct[int, int], *merge: t.Union[t.Type[enum.IntEnum], t.Type[enum.IntFlag]], **flags: int ) -> FlagsEnum[Container[bool], t.Union[int, str, t.Dict[str, bool]]]: ... def __getattr__(self, name: str) -> BitwisableString: ... class Mapping(Adapter[SubconParsedType, SubconBuildTypes, t.Any, t.Any]): decmapping: t.Dict[int, str] encmapping: t.Dict[str, int] def __new__( cls, subcon: Construct[SubconParsedType, SubconBuildTypes], mapping: t.Dict[t.Any, t.Any], ) -> Mapping[t.Any, t.Any]: ... # =============================================================================== # structures and sequences # =============================================================================== # this can maybe made better when variadic generics are available class Struct(Construct[ParsedType, BuildTypes]): subcons: t.List[Construct[t.Any, t.Any]] def __new__( cls, *subcons: Construct[t.Any, t.Any], **subconskw: Construct[t.Any, t.Any] ) -> Struct[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[ParsedType, BuildTypes]): subcons: t.List[Construct[t.Any, t.Any]] def __new__( cls, *subcons: Construct[t.Any, t.Any], **subconskw: Construct[t.Any, t.Any] ) -> Sequence[ListContainer[t.Any], t.Optional[t.List[t.Any]]]: ... def __getattr__(self, name: str) -> t.Any: ... # =============================================================================== # arrays ranges and repeaters # =============================================================================== class Array( Subconstruct[ SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes, ] ): count: ConstantOrContextLambda[int] discard: bool def __new__( cls, count: ConstantOrContextLambda[int], subcon: Construct[SubconParsedType, SubconBuildTypes], discard: bool = ..., ) -> Array[ SubconParsedType, SubconBuildTypes, ListContainer[SubconParsedType], t.List[SubconBuildTypes], ]: ... class GreedyRange( Subconstruct[ SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes, ] ): discard: bool def __new__( cls, subcon: Construct[SubconParsedType, SubconBuildTypes], discard: bool = ... ) -> GreedyRange[ SubconParsedType, SubconBuildTypes, ListContainer[SubconParsedType], t.List[SubconBuildTypes], ]: ... class RepeatUntil( Subconstruct[ SubconParsedType, SubconBuildTypes, ListContainer[SubconParsedType], t.List[SubconBuildTypes], ] ): predicate: t.Union[ bool, t.Callable[[SubconParsedType, ListContainer[SubconParsedType], Context], bool], ] discard: bool def __init__( self, predicate: t.Union[ bool, t.Callable[ [SubconParsedType, ListContainer[SubconParsedType], Context], bool ], ], subcon: Construct[SubconParsedType, SubconBuildTypes], discard: bool = ..., ) -> None: ... # =============================================================================== # specials # =============================================================================== class Renamed( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes] ): def __init__( self, subcon: Construct[SubconParsedType, SubconBuildTypes], newname: t.Optional[str] = ..., newdocs: t.Optional[str] = ..., newparsed: t.Optional[t.Callable[[t.Any, Context], None]] = ..., ) -> None: ... # =============================================================================== # miscellaneous # =============================================================================== class Const(Subconstruct[SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes]): value: SubconBuildTypes @t.overload def __new__( cls, value: bytes, ) -> Const[None, None, bytes, Bytes[bytes, int]]: ... @t.overload def __new__( cls, value: SubconBuildTypes, subcon: Construct[SubconParsedType, SubconBuildTypes], ) -> Const[None, None, SubconParsedType, t.Optional[SubconBuildTypes]]: ... class Computed(Construct[ParsedType, BuildTypes]): func: ConstantOrContextLambda2[ParsedType] @t.overload def __new__( cls, func: ConstantOrContextLambda2[ParsedType] ) -> Computed[ParsedType, None]: ... @t.overload def __new__( cls, func: ConstantOrContextLambda2[t.Any] ) -> Computed[t.Any, None]: ... Index: Construct[int, t.Any] class Rebuild(Subconstruct[SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes]): func: ConstantOrContextLambda[SubconBuildTypes] def __new__( cls, subcon: Construct[SubconParsedType, SubconBuildTypes], func: ConstantOrContextLambda[SubconBuildTypes], ) -> Rebuild[SubconParsedType, SubconBuildTypes, SubconParsedType, None]: ... class Default(Subconstruct[SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes]): value: ConstantOrContextLambda[SubconBuildTypes] def __new__( cls, subcon: Construct[SubconParsedType, SubconBuildTypes], value: ConstantOrContextLambda[SubconBuildTypes], ) -> Default[ SubconParsedType, SubconBuildTypes, SubconParsedType, t.Optional[SubconBuildTypes], ]: ... class Check(Construct[ParsedType, BuildTypes]): func: ConstantOrContextLambda[bool] def __new__(cls, func: ConstantOrContextLambda[bool]) -> Check[None, None]: ... Error: Construct[None, None] class FocusedSeq(Construct[t.Any, t.Any]): subcons: t.List[Construct[t.Any, t.Any]] def __init__( self, parsebuildfrom: ConstantOrContextLambda[str], *subcons: Construct[t.Any, t.Any], **subconskw: Construct[t.Any, t.Any] ) -> None: ... def __getattr__(self, name: str) -> t.Any: ... Pickled: Construct[t.Any, t.Any] Numpy: Construct[t.Any, t.Any] class NamedTuple( Adapter[ SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes, ] ): tuplename: str tuplefields: str factory: Construct[SubconParsedType, SubconBuildTypes] def __new__( cls, tuplename: str, tuplefields: str, subcon: Construct[SubconParsedType, SubconBuildTypes], ) -> 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"] else: MSDOS = str class TimestampAdapter( Adapter[SubconParsedType, SubconBuildTypes, arrow.Arrow, arrow.Arrow] ): ... @t.overload def Timestamp( subcon: Construct[int, int], unit: MSDOS, epoch: MSDOS ) -> TimestampAdapter[int, int]: ... @t.overload def Timestamp( subcon: Construct[int, int], unit: t.Union[int, float], epoch: t.Union[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], ) -> TimestampAdapter[float, float]: ... K = t.TypeVar("K") V = t.TypeVar("V") class Hex(Adapter[SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes]): @t.overload def __new__( cls, subcon: Construct[int, BuildTypes] ) -> Hex[int, BuildTypes, HexDisplayedInteger, BuildTypes]: ... @t.overload def __new__( cls, subcon: Construct[bytes, BuildTypes] ) -> Hex[bytes, BuildTypes, HexDisplayedBytes, BuildTypes]: ... @t.overload def __new__( cls, subcon: Construct[RawCopyObj[SubconParsedType], BuildTypes] ) -> Hex[ RawCopyObj[SubconParsedType], BuildTypes, HexDisplayedDict[str, t.Union[int, bytes, SubconParsedType]], BuildTypes, ]: ... @t.overload def __new__( cls, subcon: Construct[Container[t.Any], BuildTypes] ) -> Hex[ Container[t.Any], BuildTypes, HexDisplayedDict[str, t.Any], BuildTypes ]: ... @t.overload def __new__( cls, subcon: Construct[SubconParsedType, SubconBuildTypes] ) -> Hex[ SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes ]: ... class HexDump(Adapter[SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes]): @t.overload def __new__( cls, subcon: Construct[bytes, BuildTypes] ) -> HexDump[bytes, BuildTypes, HexDumpDisplayedBytes, BuildTypes]: ... @t.overload def __new__( cls, subcon: Construct[RawCopyObj[SubconParsedType], BuildTypes] ) -> HexDump[ RawCopyObj[SubconParsedType], BuildTypes, HexDumpDisplayedDict[str, t.Union[int, bytes, SubconParsedType]], BuildTypes, ]: ... @t.overload def __new__( cls, subcon: Construct[Container[t.Any], BuildTypes] ) -> HexDump[ Container[t.Any], BuildTypes, HexDumpDisplayedDict[str, t.Any], BuildTypes ]: ... @t.overload def __new__( cls, subcon: Construct[SubconParsedType, SubconBuildTypes] ) -> HexDump[ SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes ]: ... # =============================================================================== # conditional # =============================================================================== # 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]]] subcons: t.List[Construct[t.Any, t.Any]] def __init__( self, parsefrom: t.Optional[ConstantOrContextLambda[t.Union[int, str]]], *subcons: Construct[t.Any, t.Any], **subconskw: Construct[t.Any, t.Any] ) -> None: ... def __getattr__(self, name: str) -> t.Any: ... # this can maybe made better when variadic generics are available class Select(Construct[ParsedType, BuildTypes]): subcons: t.List[Construct[t.Any, t.Any]] def __new__( cls, *subcons: Construct[t.Any, t.Any], **subconskw: Construct[t.Any, t.Any] ) -> Select[t.Any, t.Any]: ... def Optional( subcon: Construct[SubconParsedType, SubconBuildTypes] ) -> Select[t.Union[SubconParsedType, None], t.Union[SubconBuildTypes, None]]: ... ThenParsedType = t.TypeVar("ThenParsedType") ThenBuildTypes = t.TypeVar("ThenBuildTypes") ElseParsedType = t.TypeVar("ElseParsedType") ElseBuildTypes = t.TypeVar("ElseBuildTypes") # This does not represent the original code, but it is the only solution that works good with pyright class _IfThenElse(Construct[ParsedType, BuildTypes]): condfunc: ConstantOrContextLambda[bool] thensubcon: Construct[ParsedType, BuildTypes] elsesubcon: Construct[ParsedType, BuildTypes] def IfThenElse( condfunc: ConstantOrContextLambda[bool], thensubcon: Construct[ThenParsedType, ThenBuildTypes], elsesubcon: Construct[ElseParsedType, ElseBuildTypes], ) -> _IfThenElse[ t.Union[ThenParsedType, ElseParsedType], t.Union[ThenBuildTypes, ElseBuildTypes] ]: ... def If( condfunc: ConstantOrContextLambda[bool], subcon: Construct[ThenParsedType, ThenBuildTypes], ) -> _IfThenElse[t.Union[ThenParsedType, None], t.Union[ThenBuildTypes, None]]: ... SwitchType = t.TypeVar("SwitchType") class Switch(Construct[ParsedType, BuildTypes]): keyfunc: ConstantOrContextLambda[t.Any] cases: t.Dict[t.Any, Construct[t.Any, t.Any]] default: Construct[t.Any, t.Any] @t.overload def __new__( cls, keyfunc: ConstantOrContextLambda[SwitchType], cases: t.Dict[SwitchType, Construct[int, int]], default: t.Optional[Construct[int, int]] = ..., ) -> Switch[int, t.Optional[int]]: ... @t.overload def __new__( cls, keyfunc: ConstantOrContextLambda[t.Any], cases: t.Dict[t.Any, Construct[t.Any, t.Any]], default: t.Optional[Construct[t.Any, t.Any]] = ..., ) -> Switch[t.Any, t.Any]: ... class StopIf(Construct[ParsedType, BuildTypes]): condfunc: ConstantOrContextLambda[bool] def __new__(cls, condfunc: ConstantOrContextLambda[bool]) -> StopIf[None, None]: ... # =============================================================================== # alignment and padding # =============================================================================== def Padding( length: ConstantOrContextLambda[int], pattern: bytes = ... ) -> Padded[None, None]: ... class Padded( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes] ): length: ConstantOrContextLambda[int] pattern: bytes def __init__( self, length: ConstantOrContextLambda[int], subcon: Construct[SubconParsedType, SubconBuildTypes], pattern: bytes = ..., ) -> None: ... class Aligned( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes] ): modulus: ConstantOrContextLambda[int] pattern: bytes def __init__( self, modulus: ConstantOrContextLambda[int], subcon: Construct[SubconParsedType, SubconBuildTypes], pattern: bytes = ..., ) -> None: ... def AlignedStruct( modulus: ConstantOrContextLambda[int], *subcons: Construct[t.Any, t.Any], **subconskw: Construct[t.Any, t.Any] ) -> Struct[Container[t.Any], t.Optional[t.Dict[str, t.Any]]]: ... 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]], ]: ... # =============================================================================== # stream manipulation # =============================================================================== class Pointer( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes] ): offset: ConstantOrContextLambda[int] stream: t.Optional[t.Callable[[Context], StreamType]] def __init__( self, offset: ConstantOrContextLambda[int], subcon: Construct[SubconParsedType, SubconBuildTypes], stream: t.Optional[t.Callable[[Context], StreamType]] = ..., ) -> None: ... class Peek(Subconstruct[SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes]): def __new__( cls, subcon: Construct[SubconParsedType, SubconBuildTypes], ) -> Peek[ SubconParsedType, SubconBuildTypes, SubconParsedType, t.Union[SubconBuildTypes, None], ]: ... class Seek(Construct[int, None]): at: ConstantOrContextLambda[int] if sys.version_info >= (3, 8): WHENCE = t.Literal[0, 1, 2] else: WHENCE = int whence: ConstantOrContextLambda[WHENCE] def __init__( self, at: ConstantOrContextLambda[int], whence: ConstantOrContextLambda[WHENCE] = ..., ) -> None: ... Tell: Construct[int, None] Pass: Construct[None, None] Terminated: Construct[None, None] # =============================================================================== # tunneling and byte/bit swapping # =============================================================================== @t.type_check_only class RawCopyObj(t.Generic[ParsedType], Container[t.Any]): data: bytes value: ParsedType offset1: int offset2: int length: int class RawCopy(Subconstruct[SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes]): def __new__( cls, subcon: Construct[SubconParsedType, SubconBuildTypes] ) -> RawCopy[ SubconParsedType, SubconBuildTypes, RawCopyObj[SubconParsedType], t.Optional[t.Dict[str, t.Union[SubconBuildTypes, bytes]]], ]: ... def ByteSwapped( subcon: Construct[SubconParsedType, SubconBuildTypes] ) -> Transformed[SubconParsedType, SubconBuildTypes]: ... def BitsSwapped( subcon: Construct[SubconParsedType, SubconBuildTypes] ) -> t.Union[ Transformed[SubconParsedType, SubconBuildTypes], Restreamed[SubconParsedType, SubconBuildTypes], ]: ... class Prefixed( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes] ): lengthfield: Construct[SubconParsedType, SubconBuildTypes] includelength: t.Optional[bool] def __init__( self, lengthfield: Construct[int, int], subcon: Construct[SubconParsedType, SubconBuildTypes], includelength: t.Optional[bool] = ..., ) -> None: ... def PrefixedArray( countfield: Construct[int, int], subcon: Construct[SubconParsedType, SubconBuildTypes], ) -> Array[ SubconParsedType, SubconBuildTypes, ListContainer[SubconParsedType], t.List[SubconBuildTypes], ]: ... class FixedSized( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes] ): length: ConstantOrContextLambda[int] def __init__( self, length: ConstantOrContextLambda[int], subcon: Construct[SubconParsedType, SubconBuildTypes], ) -> None: ... class NullTerminated( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes] ): term: bytes include: t.Optional[bool] consume: t.Optional[bool] require: t.Optional[bool] def __init__( self, subcon: Construct[SubconParsedType, SubconBuildTypes], term: bytes = ..., include: t.Optional[bool] = ..., consume: t.Optional[bool] = ..., require: t.Optional[bool] = ..., ) -> None: ... class NullStripped( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes] ): pad: bytes def __init__( self, subcon: Construct[SubconParsedType, SubconBuildTypes], pad: bytes = ... ) -> None: ... class RestreamData( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, None] ): datafunc: t.Union[ 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] ], subcon: Construct[SubconParsedType, SubconBuildTypes], ) -> None: ... class Transformed( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes] ): decodefunc: t.Callable[[bytes], bytes] decodeamount: t.Optional[int] encodefunc: t.Callable[[bytes], bytes] encodeamount: t.Optional[int] def __init__( self, subcon: Construct[SubconParsedType, SubconBuildTypes], decodefunc: t.Callable[[bytes], bytes], decodeamount: t.Optional[int], encodefunc: t.Callable[[bytes], bytes], encodeamount: t.Optional[int], ) -> None: ... class Restreamed( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes] ): decoder: t.Callable[[bytes], bytes] decoderunit: int encoder: t.Callable[[bytes], bytes] encoderunit: int sizecomputer: t.Callable[[int], int] def __init__( self, subcon: Construct[SubconParsedType, SubconBuildTypes], decoder: t.Callable[[bytes], bytes], decoderunit: int, encoder: t.Callable[[bytes], bytes], encoderunit: int, sizecomputer: t.Callable[[int], int], ) -> None: ... class ProcessXor( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconParsedType] ): padfunc: ConstantOrContextLambda2[t.Union[int, bytes]] def __new__( cls, padfunc: ConstantOrContextLambda2[t.Union[int, bytes]], subcon: Construct[SubconParsedType, SubconBuildTypes], ) -> ProcessXor[SubconParsedType, SubconBuildTypes]: ... class ProcessRotateLeft( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconParsedType] ): amount: ConstantOrContextLambda2[int] group: ConstantOrContextLambda2[int] def __new__( cls, amount: ConstantOrContextLambda2[int], group: ConstantOrContextLambda2[int], subcon: Construct[SubconParsedType, SubconBuildTypes], ) -> ProcessRotateLeft[SubconParsedType, SubconBuildTypes]: ... T = t.TypeVar("T") class Checksum(t.Generic[T, ParsedType, BuildTypes], Construct[ParsedType, BuildTypes]): checksumfield: Construct[ParsedType, BuildTypes] hashfunc: t.Callable[[T], BuildTypes] bytesfunc: t.Callable[[Context], T] def __init__( self, checksumfield: Construct[ParsedType, BuildTypes], hashfunc: t.Callable[[T], BuildTypes], bytesfunc: t.Callable[[Context], T], ) -> None: ... class Compressed(Tunnel[SubconParsedType, SubconBuildTypes]): encoding: str level: t.Optional[int] lib: t.Any def __init__( self, subcon: Construct[SubconParsedType, SubconBuildTypes], encoding: str, level: t.Optional[int] = ..., ) -> None: ... class CompressedLZ4(Tunnel[SubconParsedType, SubconBuildTypes]): lib: t.Any def __init__( self, subcon: Construct[SubconParsedType, SubconBuildTypes], ) -> None: ... class Rebuffered( Subconstruct[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes] ): stream2: RebufferedBytesIO def __init__( self, subcon: Construct[SubconParsedType, SubconBuildTypes], tailcutoff: t.Optional[int] = ..., ) -> None: ... # =============================================================================== # lazy equivalents # =============================================================================== class Lazy(Subconstruct[SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes]): def __new__( cls, subcon: Construct[SubconParsedType, SubconBuildTypes], ) -> Lazy[ SubconParsedType, SubconBuildTypes, t.Callable[[], SubconParsedType], t.Union[t.Callable[[], SubconParsedType], SubconParsedType], ]: ... 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]]: ... class LazyStruct(Construct[ParsedType, BuildTypes]): subcons: t.List[Construct[t.Any, t.Any]] def __new__( cls, *subcons: Construct[t.Any, t.Any], **subconskw: Construct[t.Any, t.Any] ) -> LazyStruct[LazyContainer[t.Any], t.Optional[t.Dict[str, t.Any]]]: ... def __getattr__(self, name: str) -> t.Any: ... class LazyListContainer(t.List[ListType]): ... class LazyArray( Subconstruct[ SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes, ] ): count: ConstantOrContextLambda[int] def __new__( cls, count: ConstantOrContextLambda[int], subcon: Construct[SubconParsedType, SubconBuildTypes], ) -> LazyArray[ SubconParsedType, SubconBuildTypes, ListContainer[SubconParsedType], t.List[SubconBuildTypes], ]: ... class LazyBound(Construct[ParsedType, BuildTypes]): subconfunc: t.Callable[[], Construct[ParsedType, BuildTypes]] def __new__( cls, subconfunc: t.Callable[[], Construct[ParsedType, BuildTypes]] ) -> LazyBound[ParsedType, BuildTypes]: ... # =============================================================================== # adapters and validators # =============================================================================== class ExprAdapter(Adapter[SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes]): def __new__( cls, subcon: Construct[SubconParsedType, SubconBuildTypes], decoder: t.Callable[[SubconParsedType, Context], ParsedType], encoder: t.Callable[[BuildTypes, Context], SubconBuildTypes], ) -> ExprAdapter[SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes]: ... class ExprSymmetricAdapter( ExprAdapter[SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes] ): def __new__( cls, subcon: Construct[SubconParsedType, SubconBuildTypes], encoder: t.Callable[[BuildTypes, Context], SubconBuildTypes], ) -> ExprSymmetricAdapter[ SubconParsedType, SubconBuildTypes, ParsedType, BuildTypes ]: ... class ExprValidator(Validator[SubconParsedType, SubconBuildTypes]): def __new__( cls, subcon: Construct[SubconParsedType, SubconBuildTypes], validator: t.Callable[[SubconParsedType, Context], bool], ) -> ExprValidator[SubconParsedType, SubconBuildTypes]: ... def OneOf( subcon: Construct[SubconParsedType, SubconBuildTypes], valids: t.Container[SubconParsedType], ) -> ExprValidator[SubconParsedType, SubconBuildTypes]: ... def NoneOf( subcon: Construct[SubconParsedType, SubconBuildTypes], invalids: t.Container[SubconParsedType], ) -> ExprValidator[SubconParsedType, SubconBuildTypes]: ... def Filter( predicate: t.Callable[[SubconParsedType, Context], bool], subcon: Construct[SubconParsedType, SubconBuildTypes], ) -> ExprSymmetricAdapter[ SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes ]: ... class Slicing( Adapter[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes] ): def __new__( cls, subcon: t.Union[ Array[ SubconParsedType, SubconBuildTypes, ListContainer[SubconParsedType], t.List[SubconBuildTypes], ], GreedyRange[ SubconParsedType, SubconBuildTypes, ListContainer[SubconParsedType], t.List[SubconBuildTypes], ], ], count: int, start: t.Optional[int], stop: t.Optional[int], step: int = ..., empty: t.Optional[SubconParsedType] = ..., ) -> Slicing[ListContainer[SubconParsedType], t.List[SubconBuildTypes]]: ... class Indexing( Adapter[SubconParsedType, SubconBuildTypes, SubconParsedType, SubconBuildTypes] ): def __new__( cls, subcon: t.Union[ Array[ SubconParsedType, SubconBuildTypes, ListContainer[SubconParsedType], t.List[SubconBuildTypes], ], GreedyRange[ SubconParsedType, SubconBuildTypes, ListContainer[SubconParsedType], t.List[SubconBuildTypes], ], ], count: int, index: int, empty: t.Optional[SubconParsedType] = ..., ) -> Indexing[SubconParsedType, SubconBuildTypes]: ...