| Index: third_party/protobuf/python/google/protobuf/internal/unknown_fields_test.py
|
| diff --git a/third_party/protobuf/python/google/protobuf/internal/unknown_fields_test.py b/third_party/protobuf/python/google/protobuf/internal/unknown_fields_test.py
|
| index 84073f1c5344f934d4def999fa209700fc7dd39d..d614eaa8744f79cab2c646e454e896cbd09e48ab 100755
|
| --- a/third_party/protobuf/python/google/protobuf/internal/unknown_fields_test.py
|
| +++ b/third_party/protobuf/python/google/protobuf/internal/unknown_fields_test.py
|
| @@ -47,16 +47,20 @@ from google.protobuf.internal import encoder
|
| from google.protobuf.internal import message_set_extensions_pb2
|
| from google.protobuf.internal import missing_enum_values_pb2
|
| from google.protobuf.internal import test_util
|
| +from google.protobuf.internal import testing_refleaks
|
| from google.protobuf.internal import type_checkers
|
|
|
|
|
| +BaseTestCase = testing_refleaks.BaseTestCase
|
| +
|
| +
|
| def SkipIfCppImplementation(func):
|
| return unittest.skipIf(
|
| api_implementation.Type() == 'cpp' and api_implementation.Version() == 2,
|
| 'C++ implementation does not expose unknown fields to Python')(func)
|
|
|
|
|
| -class UnknownFieldsTest(unittest.TestCase):
|
| +class UnknownFieldsTest(BaseTestCase):
|
|
|
| def setUp(self):
|
| self.descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
|
| @@ -140,7 +144,7 @@ class UnknownFieldsTest(unittest.TestCase):
|
| b'', message.repeated_nested_message[0].SerializeToString())
|
|
|
|
|
| -class UnknownFieldsAccessorsTest(unittest.TestCase):
|
| +class UnknownFieldsAccessorsTest(BaseTestCase):
|
|
|
| def setUp(self):
|
| self.descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
|
| @@ -149,21 +153,18 @@ class UnknownFieldsAccessorsTest(unittest.TestCase):
|
| self.all_fields_data = self.all_fields.SerializeToString()
|
| self.empty_message = unittest_pb2.TestEmptyMessage()
|
| self.empty_message.ParseFromString(self.all_fields_data)
|
| - if api_implementation.Type() != 'cpp':
|
| - # _unknown_fields is an implementation detail.
|
| - self.unknown_fields = self.empty_message._unknown_fields
|
|
|
| - # All the tests that use GetField() check an implementation detail of the
|
| - # Python implementation, which stores unknown fields as serialized strings.
|
| - # These tests are skipped by the C++ implementation: it's enough to check that
|
| - # the message is correctly serialized.
|
| + # GetUnknownField() checks a detail of the Python implementation, which stores
|
| + # unknown fields as serialized strings. It cannot be used by the C++
|
| + # implementation: it's enough to check that the message is correctly
|
| + # serialized.
|
|
|
| - def GetField(self, name):
|
| + def GetUnknownField(self, name):
|
| field_descriptor = self.descriptor.fields_by_name[name]
|
| wire_type = type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type]
|
| field_tag = encoder.TagBytes(field_descriptor.number, wire_type)
|
| result_dict = {}
|
| - for tag_bytes, value in self.unknown_fields:
|
| + for tag_bytes, value in self.empty_message._unknown_fields:
|
| if tag_bytes == field_tag:
|
| decoder = unittest_pb2.TestAllTypes._decoders_by_tag[tag_bytes][0]
|
| decoder(value, 0, len(value), self.all_fields, result_dict)
|
| @@ -171,37 +172,37 @@ class UnknownFieldsAccessorsTest(unittest.TestCase):
|
|
|
| @SkipIfCppImplementation
|
| def testEnum(self):
|
| - value = self.GetField('optional_nested_enum')
|
| + value = self.GetUnknownField('optional_nested_enum')
|
| self.assertEqual(self.all_fields.optional_nested_enum, value)
|
|
|
| @SkipIfCppImplementation
|
| def testRepeatedEnum(self):
|
| - value = self.GetField('repeated_nested_enum')
|
| + value = self.GetUnknownField('repeated_nested_enum')
|
| self.assertEqual(self.all_fields.repeated_nested_enum, value)
|
|
|
| @SkipIfCppImplementation
|
| def testVarint(self):
|
| - value = self.GetField('optional_int32')
|
| + value = self.GetUnknownField('optional_int32')
|
| self.assertEqual(self.all_fields.optional_int32, value)
|
|
|
| @SkipIfCppImplementation
|
| def testFixed32(self):
|
| - value = self.GetField('optional_fixed32')
|
| + value = self.GetUnknownField('optional_fixed32')
|
| self.assertEqual(self.all_fields.optional_fixed32, value)
|
|
|
| @SkipIfCppImplementation
|
| def testFixed64(self):
|
| - value = self.GetField('optional_fixed64')
|
| + value = self.GetUnknownField('optional_fixed64')
|
| self.assertEqual(self.all_fields.optional_fixed64, value)
|
|
|
| @SkipIfCppImplementation
|
| def testLengthDelimited(self):
|
| - value = self.GetField('optional_string')
|
| + value = self.GetUnknownField('optional_string')
|
| self.assertEqual(self.all_fields.optional_string, value)
|
|
|
| @SkipIfCppImplementation
|
| def testGroup(self):
|
| - value = self.GetField('optionalgroup')
|
| + value = self.GetUnknownField('optionalgroup')
|
| self.assertEqual(self.all_fields.optionalgroup, value)
|
|
|
| def testCopyFrom(self):
|
| @@ -241,43 +242,41 @@ class UnknownFieldsAccessorsTest(unittest.TestCase):
|
| self.assertEqual(message.SerializeToString(), self.all_fields_data)
|
|
|
|
|
| -class UnknownEnumValuesTest(unittest.TestCase):
|
| +class UnknownEnumValuesTest(BaseTestCase):
|
|
|
| def setUp(self):
|
| self.descriptor = missing_enum_values_pb2.TestEnumValues.DESCRIPTOR
|
|
|
| self.message = missing_enum_values_pb2.TestEnumValues()
|
| + # TestEnumValues.ZERO = 0, but does not exist in the other NestedEnum.
|
| self.message.optional_nested_enum = (
|
| - missing_enum_values_pb2.TestEnumValues.ZERO)
|
| + missing_enum_values_pb2.TestEnumValues.ZERO)
|
| self.message.repeated_nested_enum.extend([
|
| - missing_enum_values_pb2.TestEnumValues.ZERO,
|
| - missing_enum_values_pb2.TestEnumValues.ONE,
|
| - ])
|
| + missing_enum_values_pb2.TestEnumValues.ZERO,
|
| + missing_enum_values_pb2.TestEnumValues.ONE,
|
| + ])
|
| self.message.packed_nested_enum.extend([
|
| - missing_enum_values_pb2.TestEnumValues.ZERO,
|
| - missing_enum_values_pb2.TestEnumValues.ONE,
|
| - ])
|
| + missing_enum_values_pb2.TestEnumValues.ZERO,
|
| + missing_enum_values_pb2.TestEnumValues.ONE,
|
| + ])
|
| self.message_data = self.message.SerializeToString()
|
| self.missing_message = missing_enum_values_pb2.TestMissingEnumValues()
|
| self.missing_message.ParseFromString(self.message_data)
|
| - if api_implementation.Type() != 'cpp':
|
| - # _unknown_fields is an implementation detail.
|
| - self.unknown_fields = self.missing_message._unknown_fields
|
|
|
| - # All the tests that use GetField() check an implementation detail of the
|
| - # Python implementation, which stores unknown fields as serialized strings.
|
| - # These tests are skipped by the C++ implementation: it's enough to check that
|
| - # the message is correctly serialized.
|
| + # GetUnknownField() checks a detail of the Python implementation, which stores
|
| + # unknown fields as serialized strings. It cannot be used by the C++
|
| + # implementation: it's enough to check that the message is correctly
|
| + # serialized.
|
|
|
| - def GetField(self, name):
|
| + def GetUnknownField(self, name):
|
| field_descriptor = self.descriptor.fields_by_name[name]
|
| wire_type = type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type]
|
| field_tag = encoder.TagBytes(field_descriptor.number, wire_type)
|
| result_dict = {}
|
| - for tag_bytes, value in self.unknown_fields:
|
| + for tag_bytes, value in self.missing_message._unknown_fields:
|
| if tag_bytes == field_tag:
|
| decoder = missing_enum_values_pb2.TestEnumValues._decoders_by_tag[
|
| - tag_bytes][0]
|
| + tag_bytes][0]
|
| decoder(value, 0, len(value), self.message, result_dict)
|
| return result_dict[field_descriptor]
|
|
|
| @@ -294,21 +293,39 @@ class UnknownEnumValuesTest(unittest.TestCase):
|
| # default value.
|
| self.assertEqual(missing.optional_nested_enum, 0)
|
|
|
| - @SkipIfCppImplementation
|
| def testUnknownEnumValue(self):
|
| + if api_implementation.Type() == 'cpp':
|
| + # The CPP implementation of protos (wrongly) allows unknown enum values
|
| + # for proto2.
|
| + self.assertTrue(self.missing_message.HasField('optional_nested_enum'))
|
| + self.assertEqual(self.message.optional_nested_enum,
|
| + self.missing_message.optional_nested_enum)
|
| + else:
|
| + # On the other hand, the Python implementation considers unknown values
|
| + # as unknown fields. This is the correct behavior.
|
| + self.assertFalse(self.missing_message.HasField('optional_nested_enum'))
|
| + value = self.GetUnknownField('optional_nested_enum')
|
| + self.assertEqual(self.message.optional_nested_enum, value)
|
| + self.missing_message.ClearField('optional_nested_enum')
|
| self.assertFalse(self.missing_message.HasField('optional_nested_enum'))
|
| - value = self.GetField('optional_nested_enum')
|
| - self.assertEqual(self.message.optional_nested_enum, value)
|
|
|
| - @SkipIfCppImplementation
|
| def testUnknownRepeatedEnumValue(self):
|
| - value = self.GetField('repeated_nested_enum')
|
| - self.assertEqual(self.message.repeated_nested_enum, value)
|
| + if api_implementation.Type() == 'cpp':
|
| + # For repeated enums, both implementations agree.
|
| + self.assertEqual([], self.missing_message.repeated_nested_enum)
|
| + else:
|
| + self.assertEqual([], self.missing_message.repeated_nested_enum)
|
| + value = self.GetUnknownField('repeated_nested_enum')
|
| + self.assertEqual(self.message.repeated_nested_enum, value)
|
|
|
| - @SkipIfCppImplementation
|
| def testUnknownPackedEnumValue(self):
|
| - value = self.GetField('packed_nested_enum')
|
| - self.assertEqual(self.message.packed_nested_enum, value)
|
| + if api_implementation.Type() == 'cpp':
|
| + # For repeated enums, both implementations agree.
|
| + self.assertEqual([], self.missing_message.packed_nested_enum)
|
| + else:
|
| + self.assertEqual([], self.missing_message.packed_nested_enum)
|
| + value = self.GetUnknownField('packed_nested_enum')
|
| + self.assertEqual(self.message.packed_nested_enum, value)
|
|
|
| def testRoundTrip(self):
|
| new_message = missing_enum_values_pb2.TestEnumValues()
|
|
|