add docstring to construct docs
This commit is contained in:
parent
acc9f6a9e4
commit
c5d08f9b87
3 changed files with 62 additions and 16 deletions
|
|
@ -271,6 +271,11 @@ class DataclassStruct:
|
|||
if not isinstance(reverse_fields, bool): # type: ignore
|
||||
raise ValueError("`reverse_fields` parameter has to be an `bool` object")
|
||||
|
||||
# get documentation before creating the dataclass
|
||||
docs = ""
|
||||
if cls.__doc__ is not None:
|
||||
docs = textwrap.dedent(cls.__doc__).strip("\n")
|
||||
|
||||
# create dataclass
|
||||
dataclasses.dataclass(cls, kw_only=True) # type: ignore
|
||||
|
||||
|
|
@ -279,6 +284,9 @@ class DataclassStruct:
|
|||
if not isinstance(dc_constr, cs.Construct): # type: ignore
|
||||
raise ValueError("`constr` sould return a `Construct` object")
|
||||
|
||||
# save docs
|
||||
dc_constr.docs = docs
|
||||
|
||||
# save construct format and make the class compatible to `Constructable` protocol
|
||||
setattr(cls, "__constr__", lambda: dc_constr)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import enum
|
||||
import textwrap
|
||||
import typing as t
|
||||
|
||||
import construct as cs
|
||||
|
||||
from .generic import *
|
||||
from construct_typed.generic import *
|
||||
|
||||
T = t.TypeVar("T")
|
||||
|
||||
|
|
@ -26,6 +27,11 @@ class _EnumMeta(enum.EnumMeta):
|
|||
__namespace: t.Dict[str, t.Any],
|
||||
**kwargs: t.Any,
|
||||
) -> T:
|
||||
# get documentation before creating the enum
|
||||
docs = ""
|
||||
if "__doc__" in __namespace:
|
||||
docs = textwrap.dedent(__namespace["__doc__"]).strip("\n")
|
||||
|
||||
# create new enum object
|
||||
cls: T = super().__new__(metacls, __name, __bases, __namespace) # type: ignore
|
||||
|
||||
|
|
@ -49,7 +55,10 @@ class _EnumMeta(enum.EnumMeta):
|
|||
elif TFlags in __bases:
|
||||
enum_constr = TFlagsConstruct(subcon, cls) # type: ignore
|
||||
else:
|
||||
enum_constr = None
|
||||
raise TypeError("neither `TEnum` nor `TFlags` in bases")
|
||||
|
||||
# save documentation
|
||||
enum_constr.docs = docs
|
||||
|
||||
# save construct format and make the class compatible to `Constructable` protocol
|
||||
setattr(cls, "__constr__", lambda: enum_constr) # type: ignore
|
||||
|
|
|
|||
|
|
@ -277,28 +277,39 @@ def test_dataclass_struct_wrong_container() -> None:
|
|||
|
||||
|
||||
def test_dataclass_struct_doc() -> None:
|
||||
class TestContainer(DataclassStruct):
|
||||
a: int = csfield(cs.Int16ub, doc="This is the documentation of a")
|
||||
b: int = csfield(
|
||||
cs.Int8ub, doc="This is the documentation of b\nwhich is multiline"
|
||||
)
|
||||
class TestContainer1(DataclassStruct):
|
||||
"""
|
||||
Documentation of TestContainer
|
||||
"""
|
||||
|
||||
a: int = csfield(cs.Int16ub, doc="This is the doc of a")
|
||||
b: int = csfield(cs.Int8ub, doc="This is the doc of b\nwhich is multiline")
|
||||
c: int = csfield(
|
||||
cs.Int8ub,
|
||||
doc="""
|
||||
This is the documentation of c
|
||||
This is the doc of c
|
||||
which is also multiline
|
||||
""",
|
||||
)
|
||||
|
||||
format = TestContainer.__constr__()
|
||||
common(format, b"\x00\x01\x02\x03", TestContainer(a=1, b=2, c=3), 4)
|
||||
format1 = TestContainer1.__constr__()
|
||||
common(format1, b"\x00\x01\x02\x03", TestContainer1(a=1, b=2, c=3), 4)
|
||||
|
||||
assert format.subcon.a.docs == "This is the documentation of a"
|
||||
assert format.subcon.b.docs == "This is the documentation of b\nwhich is multiline"
|
||||
assert (
|
||||
format.subcon.c.docs
|
||||
== "This is the documentation of c\nwhich is also multiline"
|
||||
)
|
||||
assert format1.docs == "Documentation of TestContainer"
|
||||
assert format1.subcon.a.docs == "This is the doc of a"
|
||||
assert format1.subcon.b.docs == "This is the doc of b\nwhich is multiline"
|
||||
assert format1.subcon.c.docs == "This is the doc of c\nwhich is also multiline"
|
||||
|
||||
class TestContainer2(DataclassStruct):
|
||||
a: int = csfield(cs.Int16ub)
|
||||
b: int = csfield(cs.Int8ub)
|
||||
c: int = csfield(cs.Int8ub)
|
||||
|
||||
format2 = TestContainer2.__constr__()
|
||||
assert format2.docs == ""
|
||||
assert format2.subcon.a.docs == ""
|
||||
assert format2.subcon.b.docs == ""
|
||||
assert format2.subcon.c.docs == ""
|
||||
|
||||
|
||||
def test_dataclass_bitwise() -> None:
|
||||
|
|
@ -367,6 +378,24 @@ def test_tenum() -> None:
|
|||
assert raises(d.build, 8) == TypeError
|
||||
|
||||
|
||||
def test_tenum_doc() -> None:
|
||||
class TestEnum1(TEnum, subcon=cs.Byte):
|
||||
"""
|
||||
TestEnum documentation
|
||||
"""
|
||||
|
||||
one = 1
|
||||
|
||||
d1 = constr(TestEnum1)
|
||||
assert d1.docs == "TestEnum documentation"
|
||||
|
||||
class TestEnum2(TEnum, subcon=cs.Byte):
|
||||
two = 2
|
||||
|
||||
d2 = constr(TestEnum2)
|
||||
assert d2.docs == ""
|
||||
|
||||
|
||||
def test_tenum_in_dataclass_struct() -> None:
|
||||
class TestEnum(TEnum, subcon=cs.Int8ub):
|
||||
a = 1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue