From 359594f4bb7ff8740d8c9bc1c392e28031bbda27 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Thu, 9 Sep 2021 17:45:49 -0700 Subject: [PATCH] Removed Python 2.x support for Python. --- python/README.md | 2 +- python/google/protobuf/descriptor.py | 3 +- .../protobuf/internal/_parameterized.py | 4 +- python/google/protobuf/internal/decoder.py | 54 +--- .../internal/descriptor_database_test.py | 5 +- .../protobuf/internal/descriptor_pool_test.py | 6 +- .../protobuf/internal/descriptor_test.py | 19 +- python/google/protobuf/internal/encoder.py | 11 +- .../protobuf/internal/enum_type_wrapper.py | 4 +- .../protobuf/internal/json_format_test.py | 27 +- .../protobuf/internal/message_factory_test.py | 5 +- .../google/protobuf/internal/message_test.py | 263 ++++-------------- .../protobuf/internal/python_message.py | 28 +- .../protobuf/internal/reflection_test.py | 35 +-- .../internal/service_reflection_test.py | 5 +- .../protobuf/internal/symbol_database_test.py | 5 +- .../protobuf/internal/testing_refleaks.py | 12 +- .../protobuf/internal/text_encoding_test.py | 5 +- .../protobuf/internal/text_format_test.py | 237 ++++++++-------- .../google/protobuf/internal/type_checkers.py | 34 +-- .../protobuf/internal/unknown_fields_test.py | 6 +- .../protobuf/internal/well_known_types.py | 23 +- .../internal/well_known_types_test.py | 14 +- .../protobuf/internal/wire_format_test.py | 5 +- python/google/protobuf/json_format.py | 27 +- python/google/protobuf/message_factory.py | 2 - python/google/protobuf/proto_builder.py | 5 +- python/google/protobuf/text_encoding.py | 19 +- python/google/protobuf/text_format.py | 55 +--- python/setup.py | 2 +- python/tox.ini | 7 +- 31 files changed, 288 insertions(+), 641 deletions(-) diff --git a/python/README.md b/python/README.md index 31e649c715..f0c9ce4f44 100644 --- a/python/README.md +++ b/python/README.md @@ -26,7 +26,7 @@ use python c++ implementation. Installation ============ -1) Make sure you have Python 2.7 or newer. If in doubt, run: +1) Make sure you have Python 3.5 or newer. If in doubt, run: $ python -V diff --git a/python/google/protobuf/descriptor.py b/python/google/protobuf/descriptor.py index 70fdae16ff..0f7bd17443 100644 --- a/python/google/protobuf/descriptor.py +++ b/python/google/protobuf/descriptor.py @@ -36,7 +36,6 @@ __author__ = 'robinson@google.com (Will Robinson)' import threading import warnings -import six from google.protobuf.internal import api_implementation @@ -111,7 +110,7 @@ _Deprecated.count = 100 _internal_create_key = object() -class DescriptorBase(six.with_metaclass(DescriptorMetaclass)): +class DescriptorBase(metaclass=DescriptorMetaclass): """Descriptors base class. diff --git a/python/google/protobuf/internal/_parameterized.py b/python/google/protobuf/internal/_parameterized.py index 4cba1d479d..287ba689bf 100755 --- a/python/google/protobuf/internal/_parameterized.py +++ b/python/google/protobuf/internal/_parameterized.py @@ -154,8 +154,6 @@ except ImportError: import unittest import uuid -import six - try: # Since python 3 import collections.abc as collections_abc @@ -181,7 +179,7 @@ def _StrClass(cls): def _NonStringIterable(obj): return (isinstance(obj, collections_abc.Iterable) and not - isinstance(obj, six.string_types)) + isinstance(obj, str)) def _FormatParameterList(testcase_params): diff --git a/python/google/protobuf/internal/decoder.py b/python/google/protobuf/internal/decoder.py index 6804986b6e..bc1b7b785c 100644 --- a/python/google/protobuf/internal/decoder.py +++ b/python/google/protobuf/internal/decoder.py @@ -80,16 +80,8 @@ we repeatedly read a tag, look up the corresponding decoder, and invoke it. __author__ = 'kenton@google.com (Kenton Varda)' +import math import struct -import sys -import six - -_UCS2_MAXUNICODE = 65535 -if six.PY3: - long = int -else: - import re # pylint: disable=g-import-not-at-top - _SURROGATE_PATTERN = re.compile(six.u(r'[\ud800-\udfff]')) from google.protobuf.internal import containers from google.protobuf.internal import encoder @@ -97,13 +89,6 @@ from google.protobuf.internal import wire_format from google.protobuf import message -# This will overflow and thus become IEEE-754 "infinity". We would use -# "float('inf')" but it doesn't work on Windows pre-Python-2.6. -_POS_INF = 1e10000 -_NEG_INF = -_POS_INF -_NAN = _POS_INF * 0 - - # This is not for optimization, but rather to avoid conflicts with local # variables named "message". _DecodeError = message.DecodeError @@ -123,7 +108,7 @@ def _VarintDecoder(mask, result_type): result = 0 shift = 0 while 1: - b = six.indexbytes(buffer, pos) + b = buffer[pos] result |= ((b & 0x7f) << shift) pos += 1 if not (b & 0x80): @@ -146,7 +131,7 @@ def _SignedVarintDecoder(bits, result_type): result = 0 shift = 0 while 1: - b = six.indexbytes(buffer, pos) + b = buffer[pos] result |= ((b & 0x7f) << shift) pos += 1 if not (b & 0x80): @@ -159,12 +144,9 @@ def _SignedVarintDecoder(bits, result_type): raise _DecodeError('Too many bytes when decoding varint.') return DecodeVarint -# We force 32-bit values to int and 64-bit values to long to make -# alternate implementations where the distinction is more significant -# (e.g. the C++ implementation) simpler. - -_DecodeVarint = _VarintDecoder((1 << 64) - 1, long) -_DecodeSignedVarint = _SignedVarintDecoder(64, long) +# All 32-bit and 64-bit values are represented as int. +_DecodeVarint = _VarintDecoder((1 << 64) - 1, int) +_DecodeSignedVarint = _SignedVarintDecoder(64, int) # Use these versions for values which must be limited to 32 bits. _DecodeVarint32 = _VarintDecoder((1 << 32) - 1, int) @@ -189,7 +171,7 @@ def ReadTag(buffer, pos): Tuple[bytes, int] of the tag data and new position. """ start = pos - while six.indexbytes(buffer, pos) & 0x80: + while buffer[pos] & 0x80: pos += 1 pos += 1 @@ -333,11 +315,11 @@ def _FloatDecoder(): if (float_bytes[3:4] in b'\x7F\xFF' and float_bytes[2:3] >= b'\x80'): # If at least one significand bit is set... if float_bytes[0:3] != b'\x00\x00\x80': - return (_NAN, new_pos) + return (math.nan, new_pos) # If sign bit is set... if float_bytes[3:4] == b'\xFF': - return (_NEG_INF, new_pos) - return (_POS_INF, new_pos) + return (-math.inf, new_pos) + return (math.inf, new_pos) # Note that we expect someone up-stack to catch struct.error and convert # it to _DecodeError -- this way we don't have to set up exception- @@ -377,7 +359,7 @@ def _DoubleDecoder(): if ((double_bytes[7:8] in b'\x7F\xFF') and (double_bytes[6:7] >= b'\xF0') and (double_bytes[0:7] != b'\x00\x00\x00\x00\x00\x00\xF0')): - return (_NAN, new_pos) + return (math.nan, new_pos) # Note that we expect someone up-stack to catch struct.error and convert # it to _DecodeError -- this way we don't have to set up exception- @@ -559,31 +541,21 @@ BoolDecoder = _ModifiedDecoder( def StringDecoder(field_number, is_repeated, is_packed, key, new_default, - is_strict_utf8=False, clear_if_default=False): + clear_if_default=False): """Returns a decoder for a string field.""" local_DecodeVarint = _DecodeVarint - local_unicode = six.text_type def _ConvertToUnicode(memview): """Convert byte to unicode.""" byte_str = memview.tobytes() try: - value = local_unicode(byte_str, 'utf-8') + value = str(byte_str, 'utf-8') except UnicodeDecodeError as e: # add more information to the error message and re-raise it. e.reason = '%s in field: %s' % (e, key.full_name) raise - if is_strict_utf8 and six.PY2 and sys.maxunicode > _UCS2_MAXUNICODE: - # Only do the check for python2 ucs4 when is_strict_utf8 enabled - if _SURROGATE_PATTERN.search(value): - reason = ('String field %s contains invalid UTF-8 data when parsing' - 'a protocol buffer: surrogates not allowed. Use' - 'the bytes type if you intend to send raw bytes.') % ( - key.full_name) - raise message.DecodeError(reason) - return value assert not is_packed diff --git a/python/google/protobuf/internal/descriptor_database_test.py b/python/google/protobuf/internal/descriptor_database_test.py index 619779a5dd..3435f6887a 100755 --- a/python/google/protobuf/internal/descriptor_database_test.py +++ b/python/google/protobuf/internal/descriptor_database_test.py @@ -34,10 +34,7 @@ __author__ = 'matthewtoia@google.com (Matt Toia)' -try: - import unittest2 as unittest #PY26 -except ImportError: - import unittest +import unittest import warnings from google.protobuf import unittest_pb2 diff --git a/python/google/protobuf/internal/descriptor_pool_test.py b/python/google/protobuf/internal/descriptor_pool_test.py index fed82bfc7a..8c104b02b7 100755 --- a/python/google/protobuf/internal/descriptor_pool_test.py +++ b/python/google/protobuf/internal/descriptor_pool_test.py @@ -36,13 +36,9 @@ __author__ = 'matthewtoia@google.com (Matt Toia)' import copy import os +import unittest import warnings -try: - import unittest2 as unittest #PY26 -except ImportError: - import unittest - from google.protobuf import unittest_import_pb2 from google.protobuf import unittest_import_public_pb2 from google.protobuf import unittest_pb2 diff --git a/python/google/protobuf/internal/descriptor_test.py b/python/google/protobuf/internal/descriptor_test.py index 4fc80492b8..8680883825 100755 --- a/python/google/protobuf/internal/descriptor_test.py +++ b/python/google/protobuf/internal/descriptor_test.py @@ -34,14 +34,9 @@ __author__ = 'robinson@google.com (Will Robinson)' -import sys +import unittest import warnings -try: - import unittest2 as unittest #PY26 -except ImportError: - import unittest - from google.protobuf import unittest_custom_options_pb2 from google.protobuf import unittest_import_pb2 from google.protobuf import unittest_pb2 @@ -582,10 +577,7 @@ class GeneratedDescriptorTest(unittest.TestCase): self.assertEqual(mapping, mapping) self.assertGreater(len(mapping), 0) # Sized self.assertEqual(len(mapping), len(excepted_dict)) # Iterable - if sys.version_info >= (3,): - key, item = next(iter(mapping.items())) - else: - key, item = mapping.items()[0] + key, item = next(iter(mapping.items())) self.assertIn(key, mapping) # Container self.assertEqual(mapping.get(key), item) with self.assertRaises(TypeError): @@ -598,13 +590,6 @@ class GeneratedDescriptorTest(unittest.TestCase): # keys(), iterkeys() &co item = (next(iter(mapping.keys())), next(iter(mapping.values()))) self.assertEqual(item, next(iter(mapping.items()))) - if sys.version_info < (3,): - def CheckItems(seq, iterator): - self.assertEqual(next(iterator), seq[0]) - self.assertEqual(list(iterator), seq[1:]) - CheckItems(mapping.keys(), mapping.iterkeys()) - CheckItems(mapping.values(), mapping.itervalues()) - CheckItems(mapping.items(), mapping.iteritems()) excepted_dict[key] = 'change value' self.assertNotEqual(mapping, excepted_dict) del excepted_dict[key] diff --git a/python/google/protobuf/internal/encoder.py b/python/google/protobuf/internal/encoder.py index 0c016f3cfa..4b4f652f25 100644 --- a/python/google/protobuf/internal/encoder.py +++ b/python/google/protobuf/internal/encoder.py @@ -68,8 +68,6 @@ __author__ = 'kenton@google.com (Kenton Varda)' import struct -import six - from google.protobuf.internal import wire_format @@ -372,7 +370,8 @@ def MapSizer(field_descriptor, is_message_map): def _VarintEncoder(): """Return an encoder for a basic varint value (does not include tag).""" - local_int2byte = six.int2byte + local_int2byte = struct.Struct('>B').pack + def EncodeVarint(write, value, unused_deterministic=None): bits = value & 0x7f value >>= 7 @@ -389,7 +388,8 @@ def _SignedVarintEncoder(): """Return an encoder for a basic signed varint value (does not include tag).""" - local_int2byte = six.int2byte + local_int2byte = struct.Struct('>B').pack + def EncodeSignedVarint(write, value, unused_deterministic=None): if value < 0: value += (1 << 64) @@ -420,8 +420,7 @@ def _VarintBytes(value): def TagBytes(field_number, wire_type): """Encode the given tag and return the bytes. Only called at startup.""" - return six.binary_type( - _VarintBytes(wire_format.PackTag(field_number, wire_type))) + return bytes(_VarintBytes(wire_format.PackTag(field_number, wire_type))) # -------------------------------------------------------------------- # As with sizers (see above), we have a number of common encoder diff --git a/python/google/protobuf/internal/enum_type_wrapper.py b/python/google/protobuf/internal/enum_type_wrapper.py index 9ae0066584..9a53999a43 100644 --- a/python/google/protobuf/internal/enum_type_wrapper.py +++ b/python/google/protobuf/internal/enum_type_wrapper.py @@ -37,8 +37,6 @@ on proto classes. For usage, see: __author__ = 'rabsatt@google.com (Kevin Rabsatt)' -import six - class EnumTypeWrapper(object): """A utility for finding the names of enum values.""" @@ -57,7 +55,7 @@ class EnumTypeWrapper(object): except KeyError: pass # fall out to break exception chaining - if not isinstance(number, six.integer_types): + if not isinstance(number, int): raise TypeError( 'Enum value for {} must be an int, but got {} {!r}.'.format( self._enum_type.name, type(number), number)) diff --git a/python/google/protobuf/internal/json_format_test.py b/python/google/protobuf/internal/json_format_test.py index 672a9b424d..6a44d4c97d 100755 --- a/python/google/protobuf/internal/json_format_test.py +++ b/python/google/protobuf/internal/json_format_test.py @@ -37,12 +37,8 @@ __author__ = 'jieluo@google.com (Jie Luo)' import json import math import struct -import sys -try: - import unittest2 as unittest #PY26 -except ImportError: - import unittest +import unittest from google.protobuf import any_pb2 from google.protobuf import duration_pb2 @@ -296,11 +292,8 @@ class JsonFormatTest(JsonFormatBase): def testJsonEscapeString(self): message = json_format_proto3_pb2.TestMessage() - if sys.version_info[0] < 3: - message.string_value = '&\n<\"\r>\b\t\f\\\001/\xe2\x80\xa8\xe2\x80\xa9' - else: - message.string_value = '&\n<\"\r>\b\t\f\\\001/' - message.string_value += (b'\xe2\x80\xa8\xe2\x80\xa9').decode('utf-8') + message.string_value = '&\n<\"\r>\b\t\f\\\001/' + message.string_value += (b'\xe2\x80\xa8\xe2\x80\xa9').decode('utf-8') self.assertEqual( json_format.MessageToJson(message), '{\n "stringValue": ' @@ -1039,8 +1032,6 @@ class JsonFormatTest(JsonFormatBase): json_format.ParseError, 'Failed to parse boolMap field: Expected "true" or "false", not null.', json_format.Parse, text, message) - if sys.version_info < (2, 7): - return text = r'{"stringMap": {"a": 3, "\u0061": 2}}' self.assertRaisesRegexp( json_format.ParseError, @@ -1124,24 +1115,24 @@ class JsonFormatTest(JsonFormatBase): text = '{"value": {"foo": 123}}' self.assertRaisesRegexp( json_format.ParseError, - r"Timestamp JSON value not a string: {u?'foo': 123}", - json_format.Parse, text, message) + r"Timestamp JSON value not a string: {u?'foo': 123}", json_format.Parse, + text, message) def testDurationInvalidStringValue(self): message = json_format_proto3_pb2.TestDuration() text = '{"value": {"foo": 123}}' self.assertRaisesRegexp( json_format.ParseError, - r"Duration JSON value not a string: {u?'foo': 123}", - json_format.Parse, text, message) + r"Duration JSON value not a string: {u?'foo': 123}", json_format.Parse, + text, message) def testFieldMaskInvalidStringValue(self): message = json_format_proto3_pb2.TestFieldMask() text = '{"value": {"foo": 123}}' self.assertRaisesRegexp( json_format.ParseError, - r"FieldMask JSON value not a string: {u?'foo': 123}", - json_format.Parse, text, message) + r"FieldMask JSON value not a string: {u?'foo': 123}", json_format.Parse, + text, message) def testInvalidAny(self): message = any_pb2.Any() diff --git a/python/google/protobuf/internal/message_factory_test.py b/python/google/protobuf/internal/message_factory_test.py index 42f91b2365..088fcd642e 100755 --- a/python/google/protobuf/internal/message_factory_test.py +++ b/python/google/protobuf/internal/message_factory_test.py @@ -34,10 +34,7 @@ __author__ = 'matthewtoia@google.com (Matt Toia)' -try: - import unittest2 as unittest #PY26 -except ImportError: - import unittest +import unittest from google.protobuf import descriptor_pb2 from google.protobuf.internal import api_implementation diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py index 77122a2875..1b0710b292 100755 --- a/python/google/protobuf/internal/message_test.py +++ b/python/google/protobuf/internal/message_test.py @@ -44,31 +44,17 @@ abstract interface. __author__ = 'gps@google.com (Gregory P. Smith)' - +import collections import copy import math import operator import pickle import pydoc -import six import sys +import unittest import warnings -try: - # Since python 3 - import collections.abc as collections_abc -except ImportError: - # Won't work after python 3.8 - import collections as collections_abc - -try: - import unittest2 as unittest # PY26 -except ImportError: - import unittest -try: - cmp # Python 2 -except NameError: - cmp = lambda x, y: (x > y) - (x < y) # Python 3 +cmp = lambda x, y: (x > y) - (x < y) from google.protobuf import map_proto2_unittest_pb2 from google.protobuf import map_unittest_pb2 @@ -89,22 +75,6 @@ from google.protobuf import message from google.protobuf.internal import _parameterized UCS2_MAXUNICODE = 65535 -if six.PY3: - long = int - - -# Python pre-2.6 does not have isinf() or isnan() functions, so we have -# to provide our own. -def isnan(val): - # NaN is never equal to itself. - return val != val -def isinf(val): - # Infinity times zero equals NaN. - return not isnan(val) and isnan(val * 0) -def IsPosInf(val): - return isinf(val) and (val > 0) -def IsNegInf(val): - return isinf(val) and (val < 0) warnings.simplefilter('error', DeprecationWarning) @@ -243,10 +213,10 @@ class MessageTest(unittest.TestCase): golden_message = message_module.TestAllTypes() golden_message.ParseFromString(golden_data) - self.assertTrue(IsPosInf(golden_message.optional_float)) - self.assertTrue(IsPosInf(golden_message.optional_double)) - self.assertTrue(IsPosInf(golden_message.repeated_float[0])) - self.assertTrue(IsPosInf(golden_message.repeated_double[0])) + self.assertEqual(golden_message.optional_float, math.inf) + self.assertEqual(golden_message.optional_double, math.inf) + self.assertEqual(golden_message.repeated_float[0], math.inf) + self.assertEqual(golden_message.repeated_double[0], math.inf) self.assertEqual(golden_data, golden_message.SerializeToString()) def testNegativeInfinity(self, message_module): @@ -263,10 +233,10 @@ class MessageTest(unittest.TestCase): golden_message = message_module.TestAllTypes() golden_message.ParseFromString(golden_data) - self.assertTrue(IsNegInf(golden_message.optional_float)) - self.assertTrue(IsNegInf(golden_message.optional_double)) - self.assertTrue(IsNegInf(golden_message.repeated_float[0])) - self.assertTrue(IsNegInf(golden_message.repeated_double[0])) + self.assertEqual(golden_message.optional_float, -math.inf) + self.assertEqual(golden_message.optional_double, -math.inf) + self.assertEqual(golden_message.repeated_float[0], -math.inf) + self.assertEqual(golden_message.repeated_double[0], -math.inf) self.assertEqual(golden_data, golden_message.SerializeToString()) def testNotANumber(self, message_module): @@ -276,10 +246,10 @@ class MessageTest(unittest.TestCase): b'\xD1\x02\x00\x00\x00\x00\x00\x00\xF8\x7F') golden_message = message_module.TestAllTypes() golden_message.ParseFromString(golden_data) - self.assertTrue(isnan(golden_message.optional_float)) - self.assertTrue(isnan(golden_message.optional_double)) - self.assertTrue(isnan(golden_message.repeated_float[0])) - self.assertTrue(isnan(golden_message.repeated_double[0])) + self.assertTrue(math.isnan(golden_message.optional_float)) + self.assertTrue(math.isnan(golden_message.optional_double)) + self.assertTrue(math.isnan(golden_message.repeated_float[0])) + self.assertTrue(math.isnan(golden_message.repeated_double[0])) # The protocol buffer may serialize to any one of multiple different # representations of a NaN. Rather than verify a specific representation, @@ -288,18 +258,18 @@ class MessageTest(unittest.TestCase): serialized = golden_message.SerializeToString() message = message_module.TestAllTypes() message.ParseFromString(serialized) - self.assertTrue(isnan(message.optional_float)) - self.assertTrue(isnan(message.optional_double)) - self.assertTrue(isnan(message.repeated_float[0])) - self.assertTrue(isnan(message.repeated_double[0])) + self.assertTrue(math.isnan(message.optional_float)) + self.assertTrue(math.isnan(message.optional_double)) + self.assertTrue(math.isnan(message.repeated_float[0])) + self.assertTrue(math.isnan(message.repeated_double[0])) def testPositiveInfinityPacked(self, message_module): golden_data = (b'\xA2\x06\x04\x00\x00\x80\x7F' b'\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\x7F') golden_message = message_module.TestPackedTypes() golden_message.ParseFromString(golden_data) - self.assertTrue(IsPosInf(golden_message.packed_float[0])) - self.assertTrue(IsPosInf(golden_message.packed_double[0])) + self.assertEqual(golden_message.packed_float[0], math.inf) + self.assertEqual(golden_message.packed_double[0], math.inf) self.assertEqual(golden_data, golden_message.SerializeToString()) def testNegativeInfinityPacked(self, message_module): @@ -307,8 +277,8 @@ class MessageTest(unittest.TestCase): b'\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\xFF') golden_message = message_module.TestPackedTypes() golden_message.ParseFromString(golden_data) - self.assertTrue(IsNegInf(golden_message.packed_float[0])) - self.assertTrue(IsNegInf(golden_message.packed_double[0])) + self.assertEqual(golden_message.packed_float[0], -math.inf) + self.assertEqual(golden_message.packed_double[0], -math.inf) self.assertEqual(golden_data, golden_message.SerializeToString()) def testNotANumberPacked(self, message_module): @@ -316,14 +286,14 @@ class MessageTest(unittest.TestCase): b'\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF8\x7F') golden_message = message_module.TestPackedTypes() golden_message.ParseFromString(golden_data) - self.assertTrue(isnan(golden_message.packed_float[0])) - self.assertTrue(isnan(golden_message.packed_double[0])) + self.assertTrue(math.isnan(golden_message.packed_float[0])) + self.assertTrue(math.isnan(golden_message.packed_double[0])) serialized = golden_message.SerializeToString() message = message_module.TestPackedTypes() message.ParseFromString(serialized) - self.assertTrue(isnan(message.packed_float[0])) - self.assertTrue(isnan(message.packed_double[0])) + self.assertTrue(math.isnan(message.packed_float[0])) + self.assertTrue(math.isnan(message.packed_double[0])) def testExtremeFloatValues(self, message_module): message = message_module.TestAllTypes() @@ -451,10 +421,7 @@ class MessageTest(unittest.TestCase): def testHighPrecisionDoublePrinting(self, message_module): msg = message_module.TestAllTypes() msg.optional_double = 0.12345678912345678 - if sys.version_info >= (3,): - self.assertEqual(str(msg), 'optional_double: 0.12345678912345678\n') - else: - self.assertEqual(str(msg), 'optional_double: 0.123456789123\n') + self.assertEqual(str(msg), 'optional_double: 0.12345678912345678\n') def testUnknownFieldPrinting(self, message_module): populated = message_module.TestAllTypes() @@ -694,7 +661,6 @@ class MessageTest(unittest.TestCase): message = message_module.TestAllTypes() get_bb = operator.attrgetter('bb') - cmp_bb = lambda a, b: cmp(a.bb, b.bb) message.repeated_nested_message.add().bb = 1 message.repeated_nested_message.add().bb = 3 message.repeated_nested_message.add().bb = 2 @@ -707,13 +673,6 @@ class MessageTest(unittest.TestCase): message.repeated_nested_message.sort(key=get_bb, reverse=True) self.assertEqual([k.bb for k in message.repeated_nested_message], [6, 5, 4, 3, 2, 1]) - if sys.version_info >= (3,): return # No cmp sorting in PY3. - message.repeated_nested_message.sort(sort_function=cmp_bb) - self.assertEqual([k.bb for k in message.repeated_nested_message], - [1, 2, 3, 4, 5, 6]) - message.repeated_nested_message.sort(cmp=cmp_bb, reverse=True) - self.assertEqual([k.bb for k in message.repeated_nested_message], - [6, 5, 4, 3, 2, 1]) def testRepeatedScalarFieldSortArguments(self, message_module): """Check sorting a scalar field using list.sort() arguments.""" @@ -726,12 +685,6 @@ class MessageTest(unittest.TestCase): self.assertEqual(list(message.repeated_int32), [-1, -2, -3]) message.repeated_int32.sort(key=abs, reverse=True) self.assertEqual(list(message.repeated_int32), [-3, -2, -1]) - if sys.version_info < (3,): # No cmp sorting in PY3. - abs_cmp = lambda a, b: cmp(abs(a), abs(b)) - message.repeated_int32.sort(sort_function=abs_cmp) - self.assertEqual(list(message.repeated_int32), [-1, -2, -3]) - message.repeated_int32.sort(cmp=abs_cmp, reverse=True) - self.assertEqual(list(message.repeated_int32), [-3, -2, -1]) message.repeated_string.append('aaa') message.repeated_string.append('bb') @@ -740,12 +693,6 @@ class MessageTest(unittest.TestCase): self.assertEqual(list(message.repeated_string), ['c', 'bb', 'aaa']) message.repeated_string.sort(key=len, reverse=True) self.assertEqual(list(message.repeated_string), ['aaa', 'bb', 'c']) - if sys.version_info < (3,): # No cmp sorting in PY3. - len_cmp = lambda a, b: cmp(len(a), len(b)) - message.repeated_string.sort(sort_function=len_cmp) - self.assertEqual(list(message.repeated_string), ['c', 'bb', 'aaa']) - message.repeated_string.sort(cmp=len_cmp, reverse=True) - self.assertEqual(list(message.repeated_string), ['aaa', 'bb', 'c']) def testRepeatedFieldsComparable(self, message_module): m1 = message_module.TestAllTypes() @@ -763,30 +710,11 @@ class MessageTest(unittest.TestCase): m2.repeated_nested_message.add().bb = 2 m2.repeated_nested_message.add().bb = 3 - if sys.version_info >= (3,): return # No cmp() in PY3. - - # These comparisons should not raise errors. - _ = m1 < m2 - _ = m1.repeated_nested_message < m2.repeated_nested_message - - # Make sure cmp always works. If it wasn't defined, these would be - # id() comparisons and would all fail. - self.assertEqual(cmp(m1, m2), 0) - self.assertEqual(cmp(m1.repeated_int32, m2.repeated_int32), 0) - self.assertEqual(cmp(m1.repeated_int32, [0, 1, 2]), 0) - self.assertEqual(cmp(m1.repeated_nested_message, - m2.repeated_nested_message), 0) - with self.assertRaises(TypeError): - # Can't compare repeated composite containers to lists. - cmp(m1.repeated_nested_message, m2.repeated_nested_message[:]) - - # TODO(anuraag): Implement extensiondict comparison in C++ and then add test - def testRepeatedFieldsAreSequences(self, message_module): m = message_module.TestAllTypes() - self.assertIsInstance(m.repeated_int32, collections_abc.MutableSequence) + self.assertIsInstance(m.repeated_int32, collections.abc.MutableSequence) self.assertIsInstance(m.repeated_nested_message, - collections_abc.MutableSequence) + collections.abc.MutableSequence) def testRepeatedFieldsNotHashable(self, message_module): m = message_module.TestAllTypes() @@ -860,8 +788,8 @@ class MessageTest(unittest.TestCase): # that a sub-sliced memoryview is not being used. self.assertIsInstance(m1.optional_bytes, bytes) self.assertIsInstance(m1.repeated_bytes[0], bytes) - self.assertIsInstance(m1.optional_string, six.text_type) - self.assertIsInstance(m1.repeated_string[0], six.text_type) + self.assertIsInstance(m1.optional_string, str) + self.assertIsInstance(m1.repeated_string[0], str) def testMergeFromEmpty(self, message_module): m1 = message_module.TestAllTypes() @@ -1049,10 +977,10 @@ class MessageTest(unittest.TestCase): in the value being converted to a Unicode string.""" m = message_module.TestAllTypes() m.optional_string = str('') - self.assertIsInstance(m.optional_string, six.text_type) + self.assertIsInstance(m.optional_string, str) def testLongValuedSlice(self, message_module): - """It should be possible to use long-valued indices in slices. + """It should be possible to use int-valued indices in slices. This didn't used to work in the v2 C++ implementation. """ @@ -1060,12 +988,12 @@ class MessageTest(unittest.TestCase): # Repeated scalar m.repeated_int32.append(1) - sl = m.repeated_int32[long(0):long(len(m.repeated_int32))] + sl = m.repeated_int32[int(0):int(len(m.repeated_int32))] self.assertEqual(len(m.repeated_int32), len(sl)) # Repeated composite m.repeated_nested_message.add().bb = 3 - sl = m.repeated_nested_message[long(0):long(len(m.repeated_nested_message))] + sl = m.repeated_nested_message[int(0):int(len(m.repeated_nested_message))] self.assertEqual(len(m.repeated_nested_message), len(sl)) def testExtendShouldNotSwallowExceptions(self, message_module): @@ -1794,7 +1722,7 @@ class Proto3Test(unittest.TestCase): self.assertTrue(111 in msg.map_int32_bytes) self.assertTrue(888 in msg.map_int32_enum) - self.assertIsInstance(msg.map_string_string['abc'], six.text_type) + self.assertIsInstance(msg.map_string_string['abc'], str) # Accessing an unset key still throws TypeError if the type of the key # is incorrect. @@ -1909,8 +1837,8 @@ class Proto3Test(unittest.TestCase): self.assertEqual(key, unicode_obj) self.assertEqual(value, unicode_obj) - self.assertIsInstance(key, six.text_type) - self.assertIsInstance(value, six.text_type) + self.assertIsInstance(key, str) + self.assertIsInstance(value, str) def testMessageMap(self): msg = map_unittest_pb2.TestMap() @@ -2110,7 +2038,7 @@ class Proto3Test(unittest.TestCase): with self.assertRaisesRegexp( TypeError, r'Parameter to MergeFrom\(\) must be instance of same class: expected ' - r'.*TestMap got int\.'): + r'.+TestMap got int\.'): msg.MergeFrom(1) def testCopyFromBadType(self): @@ -2118,15 +2046,15 @@ class Proto3Test(unittest.TestCase): with self.assertRaisesRegexp( TypeError, r'Parameter to [A-Za-z]*From\(\) must be instance of same class: ' - r'expected .*TestMap got int\.'): + r'expected .+TestMap got int\.'): msg.CopyFrom(1) def testIntegerMapWithLongs(self): msg = map_unittest_pb2.TestMap() - msg.map_int32_int32[long(-123)] = long(-456) - msg.map_int64_int64[long(-2**33)] = long(-2**34) - msg.map_uint32_uint32[long(123)] = long(456) - msg.map_uint64_uint64[long(2**33)] = long(2**34) + msg.map_int32_int32[int(-123)] = int(-456) + msg.map_int64_int64[int(-2**33)] = int(-2**34) + msg.map_uint32_uint32[int(123)] = int(456) + msg.map_uint64_uint64[int(2**33)] = int(2**34) serialized = msg.SerializeToString() msg2 = map_unittest_pb2.TestMap() @@ -2238,54 +2166,6 @@ class Proto3Test(unittest.TestCase): matching_dict = {2: 4, 3: 6, 4: 8} self.assertMapIterEquals(msg.map_int32_int32.items(), matching_dict) - def testPython2Map(self): - if sys.version_info < (3,): - msg = map_unittest_pb2.TestMap() - msg.map_int32_int32[2] = 4 - msg.map_int32_int32[3] = 6 - msg.map_int32_int32[4] = 8 - msg.map_int32_int32[5] = 10 - map_int32 = msg.map_int32_int32 - self.assertEqual(4, len(map_int32)) - msg2 = map_unittest_pb2.TestMap() - msg2.ParseFromString(msg.SerializeToString()) - - def CheckItems(seq, iterator): - self.assertEqual(next(iterator), seq[0]) - self.assertEqual(list(iterator), seq[1:]) - - CheckItems(map_int32.items(), map_int32.iteritems()) - CheckItems(map_int32.keys(), map_int32.iterkeys()) - CheckItems(map_int32.values(), map_int32.itervalues()) - - self.assertEqual(6, map_int32.get(3)) - self.assertEqual(None, map_int32.get(999)) - self.assertEqual(6, map_int32.pop(3)) - self.assertEqual(0, map_int32.pop(3)) - self.assertEqual(3, len(map_int32)) - key, value = map_int32.popitem() - self.assertEqual(2 * key, value) - self.assertEqual(2, len(map_int32)) - map_int32.clear() - self.assertEqual(0, len(map_int32)) - - with self.assertRaises(KeyError): - map_int32.popitem() - - self.assertEqual(0, map_int32.setdefault(2)) - self.assertEqual(1, len(map_int32)) - - map_int32.update(msg2.map_int32_int32) - self.assertEqual(4, len(map_int32)) - - with self.assertRaises(TypeError): - map_int32.update(msg2.map_int32_int32, - msg2.map_int32_int32) - with self.assertRaises(TypeError): - map_int32.update(0) - with self.assertRaises(TypeError): - map_int32.update(value=12) - def testMapItems(self): # Map items used to have strange behaviors when use c extension. Because # [] may reorder the map and invalidate any exsting iterators. @@ -2457,11 +2337,12 @@ class Proto3Test(unittest.TestCase): def testMapsAreMapping(self): msg = map_unittest_pb2.TestMap() - self.assertIsInstance(msg.map_int32_int32, collections_abc.Mapping) - self.assertIsInstance(msg.map_int32_int32, collections_abc.MutableMapping) - self.assertIsInstance(msg.map_int32_foreign_message, collections_abc.Mapping) + self.assertIsInstance(msg.map_int32_int32, collections.abc.Mapping) + self.assertIsInstance(msg.map_int32_int32, collections.abc.MutableMapping) + self.assertIsInstance(msg.map_int32_foreign_message, + collections.abc.Mapping) self.assertIsInstance(msg.map_int32_foreign_message, - collections_abc.MutableMapping) + collections.abc.MutableMapping) def testMapsCompare(self): msg = map_unittest_pb2.TestMap() @@ -2501,19 +2382,7 @@ class Proto3Test(unittest.TestCase): optional_string=u'\ud001') self.assertEqual(msg.optional_string, u'\ud001') - @unittest.skipIf(six.PY2, 'Surrogates are acceptable in python2') def testSurrogatesInPython3(self): - # Surrogates like U+D83D is an invalid unicode character, it is - # supported by Python2 only because in some builds, unicode strings - # use 2-bytes code units. Since Python 3.3, we don't have this problem. - # - # Surrogates are utf16 code units, in a unicode string they are invalid - # characters even when they appear in pairs like u'\ud801\udc01'. Protobuf - # Python3 reject such cases at setters and parsers. Python2 accpect it - # to keep same features with the language itself. 'Unpaired pairs' - # like u'\ud801' are rejected at parsers when strict utf8 check is enabled - # in proto3 to keep same behavior with c extension. - # Surrogates are rejected at setters in Python3. with self.assertRaises(ValueError): unittest_proto3_arena_pb2.TestAllTypes( @@ -2528,33 +2397,6 @@ class Proto3Test(unittest.TestCase): unittest_proto3_arena_pb2.TestAllTypes( optional_string=u'\ud801\ud801') - @unittest.skipIf(six.PY3 or sys.maxunicode == UCS2_MAXUNICODE, - 'Surrogates are rejected at setters in Python3') - def testSurrogatesInPython2(self): - # Test optional_string=u'\ud801\udc01'. - # surrogate pair is acceptable in python2. - msg = unittest_proto3_arena_pb2.TestAllTypes( - optional_string=u'\ud801\udc01') - # TODO(jieluo): Change pure python to have same behavior with c extension. - # Some build in python2 consider u'\ud801\udc01' and u'\U00010401' are - # equal, some are not equal. - if api_implementation.Type() == 'python': - self.assertEqual(msg.optional_string, u'\ud801\udc01') - else: - self.assertEqual(msg.optional_string, u'\U00010401') - serialized = msg.SerializeToString() - msg2 = unittest_proto3_arena_pb2.TestAllTypes() - msg2.MergeFromString(serialized) - self.assertEqual(msg2.optional_string, u'\U00010401') - - # Python2 does not reject surrogates at setters. - msg = unittest_proto3_arena_pb2.TestAllTypes( - optional_string=b'\xed\xa0\x81') - unittest_proto3_arena_pb2.TestAllTypes( - optional_string=u'\ud801') - unittest_proto3_arena_pb2.TestAllTypes( - optional_string=u'\ud801\ud801') - @testing_refleaks.TestCase class ValidTypeNamesTest(unittest.TestCase): @@ -2636,9 +2478,8 @@ class PackedFieldTest(unittest.TestCase): self.assertEqual(golden_data, message.SerializeToString()) -@unittest.skipIf(api_implementation.Type() != 'cpp' or - sys.version_info < (2, 7), - 'explicit tests of the C++ implementation for PY27 and above') +@unittest.skipIf(api_implementation.Type() != 'cpp', + 'explicit tests of the C++ implementation') @testing_refleaks.TestCase class OversizeProtosTest(unittest.TestCase): diff --git a/python/google/protobuf/internal/python_message.py b/python/google/protobuf/internal/python_message.py index 99d2f078de..2921d5cb6e 100644 --- a/python/google/protobuf/internal/python_message.py +++ b/python/google/protobuf/internal/python_message.py @@ -55,9 +55,6 @@ import struct import sys import weakref -import six -from six.moves import range - # We use "as" to avoid name collisions with variables. from google.protobuf.internal import api_implementation from google.protobuf.internal import containers @@ -284,13 +281,6 @@ def _IsMessageMapField(field): return value_type.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE -def _IsStrictUtf8Check(field): - if field.containing_type.syntax != 'proto3': - return False - enforce_utf8 = True - return enforce_utf8 - - def _AttachFieldHelpers(cls, field_descriptor): is_repeated = (field_descriptor.label == _FieldDescriptor.LABEL_REPEATED) is_packable = (is_repeated and @@ -348,11 +338,10 @@ def _AttachFieldHelpers(cls, field_descriptor): field_descriptor, _GetInitializeDefaultForMap(field_descriptor), is_message_map) elif decode_type == _FieldDescriptor.TYPE_STRING: - is_strict_utf8_check = _IsStrictUtf8Check(field_descriptor) field_decoder = decoder.StringDecoder( field_descriptor.number, is_repeated, is_packed, field_descriptor, field_descriptor._default_constructor, - is_strict_utf8_check, clear_if_default) + clear_if_default) elif field_descriptor.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: field_decoder = type_checkers.TYPE_TO_DECODER[decode_type]( field_descriptor.number, is_repeated, is_packed, @@ -485,7 +474,7 @@ def _ReraiseTypeErrorWithFieldName(message_name, field_name): exc = TypeError('%s for field %s.%s' % (str(exc), message_name, field_name)) # re-raise possibly-amended exception with original traceback: - six.reraise(type(exc), exc, sys.exc_info()[2]) + raise exc.with_traceback(sys.exc_info()[2]) def _AddInitMethod(message_descriptor, cls): @@ -498,7 +487,7 @@ def _AddInitMethod(message_descriptor, cls): enum_type with the same name. If the value is not a string, it's returned as-is. (No conversion or bounds-checking is done.) """ - if isinstance(value, six.string_types): + if isinstance(value, str): try: return enum_type.values_by_name[value].number except KeyError: @@ -1305,6 +1294,14 @@ def _AddIsInitializedMethod(message_descriptor, cls): cls.FindInitializationErrors = FindInitializationErrors +def _FullyQualifiedClassName(klass): + module = klass.__module__ + name = getattr(klass, '__qualname__', klass.__name__) + if module in (None, 'builtins', '__builtin__'): + return name + return module + '.' + name + + def _AddMergeFromMethod(cls): LABEL_REPEATED = _FieldDescriptor.LABEL_REPEATED CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE @@ -1313,7 +1310,8 @@ def _AddMergeFromMethod(cls): if not isinstance(msg, cls): raise TypeError( 'Parameter to MergeFrom() must be instance of same class: ' - 'expected %s got %s.' % (cls.__name__, msg.__class__.__name__)) + 'expected %s got %s.' % (_FullyQualifiedClassName(cls), + _FullyQualifiedClassName(msg.__class__))) assert msg is not self self._Modified() diff --git a/python/google/protobuf/internal/reflection_test.py b/python/google/protobuf/internal/reflection_test.py index 2b9ed1cb5a..827998ad71 100755 --- a/python/google/protobuf/internal/reflection_test.py +++ b/python/google/protobuf/internal/reflection_test.py @@ -38,14 +38,9 @@ pure-Python protocol compiler. import copy import gc import operator -import six import struct import warnings - -try: - import unittest2 as unittest #PY26 -except ImportError: - import unittest +import unittest from google.protobuf import unittest_import_pb2 from google.protobuf import unittest_mset_pb2 @@ -67,10 +62,6 @@ from google.protobuf.internal import decoder from google.protobuf.internal import _parameterized -if six.PY3: - long = int # pylint: disable=redefined-builtin,invalid-name - - warnings.simplefilter('error', DeprecationWarning) @@ -411,7 +402,7 @@ class ReflectionTest(unittest.TestCase): TestGetAndDeserialize('optional_int32', 1, int) TestGetAndDeserialize('optional_int32', 1 << 30, int) TestGetAndDeserialize('optional_uint32', 1 << 30, int) - integer_64 = long + integer_64 = int if struct.calcsize('L') == 4: # Python only has signed ints, so 32-bit python can't fit an uint32 # in an int. @@ -852,14 +843,14 @@ class ReflectionTest(unittest.TestCase): setattr, proto, 'optional_bytes', u'unicode object') # Check that the default value is of python's 'unicode' type. - self.assertEqual(type(proto.optional_string), six.text_type) + self.assertEqual(type(proto.optional_string), str) - proto.optional_string = six.text_type('Testing') + proto.optional_string = str('Testing') self.assertEqual(proto.optional_string, str('Testing')) # Assign a value of type 'str' which can be encoded in UTF-8. proto.optional_string = str('Testing') - self.assertEqual(proto.optional_string, six.text_type('Testing')) + self.assertEqual(proto.optional_string, str('Testing')) # Try to assign a 'bytes' object which contains non-UTF-8. self.assertRaises(ValueError, @@ -874,8 +865,7 @@ class ReflectionTest(unittest.TestCase): def testBytesInTextFormat(self, message_module): proto = message_module.TestAllTypes(optional_bytes=b'\x00\x7f\x80\xff') - self.assertEqual(u'optional_bytes: "\\000\\177\\200\\377"\n', - six.text_type(proto)) + self.assertEqual(u'optional_bytes: "\\000\\177\\200\\377"\n', str(proto)) def testEmptyNestedMessage(self, message_module): proto = message_module.TestAllTypes() @@ -1508,7 +1498,9 @@ class Proto2ReflectionTest(unittest.TestCase): options=descriptor_pb2.MessageOptions(), # pylint: disable=protected-access create_key=descriptor._internal_create_key) - class MyProtoClass(six.with_metaclass(reflection.GeneratedProtocolMessageType, message.Message)): + + class MyProtoClass( + message.Message, metaclass=reflection.GeneratedProtocolMessageType): DESCRIPTOR = mydescriptor myproto_instance = MyProtoClass() self.assertEqual(0, myproto_instance.foo_field) @@ -1556,8 +1548,8 @@ class Proto2ReflectionTest(unittest.TestCase): self.assertTrue('price' in desc.fields_by_name) self.assertTrue('owners' in desc.fields_by_name) - class CarMessage(six.with_metaclass(reflection.GeneratedProtocolMessageType, - message.Message)): + class CarMessage( + message.Message, metaclass=reflection.GeneratedProtocolMessageType): DESCRIPTOR = desc prius = CarMessage() @@ -2094,7 +2086,7 @@ class Proto2ReflectionTest(unittest.TestCase): bytes_read = message2.MergeFromString(raw.item[0].message) self.assertEqual(len(raw.item[0].message), bytes_read) - self.assertEqual(type(message2.str), six.text_type) + self.assertEqual(type(message2.str), str) self.assertEqual(message2.str, test_utf8) # The pure Python API throws an exception on MergeFromString(), @@ -3340,7 +3332,8 @@ class ClassAPITest(unittest.TestCase): msg_descriptor = descriptor.MakeDescriptor( file_descriptor.message_type[0]) - class MessageClass(six.with_metaclass(reflection.GeneratedProtocolMessageType, message.Message)): + class MessageClass( + message.Message, metaclass=reflection.GeneratedProtocolMessageType): DESCRIPTOR = msg_descriptor msg = MessageClass() msg_str = ( diff --git a/python/google/protobuf/internal/service_reflection_test.py b/python/google/protobuf/internal/service_reflection_test.py index 77239f4462..343db4db0c 100755 --- a/python/google/protobuf/internal/service_reflection_test.py +++ b/python/google/protobuf/internal/service_reflection_test.py @@ -35,10 +35,7 @@ __author__ = 'petar@google.com (Petar Petrov)' -try: - import unittest2 as unittest #PY26 -except ImportError: - import unittest +import unittest from google.protobuf import unittest_pb2 from google.protobuf import service_reflection diff --git a/python/google/protobuf/internal/symbol_database_test.py b/python/google/protobuf/internal/symbol_database_test.py index af42681ae2..3c51aecf5b 100755 --- a/python/google/protobuf/internal/symbol_database_test.py +++ b/python/google/protobuf/internal/symbol_database_test.py @@ -32,10 +32,7 @@ """Tests for google.protobuf.symbol_database.""" -try: - import unittest2 as unittest #PY26 -except ImportError: - import unittest +import unittest from google.protobuf import unittest_pb2 from google.protobuf import descriptor diff --git a/python/google/protobuf/internal/testing_refleaks.py b/python/google/protobuf/internal/testing_refleaks.py index e448fceef4..abe88ed578 100644 --- a/python/google/protobuf/internal/testing_refleaks.py +++ b/python/google/protobuf/internal/testing_refleaks.py @@ -38,18 +38,10 @@ If sys.gettotalrefcount() is not available (because Python was built without the Py_DEBUG option), then this module is a no-op and tests will run normally. """ +import copyreg import gc import sys - -try: - import copy_reg as copyreg #PY26 -except ImportError: - import copyreg - -try: - import unittest2 as unittest #PY26 -except ImportError: - import unittest +import unittest class LocalTestResult(unittest.TestResult): diff --git a/python/google/protobuf/internal/text_encoding_test.py b/python/google/protobuf/internal/text_encoding_test.py index c7d182c444..8f4351d13f 100755 --- a/python/google/protobuf/internal/text_encoding_test.py +++ b/python/google/protobuf/internal/text_encoding_test.py @@ -32,10 +32,7 @@ """Tests for google.protobuf.text_encoding.""" -try: - import unittest2 as unittest #PY26 -except ImportError: - import unittest +import unittest from google.protobuf import text_encoding diff --git a/python/google/protobuf/internal/text_format_test.py b/python/google/protobuf/internal/text_format_test.py index 6f75251dbe..bb2d675d62 100755 --- a/python/google/protobuf/internal/text_format_test.py +++ b/python/google/protobuf/internal/text_format_test.py @@ -39,13 +39,7 @@ import re import string import textwrap -import six - -# pylint: disable=g-import-not-at-top -try: - import unittest2 as unittest # PY26 -except ImportError: - import unittest +import unittest from google.protobuf import any_pb2 from google.protobuf import any_test_pb2 @@ -207,14 +201,10 @@ class TextFormatMessageToStringTests(TextFormatBase): 'repeated_double: 1.23456789\n' 'repeated_double: 1.234567898\n' 'repeated_double: 1.2345678987\n' - 'repeated_double: 1.23456789876\n' + - ('repeated_double: 1.23456789876\n' - 'repeated_double: 1.23456789877\n' - 'repeated_double: 1.23456789877\n' - if six.PY2 else - 'repeated_double: 1.234567898765\n' - 'repeated_double: 1.2345678987654\n' - 'repeated_double: 1.23456789876543\n') + + 'repeated_double: 1.23456789876\n' + 'repeated_double: 1.234567898765\n' + 'repeated_double: 1.2345678987654\n' + 'repeated_double: 1.23456789876543\n' 'repeated_double: 1.2e+100\n' 'repeated_double: 1.23e+100\n' 'repeated_double: 1.234e+100\n' @@ -225,18 +215,14 @@ class TextFormatMessageToStringTests(TextFormatBase): 'repeated_double: 1.23456789e+100\n' 'repeated_double: 1.234567898e+100\n' 'repeated_double: 1.2345678987e+100\n' - 'repeated_double: 1.23456789876e+100\n' + - ('repeated_double: 1.23456789877e+100\n' - 'repeated_double: 1.23456789877e+100\n' - 'repeated_double: 1.23456789877e+100\n' - if six.PY2 else - 'repeated_double: 1.234567898765e+100\n' - 'repeated_double: 1.2345678987654e+100\n' - 'repeated_double: 1.23456789876543e+100\n')) + 'repeated_double: 1.23456789876e+100\n' + 'repeated_double: 1.234567898765e+100\n' + 'repeated_double: 1.2345678987654e+100\n' + 'repeated_double: 1.23456789876543e+100\n') def testPrintExoticUnicodeSubclass(self, message_module): - class UnicodeSub(six.text_type): + class UnicodeSub(str): pass message = message_module.TestAllTypes() @@ -364,7 +350,7 @@ class TextFormatMessageToStringTests(TextFormatBase): message.repeated_string.append(u'\u00fc\t\ua71f') text = text_format.MessageToString(message, as_utf8=True) golden_unicode = u'repeated_string: "\u00fc\\t\ua71f"\n' - golden_text = golden_unicode if six.PY3 else golden_unicode.encode('utf-8') + golden_text = golden_unicode # MessageToString always returns a native str. self.CompareToGoldenText(text, golden_text) parsed_message = message_module.TestAllTypes() @@ -777,16 +763,18 @@ class TextFormatParserTests(TextFormatBase): def testParseSingleWord(self, message_module): message = message_module.TestAllTypes() text = 'foo' - six.assertRaisesRegex(self, text_format.ParseError, ( - r'1:1 : Message type "\w+.TestAllTypes" has no field named ' - r'"foo".'), text_format.Parse, text, message) + self.assertRaisesRegex( + text_format.ParseError, + (r'1:1 : Message type "\w+.TestAllTypes" has no field named ' + r'"foo".'), text_format.Parse, text, message) def testParseUnknownField(self, message_module): message = message_module.TestAllTypes() text = 'unknown_field: 8\n' - six.assertRaisesRegex(self, text_format.ParseError, ( - r'1:1 : Message type "\w+.TestAllTypes" has no field named ' - r'"unknown_field".'), text_format.Parse, text, message) + self.assertRaisesRegex( + text_format.ParseError, + (r'1:1 : Message type "\w+.TestAllTypes" has no field named ' + r'"unknown_field".'), text_format.Parse, text, message) text = ('optional_int32: 123\n' 'unknown_field: 8\n' 'optional_nested_message { bb: 45 }') @@ -797,19 +785,19 @@ class TextFormatParserTests(TextFormatBase): def testParseBadEnumValue(self, message_module): message = message_module.TestAllTypes() text = 'optional_nested_enum: BARR' - six.assertRaisesRegex(self, text_format.ParseError, - (r'1:23 : \'optional_nested_enum: BARR\': ' - r'Enum type "\w+.TestAllTypes.NestedEnum" ' - r'has no value named BARR.'), text_format.Parse, - text, message) + self.assertRaisesRegex(text_format.ParseError, + (r'1:23 : \'optional_nested_enum: BARR\': ' + r'Enum type "\w+.TestAllTypes.NestedEnum" ' + r'has no value named BARR.'), text_format.Parse, + text, message) def testParseBadIntValue(self, message_module): message = message_module.TestAllTypes() text = 'optional_int32: bork' - six.assertRaisesRegex(self, text_format.ParseError, - ('1:17 : \'optional_int32: bork\': ' - 'Couldn\'t parse integer: bork'), - text_format.Parse, text, message) + self.assertRaisesRegex(text_format.ParseError, + ('1:17 : \'optional_int32: bork\': ' + 'Couldn\'t parse integer: bork'), text_format.Parse, + text, message) def testParseStringFieldUnescape(self, message_module): message = message_module.TestAllTypes() @@ -842,8 +830,8 @@ class TextFormatParserTests(TextFormatBase): def testParseMultipleOneof(self, message_module): m_string = '\n'.join(['oneof_uint32: 11', 'oneof_string: "foo"']) m2 = message_module.TestAllTypes() - with six.assertRaisesRegex(self, text_format.ParseError, - ' is specified along with field '): + with self.assertRaisesRegex(text_format.ParseError, + ' is specified along with field '): text_format.Parse(m_string, m2) # This example contains non-ASCII codepoint unicode data as literals @@ -922,27 +910,28 @@ class TextFormatParserTests(TextFormatBase): message = message_module.TestAllTypes() text = ('optional_nested_message { bb: 1 } ' 'optional_nested_message { bb: 2 }') - six.assertRaisesRegex(self, text_format.ParseError, ( - r'1:59 : Message type "\w+.TestAllTypes" ' - r'should not have multiple "optional_nested_message" fields.'), - text_format.Parse, text, - message) + self.assertRaisesRegex( + text_format.ParseError, + (r'1:59 : Message type "\w+.TestAllTypes" ' + r'should not have multiple "optional_nested_message" fields.'), + text_format.Parse, text, message) def testParseDuplicateScalars(self, message_module): message = message_module.TestAllTypes() text = ('optional_int32: 42 ' 'optional_int32: 67') - six.assertRaisesRegex(self, text_format.ParseError, ( - r'1:36 : Message type "\w+.TestAllTypes" should not ' - r'have multiple "optional_int32" fields.'), text_format.Parse, text, - message) + self.assertRaisesRegex( + text_format.ParseError, + (r'1:36 : Message type "\w+.TestAllTypes" should not ' + r'have multiple "optional_int32" fields.'), text_format.Parse, text, + message) def testParseExistingScalarInMessage(self, message_module): message = message_module.TestAllTypes(optional_int32=42) text = 'optional_int32: 67' - six.assertRaisesRegex(self, text_format.ParseError, - (r'Message type "\w+.TestAllTypes" should not ' - r'have multiple "optional_int32" fields.'), - text_format.Parse, text, message) + self.assertRaisesRegex(text_format.ParseError, + (r'Message type "\w+.TestAllTypes" should not ' + r'have multiple "optional_int32" fields.'), + text_format.Parse, text, message) @_parameterized.parameters(unittest_pb2, unittest_proto3_arena_pb2) @@ -1398,14 +1387,14 @@ class Proto2Tests(TextFormatBase): # Can't parse field number without set allow_field_number=True. message = unittest_pb2.TestAllTypes() text = '34:1\n' - six.assertRaisesRegex(self, text_format.ParseError, ( - r'1:1 : Message type "\w+.TestAllTypes" has no field named ' - r'"34".'), text_format.Parse, text, message) + self.assertRaisesRegex( + text_format.ParseError, + (r'1:1 : Message type "\w+.TestAllTypes" has no field named ' + r'"34".'), text_format.Parse, text, message) # Can't parse if field number is not found. text = '1234:1\n' - six.assertRaisesRegex( - self, + self.assertRaisesRegex( text_format.ParseError, (r'1:1 : Message type "\w+.TestAllTypes" has no field named ' r'"1234".'), @@ -1492,13 +1481,13 @@ class Proto2Tests(TextFormatBase): ' i:\n' # Missing value. ' }\n' '}\n') - six.assertRaisesRegex(self, - text_format.ParseError, - 'Invalid field value: }', - text_format.Parse, - malformed, - message, - allow_unknown_extension=True) + self.assertRaisesRegex( + text_format.ParseError, + 'Invalid field value: }', + text_format.Parse, + malformed, + message, + allow_unknown_extension=True) message = unittest_mset_pb2.TestMessageSetContainer() malformed = ('message_set {\n' @@ -1506,13 +1495,13 @@ class Proto2Tests(TextFormatBase): ' str: "malformed string\n' # Missing closing quote. ' }\n' '}\n') - six.assertRaisesRegex(self, - text_format.ParseError, - 'Invalid field value: "', - text_format.Parse, - malformed, - message, - allow_unknown_extension=True) + self.assertRaisesRegex( + text_format.ParseError, + 'Invalid field value: "', + text_format.Parse, + malformed, + message, + allow_unknown_extension=True) message = unittest_mset_pb2.TestMessageSetContainer() malformed = ('message_set {\n' @@ -1520,13 +1509,13 @@ class Proto2Tests(TextFormatBase): ' str: "malformed\n multiline\n string\n' ' }\n' '}\n') - six.assertRaisesRegex(self, - text_format.ParseError, - 'Invalid field value: "', - text_format.Parse, - malformed, - message, - allow_unknown_extension=True) + self.assertRaisesRegex( + text_format.ParseError, + 'Invalid field value: "', + text_format.Parse, + malformed, + message, + allow_unknown_extension=True) message = unittest_mset_pb2.TestMessageSetContainer() malformed = ('message_set {\n' @@ -1534,28 +1523,28 @@ class Proto2Tests(TextFormatBase): ' i: -5\n' ' \n' # Missing '>' here. '}\n') - six.assertRaisesRegex(self, - text_format.ParseError, - '5:1 : \'}\': Expected ">".', - text_format.Parse, - malformed, - message, - allow_unknown_extension=True) + self.assertRaisesRegex( + text_format.ParseError, + '5:1 : \'}\': Expected ">".', + text_format.Parse, + malformed, + message, + allow_unknown_extension=True) # Don't allow unknown fields with allow_unknown_extension=True. message = unittest_mset_pb2.TestMessageSetContainer() malformed = ('message_set {\n' ' unknown_field: true\n' '}\n') - six.assertRaisesRegex(self, - text_format.ParseError, - ('2:3 : Message type ' - '"proto2_wireformat_unittest.TestMessageSet" has no' - ' field named "unknown_field".'), - text_format.Parse, - malformed, - message, - allow_unknown_extension=True) + self.assertRaisesRegex( + text_format.ParseError, + ('2:3 : Message type ' + '"proto2_wireformat_unittest.TestMessageSet" has no' + ' field named "unknown_field".'), + text_format.Parse, + malformed, + message, + allow_unknown_extension=True) # Parse known extension correctly. message = unittest_mset_pb2.TestMessageSetContainer() @@ -1585,22 +1574,24 @@ class Proto2Tests(TextFormatBase): def testParseBadExtension(self): message = unittest_pb2.TestAllExtensions() text = '[unknown_extension]: 8\n' - six.assertRaisesRegex(self, text_format.ParseError, - '1:2 : Extension "unknown_extension" not registered.', - text_format.Parse, text, message) + self.assertRaisesRegex( + text_format.ParseError, + '1:2 : Extension "unknown_extension" not registered.', + text_format.Parse, text, message) message = unittest_pb2.TestAllTypes() - six.assertRaisesRegex(self, text_format.ParseError, ( - '1:2 : Message type "protobuf_unittest.TestAllTypes" does not have ' - 'extensions.'), text_format.Parse, text, message) + self.assertRaisesRegex( + text_format.ParseError, + ('1:2 : Message type "protobuf_unittest.TestAllTypes" does not have ' + 'extensions.'), text_format.Parse, text, message) def testParseNumericUnknownEnum(self): message = unittest_pb2.TestAllTypes() text = 'optional_nested_enum: 100' - six.assertRaisesRegex(self, text_format.ParseError, - (r'1:23 : \'optional_nested_enum: 100\': ' - r'Enum type "\w+.TestAllTypes.NestedEnum" ' - r'has no value with number 100.'), text_format.Parse, - text, message) + self.assertRaisesRegex(text_format.ParseError, + (r'1:23 : \'optional_nested_enum: 100\': ' + r'Enum type "\w+.TestAllTypes.NestedEnum" ' + r'has no value with number 100.'), + text_format.Parse, text, message) def testMergeDuplicateExtensionScalars(self): message = unittest_pb2.TestAllExtensions() @@ -1614,30 +1605,32 @@ class Proto2Tests(TextFormatBase): message = unittest_pb2.TestAllExtensions() text = ('[protobuf_unittest.optional_int32_extension]: 42 ' '[protobuf_unittest.optional_int32_extension]: 67') - six.assertRaisesRegex(self, text_format.ParseError, ( - '1:96 : Message type "protobuf_unittest.TestAllExtensions" ' - 'should not have multiple ' - '"protobuf_unittest.optional_int32_extension" extensions.'), - text_format.Parse, text, message) + self.assertRaisesRegex( + text_format.ParseError, + ('1:96 : Message type "protobuf_unittest.TestAllExtensions" ' + 'should not have multiple ' + '"protobuf_unittest.optional_int32_extension" extensions.'), + text_format.Parse, text, message) def testParseDuplicateExtensionMessages(self): message = unittest_pb2.TestAllExtensions() text = ('[protobuf_unittest.optional_nested_message_extension]: {} ' '[protobuf_unittest.optional_nested_message_extension]: {}') - six.assertRaisesRegex(self, text_format.ParseError, ( - '1:114 : Message type "protobuf_unittest.TestAllExtensions" ' - 'should not have multiple ' - '"protobuf_unittest.optional_nested_message_extension" extensions.'), - text_format.Parse, text, message) + self.assertRaisesRegex( + text_format.ParseError, + ('1:114 : Message type "protobuf_unittest.TestAllExtensions" ' + 'should not have multiple ' + '"protobuf_unittest.optional_nested_message_extension" extensions.'), + text_format.Parse, text, message) def testParseGroupNotClosed(self): message = unittest_pb2.TestAllTypes() text = 'RepeatedGroup: <' - six.assertRaisesRegex(self, text_format.ParseError, '1:16 : Expected ">".', - text_format.Parse, text, message) + self.assertRaisesRegex(text_format.ParseError, '1:16 : Expected ">".', + text_format.Parse, text, message) text = 'RepeatedGroup: {' - six.assertRaisesRegex(self, text_format.ParseError, '1:16 : Expected "}".', - text_format.Parse, text, message) + self.assertRaisesRegex(text_format.ParseError, '1:16 : Expected "}".', + text_format.Parse, text, message) def testParseEmptyGroup(self): message = unittest_pb2.TestAllTypes() diff --git a/python/google/protobuf/internal/type_checkers.py b/python/google/protobuf/internal/type_checkers.py index eb66f9f6fb..9b9b859e1e 100644 --- a/python/google/protobuf/internal/type_checkers.py +++ b/python/google/protobuf/internal/type_checkers.py @@ -45,16 +45,8 @@ TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization __author__ = 'robinson@google.com (Will Robinson)' -try: - import ctypes -except Exception: # pylint: disable=broad-except - ctypes = None - import struct +import ctypes import numbers -import six - -if six.PY3: - long = int from google.protobuf.internal import api_implementation from google.protobuf.internal import decoder @@ -66,10 +58,7 @@ _FieldDescriptor = descriptor.FieldDescriptor def TruncateToFourByteFloat(original): - if ctypes: - return ctypes.c_float(original).value - else: - return struct.unpack('=1.9'] + install_requires = [] setup( name='protobuf', diff --git a/python/tox.ini b/python/tox.ini index eab095c0d0..88dd842e82 100644 --- a/python/tox.ini +++ b/python/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{33,34,35,36,37,38,39}-{cpp,python} + py{35,36,37,38,39}-{cpp,python} [testenv] usedevelop=true @@ -14,11 +14,8 @@ setenv = commands = python setup.py -q build_py python: python setup.py -q build - py{33,34,35,36,37,38,39}-cpp: python setup.py -q build --cpp_implementation --warnings_as_errors --compile_static_extension + py{35,36,37,38,39}-cpp: python setup.py -q build --cpp_implementation --warnings_as_errors --compile_static_extension python: python setup.py -q test -q cpp: python setup.py -q test -q --cpp_implementation python: python setup.py -q test_conformance cpp: python setup.py -q test_conformance --cpp_implementation -deps = - # Keep this list of dependencies in sync with setup.py. - six>=1.9