Skip to content

Commit

Permalink
Support tuples when parsing JSON dicts
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 696911739
  • Loading branch information
protobuf-github-bot authored and copybara-github committed Nov 15, 2024
1 parent 1963073 commit 75bb72e
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 25 deletions.
17 changes: 0 additions & 17 deletions csharp/src/Google.Protobuf/Reflection/FeatureSetDescriptor.g.cs

This file was deleted.

28 changes: 26 additions & 2 deletions python/google/protobuf/internal/json_format_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -597,8 +597,8 @@ def testStructMessage(self):
parsed_message = json_format_proto3_pb2.TestStruct()
self.CheckParseBack(message, parsed_message)
# check for regression; this used to raise
parsed_message.value['empty_struct']
parsed_message.value['empty_list']
_ = parsed_message.value['empty_struct']
_ = parsed_message.value['empty_list']

def testValueMessage(self):
message = json_format_proto3_pb2.TestValue()
Expand Down Expand Up @@ -1530,6 +1530,30 @@ def testParseDict(self):
json_format.ParseDict(js_dict, message)
self.assertEqual(expected, message.int32_value)

def testParseDictAcceptsPairValueTuples(self):
expected = [1, 2, 3]
js_dict = {'repeatedInt32Value': (1, 2, 3)}
message = json_format_proto3_pb2.TestMessage()
json_format.ParseDict(js_dict, message)
self.assertEqual(expected, message.repeated_int32_value)

def testParseDictAcceptsRepeatedValueTuples(self):
expected = json_format_proto3_pb2.TestListValue(
repeated_value=[
struct_pb2.ListValue(
values=[
struct_pb2.Value(number_value=4),
struct_pb2.Value(number_value=5),
]
),
struct_pb2.ListValue(values=[struct_pb2.Value(number_value=6)]),
]
)
js_dict = {'repeated_value': ((4, 5), (6,))}
message = json_format_proto3_pb2.TestListValue()
json_format.ParseDict(js_dict, message)
self.assertEqual(expected, message)

def testParseDictAnyDescriptorPoolMissingType(self):
# Confirm that ParseDict does not raise ParseError with default pool
js_dict = {
Expand Down
13 changes: 7 additions & 6 deletions python/google/protobuf/json_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,7 @@ def ParseDict(


_INT_OR_FLOAT = (int, float)
_LIST_LIKE = (list, tuple)


class _Parser(object):
Expand Down Expand Up @@ -638,7 +639,7 @@ def _ConvertFieldValuePair(self, js, message, path):
)
elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
message.ClearField(field.name)
if not isinstance(value, list):
if not isinstance(value, _LIST_LIKE):
raise ParseError(
'repeated field {0} must be in [] which is {1} at {2}'.format(
name, value, path
Expand Down Expand Up @@ -752,8 +753,8 @@ def _ConvertValueMessage(self, value, message, path):
"""Convert a JSON representation into Value message."""
if isinstance(value, dict):
self._ConvertStructMessage(value, message.struct_value, path)
elif isinstance(value, list):
self._ConvertListValueMessage(value, message.list_value, path)
elif isinstance(value, _LIST_LIKE):
self._ConvertListOrTupleValueMessage(value, message.list_value, path)
elif value is None:
message.null_value = 0
elif isinstance(value, bool):
Expand All @@ -769,9 +770,9 @@ def _ConvertValueMessage(self, value, message, path):
)
)

def _ConvertListValueMessage(self, value, message, path):
def _ConvertListOrTupleValueMessage(self, value, message, path):
"""Convert a JSON representation into ListValue message."""
if not isinstance(value, list):
if not isinstance(value, _LIST_LIKE):
raise ParseError(
'ListValue must be in [] which is {0} at {1}'.format(value, path)
)
Expand Down Expand Up @@ -1052,7 +1053,7 @@ def _ConvertBool(value, require_str):
],
'google.protobuf.ListValue': [
'_ListValueMessageToJsonObject',
'_ConvertListValueMessage',
'_ConvertListOrTupleValueMessage',
],
'google.protobuf.Struct': [
'_StructMessageToJsonObject',
Expand Down

0 comments on commit 75bb72e

Please sign in to comment.