aboutsummaryrefslogtreecommitdiffhomepage
path: root/python/google/protobuf/pyext
diff options
context:
space:
mode:
authorGravatar Josh Haberman <jhaberman@gmail.com>2015-02-25 20:17:32 -0800
committerGravatar Josh Haberman <jhaberman@gmail.com>2015-02-25 20:17:32 -0800
commit0b70a43736fe070bee49141d493c74079ea68f97 (patch)
tree678b53cbc408c7520d893a8e0f705103c9f05608 /python/google/protobuf/pyext
parentada65567852b96fdb4d070c0c3f86ca7b77824f9 (diff)
Fixes for Python/C++ implementation in open-source:
* Rosy hack doesn't apply (that test should be removed for the open-source release). * Added our own copy of parameterized.py (the open-source version of Google Apputils doesn't contain it). * The C++ Descriptor object didn't implement extension_ranges. * Had to implement a hack around returning EncodeError, to work around the module-loading behavior of the test runner.
Diffstat (limited to 'python/google/protobuf/pyext')
-rw-r--r--python/google/protobuf/pyext/descriptor.cc15
-rw-r--r--python/google/protobuf/pyext/message.cc26
-rw-r--r--python/google/protobuf/pyext/repeated_composite_container.cc4
-rw-r--r--python/google/protobuf/pyext/repeated_scalar_container.cc4
4 files changed, 42 insertions, 7 deletions
diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc
index d9b90ddb..6890cd04 100644
--- a/python/google/protobuf/pyext/descriptor.cc
+++ b/python/google/protobuf/pyext/descriptor.cc
@@ -433,6 +433,20 @@ static PyObject* IsExtendable(PyBaseDescriptor *self, void *closure) {
}
}
+static PyObject* GetExtensionRanges(PyBaseDescriptor *self, void *closure) {
+ const Descriptor* descriptor = _GetDescriptor(self);
+ PyObject* range_list = PyList_New(descriptor->extension_range_count());
+
+ for (int i = 0; i < descriptor->extension_range_count(); i++) {
+ const Descriptor::ExtensionRange* range = descriptor->extension_range(i);
+ PyObject* start = PyInt_FromLong(range->start);
+ PyObject* end = PyInt_FromLong(range->end);
+ PyList_SetItem(range_list, i, PyTuple_Pack(2, start, end));
+ }
+
+ return range_list;
+}
+
static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
const Descriptor* containing_type =
_GetDescriptor(self)->containing_type();
@@ -512,6 +526,7 @@ static PyGetSetDef Getters[] = {
{ C("nested_types_by_name"), (getter)GetNestedTypesByName, NULL, "Nested types by name", NULL},
{ C("extensions"), (getter)GetExtensions, NULL, "Extensions Sequence", NULL},
{ C("extensions_by_name"), (getter)GetExtensionsByName, NULL, "Extensions by name", NULL},
+ { C("extension_ranges"), (getter)GetExtensionRanges, NULL, "Extension ranges", NULL},
{ C("enum_types"), (getter)GetEnumsSeq, NULL, "Enum sequence", NULL},
{ C("enum_types_by_name"), (getter)GetEnumTypesByName, NULL, "Enum types by name", NULL},
{ C("enum_values_by_name"), (getter)GetEnumValuesByName, NULL, "Enum values by name", NULL},
diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc
index 137f5d5f..c48f94c3 100644
--- a/python/google/protobuf/pyext/message.cc
+++ b/python/google/protobuf/pyext/message.cc
@@ -1264,7 +1264,27 @@ static PyObject* SerializeToString(CMessage* self, PyObject* args) {
if (joined == NULL) {
return NULL;
}
- PyErr_Format(EncodeError_class, "Message %s is missing required fields: %s",
+
+ // TODO(haberman): this is a (hopefully temporary) hack. The unit testing
+ // infrastructure reloads all pure-Python modules for every test, but not
+ // C++ modules (because that's generally impossible:
+ // http://bugs.python.org/issue1144263). But if we cache EncodeError, we'll
+ // return the EncodeError from a previous load of the module, which won't
+ // match a user's attempt to catch EncodeError. So we have to look it up
+ // again every time.
+ ScopedPyObjectPtr message_module(PyImport_ImportModule(
+ "google.protobuf.message"));
+ if (message_module.get() == NULL) {
+ return NULL;
+ }
+
+ ScopedPyObjectPtr encode_error(
+ PyObject_GetAttrString(message_module, "EncodeError"));
+ if (encode_error.get() == NULL) {
+ return NULL;
+ }
+ PyErr_Format(encode_error.get(),
+ "Message %s is missing required fields: %s",
GetMessageName(self).c_str(), PyString_AsString(joined));
return NULL;
}
@@ -2284,8 +2304,8 @@ int SetAttr(CMessage* self, PyObject* name, PyObject* value) {
PyTypeObject CMessage_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
- "google.protobuf.internal."
- "cpp._message.CMessage", // tp_name
+ "google.protobuf."
+ "pyext._message.CMessage", // tp_name
sizeof(CMessage), // tp_basicsize
0, // tp_itemsize
(destructor)cmessage::Dealloc, // tp_dealloc
diff --git a/python/google/protobuf/pyext/repeated_composite_container.cc b/python/google/protobuf/pyext/repeated_composite_container.cc
index 49ef7991..abc859d7 100644
--- a/python/google/protobuf/pyext/repeated_composite_container.cc
+++ b/python/google/protobuf/pyext/repeated_composite_container.cc
@@ -732,8 +732,8 @@ static PyMethodDef Methods[] = {
PyTypeObject RepeatedCompositeContainer_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
- "google.protobuf.internal."
- "cpp._message.RepeatedCompositeContainer", // tp_name
+ "google.protobuf.pyext."
+ "_message.RepeatedCompositeContainer", // tp_name
sizeof(RepeatedCompositeContainer), // tp_basicsize
0, // tp_itemsize
(destructor)repeated_composite_container::Dealloc, // tp_dealloc
diff --git a/python/google/protobuf/pyext/repeated_scalar_container.cc b/python/google/protobuf/pyext/repeated_scalar_container.cc
index 9f8075b2..17474598 100644
--- a/python/google/protobuf/pyext/repeated_scalar_container.cc
+++ b/python/google/protobuf/pyext/repeated_scalar_container.cc
@@ -769,8 +769,8 @@ static PyMethodDef Methods[] = {
PyTypeObject RepeatedScalarContainer_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
- "google.protobuf.internal."
- "cpp._message.RepeatedScalarContainer", // tp_name
+ "google.protobuf."
+ "pyext._message.RepeatedScalarContainer", // tp_name
sizeof(RepeatedScalarContainer), // tp_basicsize
0, // tp_itemsize
(destructor)repeated_scalar_container::Dealloc, // tp_dealloc