From de5d071f44cbce8520303b9b5344c3c67d2ae431 Mon Sep 17 00:00:00 2001 From: Leon Barrett Date: Fri, 19 Jul 2019 15:47:52 -0700 Subject: [PATCH] Fix assignment between Python protobuf Structs (#6377) Currently, if you access a ListValue from a Struct and attempted to assign it to another Struct, you would get an exception: > s1 = spb.Struct() > s1['a'] = [1] > s2 = spb.Struct() > s2['a'] = s1['a'] ValueError: Unexpected type This fixes that case. --- python/google/protobuf/internal/well_known_types.py | 4 ++-- python/google/protobuf/internal/well_known_types_test.py | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/python/google/protobuf/internal/well_known_types.py b/python/google/protobuf/internal/well_known_types.py index 7d7fe15036..308fbfef6e 100644 --- a/python/google/protobuf/internal/well_known_types.py +++ b/python/google/protobuf/internal/well_known_types.py @@ -722,10 +722,10 @@ def _SetStructValue(struct_value, value): struct_value.string_value = value elif isinstance(value, _INT_OR_FLOAT): struct_value.number_value = value - elif isinstance(value, dict): + elif isinstance(value, (dict, Struct)): struct_value.struct_value.Clear() struct_value.struct_value.update(value) - elif isinstance(value, list): + elif isinstance(value, (list, ListValue)): struct_value.list_value.Clear() struct_value.list_value.extend(value) else: diff --git a/python/google/protobuf/internal/well_known_types_test.py b/python/google/protobuf/internal/well_known_types_test.py index 61b41ec523..8089f035c6 100644 --- a/python/google/protobuf/internal/well_known_types_test.py +++ b/python/google/protobuf/internal/well_known_types_test.py @@ -871,6 +871,15 @@ class StructTest(unittest.TestCase): self.assertEqual([6, True, False, None, inner_struct], list(struct['key5'].items())) + def testStructAssignment(self): + # Tests struct assignment from another struct + s1 = struct_pb2.Struct() + s2 = struct_pb2.Struct() + for value in [1, 'a', [1], ['a'], {'a': 'b'}]: + s1['x'] = value + s2['x'] = s1['x'] + self.assertEqual(s1['x'], s2['x']) + def testMergeFrom(self): struct = struct_pb2.Struct() struct_class = struct.__class__