1. youngking
  2. protobuf

Commits

ken...@google.com@630680e5-0e50-0410-840e-4b1c322b438d  committed e22a663

Fix issue 207

  • Participants
  • Parent commits 56e07a7
  • Branches default

Comments (0)

Files changed (2)

File python/google/protobuf/internal/reflection_test.py

View file
     self.assertEqual(222, ext2[1].bb)
     self.assertEqual(333, ext2[2].bb)
 
+  def testMergeFromBug(self):
+    message1 = unittest_pb2.TestAllTypes()
+    message2 = unittest_pb2.TestAllTypes()
+    
+    # Cause optional_nested_message to be instantiated within message1, even
+    # though it is not considered to be "present".
+    message1.optional_nested_message
+    self.assertFalse(message1.HasField('optional_nested_message'))
+    
+    # Merge into message2.  This should not instantiate the field is message2.
+    message2.MergeFrom(message1)
+    self.assertFalse(message2.HasField('optional_nested_message'))
+
   def testCopyFromSingularField(self):
     # Test copy with just a singular field.
     proto1 = unittest_pb2.TestAllTypes()

File python/google/protobuf/reflection.py

View file
     fields = self._fields
 
     for field, value in msg._fields.iteritems():
-      if field.label == LABEL_REPEATED or field.cpp_type == CPPTYPE_MESSAGE:
+      if field.label == LABEL_REPEATED:
         field_value = fields.get(field)
         if field_value is None:
           # Construct a new object to represent this field.
           field_value = field._default_constructor(self)
           fields[field] = field_value
         field_value.MergeFrom(value)
+      elif field.cpp_type == CPPTYPE_MESSAGE:
+        if value._is_present_in_parent:
+          field_value = fields.get(field)
+          if field_value is None:
+            # Construct a new object to represent this field.
+            field_value = field._default_constructor(self)
+            fields[field] = field_value
+          field_value.MergeFrom(value)
       else:
         self._fields[field] = value
   cls.MergeFrom = MergeFrom