Explorar o código

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.
Leon Barrett %!s(int64=6) %!d(string=hai) anos
pai
achega
de5d071f44

+ 2 - 2
python/google/protobuf/internal/well_known_types.py

@@ -722,10 +722,10 @@ def _SetStructValue(struct_value, value):
     struct_value.string_value = value
     struct_value.string_value = value
   elif isinstance(value, _INT_OR_FLOAT):
   elif isinstance(value, _INT_OR_FLOAT):
     struct_value.number_value = value
     struct_value.number_value = value
-  elif isinstance(value, dict):
+  elif isinstance(value, (dict, Struct)):
     struct_value.struct_value.Clear()
     struct_value.struct_value.Clear()
     struct_value.struct_value.update(value)
     struct_value.struct_value.update(value)
-  elif isinstance(value, list):
+  elif isinstance(value, (list, ListValue)):
     struct_value.list_value.Clear()
     struct_value.list_value.Clear()
     struct_value.list_value.extend(value)
     struct_value.list_value.extend(value)
   else:
   else:

+ 9 - 0
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],
     self.assertEqual([6, True, False, None, inner_struct],
                      list(struct['key5'].items()))
                      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):
   def testMergeFrom(self):
     struct = struct_pb2.Struct()
     struct = struct_pb2.Struct()
     struct_class = struct.__class__
     struct_class = struct.__class__