diff --git a/proto/message.py b/proto/message.py index 08e6623f..28a87a80 100644 --- a/proto/message.py +++ b/proto/message.py @@ -327,7 +327,13 @@ def deserialize(cls, payload: bytes) -> "Message": """ return cls.wrap(cls.pb().FromString(payload)) - def to_json(cls, instance, *, use_integers_for_enums=True) -> str: + def to_json( + cls, + instance, + *, + use_integers_for_enums=True, + including_default_value_fields=True + ) -> str: """Given a message instance, serialize it to json Args: @@ -343,7 +349,7 @@ def to_json(cls, instance, *, use_integers_for_enums=True) -> str: return MessageToJson( cls.pb(instance), use_integers_for_enums=use_integers_for_enums, - including_default_value_fields=True, + including_default_value_fields=including_default_value_fields, ) def from_json(cls, payload, *, ignore_unknown_fields=False) -> "Message": diff --git a/tests/test_json.py b/tests/test_json.py index 34c2d438..4b7be8be 100644 --- a/tests/test_json.py +++ b/tests/test_json.py @@ -97,6 +97,29 @@ class Zone(proto.Enum): assert json2 == '{"zone":"EPIPELAGIC"}' +def test_json_default_values(): + class Squid(proto.Message): + mass_kg = proto.Field(proto.INT32, number=1) + name = proto.Field(proto.STRING, number=2) + + s = Squid(name="Steve") + json1 = ( + Squid.to_json(s, including_default_value_fields=False) + .replace(" ", "") + .replace("\n", "") + ) + assert json1 == '{"name":"Steve"}' + + json2 = Squid.to_json(s).replace(" ", "").replace("\n", "") + assert ( + json2 == '{"name":"Steve","massKg":0}' or json2 == '{"massKg":0,"name":"Steve"}' + ) + + s1 = Squid.from_json(json1) + s2 = Squid.from_json(json2) + assert s == s1 == s2 + + def test_json_unknown_field(): # Note that 'lengthCm' is unknown in the local definition. # This could happen if the client is using an older proto definition