a TypedStruct is always parsed to an object of the container_type
This commit is contained in:
parent
29f6af7936
commit
a564ff55fd
4 changed files with 55 additions and 9 deletions
|
|
@ -57,6 +57,15 @@ __all__ = [
|
|||
'FixedSized',
|
||||
'Flag',
|
||||
'FlagsEnum',
|
||||
"Float16b",
|
||||
"Float16l",
|
||||
"Float16n",
|
||||
"Float32b",
|
||||
"Float32l",
|
||||
"Float32n",
|
||||
"Float64b",
|
||||
"Float64l",
|
||||
"Float64n",
|
||||
'FocusedSeq',
|
||||
'FormatField',
|
||||
'FormatFieldError',
|
||||
|
|
@ -75,6 +84,36 @@ __all__ = [
|
|||
'IndexFieldError',
|
||||
'Indexing',
|
||||
'Int',
|
||||
"Int8sb",
|
||||
"Int8sl",
|
||||
"Int8sn",
|
||||
"Int8ub",
|
||||
"Int8ul",
|
||||
"Int8un",
|
||||
"Int16sb",
|
||||
"Int16sl",
|
||||
"Int16sn",
|
||||
"Int16ub",
|
||||
"Int16ul",
|
||||
"Int16un",
|
||||
"Int24sb",
|
||||
"Int24sl",
|
||||
"Int24sn",
|
||||
"Int24ub",
|
||||
"Int24ul",
|
||||
"Int24un",
|
||||
"Int32sb",
|
||||
"Int32sl",
|
||||
"Int32sn",
|
||||
"Int32ub",
|
||||
"Int32ul",
|
||||
"Int32un",
|
||||
"Int64sb",
|
||||
"Int64sl",
|
||||
"Int64sn",
|
||||
"Int64ub",
|
||||
"Int64ul",
|
||||
"Int64un",
|
||||
'IntegerError',
|
||||
'Lazy',
|
||||
'LazyArray',
|
||||
|
|
@ -176,6 +215,4 @@ __all__ = [
|
|||
'VarInt',
|
||||
'version',
|
||||
'version_string',
|
||||
]
|
||||
__all__ += ["Int%s%s%s" % (n,us,bln) for n in (8,16,24,32,64) for us in "us" for bln in "bln"]
|
||||
__all__ += ["Float%s%s" % (n,bln) for n in (16,32,64) for bln in "bln"]
|
||||
]
|
||||
|
|
@ -101,13 +101,14 @@ else:
|
|||
|
||||
if TYPE_CHECKING:
|
||||
ContainerType = TypeVar("ContainerType", bound=TypedContainer)
|
||||
class TypedStruct(Construct[ContainerType, Dict[str, Any]]):
|
||||
class TypedStruct(Adapter[Container[Any], Dict[str, Any], ContainerType, Dict[str, Any]]):
|
||||
def __init__(self, container_type: Type[ContainerType], swapped: bool = False) -> None: ...
|
||||
else:
|
||||
class TypedStruct(Struct):
|
||||
class TypedStruct(Adapter):
|
||||
def __init__(self, container_type, swapped = False):
|
||||
if not issubclass(container_type, TypedContainer):
|
||||
raise TypeError("the subcon has to be a TypedContainer")
|
||||
self.container_type = container_type
|
||||
|
||||
# extract the construct formats from the struct_type
|
||||
subcons = {}
|
||||
|
|
@ -118,4 +119,11 @@ else:
|
|||
for subcon_name, subcon_format in subcon_items:
|
||||
subcons[subcon_name] = subcon_format
|
||||
|
||||
super(TypedStruct, self).__init__(**subcons)
|
||||
# init Adatper with a Struct as subcon
|
||||
super(TypedStruct, self).__init__(Struct(**subcons))
|
||||
|
||||
def _decode(self, obj, context, path):
|
||||
return self.container_type(obj)
|
||||
|
||||
def _encode(self, obj, context, path):
|
||||
return obj
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ def raises(func, *args, **kw):
|
|||
def common(format, datasample, objsample, sizesample=SizeofError, **kw):
|
||||
obj = format.parse(datasample, **kw)
|
||||
assert obj == objsample
|
||||
assert isinstance(obj, type(objsample))
|
||||
data = format.build(objsample, **kw)
|
||||
assert data == datasample
|
||||
# following are implied by above (re-parse and re-build)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import enum
|
||||
from .declarativeunittest import common, raises
|
||||
from construct.core import (
|
||||
from construct import (
|
||||
Int8ub,
|
||||
Int16ub,
|
||||
Const,
|
||||
|
|
@ -26,12 +26,12 @@ def test_typed_struct():
|
|||
|
||||
common(TypedStruct(Container1), b"\x00\x01\x02", Container1(a=1, b=2), 3)
|
||||
|
||||
class Container1Reversing(TypedContainer):
|
||||
class Container1Swapped(TypedContainer):
|
||||
a: Subcon(Int16ub)
|
||||
b: Subcon(Int8ub)
|
||||
|
||||
common(
|
||||
TypedStruct(Container1Reversing, swapped=True),
|
||||
TypedStruct(Container1Swapped, swapped=True),
|
||||
b"\x02\x00\x01",
|
||||
Container(a=1, b=2),
|
||||
3,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue