Skip to content

Fix serialization of dataclass constructor parameters #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion betterproto/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,9 @@ class Message(ABC):
_group_map: Dict[str, dict]

def __post_init__(self) -> None:
# Keep track of whether every field was default
all_sentinel = True

# Set a default value for each field in the class after `__init__` has
# already been run.
group_map: Dict[str, dict] = {"fields": {}, "groups": {}}
Expand All @@ -446,6 +449,7 @@ def __post_init__(self) -> None:

if getattr(self, field.name) != PLACEHOLDER:
# Skip anything not set to the sentinel value
all_sentinel = False

if meta.group:
# This was set, so make it the selected value of the one-of.
Expand All @@ -456,7 +460,7 @@ def __post_init__(self) -> None:
setattr(self, field.name, self._get_field_default(field, meta))

# Now that all the defaults are set, reset it!
self.__dict__["_serialized_on_wire"] = False
self.__dict__["_serialized_on_wire"] = not all_sentinel
self.__dict__["_unknown_fields"] = b""
self.__dict__["_group_map"] = group_map

Expand Down
15 changes: 15 additions & 0 deletions betterproto/tests/test_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,21 @@ class Foo(betterproto.Message):
assert betterproto.serialized_on_wire(foo.bar) == False


def test_class_init():
@dataclass
class Bar(betterproto.Message):
name: str = betterproto.string_field(1)

@dataclass
class Foo(betterproto.Message):
name: str = betterproto.string_field(1)
child: Bar = betterproto.message_field(2)

foo = Foo(name="foo", child=Bar(name="bar"))

assert foo.to_dict() == {"name": "foo", "child": {"name": "bar"}}


def test_enum_as_int_json():
class TestEnum(betterproto.Enum):
ZERO = 0
Expand Down