aboutsummaryrefslogtreecommitdiffhomepage
path: root/python/google
diff options
context:
space:
mode:
authorGravatar kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2010-07-27 20:45:09 +0000
committerGravatar kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2010-07-27 20:45:09 +0000
commit0c293def6c23cc73b28e0adb55f70b1f47382563 (patch)
tree26615376a8fddec8389f99966ec48c6ebe71e4f8 /python/google
parent15b675eea572ed092d5f01148c9ebabf09186972 (diff)
Fix issue 207
Diffstat (limited to 'python/google')
-rwxr-xr-xpython/google/protobuf/internal/reflection_test.py13
-rwxr-xr-xpython/google/protobuf/reflection.py10
2 files changed, 22 insertions, 1 deletions
diff --git a/python/google/protobuf/internal/reflection_test.py b/python/google/protobuf/internal/reflection_test.py
index 2c9fa30b..922855b6 100755
--- a/python/google/protobuf/internal/reflection_test.py
+++ b/python/google/protobuf/internal/reflection_test.py
@@ -1035,6 +1035,19 @@ class ReflectionTest(unittest.TestCase):
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()
diff --git a/python/google/protobuf/reflection.py b/python/google/protobuf/reflection.py
index 5b238031..13bd8e5e 100755
--- a/python/google/protobuf/reflection.py
+++ b/python/google/protobuf/reflection.py
@@ -943,13 +943,21 @@ def _AddMergeFromMethod(cls):
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