diff --git a/python/google/protobuf/internal/reflection_test.py b/python/google/protobuf/internal/reflection_test.py index 922855b64..54eeebe66 100755 --- a/python/google/protobuf/internal/reflection_test.py +++ b/python/google/protobuf/internal/reflection_test.py @@ -200,6 +200,32 @@ class ReflectionTest(unittest.TestCase): unittest_pb2.ForeignMessage(c=12)], list(proto.repeated_foreign_message)) + def testConstructorTypeError(self): + self.assertRaises(TypeError, unittest_pb2.TestAllTypes, optional_int32="foo") + self.assertRaises(TypeError, unittest_pb2.TestAllTypes, optional_string=1234) + self.assertRaises(TypeError, unittest_pb2.TestAllTypes, optional_nested_message=1234) + self.assertRaises(TypeError, unittest_pb2.TestAllTypes, repeated_int32=1234) + self.assertRaises(TypeError, unittest_pb2.TestAllTypes, repeated_int32=["foo"]) + self.assertRaises(TypeError, unittest_pb2.TestAllTypes, repeated_string=1234) + self.assertRaises(TypeError, unittest_pb2.TestAllTypes, repeated_string=[1234]) + self.assertRaises(TypeError, unittest_pb2.TestAllTypes, repeated_nested_message=1234) + self.assertRaises(TypeError, unittest_pb2.TestAllTypes, repeated_nested_message=[1234]) + + def testConstructorInvalidatesCachedByteSize(self): + message = unittest_pb2.TestAllTypes(optional_int32 = 12) + self.assertEquals(2, message.ByteSize()) + + message = unittest_pb2.TestAllTypes( + optional_nested_message = unittest_pb2.TestAllTypes.NestedMessage()) + self.assertEquals(3, message.ByteSize()) + + message = unittest_pb2.TestAllTypes(repeated_int32 = [12]) + self.assertEquals(3, message.ByteSize()) + + message = unittest_pb2.TestAllTypes( + repeated_nested_message = [unittest_pb2.TestAllTypes.NestedMessage()]) + self.assertEquals(3, message.ByteSize()) + def testSimpleHasBits(self): # Test a scalar. proto = unittest_pb2.TestAllTypes() @@ -1038,12 +1064,12 @@ class ReflectionTest(unittest.TestCase): 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')) diff --git a/python/google/protobuf/reflection.py b/python/google/protobuf/reflection.py index 13bd8e5eb..45e5ba887 100755 --- a/python/google/protobuf/reflection.py +++ b/python/google/protobuf/reflection.py @@ -384,7 +384,7 @@ def _AddInitMethod(message_descriptor, cls): copy.MergeFrom(field_value) self._fields[field] = copy else: - self._fields[field] = field_value + setattr(self, field_name, field_value) init.__module__ = None init.__doc__ = None @@ -937,6 +937,10 @@ def _AddMergeFromMethod(cls): CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE def MergeFrom(self, msg): + if not isinstance(msg, cls): + raise TypeError( + "Parameter to MergeFrom() must be instance of same class.") + assert msg is not self self._Modified()