| Index: third_party/protobuf/python/google/protobuf/pyext/map_container.cc
|
| diff --git a/third_party/protobuf/python/google/protobuf/pyext/map_container.cc b/third_party/protobuf/python/google/protobuf/pyext/map_container.cc
|
| index e022406d11f0400a12b01f1072773c4cf3813f03..088ddf93536ac75e76d78c0412bb2344ac75cdea 100644
|
| --- a/third_party/protobuf/python/google/protobuf/pyext/map_container.cc
|
| +++ b/third_party/protobuf/python/google/protobuf/pyext/map_container.cc
|
| @@ -39,11 +39,12 @@
|
|
|
| #include <google/protobuf/stubs/logging.h>
|
| #include <google/protobuf/stubs/common.h>
|
| -#include <google/protobuf/stubs/scoped_ptr.h>
|
| #include <google/protobuf/map_field.h>
|
| #include <google/protobuf/map.h>
|
| #include <google/protobuf/message.h>
|
| +#include <google/protobuf/pyext/message_factory.h>
|
| #include <google/protobuf/pyext/message.h>
|
| +#include <google/protobuf/pyext/repeated_composite_container.h>
|
| #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
|
|
|
| #if PY_MAJOR_VERSION >= 3
|
| @@ -329,6 +330,15 @@ PyObject* Clear(PyObject* _self) {
|
| Py_RETURN_NONE;
|
| }
|
|
|
| +PyObject* GetEntryClass(PyObject* _self) {
|
| + MapContainer* self = GetMap(_self);
|
| + CMessageClass* message_class = message_factory::GetMessageClass(
|
| + cmessage::GetFactoryForMessage(self->parent),
|
| + self->parent_field_descriptor->message_type());
|
| + Py_XINCREF(message_class);
|
| + return reinterpret_cast<PyObject*>(message_class);
|
| +}
|
| +
|
| PyObject* MapReflectionFriend::Contains(PyObject* _self, PyObject* key) {
|
| MapContainer* self = GetMap(_self);
|
|
|
| @@ -349,9 +359,10 @@ PyObject* MapReflectionFriend::Contains(PyObject* _self, PyObject* key) {
|
| }
|
|
|
| // Initializes the underlying Message object of "to" so it becomes a new parent
|
| -// repeated scalar, and copies all the values from "from" to it. A child scalar
|
| +// map container, and copies all the values from "from" to it. A child map
|
| // container can be released by passing it as both from and to (e.g. making it
|
| // the recipient of the new parent message and copying the values from itself).
|
| +// In fact, this is the only supported use at the moment.
|
| static int InitializeAndCopyToParentContainer(MapContainer* from,
|
| MapContainer* to) {
|
| // For now we require from == to, re-evaluate if we want to support deep copy
|
| @@ -363,7 +374,7 @@ static int InitializeAndCopyToParentContainer(MapContainer* from,
|
| // A somewhat roundabout way of copying just one field from old_message to
|
| // new_message. This is the best we can do with what Reflection gives us.
|
| Message* mutable_old = from->GetMutableMessage();
|
| - vector<const FieldDescriptor*> fields;
|
| + std::vector<const FieldDescriptor*> fields;
|
| fields.push_back(from->parent_field_descriptor);
|
|
|
| // Move the map field into the new message.
|
| @@ -400,12 +411,7 @@ PyObject *NewScalarMapContainer(
|
| return NULL;
|
| }
|
|
|
| -#if PY_MAJOR_VERSION >= 3
|
| - ScopedPyObjectPtr obj(PyType_GenericAlloc(
|
| - reinterpret_cast<PyTypeObject *>(ScalarMapContainer_Type), 0));
|
| -#else
|
| - ScopedPyObjectPtr obj(PyType_GenericAlloc(&ScalarMapContainer_Type, 0));
|
| -#endif
|
| + ScopedPyObjectPtr obj(PyType_GenericAlloc(ScalarMapContainer_Type, 0));
|
| if (obj.get() == NULL) {
|
| return PyErr_Format(PyExc_RuntimeError,
|
| "Could not allocate new container.");
|
| @@ -527,6 +533,8 @@ static PyMethodDef ScalarMapMethods[] = {
|
| "Removes all elements from the map." },
|
| { "get", ScalarMapGet, METH_VARARGS,
|
| "Gets the value for the given key if present, or otherwise a default" },
|
| + { "GetEntryClass", (PyCFunction)GetEntryClass, METH_NOARGS,
|
| + "Return the class used to build Entries of (key, value) pairs." },
|
| /*
|
| { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
|
| "Makes a deep copy of the class." },
|
| @@ -536,6 +544,7 @@ static PyMethodDef ScalarMapMethods[] = {
|
| {NULL, NULL},
|
| };
|
|
|
| +PyTypeObject *ScalarMapContainer_Type;
|
| #if PY_MAJOR_VERSION >= 3
|
| static PyType_Slot ScalarMapContainer_Type_slots[] = {
|
| {Py_tp_dealloc, (void *)ScalarMapDealloc},
|
| @@ -554,7 +563,6 @@ static PyMethodDef ScalarMapMethods[] = {
|
| Py_TPFLAGS_DEFAULT,
|
| ScalarMapContainer_Type_slots
|
| };
|
| - PyObject *ScalarMapContainer_Type;
|
| #else
|
| static PyMappingMethods ScalarMapMappingMethods = {
|
| MapReflectionFriend::Length, // mp_length
|
| @@ -562,7 +570,7 @@ static PyMethodDef ScalarMapMethods[] = {
|
| MapReflectionFriend::ScalarMapSetItem, // mp_ass_subscript
|
| };
|
|
|
| - PyTypeObject ScalarMapContainer_Type = {
|
| + PyTypeObject _ScalarMapContainer_Type = {
|
| PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
| FULL_MODULE_NAME ".ScalarMapContainer", // tp_name
|
| sizeof(MapContainer), // tp_basicsize
|
| @@ -643,12 +651,7 @@ PyObject* NewMessageMapContainer(
|
| return NULL;
|
| }
|
|
|
| -#if PY_MAJOR_VERSION >= 3
|
| - PyObject* obj = PyType_GenericAlloc(
|
| - reinterpret_cast<PyTypeObject *>(MessageMapContainer_Type), 0);
|
| -#else
|
| - PyObject* obj = PyType_GenericAlloc(&MessageMapContainer_Type, 0);
|
| -#endif
|
| + PyObject* obj = PyType_GenericAlloc(MessageMapContainer_Type, 0);
|
| if (obj == NULL) {
|
| return PyErr_Format(PyExc_RuntimeError,
|
| "Could not allocate new container.");
|
| @@ -780,6 +783,8 @@ static PyMethodDef MessageMapMethods[] = {
|
| "Gets the value for the given key if present, or otherwise a default" },
|
| { "get_or_create", MapReflectionFriend::MessageMapGetItem, METH_O,
|
| "Alias for getitem, useful to make explicit that the map is mutated." },
|
| + { "GetEntryClass", (PyCFunction)GetEntryClass, METH_NOARGS,
|
| + "Return the class used to build Entries of (key, value) pairs." },
|
| /*
|
| { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
|
| "Makes a deep copy of the class." },
|
| @@ -789,6 +794,7 @@ static PyMethodDef MessageMapMethods[] = {
|
| {NULL, NULL},
|
| };
|
|
|
| +PyTypeObject *MessageMapContainer_Type;
|
| #if PY_MAJOR_VERSION >= 3
|
| static PyType_Slot MessageMapContainer_Type_slots[] = {
|
| {Py_tp_dealloc, (void *)MessageMapDealloc},
|
| @@ -807,8 +813,6 @@ static PyMethodDef MessageMapMethods[] = {
|
| Py_TPFLAGS_DEFAULT,
|
| MessageMapContainer_Type_slots
|
| };
|
| -
|
| - PyObject *MessageMapContainer_Type;
|
| #else
|
| static PyMappingMethods MessageMapMappingMethods = {
|
| MapReflectionFriend::Length, // mp_length
|
| @@ -816,7 +820,7 @@ static PyMethodDef MessageMapMethods[] = {
|
| MapReflectionFriend::MessageMapSetItem, // mp_ass_subscript
|
| };
|
|
|
| - PyTypeObject MessageMapContainer_Type = {
|
| + PyTypeObject _MessageMapContainer_Type = {
|
| PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
| FULL_MODULE_NAME ".MessageMapContainer", // tp_name
|
| sizeof(MessageMapContainer), // tp_basicsize
|
| @@ -965,6 +969,63 @@ PyTypeObject MapIterator_Type = {
|
| 0, // tp_init
|
| };
|
|
|
| +bool InitMapContainers() {
|
| + // ScalarMapContainer_Type derives from our MutableMapping type.
|
| + ScopedPyObjectPtr containers(PyImport_ImportModule(
|
| + "google.protobuf.internal.containers"));
|
| + if (containers == NULL) {
|
| + return false;
|
| + }
|
| +
|
| + ScopedPyObjectPtr mutable_mapping(
|
| + PyObject_GetAttrString(containers.get(), "MutableMapping"));
|
| + if (mutable_mapping == NULL) {
|
| + return false;
|
| + }
|
| +
|
| + if (!PyObject_TypeCheck(mutable_mapping.get(), &PyType_Type)) {
|
| + return false;
|
| + }
|
| +
|
| + Py_INCREF(mutable_mapping.get());
|
| +#if PY_MAJOR_VERSION >= 3
|
| + PyObject* bases = PyTuple_New(1);
|
| + PyTuple_SET_ITEM(bases, 0, mutable_mapping.get());
|
| +
|
| + ScalarMapContainer_Type = reinterpret_cast<PyTypeObject*>(
|
| + PyType_FromSpecWithBases(&ScalarMapContainer_Type_spec, bases));
|
| +#else
|
| + _ScalarMapContainer_Type.tp_base =
|
| + reinterpret_cast<PyTypeObject*>(mutable_mapping.get());
|
| +
|
| + if (PyType_Ready(&_ScalarMapContainer_Type) < 0) {
|
| + return false;
|
| + }
|
| +
|
| + ScalarMapContainer_Type = &_ScalarMapContainer_Type;
|
| +#endif
|
| +
|
| + if (PyType_Ready(&MapIterator_Type) < 0) {
|
| + return false;
|
| + }
|
| +
|
| +#if PY_MAJOR_VERSION >= 3
|
| + MessageMapContainer_Type = reinterpret_cast<PyTypeObject*>(
|
| + PyType_FromSpecWithBases(&MessageMapContainer_Type_spec, bases));
|
| +#else
|
| + Py_INCREF(mutable_mapping.get());
|
| + _MessageMapContainer_Type.tp_base =
|
| + reinterpret_cast<PyTypeObject*>(mutable_mapping.get());
|
| +
|
| + if (PyType_Ready(&_MessageMapContainer_Type) < 0) {
|
| + return false;
|
| + }
|
| +
|
| + MessageMapContainer_Type = &_MessageMapContainer_Type;
|
| +#endif
|
| + return true;
|
| +}
|
| +
|
| } // namespace python
|
| } // namespace protobuf
|
| } // namespace google
|
|
|