diff --git a/src/betterproto/__init__.py b/src/betterproto/__init__.py index b26ec4bca..8bd32b53b 100644 --- a/src/betterproto/__init__.py +++ b/src/betterproto/__init__.py @@ -591,7 +591,6 @@ def __getattribute__(self, name: str) -> Any: return value value = self._get_field_default(name) - super().__setattr__(name, value) return value def __setattr__(self, attr: str, value: Any) -> None: @@ -875,6 +874,10 @@ def parse(self: T, data: bytes) -> T: ) current = getattr(self, field_name) + + if self.__raw_get(field_name) == PLACEHOLDER: + setattr(self, field_name, current) + if meta.proto_type == TYPE_MAP: # Value represents a single key/value pair entry in the map. current[value.key] = value.value @@ -972,6 +975,8 @@ def to_dict( ) ): output[cased_name] = value.to_dict(casing, include_default_values) + elif self.__raw_get(field_name) != PLACEHOLDER: + output[cased_name] = {} elif meta.proto_type == TYPE_MAP: for k in value: if hasattr(value[k], "to_dict"): diff --git a/tests/test_features.py b/tests/test_features.py index ef33d8730..1f0025e31 100644 --- a/tests/test_features.py +++ b/tests/test_features.py @@ -17,7 +17,7 @@ class Foo(betterproto.Message): assert betterproto.serialized_on_wire(foo.bar) is False # Serialized after setting something - foo.bar.baz = 1 + foo.bar = Bar(baz=1) assert betterproto.serialized_on_wire(foo.bar) is True # Still has it after setting the default value @@ -130,7 +130,7 @@ class Foo(betterproto.Message): assert foo.bar == 0 assert betterproto.which_one_of(foo, "group1")[0] == "baz" - foo.sub.val = 1 + foo.sub = Sub(val=1) assert betterproto.serialized_on_wire(foo.sub) foo.abc = "test" @@ -348,7 +348,7 @@ def test_recursive_message_defaults(): assert msg != RecursiveMessage( name="bob", intermediate=Intermediate(42), child=RecursiveMessage(name="jude") ) - msg.child.child.name = "jude" + msg.child = RecursiveMessage(child=RecursiveMessage(name="jude")) assert msg == RecursiveMessage( name="bob", intermediate=Intermediate(42),