aboutsummaryrefslogtreecommitdiffhomepage
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/google/protobuf/internal/descriptor_database_test.py3
-rw-r--r--python/google/protobuf/internal/descriptor_pool_test.py13
-rwxr-xr-xpython/google/protobuf/internal/descriptor_test.py5
-rwxr-xr-xpython/google/protobuf/internal/generator_test.py3
-rw-r--r--python/google/protobuf/internal/json_format_test.py5
-rw-r--r--python/google/protobuf/internal/message_factory_test.py3
-rwxr-xr-xpython/google/protobuf/internal/message_test.py53
-rwxr-xr-xpython/google/protobuf/internal/reflection_test.py3
-rwxr-xr-xpython/google/protobuf/internal/service_reflection_test.py4
-rw-r--r--python/google/protobuf/internal/symbol_database_test.py3
-rwxr-xr-xpython/google/protobuf/internal/test_util.py2
-rwxr-xr-xpython/google/protobuf/internal/text_encoding_test.py3
-rwxr-xr-xpython/google/protobuf/internal/text_format_test.py37
-rwxr-xr-xpython/google/protobuf/internal/unknown_fields_test.py2
-rw-r--r--python/google/protobuf/internal/well_known_types_test.py2
-rwxr-xr-xpython/google/protobuf/internal/wire_format_test.py3
-rw-r--r--python/google/protobuf/json_format.py8
-rw-r--r--python/google/protobuf/pyext/descriptor.cc10
-rw-r--r--python/google/protobuf/pyext/descriptor_database.cc3
-rw-r--r--python/google/protobuf/pyext/extension_dict.h2
-rw-r--r--python/google/protobuf/pyext/map_container.h2
-rw-r--r--python/google/protobuf/pyext/message.cc34
-rw-r--r--python/google/protobuf/pyext/message.h4
-rw-r--r--python/google/protobuf/pyext/repeated_composite_container.h2
-rw-r--r--python/google/protobuf/pyext/repeated_scalar_container.h2
-rwxr-xr-xpython/google/protobuf/text_format.py137
-rwxr-xr-xpython/setup.py4
27 files changed, 220 insertions, 132 deletions
diff --git a/python/google/protobuf/internal/descriptor_database_test.py b/python/google/protobuf/internal/descriptor_database_test.py
index 1baff7d1..5225a458 100644
--- a/python/google/protobuf/internal/descriptor_database_test.py
+++ b/python/google/protobuf/internal/descriptor_database_test.py
@@ -35,9 +35,10 @@
__author__ = 'matthewtoia@google.com (Matt Toia)'
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf import descriptor_pb2
from google.protobuf.internal import factory_test2_pb2
from google.protobuf import descriptor_database
diff --git a/python/google/protobuf/internal/descriptor_pool_test.py b/python/google/protobuf/internal/descriptor_pool_test.py
index f1d6bf99..4b1811d8 100644
--- a/python/google/protobuf/internal/descriptor_pool_test.py
+++ b/python/google/protobuf/internal/descriptor_pool_test.py
@@ -35,11 +35,13 @@
__author__ = 'matthewtoia@google.com (Matt Toia)'
import os
+import sys
try:
- import unittest2 as unittest
+ 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
@@ -49,7 +51,6 @@ from google.protobuf.internal import descriptor_pool_test1_pb2
from google.protobuf.internal import descriptor_pool_test2_pb2
from google.protobuf.internal import factory_test1_pb2
from google.protobuf.internal import factory_test2_pb2
-from google.protobuf.internal import test_util
from google.protobuf import descriptor
from google.protobuf import descriptor_database
from google.protobuf import descriptor_pool
@@ -350,7 +351,7 @@ class DescriptorPoolTest(unittest.TestCase):
@unittest.skipIf(api_implementation.Type() != 'cpp',
- 'explicit tests of the C++ implementation')
+ 'explicit tests of the C++ implementation')
class CppDescriptorPoolTest(DescriptorPoolTest):
# TODO(amauryfa): remove when descriptor_pool.DescriptorPool() creates true
# C++ descriptor pool object for C++ implementation.
@@ -555,7 +556,7 @@ class AddDescriptorTest(unittest.TestCase):
prefix + 'protobuf_unittest.TestAllTypes.NestedMessage').name)
@unittest.skipIf(api_implementation.Type() == 'cpp',
- 'With the cpp implementation, Add() must be called first')
+ 'With the cpp implementation, Add() must be called first')
def testMessage(self):
self._TestMessage('')
self._TestMessage('.')
@@ -591,13 +592,13 @@ class AddDescriptorTest(unittest.TestCase):
prefix + 'protobuf_unittest.TestAllTypes.NestedEnum').name)
@unittest.skipIf(api_implementation.Type() == 'cpp',
- 'With the cpp implementation, Add() must be called first')
+ 'With the cpp implementation, Add() must be called first')
def testEnum(self):
self._TestEnum('')
self._TestEnum('.')
@unittest.skipIf(api_implementation.Type() == 'cpp',
- 'With the cpp implementation, Add() must be called first')
+ 'With the cpp implementation, Add() must be called first')
def testFile(self):
pool = descriptor_pool.DescriptorPool()
pool.AddFileDescriptor(unittest_pb2.DESCRIPTOR)
diff --git a/python/google/protobuf/internal/descriptor_test.py b/python/google/protobuf/internal/descriptor_test.py
index fee09a56..b8e75553 100755
--- a/python/google/protobuf/internal/descriptor_test.py
+++ b/python/google/protobuf/internal/descriptor_test.py
@@ -37,9 +37,10 @@ __author__ = 'robinson@google.com (Will Robinson)'
import sys
try:
- import unittest2 as unittest
+ 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
@@ -596,7 +597,7 @@ class DescriptorCopyToProtoTest(unittest.TestCase):
"""
self._InternalTestCopyToProto(
- unittest_pb2._FOREIGNENUM,
+ unittest_pb2.ForeignEnum.DESCRIPTOR,
descriptor_pb2.EnumDescriptorProto,
TEST_FOREIGN_ENUM_ASCII)
diff --git a/python/google/protobuf/internal/generator_test.py b/python/google/protobuf/internal/generator_test.py
index 9956da59..83ea5f50 100755
--- a/python/google/protobuf/internal/generator_test.py
+++ b/python/google/protobuf/internal/generator_test.py
@@ -42,9 +42,10 @@ further ensures that we can use Python protocol message objects as we expect.
__author__ = 'robinson@google.com (Will Robinson)'
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf.internal import test_bad_identifiers_pb2
from google.protobuf import unittest_custom_options_pb2
from google.protobuf import unittest_import_pb2
diff --git a/python/google/protobuf/internal/json_format_test.py b/python/google/protobuf/internal/json_format_test.py
index 49e96a46..bdc9f49a 100644
--- a/python/google/protobuf/internal/json_format_test.py
+++ b/python/google/protobuf/internal/json_format_test.py
@@ -39,9 +39,10 @@ import math
import sys
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf import any_pb2
from google.protobuf import duration_pb2
from google.protobuf import field_mask_pb2
@@ -758,7 +759,7 @@ class JsonFormatTest(JsonFormatBase):
'Can not find message descriptor by type_url: '
'type.googleapis.com/MessageNotExist.',
json_format.Parse, text, message)
- # Only last part is to be used.
+ # Only last part is to be used: b/25630112
text = (r'{"@type": "incorrect.googleapis.com/google.protobuf.Int32Value",'
r'"value": 1234}')
json_format.Parse(text, message)
diff --git a/python/google/protobuf/internal/message_factory_test.py b/python/google/protobuf/internal/message_factory_test.py
index 2fbe5ea7..54b1f688 100644
--- a/python/google/protobuf/internal/message_factory_test.py
+++ b/python/google/protobuf/internal/message_factory_test.py
@@ -35,9 +35,10 @@
__author__ = 'matthewtoia@google.com (Matt Toia)'
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf import descriptor_pb2
from google.protobuf.internal import factory_test1_pb2
from google.protobuf.internal import factory_test2_pb2
diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py
index ee6b944a..1232ccc9 100755
--- a/python/google/protobuf/internal/message_test.py
+++ b/python/google/protobuf/internal/message_test.py
@@ -53,9 +53,10 @@ import six
import sys
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf.internal import _parameterized
from google.protobuf import descriptor_pb2
from google.protobuf import descriptor_pool
@@ -64,7 +65,6 @@ from google.protobuf import message_factory
from google.protobuf import text_format
from google.protobuf import unittest_pb2
from google.protobuf import unittest_proto3_arena_pb2
-from google.protobuf.internal import any_test_pb2
from google.protobuf.internal import api_implementation
from google.protobuf.internal import packed_field_test_pb2
from google.protobuf.internal import test_util
@@ -73,6 +73,7 @@ from google.protobuf import message
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):
@@ -1161,6 +1162,7 @@ class Proto2Test(unittest.TestCase):
unittest_pb2.TestAllTypes(repeated_nested_enum='FOO')
+
# Class to test proto3-only features/behavior (updated field presence & enums)
class Proto3Test(unittest.TestCase):
@@ -1452,6 +1454,22 @@ class Proto3Test(unittest.TestCase):
del msg2.map_int32_foreign_message[222]
self.assertFalse(222 in msg2.map_int32_foreign_message)
+ def testMergeFromBadType(self):
+ msg = map_unittest_pb2.TestMap()
+ with self.assertRaisesRegexp(
+ TypeError,
+ r'Parameter to MergeFrom\(\) must be instance of same class: expected '
+ r'.*TestMap got int\.'):
+ msg.MergeFrom(1)
+
+ def testCopyFromBadType(self):
+ msg = map_unittest_pb2.TestMap()
+ with self.assertRaisesRegexp(
+ TypeError,
+ r'Parameter to [A-Za-z]*From\(\) must be instance of same class: '
+ r'expected .*TestMap got int\.'):
+ msg.CopyFrom(1)
+
def testIntegerMapWithLongs(self):
msg = map_unittest_pb2.TestMap()
msg.map_int32_int32[long(-123)] = long(-456)
@@ -1670,37 +1688,6 @@ class Proto3Test(unittest.TestCase):
msg.map_string_foreign_message['foo'].c = 5
self.assertEqual(0, len(msg.FindInitializationErrors()))
- def testAnyMessage(self):
- # Creates and sets message.
- msg = any_test_pb2.TestAny()
- msg_descriptor = msg.DESCRIPTOR
- all_types = unittest_pb2.TestAllTypes()
- all_descriptor = all_types.DESCRIPTOR
- all_types.repeated_string.append(u'\u00fc\ua71f')
- # Packs to Any.
- msg.value.Pack(all_types)
- self.assertEqual(msg.value.type_url,
- 'type.googleapis.com/%s' % all_descriptor.full_name)
- self.assertEqual(msg.value.value,
- all_types.SerializeToString())
- # Tests Is() method.
- self.assertTrue(msg.value.Is(all_descriptor))
- self.assertFalse(msg.value.Is(msg_descriptor))
- # Unpacks Any.
- unpacked_message = unittest_pb2.TestAllTypes()
- self.assertTrue(msg.value.Unpack(unpacked_message))
- self.assertEqual(all_types, unpacked_message)
- # Unpacks to different type.
- self.assertFalse(msg.value.Unpack(msg))
- # Only Any messages have Pack method.
- try:
- msg.Pack(all_types)
- except AttributeError:
- pass
- else:
- raise AttributeError('%s should not have Pack method.' %
- msg_descriptor.full_name)
-
class ValidTypeNamesTest(unittest.TestCase):
diff --git a/python/google/protobuf/internal/reflection_test.py b/python/google/protobuf/internal/reflection_test.py
index 752f2f5d..9e61ea0e 100755
--- a/python/google/protobuf/internal/reflection_test.py
+++ b/python/google/protobuf/internal/reflection_test.py
@@ -42,9 +42,10 @@ import six
import struct
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf import unittest_import_pb2
from google.protobuf import unittest_mset_pb2
from google.protobuf import unittest_pb2
diff --git a/python/google/protobuf/internal/service_reflection_test.py b/python/google/protobuf/internal/service_reflection_test.py
index 98614b77..62900b1d 100755
--- a/python/google/protobuf/internal/service_reflection_test.py
+++ b/python/google/protobuf/internal/service_reflection_test.py
@@ -34,10 +34,12 @@
__author__ = 'petar@google.com (Petar Petrov)'
+
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf import unittest_pb2
from google.protobuf import service_reflection
from google.protobuf import service
diff --git a/python/google/protobuf/internal/symbol_database_test.py b/python/google/protobuf/internal/symbol_database_test.py
index 0cb935a8..c99b426d 100644
--- a/python/google/protobuf/internal/symbol_database_test.py
+++ b/python/google/protobuf/internal/symbol_database_test.py
@@ -33,9 +33,10 @@
"""Tests for google.protobuf.symbol_database."""
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf import unittest_pb2
from google.protobuf import descriptor
from google.protobuf import symbol_database
diff --git a/python/google/protobuf/internal/test_util.py b/python/google/protobuf/internal/test_util.py
index ac88fa81..2c805599 100755
--- a/python/google/protobuf/internal/test_util.py
+++ b/python/google/protobuf/internal/test_util.py
@@ -38,6 +38,8 @@ __author__ = 'robinson@google.com (Will Robinson)'
import os.path
+import sys
+
from google.protobuf import unittest_import_pb2
from google.protobuf import unittest_pb2
from google.protobuf import descriptor_pb2
diff --git a/python/google/protobuf/internal/text_encoding_test.py b/python/google/protobuf/internal/text_encoding_test.py
index 338a287b..c7d182c4 100755
--- a/python/google/protobuf/internal/text_encoding_test.py
+++ b/python/google/protobuf/internal/text_encoding_test.py
@@ -33,9 +33,10 @@
"""Tests for google.protobuf.text_encoding."""
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf import text_encoding
TEST_VALUES = [
diff --git a/python/google/protobuf/internal/text_format_test.py b/python/google/protobuf/internal/text_format_test.py
index 0e14556c..8ce0a44f 100755
--- a/python/google/protobuf/internal/text_format_test.py
+++ b/python/google/protobuf/internal/text_format_test.py
@@ -40,9 +40,10 @@ import six
import string
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf.internal import _parameterized
from google.protobuf import map_unittest_pb2
@@ -62,7 +63,7 @@ class SimpleTextFormatTests(unittest.TestCase):
# expects single characters. Therefore it's an error (in addition to being
# non-sensical in the first place) to try to specify a "quote mark" that is
# more than one character.
- def TestQuoteMarksAreSingleChars(self):
+ def testQuoteMarksAreSingleChars(self):
for quote in text_format._QUOTES:
self.assertEqual(1, len(quote))
@@ -314,6 +315,18 @@ class TextFormatTest(TextFormatBase):
self.assertEqual(u'one', message.repeated_string[0])
self.assertEqual(u'two', message.repeated_string[1])
+ def testParseRepeatedMessageShortFormat(self, message_module):
+ message = message_module.TestAllTypes()
+ text = ('repeated_nested_message: [{bb: 100}, {bb: 200}],\n'
+ 'repeated_nested_message: {bb: 300}\n'
+ 'repeated_nested_message [{bb: 400}];\n')
+ text_format.Parse(text, message)
+
+ self.assertEqual(100, message.repeated_nested_message[0].bb)
+ self.assertEqual(200, message.repeated_nested_message[1].bb)
+ self.assertEqual(300, message.repeated_nested_message[2].bb)
+ self.assertEqual(400, message.repeated_nested_message[3].bb)
+
def testParseEmptyText(self, message_module):
message = message_module.TestAllTypes()
text = ''
@@ -411,6 +424,19 @@ class TextFormatTest(TextFormatBase):
text_format.Parse(text_format.MessageToString(m), m2)
self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field'))
+ def testParseMultipleOneof(self, message_module):
+ m_string = '\n'.join([
+ 'oneof_uint32: 11',
+ 'oneof_string: "foo"'])
+ m2 = message_module.TestAllTypes()
+ if message_module is unittest_pb2:
+ with self.assertRaisesRegexp(
+ text_format.ParseError, ' is specified along with field '):
+ text_format.Parse(m_string, m2)
+ else:
+ text_format.Parse(m_string, m2)
+ self.assertEqual('oneof_string', m2.WhichOneof('oneof_field'))
+
# These are tests that aren't fundamentally specific to proto2, but are at
# the moment because of differences between the proto2 and proto3 test schemas.
@@ -426,7 +452,8 @@ class OnlyWorksWithProto2RightNowTests(TextFormatBase):
'text_format_unittest_data_pointy_oneof.txt')
def testParseGolden(self):
- golden_text = '\n'.join(self.ReadGolden('text_format_unittest_data.txt'))
+ golden_text = '\n'.join(self.ReadGolden(
+ 'text_format_unittest_data_oneof_implemented.txt'))
parsed_message = unittest_pb2.TestAllTypes()
r = text_format.Parse(golden_text, parsed_message)
self.assertIs(r, parsed_message)
@@ -469,7 +496,7 @@ class OnlyWorksWithProto2RightNowTests(TextFormatBase):
'optional_nested_message {\n bb: 1\n oo: 0\n}\n')
def testMergeLinesGolden(self):
- opened = self.ReadGolden('text_format_unittest_data.txt')
+ opened = self.ReadGolden('text_format_unittest_data_oneof_implemented.txt')
parsed_message = unittest_pb2.TestAllTypes()
r = text_format.MergeLines(opened, parsed_message)
self.assertIs(r, parsed_message)
@@ -479,7 +506,7 @@ class OnlyWorksWithProto2RightNowTests(TextFormatBase):
self.assertEqual(message, parsed_message)
def testParseLinesGolden(self):
- opened = self.ReadGolden('text_format_unittest_data.txt')
+ opened = self.ReadGolden('text_format_unittest_data_oneof_implemented.txt')
parsed_message = unittest_pb2.TestAllTypes()
r = text_format.ParseLines(opened, parsed_message)
self.assertIs(r, parsed_message)
diff --git a/python/google/protobuf/internal/unknown_fields_test.py b/python/google/protobuf/internal/unknown_fields_test.py
index 9685b8b4..bb2748e4 100755
--- a/python/google/protobuf/internal/unknown_fields_test.py
+++ b/python/google/protobuf/internal/unknown_fields_test.py
@@ -36,7 +36,7 @@
__author__ = 'bohdank@google.com (Bohdan Koval)'
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
from google.protobuf import unittest_mset_pb2
diff --git a/python/google/protobuf/internal/well_known_types_test.py b/python/google/protobuf/internal/well_known_types_test.py
index 6acbee22..18329205 100644
--- a/python/google/protobuf/internal/well_known_types_test.py
+++ b/python/google/protobuf/internal/well_known_types_test.py
@@ -37,7 +37,7 @@ __author__ = 'jieluo@google.com (Jie Luo)'
from datetime import datetime
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
diff --git a/python/google/protobuf/internal/wire_format_test.py b/python/google/protobuf/internal/wire_format_test.py
index f659d18e..da120f33 100755
--- a/python/google/protobuf/internal/wire_format_test.py
+++ b/python/google/protobuf/internal/wire_format_test.py
@@ -35,9 +35,10 @@
__author__ = 'robinson@google.com (Will Robinson)'
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf import message
from google.protobuf.internal import wire_format
diff --git a/python/google/protobuf/json_format.py b/python/google/protobuf/json_format.py
index 23382bdb..7921556e 100644
--- a/python/google/protobuf/json_format.py
+++ b/python/google/protobuf/json_format.py
@@ -271,10 +271,10 @@ def _ListValueMessageToJsonObject(message, unused_including_default=False):
def _StructMessageToJsonObject(message, unused_including_default=False):
"""Converts Struct message according to Proto3 JSON Specification."""
fields = message.fields
- js = {}
- for key in fields.keys():
- js[key] = _ValueMessageToJsonObject(fields[key])
- return js
+ ret = {}
+ for key in fields:
+ ret[key] = _ValueMessageToJsonObject(fields[key])
+ return ret
def _IsWrapperMessage(message_descriptor):
diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc
index a875a7be..07550706 100644
--- a/python/google/protobuf/pyext/descriptor.cc
+++ b/python/google/protobuf/pyext/descriptor.cc
@@ -92,11 +92,10 @@ PyObject* PyString_FromCppString(const string& str) {
// TODO(amauryfa): Change the proto2 compiler to remove the assignments, and
// remove this hack.
bool _CalledFromGeneratedFile(int stacklevel) {
- PyThreadState *state = PyThreadState_GET();
- if (state == NULL) {
- return false;
- }
- PyFrameObject* frame = state->frame;
+#ifndef PYPY_VERSION
+ // This check is not critical and is somewhat difficult to implement correctly
+ // in PyPy.
+ PyFrameObject* frame = PyEval_GetFrame();
if (frame == NULL) {
return false;
}
@@ -130,6 +129,7 @@ bool _CalledFromGeneratedFile(int stacklevel) {
// Filename is not ending with _pb2.
return false;
}
+#endif
return true;
}
diff --git a/python/google/protobuf/pyext/descriptor_database.cc b/python/google/protobuf/pyext/descriptor_database.cc
index 514722b4..daa40cc7 100644
--- a/python/google/protobuf/pyext/descriptor_database.cc
+++ b/python/google/protobuf/pyext/descriptor_database.cc
@@ -64,6 +64,9 @@ static bool GetFileDescriptorProto(PyObject* py_descriptor,
}
return false;
}
+ if (py_descriptor == Py_None) {
+ return false;
+ }
const Descriptor* filedescriptor_descriptor =
FileDescriptorProto::default_instance().GetDescriptor();
CMessage* message = reinterpret_cast<CMessage*>(py_descriptor);
diff --git a/python/google/protobuf/pyext/extension_dict.h b/python/google/protobuf/pyext/extension_dict.h
index d92cf956..1e7f6f7b 100644
--- a/python/google/protobuf/pyext/extension_dict.h
+++ b/python/google/protobuf/pyext/extension_dict.h
@@ -48,7 +48,7 @@ class Message;
class FieldDescriptor;
#ifdef _SHARED_PTR_H
-using std::shared_ptr;
+using shared_ptr;
#else
using internal::shared_ptr;
#endif
diff --git a/python/google/protobuf/pyext/map_container.h b/python/google/protobuf/pyext/map_container.h
index ddf94be7..27ee6dbd 100644
--- a/python/google/protobuf/pyext/map_container.h
+++ b/python/google/protobuf/pyext/map_container.h
@@ -47,7 +47,7 @@ namespace protobuf {
class Message;
#ifdef _SHARED_PTR_H
-using std::shared_ptr;
+using shared_ptr;
#else
using internal::shared_ptr;
#endif
diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc
index 7d3e8c37..6d7b2b0f 100644
--- a/python/google/protobuf/pyext/message.cc
+++ b/python/google/protobuf/pyext/message.cc
@@ -1851,8 +1851,12 @@ static PyObject* ToStr(CMessage* self) {
PyObject* MergeFrom(CMessage* self, PyObject* arg) {
CMessage* other_message;
- if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) {
- PyErr_SetString(PyExc_TypeError, "Must be a message");
+ if (!PyObject_TypeCheck(arg, &CMessage_Type)) {
+ PyErr_Format(PyExc_TypeError,
+ "Parameter to MergeFrom() must be instance of same class: "
+ "expected %s got %s.",
+ self->message->GetDescriptor()->full_name().c_str(),
+ Py_TYPE(arg)->tp_name);
return NULL;
}
@@ -1860,8 +1864,8 @@ PyObject* MergeFrom(CMessage* self, PyObject* arg) {
if (other_message->message->GetDescriptor() !=
self->message->GetDescriptor()) {
PyErr_Format(PyExc_TypeError,
- "Tried to merge from a message with a different type. "
- "to: %s, from: %s",
+ "Parameter to MergeFrom() must be instance of same class: "
+ "expected %s got %s.",
self->message->GetDescriptor()->full_name().c_str(),
other_message->message->GetDescriptor()->full_name().c_str());
return NULL;
@@ -1879,8 +1883,12 @@ PyObject* MergeFrom(CMessage* self, PyObject* arg) {
static PyObject* CopyFrom(CMessage* self, PyObject* arg) {
CMessage* other_message;
- if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) {
- PyErr_SetString(PyExc_TypeError, "Must be a message");
+ if (!PyObject_TypeCheck(arg, &CMessage_Type)) {
+ PyErr_Format(PyExc_TypeError,
+ "Parameter to CopyFrom() must be instance of same class: "
+ "expected %s got %s.",
+ self->message->GetDescriptor()->full_name().c_str(),
+ Py_TYPE(arg)->tp_name);
return NULL;
}
@@ -1893,8 +1901,8 @@ static PyObject* CopyFrom(CMessage* self, PyObject* arg) {
if (other_message->message->GetDescriptor() !=
self->message->GetDescriptor()) {
PyErr_Format(PyExc_TypeError,
- "Tried to copy from a message with a different type. "
- "to: %s, from: %s",
+ "Parameter to CopyFrom() must be instance of same class: "
+ "expected %s got %s.",
self->message->GetDescriptor()->full_name().c_str(),
other_message->message->GetDescriptor()->full_name().c_str());
return NULL;
@@ -2150,7 +2158,11 @@ static PyObject* ListFields(CMessage* self) {
PyList_SET_ITEM(all_fields.get(), actual_size, t.release());
++actual_size;
}
- Py_SIZE(all_fields.get()) = actual_size;
+ if (static_cast<size_t>(actual_size) != fields.size() &&
+ (PyList_SetSlice(all_fields.get(), actual_size, fields.size(), NULL) <
+ 0)) {
+ return NULL;
+ }
return all_fields.release();
}
@@ -2729,7 +2741,7 @@ int SetAttr(CMessage* self, PyObject* name, PyObject* value) {
PyErr_Format(PyExc_AttributeError,
"Assignment not allowed "
- "(no field \"%s\"in protocol message object).",
+ "(no field \"%s\" in protocol message object).",
PyString_AsString(name));
return -1;
}
@@ -2746,7 +2758,7 @@ PyTypeObject CMessage_Type = {
0, // tp_getattr
0, // tp_setattr
0, // tp_compare
- 0, // tp_repr
+ (reprfunc)cmessage::ToStr, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
0, // tp_as_mapping
diff --git a/python/google/protobuf/pyext/message.h b/python/google/protobuf/pyext/message.h
index cc0012e9..c2b62649 100644
--- a/python/google/protobuf/pyext/message.h
+++ b/python/google/protobuf/pyext/message.h
@@ -53,8 +53,8 @@ class DescriptorPool;
class MessageFactory;
#ifdef _SHARED_PTR_H
-using std::shared_ptr;
-using std::string;
+using shared_ptr;
+using std::std::string;
#else
using internal::shared_ptr;
#endif
diff --git a/python/google/protobuf/pyext/repeated_composite_container.h b/python/google/protobuf/pyext/repeated_composite_container.h
index 58d37b02..442ce7e3 100644
--- a/python/google/protobuf/pyext/repeated_composite_container.h
+++ b/python/google/protobuf/pyext/repeated_composite_container.h
@@ -50,7 +50,7 @@ class FieldDescriptor;
class Message;
#ifdef _SHARED_PTR_H
-using std::shared_ptr;
+using shared_ptr;
#else
using internal::shared_ptr;
#endif
diff --git a/python/google/protobuf/pyext/repeated_scalar_container.h b/python/google/protobuf/pyext/repeated_scalar_container.h
index 555e621c..608222e0 100644
--- a/python/google/protobuf/pyext/repeated_scalar_container.h
+++ b/python/google/protobuf/pyext/repeated_scalar_container.h
@@ -49,7 +49,7 @@ namespace protobuf {
class Message;
#ifdef _SHARED_PTR_H
-using std::shared_ptr;
+using shared_ptr;
#else
using internal::shared_ptr;
#endif
diff --git a/python/google/protobuf/text_format.py b/python/google/protobuf/text_format.py
index 8d256076..a6f41ca8 100755
--- a/python/google/protobuf/text_format.py
+++ b/python/google/protobuf/text_format.py
@@ -384,7 +384,7 @@ def _MergeField(tokenizer,
field are permitted, e.g., the string "foo: 1 foo: 2" for a
required/optional field named "foo".
allow_unknown_extension: if True, skip over missing extensions and keep
- parsing
+ parsing.
Raises:
ParseError: In case of text parsing problems.
@@ -442,55 +442,39 @@ def _MergeField(tokenizer,
'Message type "%s" has no field named "%s".' % (
message_descriptor.full_name, name))
- if field and field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
- is_map_entry = _IsMapEntry(field)
- tokenizer.TryConsume(':')
-
- if tokenizer.TryConsume('<'):
- end_token = '>'
- else:
- tokenizer.Consume('{')
- end_token = '}'
-
- if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
- if field.is_extension:
- sub_message = message.Extensions[field].add()
- elif is_map_entry:
- sub_message = field.message_type._concrete_class()
- else:
- sub_message = getattr(message, field.name).add()
+ if field:
+ if not allow_multiple_scalars and field.containing_oneof:
+ # Check if there's a different field set in this oneof.
+ # Note that we ignore the case if the same field was set before, and we
+ # apply allow_multiple_scalars to non-scalar fields as well.
+ which_oneof = message.WhichOneof(field.containing_oneof.name)
+ if which_oneof is not None and which_oneof != field.name:
+ raise tokenizer.ParseErrorPreviousToken(
+ 'Field "%s" is specified along with field "%s", another member of '
+ 'oneof "%s" for message type "%s".' % (
+ field.name, which_oneof, field.containing_oneof.name,
+ message_descriptor.full_name))
+
+ if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+ tokenizer.TryConsume(':')
+ merger = _MergeMessageField
else:
- if field.is_extension:
- sub_message = message.Extensions[field]
- else:
- sub_message = getattr(message, field.name)
- sub_message.SetInParent()
-
- while not tokenizer.TryConsume(end_token):
- if tokenizer.AtEnd():
- raise tokenizer.ParseErrorPreviousToken('Expected "%s".' % (end_token))
- _MergeField(tokenizer, sub_message, allow_multiple_scalars,
- allow_unknown_extension)
-
- if is_map_entry:
- value_cpptype = field.message_type.fields_by_name['value'].cpp_type
- if value_cpptype == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
- value = getattr(message, field.name)[sub_message.key]
- value.MergeFrom(sub_message.value)
- else:
- getattr(message, field.name)[sub_message.key] = sub_message.value
- elif field:
- tokenizer.Consume(':')
- if (field.label == descriptor.FieldDescriptor.LABEL_REPEATED and
- tokenizer.TryConsume('[')):
+ tokenizer.Consume(':')
+ merger = _MergeScalarField
+
+ if (field.label == descriptor.FieldDescriptor.LABEL_REPEATED
+ and tokenizer.TryConsume('[')):
# Short repeated format, e.g. "foo: [1, 2, 3]"
while True:
- _MergeScalarField(tokenizer, message, field, allow_multiple_scalars)
- if tokenizer.TryConsume(']'):
- break
+ merger(tokenizer, message, field, allow_multiple_scalars,
+ allow_unknown_extension)
+ if tokenizer.TryConsume(']'): break
tokenizer.Consume(',')
+
else:
- _MergeScalarField(tokenizer, message, field, allow_multiple_scalars)
+ merger(tokenizer, message, field, allow_multiple_scalars,
+ allow_unknown_extension)
+
else: # Proto field is unknown.
assert allow_unknown_extension
_SkipFieldContents(tokenizer)
@@ -585,8 +569,64 @@ def _SkipFieldValue(tokenizer):
raise ParseError('Invalid field value: ' + tokenizer.token)
-def _MergeScalarField(tokenizer, message, field, allow_multiple_scalars):
- """Merges a single protocol message scalar field into a message.
+def _MergeMessageField(tokenizer, message, field, allow_multiple_scalars,
+ allow_unknown_extension):
+ """Merges a single scalar field into a message.
+
+ Args:
+ tokenizer: A tokenizer to parse the field value.
+ message: The message of which field is a member.
+ field: The descriptor of the field to be merged.
+ allow_multiple_scalars: Determines if repeated values for a non-repeated
+ field are permitted, e.g., the string "foo: 1 foo: 2" for a
+ required/optional field named "foo".
+ allow_unknown_extension: if True, skip over missing extensions and keep
+ parsing.
+
+ Raises:
+ ParseError: In case of text parsing problems.
+ """
+ is_map_entry = _IsMapEntry(field)
+
+ if tokenizer.TryConsume('<'):
+ end_token = '>'
+ else:
+ tokenizer.Consume('{')
+ end_token = '}'
+
+ if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+ if field.is_extension:
+ sub_message = message.Extensions[field].add()
+ elif is_map_entry:
+ # pylint: disable=protected-access
+ sub_message = field.message_type._concrete_class()
+ else:
+ sub_message = getattr(message, field.name).add()
+ else:
+ if field.is_extension:
+ sub_message = message.Extensions[field]
+ else:
+ sub_message = getattr(message, field.name)
+ sub_message.SetInParent()
+
+ while not tokenizer.TryConsume(end_token):
+ if tokenizer.AtEnd():
+ raise tokenizer.ParseErrorPreviousToken('Expected "%s".' % (end_token,))
+ _MergeField(tokenizer, sub_message, allow_multiple_scalars,
+ allow_unknown_extension)
+
+ if is_map_entry:
+ value_cpptype = field.message_type.fields_by_name['value'].cpp_type
+ if value_cpptype == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+ value = getattr(message, field.name)[sub_message.key]
+ value.MergeFrom(sub_message.value)
+ else:
+ getattr(message, field.name)[sub_message.key] = sub_message.value
+
+
+def _MergeScalarField(tokenizer, message, field, allow_multiple_scalars,
+ allow_unknown_extension):
+ """Merges a single scalar field into a message.
Args:
tokenizer: A tokenizer to parse the field value.
@@ -595,11 +635,14 @@ def _MergeScalarField(tokenizer, message, field, allow_multiple_scalars):
allow_multiple_scalars: Determines if repeated values for a non-repeated
field are permitted, e.g., the string "foo: 1 foo: 2" for a
required/optional field named "foo".
+ allow_unknown_extension: Unused, just here for consistency with
+ _MergeMessageField.
Raises:
ParseError: In case of text parsing problems.
RuntimeError: On runtime errors.
"""
+ _ = allow_unknown_extension
value = None
if field.type in (descriptor.FieldDescriptor.TYPE_INT32,
diff --git a/python/setup.py b/python/setup.py
index f5c00a72..0f4b53c4 100755
--- a/python/setup.py
+++ b/python/setup.py
@@ -172,7 +172,9 @@ if __name__ == '__main__':
# extension. Note that those libraries have to be compiled with
# -fPIC for this to work.
compile_static_ext = get_option_from_sys_argv('--compile_static_extension')
- extra_compile_args = ['-Wno-write-strings', '-Wno-invalid-offsetof']
+ extra_compile_args = ['-Wno-write-strings',
+ '-Wno-invalid-offsetof',
+ '-Wno-sign-compare']
libraries = ['protobuf']
extra_objects = None
if compile_static_ext: