diff options
Diffstat (limited to 'python/google/protobuf/pyext/descriptor.cc')
-rw-r--r-- | python/google/protobuf/pyext/descriptor.cc | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc index 8af0cb12..3cb16b74 100644 --- a/python/google/protobuf/pyext/descriptor.cc +++ b/python/google/protobuf/pyext/descriptor.cc @@ -32,8 +32,8 @@ #include <Python.h> #include <frameobject.h> -#include <google/protobuf/stubs/hash.h> #include <string> +#include <unordered_map> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/descriptor.pb.h> @@ -44,6 +44,7 @@ #include <google/protobuf/pyext/message.h> #include <google/protobuf/pyext/message_factory.h> #include <google/protobuf/pyext/scoped_pyobject_ptr.h> +#include <google/protobuf/stubs/hash.h> #if PY_MAJOR_VERSION >= 3 #define PyString_FromStringAndSize PyUnicode_FromStringAndSize @@ -54,10 +55,12 @@ #if PY_VERSION_HEX < 0x03030000 #error "Python 3.0 - 3.2 are not supported." #endif - #define PyString_AsStringAndSize(ob, charpp, sizep) \ - (PyUnicode_Check(ob)? \ - ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \ - PyBytes_AsStringAndSize(ob, (charpp), (sizep))) +#define PyString_AsStringAndSize(ob, charpp, sizep) \ + (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>( \ + PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \ + ? -1 \ + : 0) \ + : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) #endif namespace google { @@ -70,7 +73,7 @@ namespace python { // released. // This is enough to support the "is" operator on live objects. // All descriptors are stored here. -hash_map<const void*, PyObject*> interned_descriptors; +std::unordered_map<const void*, PyObject*>* interned_descriptors; PyObject* PyString_FromCppString(const string& str) { return PyString_FromStringAndSize(str.c_str(), str.size()); @@ -119,8 +122,10 @@ bool _CalledFromGeneratedFile(int stacklevel) { PyErr_Clear(); return false; } - if ((filename_size < 3) || (strcmp(&filename[filename_size - 3], ".py") != 0)) { - // Cython's stack does not have .py file name and is not at global module scope. + if ((filename_size < 3) || + (strcmp(&filename[filename_size - 3], ".py") != 0)) { + // Cython's stack does not have .py file name and is not at global module + // scope. return true; } if (filename_size < 7) { @@ -131,7 +136,7 @@ bool _CalledFromGeneratedFile(int stacklevel) { // Filename is not ending with _pb2. return false; } - + if (frame->f_globals != frame->f_locals) { // Not at global module scope return false; @@ -197,7 +202,7 @@ static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) { // First search in the cache. PyDescriptorPool* caching_pool = GetDescriptorPool_FromPool( GetFileDescriptor(descriptor)->pool()); - hash_map<const void*, PyObject*>* descriptor_options = + std::unordered_map<const void*, PyObject*>* descriptor_options = caching_pool->descriptor_options; if (descriptor_options->find(descriptor) != descriptor_options->end()) { PyObject *value = (*descriptor_options)[descriptor]; @@ -232,7 +237,7 @@ static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) { if (value == NULL) { return NULL; } - if (!PyObject_TypeCheck(value.get(), &CMessage_Type)) { + if (!PyObject_TypeCheck(value.get(), CMessage_Type)) { PyErr_Format(PyExc_TypeError, "Invalid class for %s: %s", message_type->full_name().c_str(), Py_TYPE(value.get())->tp_name); @@ -275,7 +280,7 @@ static PyObject* CopyToPythonProto(const DescriptorClass *descriptor, const Descriptor* self_descriptor = DescriptorProtoClass::default_instance().GetDescriptor(); CMessage* message = reinterpret_cast<CMessage*>(target); - if (!PyObject_TypeCheck(target, &CMessage_Type) || + if (!PyObject_TypeCheck(target, CMessage_Type) || message->message->GetDescriptor() != self_descriptor) { PyErr_Format(PyExc_TypeError, "Not a %s message", self_descriptor->full_name().c_str()); @@ -332,9 +337,9 @@ PyObject* NewInternedDescriptor(PyTypeObject* type, } // See if the object is in the map of interned descriptors - hash_map<const void*, PyObject*>::iterator it = - interned_descriptors.find(descriptor); - if (it != interned_descriptors.end()) { + std::unordered_map<const void*, PyObject*>::iterator it = + interned_descriptors->find(descriptor); + if (it != interned_descriptors->end()) { GOOGLE_DCHECK(Py_TYPE(it->second) == type); Py_INCREF(it->second); return it->second; @@ -348,7 +353,7 @@ PyObject* NewInternedDescriptor(PyTypeObject* type, py_descriptor->descriptor = descriptor; // and cache it. - interned_descriptors.insert( + interned_descriptors->insert( std::make_pair(descriptor, reinterpret_cast<PyObject*>(py_descriptor))); // Ensures that the DescriptorPool stays alive. @@ -370,7 +375,7 @@ PyObject* NewInternedDescriptor(PyTypeObject* type, static void Dealloc(PyBaseDescriptor* self) { // Remove from interned dictionary - interned_descriptors.erase(self->descriptor); + interned_descriptors->erase(self->descriptor); Py_CLEAR(self->pool); Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); } @@ -758,6 +763,11 @@ static PyObject* HasDefaultValue(PyBaseDescriptor *self, void *closure) { static PyObject* GetDefaultValue(PyBaseDescriptor *self, void *closure) { PyObject *result; + if (_GetDescriptor(self)->is_repeated()) { + return PyList_New(0); + } + + switch (_GetDescriptor(self)->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: { int32 value = _GetDescriptor(self)->default_value_int32(); @@ -805,6 +815,10 @@ static PyObject* GetDefaultValue(PyBaseDescriptor *self, void *closure) { result = PyInt_FromLong(value->number()); break; } + case FieldDescriptor::CPPTYPE_MESSAGE: { + Py_RETURN_NONE; + break; + } default: PyErr_Format(PyExc_NotImplementedError, "default value for %s", _GetDescriptor(self)->full_name().c_str()); @@ -1919,6 +1933,9 @@ bool InitDescriptor() { if (!InitDescriptorMappingTypes()) return false; + // Initialize globals defined in this file. + interned_descriptors = new std::unordered_map<const void*, PyObject*>; + return true; } |