- added tests "test_tstruct_default_field" and "test_tstruct_const_field"
- added setattrs
This commit is contained in:
parent
4aa3013a82
commit
944cf85797
5 changed files with 80 additions and 17 deletions
|
|
@ -1,3 +1,11 @@
|
|||
from .generic_wrapper import (
|
||||
Construct,
|
||||
Adapter,
|
||||
ListContainer,
|
||||
Context,
|
||||
ConstantOrContextLambda,
|
||||
PathType,
|
||||
)
|
||||
from .tarray import TArray
|
||||
from .tenum import TEnum
|
||||
from .tstruct import TStruct, TBitStruct, TStructField
|
||||
|
|
@ -10,5 +18,11 @@ __all__ = [
|
|||
"TEnum",
|
||||
"TUnionField",
|
||||
"TUnion",
|
||||
"TArray"
|
||||
"TArray",
|
||||
"Construct",
|
||||
"Adapter",
|
||||
"ListContainer",
|
||||
"Context",
|
||||
"ConstantOrContextLambda",
|
||||
"PathType",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -21,16 +21,9 @@ def TStructField(
|
|||
subcon = cs.Renamed(subcon, newdocs=doc, newparsed=parsed)
|
||||
|
||||
if subcon.flagbuildnone is True:
|
||||
# some subcons have a predefined default value. all other have "None"
|
||||
default: t.Any = None
|
||||
if isinstance(subcon, (cs.Const, cs.Default)):
|
||||
if callable(subcon.value): # type: ignore
|
||||
raise ValueError("lamda as default is not supported")
|
||||
default = subcon.value # type: ignore
|
||||
|
||||
# if subcon builds from "None", set default to "None"
|
||||
field = dataclasses.field(
|
||||
default=default,
|
||||
default=None,
|
||||
init=False,
|
||||
metadata={"subcon": cs.Renamed(subcon, newdocs=doc)},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import pytest
|
||||
|
||||
xfail = pytest.mark.xfail
|
||||
skip = pytest.mark.skip
|
||||
skipif = pytest.mark.skipif
|
||||
|
|
@ -8,16 +9,18 @@ import os, math, random, collections, itertools, io, hashlib, binascii
|
|||
from construct import *
|
||||
from construct.lib import *
|
||||
|
||||
|
||||
class ZeroIO(io.BufferedIOBase):
|
||||
def read(self, __size = None):
|
||||
def read(self, __size=None):
|
||||
if __size is not None:
|
||||
return bytes(__size)
|
||||
else:
|
||||
return bytes(0)
|
||||
|
||||
def read1(self, __size = 0):
|
||||
def read1(self, __size=0):
|
||||
return bytes(__size)
|
||||
|
||||
|
||||
ident = lambda x: x
|
||||
devzero = ZeroIO()
|
||||
|
||||
|
|
@ -46,20 +49,26 @@ def common(format, datasample, objsample, sizesample=SizeofError, **kw):
|
|||
assert size == sizesample
|
||||
|
||||
|
||||
def setattrs(obj, **kwargs):
|
||||
for name, value in kwargs.items():
|
||||
setattr(obj, name, value)
|
||||
return obj
|
||||
|
||||
|
||||
def commonhex(format, hexdata):
|
||||
commonbytes(format, binascii.unhexlify(hexdata))
|
||||
|
||||
|
||||
def commondumpdeprecated(format, filename):
|
||||
filename = "tests/deprecated_gallery/blobs/" + filename
|
||||
with open(filename,'rb') as f:
|
||||
with open(filename, "rb") as f:
|
||||
data = f.read()
|
||||
commonbytes(format, data)
|
||||
|
||||
|
||||
def commondump(format, filename):
|
||||
filename = "tests/gallery/blobs/" + filename
|
||||
with open(filename,'rb') as f:
|
||||
with open(filename, "rb") as f:
|
||||
data = f.read()
|
||||
commonbytes(format, data)
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import construct_typed as cst
|
|||
Buffer = t.Union[bytes, memoryview, bytearray]
|
||||
ParsedType = t.TypeVar("ParsedType")
|
||||
BuildTypes = t.TypeVar("BuildTypes")
|
||||
T = t.TypeVar("T")
|
||||
|
||||
IdentType = t.TypeVar("IdentType")
|
||||
|
||||
|
|
@ -32,6 +33,7 @@ def common(
|
|||
sizesample: t.Union[int, t.Type[Exception]] = ...,
|
||||
**kw: t.Any
|
||||
) -> None: ...
|
||||
def setattrs(obj: T, **kwargs: t.Any) -> T: ...
|
||||
def commonhex(format: Construct[ParsedType, BuildTypes], hexdata: str) -> None: ...
|
||||
def commondumpdeprecated(
|
||||
format: Construct[ParsedType, BuildTypes], filename: str
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@
|
|||
import enum
|
||||
import dataclasses
|
||||
import typing as t
|
||||
from .declarativeunittest import common, raises
|
||||
from .declarativeunittest import common, raises, setattrs
|
||||
import construct as cs
|
||||
import construct_typed as cst
|
||||
|
||||
def test_tstruct_1() -> None:
|
||||
|
||||
def test_tstruct() -> None:
|
||||
@dataclasses.dataclass
|
||||
class TestDataclass:
|
||||
a: int = cst.TStructField(cs.Int16ub)
|
||||
|
|
@ -50,6 +51,47 @@ def test_tstruct_nested() -> None:
|
|||
)
|
||||
|
||||
|
||||
def test_tstruct_default_field() -> None:
|
||||
@dataclasses.dataclass
|
||||
class Image:
|
||||
width: int = cst.TStructField(cs.Int8ub)
|
||||
height: int = cst.TStructField(cs.Int8ub)
|
||||
pixels: t.Optional[bytes] = cst.TStructField(
|
||||
cs.Default(
|
||||
cs.Bytes(cs.this.width * cs.this.height),
|
||||
lambda ctx: bytes(ctx.width * ctx.height),
|
||||
)
|
||||
)
|
||||
|
||||
common(
|
||||
cst.TStruct(Image),
|
||||
b"\x02\x03\x00\x00\x00\x00\x00\x00",
|
||||
setattrs(Image(2, 3), pixels=bytes(6)),
|
||||
sample_building=Image(2, 3),
|
||||
)
|
||||
|
||||
|
||||
def test_tstruct_const_field() -> None:
|
||||
@dataclasses.dataclass
|
||||
class TestDataclass:
|
||||
const_field: t.Optional[bytes] = cst.TStructField(cs.Const(b"\x00"))
|
||||
|
||||
common(
|
||||
cst.TStruct(TestDataclass),
|
||||
bytes(1),
|
||||
setattrs(TestDataclass(), const_field=b"\x00"),
|
||||
1,
|
||||
)
|
||||
|
||||
assert (
|
||||
raises(
|
||||
cst.TStruct(TestDataclass).build,
|
||||
setattrs(TestDataclass(), const_field=b"\x01"),
|
||||
)
|
||||
== cs.ConstError
|
||||
)
|
||||
|
||||
|
||||
def test_tstruct_anonymus_fields_1() -> None:
|
||||
@dataclasses.dataclass
|
||||
class TestDataclass:
|
||||
|
|
@ -61,7 +103,7 @@ def test_tstruct_anonymus_fields_1() -> None:
|
|||
common(
|
||||
cst.TStruct(TestDataclass),
|
||||
bytes(2),
|
||||
TestDataclass(),
|
||||
setattrs(TestDataclass(), _1=b"\x00"),
|
||||
cs.SizeofError,
|
||||
)
|
||||
|
||||
|
|
@ -97,7 +139,10 @@ def test_tstruct_wrong_dataclass() -> None:
|
|||
a: int = cst.TStructField(cs.Int16ub)
|
||||
b: int = cst.TStructField(cs.Int8ub)
|
||||
|
||||
assert raises(cst.TStruct(TestDataclass1).build, TestDataclass2(a=1, b=2)) == TypeError
|
||||
assert (
|
||||
raises(cst.TStruct(TestDataclass1).build, TestDataclass2(a=1, b=2)) == TypeError
|
||||
)
|
||||
|
||||
|
||||
def test_tbitstruct() -> None:
|
||||
assert False
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue