diff options
author | Adam Cozzette <acozzette@google.com> | 2018-03-13 16:37:29 -0700 |
---|---|---|
committer | Adam Cozzette <acozzette@google.com> | 2018-03-13 16:37:29 -0700 |
commit | 0400cca3236de1ca303af38bf81eab332d042b7c (patch) | |
tree | a8a9b19853f64567c96750a1c7d253926471daa5 /python/google/protobuf/pyext | |
parent | 96b535cc2f4f7b7e22a1b8622149f7c26a5a3f63 (diff) |
Integrated internal changes from Google
Diffstat (limited to 'python/google/protobuf/pyext')
-rw-r--r-- | python/google/protobuf/pyext/descriptor.cc | 80 | ||||
-rw-r--r-- | python/google/protobuf/pyext/descriptor_pool.cc | 122 | ||||
-rw-r--r-- | python/google/protobuf/pyext/extension_dict.cc | 3 | ||||
-rw-r--r-- | python/google/protobuf/pyext/extension_dict.h | 15 | ||||
-rw-r--r-- | python/google/protobuf/pyext/map_container.cc | 29 | ||||
-rw-r--r-- | python/google/protobuf/pyext/map_container.h | 17 | ||||
-rw-r--r-- | python/google/protobuf/pyext/message.cc | 29 | ||||
-rw-r--r-- | python/google/protobuf/pyext/message.h | 24 | ||||
-rw-r--r-- | python/google/protobuf/pyext/message_factory.cc | 8 | ||||
-rw-r--r-- | python/google/protobuf/pyext/repeated_composite_container.cc | 129 | ||||
-rw-r--r-- | python/google/protobuf/pyext/repeated_composite_container.h | 21 | ||||
-rw-r--r-- | python/google/protobuf/pyext/repeated_scalar_container.cc | 174 | ||||
-rw-r--r-- | python/google/protobuf/pyext/repeated_scalar_container.h | 19 |
13 files changed, 394 insertions, 276 deletions
diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc index 9634ea05..bacaaf31 100644 --- a/python/google/protobuf/pyext/descriptor.cc +++ b/python/google/protobuf/pyext/descriptor.cc @@ -188,39 +188,36 @@ const FileDescriptor* GetFileDescriptor(const MethodDescriptor* descriptor) { // Always returns a new reference. template<class DescriptorClass> static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) { - // Options (and their extensions) are completely resolved in the proto file - // containing the descriptor. - PyDescriptorPool* pool = GetDescriptorPool_FromPool( + // Options are cached in the pool that owns the descriptor. + // First search in the cache. + PyDescriptorPool* caching_pool = GetDescriptorPool_FromPool( GetFileDescriptor(descriptor)->pool()); - hash_map<const void*, PyObject*>* descriptor_options = - pool->descriptor_options; - // First search in the cache. + caching_pool->descriptor_options; if (descriptor_options->find(descriptor) != descriptor_options->end()) { PyObject *value = (*descriptor_options)[descriptor]; Py_INCREF(value); return value; } + // Similar to the C++ implementation, we return an Options object from the + // default (generated) factory, so that client code know that they can use + // extensions from generated files: + // d.GetOptions().Extensions[some_pb2.extension] + // + // The consequence is that extensions not defined in the default pool won't + // be available. If needed, we could add an optional 'message_factory' + // parameter to the GetOptions() function. + PyMessageFactory* message_factory = + GetDefaultDescriptorPool()->py_message_factory; + // Build the Options object: get its Python class, and make a copy of the C++ // read-only instance. const Message& options(descriptor->options()); const Descriptor *message_type = options.GetDescriptor(); - PyMessageFactory* message_factory = pool->py_message_factory; - CMessageClass* message_class = message_factory::GetMessageClass( + CMessageClass* message_class = message_factory::GetOrCreateMessageClass( message_factory, message_type); if (message_class == NULL) { - // The Options message was not found in the current DescriptorPool. - // This means that the pool cannot contain any extensions to the Options - // message either, so falling back to the basic pool we can only increase - // the chances of successfully parsing the options. - PyErr_Clear(); - pool = GetDefaultDescriptorPool(); - message_factory = pool->py_message_factory; - message_class = message_factory::GetMessageClass( - message_factory, message_type); - } - if (message_class == NULL) { PyErr_Format(PyExc_TypeError, "Could not retrieve class for Options: %s", message_type->full_name().c_str()); return NULL; @@ -248,7 +245,8 @@ static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) { options.SerializeToString(&serialized); io::CodedInputStream input( reinterpret_cast<const uint8*>(serialized.c_str()), serialized.size()); - input.SetExtensionRegistry(pool->pool, message_factory->message_factory); + input.SetExtensionRegistry(message_factory->pool->pool, + message_factory->message_factory); bool success = cmsg->message->MergePartialFromCodedStream(&input); if (!success) { PyErr_Format(PyExc_ValueError, "Error parsing Options message"); @@ -564,6 +562,11 @@ static int SetOptions(PyBaseDescriptor *self, PyObject *value, return CheckCalledFromGeneratedFile("_options"); } +static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value, + void *closure) { + return CheckCalledFromGeneratedFile("_serialized_options"); +} + static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { return CopyToPythonProto<DescriptorProto>(_GetDescriptor(self), target); } @@ -623,6 +626,8 @@ static PyGetSetDef Getters[] = { { "is_extendable", (getter)IsExtendable, (setter)NULL}, { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, { "_options", (getter)NULL, (setter)SetOptions, "Options"}, + { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, + "Serialized Options"}, { "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"}, {NULL} }; @@ -785,7 +790,7 @@ static PyObject* GetDefaultValue(PyBaseDescriptor *self, void *closure) { break; } case FieldDescriptor::CPPTYPE_STRING: { - string value = _GetDescriptor(self)->default_value_string(); + const string& value = _GetDescriptor(self)->default_value_string(); result = ToStringObject(_GetDescriptor(self), value); break; } @@ -897,6 +902,10 @@ static int SetOptions(PyBaseDescriptor *self, PyObject *value, return CheckCalledFromGeneratedFile("_options"); } +static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value, + void *closure) { + return CheckCalledFromGeneratedFile("_serialized_options"); +} static PyGetSetDef Getters[] = { { "full_name", (getter)GetFullName, NULL, "Full name"}, @@ -926,6 +935,8 @@ static PyGetSetDef Getters[] = { "Containing oneof"}, { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, { "_options", (getter)NULL, (setter)SetOptions, "Options"}, + { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, + "Serialized Options"}, {NULL} }; @@ -1055,6 +1066,11 @@ static int SetOptions(PyBaseDescriptor *self, PyObject *value, return CheckCalledFromGeneratedFile("_options"); } +static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value, + void *closure) { + return CheckCalledFromGeneratedFile("_serialized_options"); +} + static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { return CopyToPythonProto<EnumDescriptorProto>(_GetDescriptor(self), target); } @@ -1079,6 +1095,8 @@ static PyGetSetDef Getters[] = { "Containing type"}, { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, { "_options", (getter)NULL, (setter)SetOptions, "Options"}, + { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, + "Serialized Options"}, {NULL} }; @@ -1179,6 +1197,10 @@ static int SetOptions(PyBaseDescriptor *self, PyObject *value, return CheckCalledFromGeneratedFile("_options"); } +static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value, + void *closure) { + return CheckCalledFromGeneratedFile("_serialized_options"); +} static PyGetSetDef Getters[] = { { "name", (getter)GetName, NULL, "name"}, @@ -1188,6 +1210,8 @@ static PyGetSetDef Getters[] = { { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, { "_options", (getter)NULL, (setter)SetOptions, "Options"}, + { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, + "Serialized Options"}, {NULL} }; @@ -1330,6 +1354,11 @@ static int SetOptions(PyFileDescriptor *self, PyObject *value, return CheckCalledFromGeneratedFile("_options"); } +static int SetSerializedOptions(PyFileDescriptor *self, PyObject *value, + void *closure) { + return CheckCalledFromGeneratedFile("_serialized_options"); +} + static PyObject* GetSyntax(PyFileDescriptor *self, void *closure) { return PyString_InternFromString( FileDescriptor::SyntaxName(_GetDescriptor(self)->syntax())); @@ -1355,6 +1384,8 @@ static PyGetSetDef Getters[] = { { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, { "_options", (getter)NULL, (setter)SetOptions, "Options"}, + { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, + "Serialized Options"}, { "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"}, {NULL} }; @@ -1500,6 +1531,11 @@ static int SetOptions(PyBaseDescriptor *self, PyObject *value, return CheckCalledFromGeneratedFile("_options"); } +static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value, + void *closure) { + return CheckCalledFromGeneratedFile("_serialized_options"); +} + static PyGetSetDef Getters[] = { { "name", (getter)GetName, NULL, "Name"}, { "full_name", (getter)GetFullName, NULL, "Full name"}, @@ -1508,6 +1544,8 @@ static PyGetSetDef Getters[] = { { "containing_type", (getter)GetContainingType, NULL, "Containing type"}, { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, { "_options", (getter)NULL, (setter)SetOptions, "Options"}, + { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, + "Serialized Options"}, { "fields", (getter)GetFields, NULL, "Fields"}, {NULL} }; diff --git a/python/google/protobuf/pyext/descriptor_pool.cc b/python/google/protobuf/pyext/descriptor_pool.cc index 16f4d49d..95882aeb 100644 --- a/python/google/protobuf/pyext/descriptor_pool.cc +++ b/python/google/protobuf/pyext/descriptor_pool.cc @@ -149,7 +149,8 @@ static PyObject* New(PyTypeObject* type, PyDescriptorPool_NewWithDatabase(database)); } -static void Dealloc(PyDescriptorPool* self) { +static void Dealloc(PyObject* pself) { + PyDescriptorPool* self = reinterpret_cast<PyDescriptorPool*>(pself); descriptor_pool_map.erase(self->pool); Py_CLEAR(self->py_message_factory); for (hash_map<const void*, PyObject*>::iterator it = @@ -163,7 +164,7 @@ static void Dealloc(PyDescriptorPool* self) { Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); } -PyObject* FindMessageByName(PyDescriptorPool* self, PyObject* arg) { +static PyObject* FindMessageByName(PyObject* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { @@ -171,7 +172,8 @@ PyObject* FindMessageByName(PyDescriptorPool* self, PyObject* arg) { } const Descriptor* message_descriptor = - self->pool->FindMessageTypeByName(string(name, name_size)); + reinterpret_cast<PyDescriptorPool*>(self)->pool->FindMessageTypeByName( + string(name, name_size)); if (message_descriptor == NULL) { PyErr_Format(PyExc_KeyError, "Couldn't find message %.200s", name); @@ -184,7 +186,7 @@ PyObject* FindMessageByName(PyDescriptorPool* self, PyObject* arg) { -PyObject* FindFileByName(PyDescriptorPool* self, PyObject* arg) { +static PyObject* FindFileByName(PyObject* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { @@ -192,7 +194,8 @@ PyObject* FindFileByName(PyDescriptorPool* self, PyObject* arg) { } const FileDescriptor* file_descriptor = - self->pool->FindFileByName(string(name, name_size)); + reinterpret_cast<PyDescriptorPool*>(self)->pool->FindFileByName( + string(name, name_size)); if (file_descriptor == NULL) { PyErr_Format(PyExc_KeyError, "Couldn't find file %.200s", name); return NULL; @@ -218,6 +221,10 @@ PyObject* FindFieldByName(PyDescriptorPool* self, PyObject* arg) { return PyFieldDescriptor_FromDescriptor(field_descriptor); } +static PyObject* FindFieldByNameMethod(PyObject* self, PyObject* arg) { + return FindFieldByName(reinterpret_cast<PyDescriptorPool*>(self), arg); +} + PyObject* FindExtensionByName(PyDescriptorPool* self, PyObject* arg) { Py_ssize_t name_size; char* name; @@ -235,6 +242,10 @@ PyObject* FindExtensionByName(PyDescriptorPool* self, PyObject* arg) { return PyFieldDescriptor_FromDescriptor(field_descriptor); } +static PyObject* FindExtensionByNameMethod(PyObject* self, PyObject* arg) { + return FindExtensionByName(reinterpret_cast<PyDescriptorPool*>(self), arg); +} + PyObject* FindEnumTypeByName(PyDescriptorPool* self, PyObject* arg) { Py_ssize_t name_size; char* name; @@ -252,6 +263,10 @@ PyObject* FindEnumTypeByName(PyDescriptorPool* self, PyObject* arg) { return PyEnumDescriptor_FromDescriptor(enum_descriptor); } +static PyObject* FindEnumTypeByNameMethod(PyObject* self, PyObject* arg) { + return FindEnumTypeByName(reinterpret_cast<PyDescriptorPool*>(self), arg); +} + PyObject* FindOneofByName(PyDescriptorPool* self, PyObject* arg) { Py_ssize_t name_size; char* name; @@ -269,7 +284,11 @@ PyObject* FindOneofByName(PyDescriptorPool* self, PyObject* arg) { return PyOneofDescriptor_FromDescriptor(oneof_descriptor); } -PyObject* FindServiceByName(PyDescriptorPool* self, PyObject* arg) { +static PyObject* FindOneofByNameMethod(PyObject* self, PyObject* arg) { + return FindOneofByName(reinterpret_cast<PyDescriptorPool*>(self), arg); +} + +static PyObject* FindServiceByName(PyObject* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { @@ -277,7 +296,8 @@ PyObject* FindServiceByName(PyDescriptorPool* self, PyObject* arg) { } const ServiceDescriptor* service_descriptor = - self->pool->FindServiceByName(string(name, name_size)); + reinterpret_cast<PyDescriptorPool*>(self)->pool->FindServiceByName( + string(name, name_size)); if (service_descriptor == NULL) { PyErr_Format(PyExc_KeyError, "Couldn't find service %.200s", name); return NULL; @@ -286,7 +306,7 @@ PyObject* FindServiceByName(PyDescriptorPool* self, PyObject* arg) { return PyServiceDescriptor_FromDescriptor(service_descriptor); } -PyObject* FindMethodByName(PyDescriptorPool* self, PyObject* arg) { +static PyObject* FindMethodByName(PyObject* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { @@ -294,7 +314,8 @@ PyObject* FindMethodByName(PyDescriptorPool* self, PyObject* arg) { } const MethodDescriptor* method_descriptor = - self->pool->FindMethodByName(string(name, name_size)); + reinterpret_cast<PyDescriptorPool*>(self)->pool->FindMethodByName( + string(name, name_size)); if (method_descriptor == NULL) { PyErr_Format(PyExc_KeyError, "Couldn't find method %.200s", name); return NULL; @@ -303,7 +324,7 @@ PyObject* FindMethodByName(PyDescriptorPool* self, PyObject* arg) { return PyMethodDescriptor_FromDescriptor(method_descriptor); } -PyObject* FindFileContainingSymbol(PyDescriptorPool* self, PyObject* arg) { +static PyObject* FindFileContainingSymbol(PyObject* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { @@ -311,7 +332,8 @@ PyObject* FindFileContainingSymbol(PyDescriptorPool* self, PyObject* arg) { } const FileDescriptor* file_descriptor = - self->pool->FindFileContainingSymbol(string(name, name_size)); + reinterpret_cast<PyDescriptorPool*>(self)->pool->FindFileContainingSymbol( + string(name, name_size)); if (file_descriptor == NULL) { PyErr_Format(PyExc_KeyError, "Couldn't find symbol %.200s", name); return NULL; @@ -320,7 +342,7 @@ PyObject* FindFileContainingSymbol(PyDescriptorPool* self, PyObject* arg) { return PyFileDescriptor_FromDescriptor(file_descriptor); } -PyObject* FindExtensionByNumber(PyDescriptorPool* self, PyObject* args) { +static PyObject* FindExtensionByNumber(PyObject* self, PyObject* args) { PyObject* message_descriptor; int number; if (!PyArg_ParseTuple(args, "Oi", &message_descriptor, &number)) { @@ -333,7 +355,8 @@ PyObject* FindExtensionByNumber(PyDescriptorPool* self, PyObject* args) { } const FieldDescriptor* extension_descriptor = - self->pool->FindExtensionByNumber(descriptor, number); + reinterpret_cast<PyDescriptorPool*>(self)->pool->FindExtensionByNumber( + descriptor, number); if (extension_descriptor == NULL) { PyErr_Format(PyExc_KeyError, "Couldn't find extension %d", number); return NULL; @@ -342,14 +365,15 @@ PyObject* FindExtensionByNumber(PyDescriptorPool* self, PyObject* args) { return PyFieldDescriptor_FromDescriptor(extension_descriptor); } -PyObject* FindAllExtensions(PyDescriptorPool* self, PyObject* arg) { +static PyObject* FindAllExtensions(PyObject* self, PyObject* arg) { const Descriptor* descriptor = PyMessageDescriptor_AsDescriptor(arg); if (descriptor == NULL) { return NULL; } std::vector<const FieldDescriptor*> extensions; - self->pool->FindAllExtensions(descriptor, &extensions); + reinterpret_cast<PyDescriptorPool*>(self)->pool->FindAllExtensions( + descriptor, &extensions); ScopedPyObjectPtr result(PyList_New(extensions.size())); if (result == NULL) { @@ -374,14 +398,15 @@ PyObject* FindAllExtensions(PyDescriptorPool* self, PyObject* arg) { // call a function that will just be a no-op? // TODO(amauryfa): Need to investigate further. -PyObject* AddFileDescriptor(PyDescriptorPool* self, PyObject* descriptor) { +static PyObject* AddFileDescriptor(PyObject* self, PyObject* descriptor) { const FileDescriptor* file_descriptor = PyFileDescriptor_AsDescriptor(descriptor); if (!file_descriptor) { return NULL; } if (file_descriptor != - self->pool->FindFileByName(file_descriptor->name())) { + reinterpret_cast<PyDescriptorPool*>(self)->pool->FindFileByName( + file_descriptor->name())) { PyErr_Format(PyExc_ValueError, "The file descriptor %s does not belong to this pool", file_descriptor->name().c_str()); @@ -390,14 +415,15 @@ PyObject* AddFileDescriptor(PyDescriptorPool* self, PyObject* descriptor) { Py_RETURN_NONE; } -PyObject* AddDescriptor(PyDescriptorPool* self, PyObject* descriptor) { +static PyObject* AddDescriptor(PyObject* self, PyObject* descriptor) { const Descriptor* message_descriptor = PyMessageDescriptor_AsDescriptor(descriptor); if (!message_descriptor) { return NULL; } if (message_descriptor != - self->pool->FindMessageTypeByName(message_descriptor->full_name())) { + reinterpret_cast<PyDescriptorPool*>(self)->pool->FindMessageTypeByName( + message_descriptor->full_name())) { PyErr_Format(PyExc_ValueError, "The message descriptor %s does not belong to this pool", message_descriptor->full_name().c_str()); @@ -406,14 +432,15 @@ PyObject* AddDescriptor(PyDescriptorPool* self, PyObject* descriptor) { Py_RETURN_NONE; } -PyObject* AddEnumDescriptor(PyDescriptorPool* self, PyObject* descriptor) { +static PyObject* AddEnumDescriptor(PyObject* self, PyObject* descriptor) { const EnumDescriptor* enum_descriptor = PyEnumDescriptor_AsDescriptor(descriptor); if (!enum_descriptor) { return NULL; } if (enum_descriptor != - self->pool->FindEnumTypeByName(enum_descriptor->full_name())) { + reinterpret_cast<PyDescriptorPool*>(self)->pool->FindEnumTypeByName( + enum_descriptor->full_name())) { PyErr_Format(PyExc_ValueError, "The enum descriptor %s does not belong to this pool", enum_descriptor->full_name().c_str()); @@ -422,14 +449,15 @@ PyObject* AddEnumDescriptor(PyDescriptorPool* self, PyObject* descriptor) { Py_RETURN_NONE; } -PyObject* AddExtensionDescriptor(PyDescriptorPool* self, PyObject* descriptor) { +static PyObject* AddExtensionDescriptor(PyObject* self, PyObject* descriptor) { const FieldDescriptor* extension_descriptor = PyFieldDescriptor_AsDescriptor(descriptor); if (!extension_descriptor) { return NULL; } if (extension_descriptor != - self->pool->FindExtensionByName(extension_descriptor->full_name())) { + reinterpret_cast<PyDescriptorPool*>(self)->pool->FindExtensionByName( + extension_descriptor->full_name())) { PyErr_Format(PyExc_ValueError, "The extension descriptor %s does not belong to this pool", extension_descriptor->full_name().c_str()); @@ -438,14 +466,15 @@ PyObject* AddExtensionDescriptor(PyDescriptorPool* self, PyObject* descriptor) { Py_RETURN_NONE; } -PyObject* AddServiceDescriptor(PyDescriptorPool* self, PyObject* descriptor) { +static PyObject* AddServiceDescriptor(PyObject* self, PyObject* descriptor) { const ServiceDescriptor* service_descriptor = PyServiceDescriptor_AsDescriptor(descriptor); if (!service_descriptor) { return NULL; } if (service_descriptor != - self->pool->FindServiceByName(service_descriptor->full_name())) { + reinterpret_cast<PyDescriptorPool*>(self)->pool->FindServiceByName( + service_descriptor->full_name())) { PyErr_Format(PyExc_ValueError, "The service descriptor %s does not belong to this pool", service_descriptor->full_name().c_str()); @@ -481,7 +510,8 @@ class BuildFileErrorCollector : public DescriptorPool::ErrorCollector { bool had_errors; }; -PyObject* AddSerializedFile(PyDescriptorPool* self, PyObject* serialized_pb) { +static PyObject* AddSerializedFile(PyObject* pself, PyObject* serialized_pb) { + PyDescriptorPool* self = reinterpret_cast<PyDescriptorPool*>(pself); char* message_type; Py_ssize_t message_len; @@ -529,7 +559,7 @@ PyObject* AddSerializedFile(PyDescriptorPool* self, PyObject* serialized_pb) { descriptor, serialized_pb); } -PyObject* Add(PyDescriptorPool* self, PyObject* file_descriptor_proto) { +static PyObject* Add(PyObject* self, PyObject* file_descriptor_proto) { ScopedPyObjectPtr serialized_pb( PyObject_CallMethod(file_descriptor_proto, "SerializeToString", NULL)); if (serialized_pb == NULL) { @@ -539,46 +569,46 @@ PyObject* Add(PyDescriptorPool* self, PyObject* file_descriptor_proto) { } static PyMethodDef Methods[] = { - { "Add", (PyCFunction)Add, METH_O, + { "Add", Add, METH_O, "Adds the FileDescriptorProto and its types to this pool." }, - { "AddSerializedFile", (PyCFunction)AddSerializedFile, METH_O, + { "AddSerializedFile", AddSerializedFile, METH_O, "Adds a serialized FileDescriptorProto to this pool." }, // TODO(amauryfa): Understand why the Python implementation differs from // this one, ask users to use another API and deprecate these functions. - { "AddFileDescriptor", (PyCFunction)AddFileDescriptor, METH_O, + { "AddFileDescriptor", AddFileDescriptor, METH_O, "No-op. Add() must have been called before." }, - { "AddDescriptor", (PyCFunction)AddDescriptor, METH_O, + { "AddDescriptor", AddDescriptor, METH_O, "No-op. Add() must have been called before." }, - { "AddEnumDescriptor", (PyCFunction)AddEnumDescriptor, METH_O, + { "AddEnumDescriptor", AddEnumDescriptor, METH_O, "No-op. Add() must have been called before." }, - { "AddExtensionDescriptor", (PyCFunction)AddExtensionDescriptor, METH_O, + { "AddExtensionDescriptor", AddExtensionDescriptor, METH_O, "No-op. Add() must have been called before." }, - { "AddServiceDescriptor", (PyCFunction)AddServiceDescriptor, METH_O, + { "AddServiceDescriptor", AddServiceDescriptor, METH_O, "No-op. Add() must have been called before." }, - { "FindFileByName", (PyCFunction)FindFileByName, METH_O, + { "FindFileByName", FindFileByName, METH_O, "Searches for a file descriptor by its .proto name." }, - { "FindMessageTypeByName", (PyCFunction)FindMessageByName, METH_O, + { "FindMessageTypeByName", FindMessageByName, METH_O, "Searches for a message descriptor by full name." }, - { "FindFieldByName", (PyCFunction)FindFieldByName, METH_O, + { "FindFieldByName", FindFieldByNameMethod, METH_O, "Searches for a field descriptor by full name." }, - { "FindExtensionByName", (PyCFunction)FindExtensionByName, METH_O, + { "FindExtensionByName", FindExtensionByNameMethod, METH_O, "Searches for extension descriptor by full name." }, - { "FindEnumTypeByName", (PyCFunction)FindEnumTypeByName, METH_O, + { "FindEnumTypeByName", FindEnumTypeByNameMethod, METH_O, "Searches for enum type descriptor by full name." }, - { "FindOneofByName", (PyCFunction)FindOneofByName, METH_O, + { "FindOneofByName", FindOneofByNameMethod, METH_O, "Searches for oneof descriptor by full name." }, - { "FindServiceByName", (PyCFunction)FindServiceByName, METH_O, + { "FindServiceByName", FindServiceByName, METH_O, "Searches for service descriptor by full name." }, - { "FindMethodByName", (PyCFunction)FindMethodByName, METH_O, + { "FindMethodByName", FindMethodByName, METH_O, "Searches for method descriptor by full name." }, - { "FindFileContainingSymbol", (PyCFunction)FindFileContainingSymbol, METH_O, + { "FindFileContainingSymbol", FindFileContainingSymbol, METH_O, "Gets the FileDescriptor containing the specified symbol." }, - { "FindExtensionByNumber", (PyCFunction)FindExtensionByNumber, METH_VARARGS, + { "FindExtensionByNumber", FindExtensionByNumber, METH_VARARGS, "Gets the extension descriptor for the given number." }, - { "FindAllExtensions", (PyCFunction)FindAllExtensions, METH_O, + { "FindAllExtensions", FindAllExtensions, METH_O, "Gets all known extensions of the given message descriptor." }, {NULL} }; @@ -590,7 +620,7 @@ PyTypeObject PyDescriptorPool_Type = { FULL_MODULE_NAME ".DescriptorPool", // tp_name sizeof(PyDescriptorPool), // tp_basicsize 0, // tp_itemsize - (destructor)cdescriptor_pool::Dealloc, // tp_dealloc + cdescriptor_pool::Dealloc, // tp_dealloc 0, // tp_print 0, // tp_getattr 0, // tp_setattr diff --git a/python/google/protobuf/pyext/extension_dict.cc b/python/google/protobuf/pyext/extension_dict.cc index 6830b10d..018b5c2c 100644 --- a/python/google/protobuf/pyext/extension_dict.cc +++ b/python/google/protobuf/pyext/extension_dict.cc @@ -33,9 +33,6 @@ #include <google/protobuf/pyext/extension_dict.h> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> diff --git a/python/google/protobuf/pyext/extension_dict.h b/python/google/protobuf/pyext/extension_dict.h index 65b87862..0de2c4ee 100644 --- a/python/google/protobuf/pyext/extension_dict.h +++ b/python/google/protobuf/pyext/extension_dict.h @@ -37,9 +37,8 @@ #include <Python.h> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif + +#include <google/protobuf/pyext/message.h> namespace google { namespace protobuf { @@ -47,16 +46,8 @@ namespace protobuf { class Message; class FieldDescriptor; -#ifdef _SHARED_PTR_H -using std::shared_ptr; -#else -using internal::shared_ptr; -#endif - namespace python { -struct CMessage; - typedef struct ExtensionDict { PyObject_HEAD; @@ -64,7 +55,7 @@ typedef struct ExtensionDict { // proto tree. Every Python container class holds a // reference to it in order to keep it alive as long as there's a // Python object that references any part of the tree. - shared_ptr<Message> owner; + CMessage::OwnerRef owner; // Weak reference to parent message. Used to make sure // the parent is writable when an extension field is modified. diff --git a/python/google/protobuf/pyext/map_container.cc b/python/google/protobuf/pyext/map_container.cc index abd15b77..6d7ee285 100644 --- a/python/google/protobuf/pyext/map_container.cc +++ b/python/google/protobuf/pyext/map_container.cc @@ -33,9 +33,6 @@ #include <google/protobuf/pyext/map_container.h> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> @@ -76,7 +73,7 @@ class MapReflectionFriend { struct MapIterator { PyObject_HEAD; - google::protobuf::scoped_ptr< ::google::protobuf::MapIterator> iter; + std::unique_ptr<::google::protobuf::MapIterator> iter; // A pointer back to the container, so we can notice changes to the version. // We own a ref on this. @@ -94,7 +91,7 @@ struct MapIterator { // as this iterator does. This is solely for the benefit of the MapIterator // destructor -- we should never actually access the iterator in this state // except to delete it. - shared_ptr<Message> owner; + CMessage::OwnerRef owner; // The version of the map when we took the iterator to it. // @@ -339,6 +336,24 @@ PyObject* GetEntryClass(PyObject* _self) { return reinterpret_cast<PyObject*>(message_class); } +PyObject* MergeFrom(PyObject* _self, PyObject* arg) { + MapContainer* self = GetMap(_self); + MapContainer* other_map = GetMap(arg); + Message* message = self->GetMutableMessage(); + const Message* other_message = other_map->message; + const Reflection* reflection = message->GetReflection(); + const Reflection* other_reflection = other_message->GetReflection(); + int count = other_reflection->FieldSize( + *other_message, other_map->parent_field_descriptor); + for (int i = 0 ; i < count; i ++) { + reflection->AddMessage(message, self->parent_field_descriptor)->MergeFrom( + other_reflection->GetRepeatedMessage( + *other_message, other_map->parent_field_descriptor, i)); + } + self->version++; + Py_RETURN_NONE; +} + PyObject* MapReflectionFriend::Contains(PyObject* _self, PyObject* key) { MapContainer* self = GetMap(_self); @@ -535,6 +550,8 @@ static PyMethodDef ScalarMapMethods[] = { "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." }, + { "MergeFrom", (PyCFunction)MergeFrom, METH_O, + "Merges a map into the current map." }, /* { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS, "Makes a deep copy of the class." }, @@ -810,6 +827,8 @@ static PyMethodDef MessageMapMethods[] = { "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." }, + { "MergeFrom", (PyCFunction)MergeFrom, METH_O, + "Merges a map into the current map." }, /* { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS, "Makes a deep copy of the class." }, diff --git a/python/google/protobuf/pyext/map_container.h b/python/google/protobuf/pyext/map_container.h index 615657b0..111fafbf 100644 --- a/python/google/protobuf/pyext/map_container.h +++ b/python/google/protobuf/pyext/map_container.h @@ -34,27 +34,18 @@ #include <Python.h> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <google/protobuf/descriptor.h> #include <google/protobuf/message.h> +#include <google/protobuf/pyext/message.h> namespace google { namespace protobuf { class Message; -#ifdef _SHARED_PTR_H -using std::shared_ptr; -#else -using internal::shared_ptr; -#endif - namespace python { -struct CMessage; struct CMessageClass; // This struct is used directly for ScalarMap, and is the base class of @@ -66,7 +57,7 @@ struct MapContainer { // proto tree. Every Python MapContainer holds a // reference to it in order to keep it alive as long as there's a // Python object that references any part of the tree. - shared_ptr<Message> owner; + CMessage::OwnerRef owner; // Pointer to the C++ Message that contains this container. The // MapContainer does not own this pointer. @@ -99,9 +90,7 @@ struct MapContainer { int Release(); // Set the owner field of self and any children of self. - void SetOwner(const shared_ptr<Message>& new_owner) { - owner = new_owner; - } + void SetOwner(const CMessage::OwnerRef& new_owner) { owner = new_owner; } }; struct MessageMapContainer : public MapContainer { diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc index f515b560..5893533a 100644 --- a/python/google/protobuf/pyext/message.cc +++ b/python/google/protobuf/pyext/message.cc @@ -35,9 +35,6 @@ #include <map> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <string> #include <vector> #include <structmember.h> // A Python header file. @@ -658,7 +655,7 @@ bool CheckAndGetInteger(PyObject* arg, T* value) { // Unlike PyLong_AsLongLong, PyLong_AsUnsignedLongLong is very // picky about the exact type. PyObject* casted = PyNumber_Long(arg); - if (GOOGLE_PREDICT_FALSE(casted == NULL)) { + if (GOOGLE_PREDICT_FALSE(casted == nullptr)) { // Propagate existing error. return false; } @@ -683,7 +680,7 @@ bool CheckAndGetInteger(PyObject* arg, T* value) { // Valid subclasses of numbers.Integral should have a __long__() method // so fall back to that. PyObject* casted = PyNumber_Long(arg); - if (GOOGLE_PREDICT_FALSE(casted == NULL)) { + if (GOOGLE_PREDICT_FALSE(casted == nullptr)) { // Propagate existing error. return false; } @@ -830,7 +827,8 @@ bool CheckAndSetString( return true; } -PyObject* ToStringObject(const FieldDescriptor* descriptor, string value) { +PyObject* ToStringObject(const FieldDescriptor* descriptor, + const string& value) { if (descriptor->type() != FieldDescriptor::TYPE_STRING) { return PyBytes_FromStringAndSize(value.c_str(), value.length()); } @@ -1318,6 +1316,8 @@ CMessage* NewEmptyMessage(CMessageClass* type) { return NULL; } + // Use "placement new" syntax to initialize the C++ object. + new (&self->owner) CMessage::OwnerRef(NULL); self->message = NULL; self->parent = NULL; self->parent_field_descriptor = NULL; @@ -1414,7 +1414,7 @@ static void Dealloc(CMessage* self) { Py_CLEAR(self->extensions); Py_CLEAR(self->composite_fields); - self->owner.reset(); + self->owner.~ThreadUnsafeSharedPtr<Message>(); Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); } @@ -1616,9 +1616,10 @@ PyObject* HasExtension(CMessage* self, PyObject* extension) { // * Clear the weak references from the released container to the // parent. -struct SetOwnerVisitor : public ChildVisitor { +class SetOwnerVisitor : public ChildVisitor { + public: // new_owner must outlive this object. - explicit SetOwnerVisitor(const shared_ptr<Message>& new_owner) + explicit SetOwnerVisitor(const CMessage::OwnerRef& new_owner) : new_owner_(new_owner) {} int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) { @@ -1642,11 +1643,11 @@ struct SetOwnerVisitor : public ChildVisitor { } private: - const shared_ptr<Message>& new_owner_; + const CMessage::OwnerRef& new_owner_; }; // Change the owner of this CMessage and all its children, recursively. -int SetOwner(CMessage* self, const shared_ptr<Message>& new_owner) { +int SetOwner(CMessage* self, const CMessage::OwnerRef& new_owner) { self->owner = new_owner; if (ForEachCompositeField(self, SetOwnerVisitor(new_owner)) == -1) return -1; @@ -1679,7 +1680,7 @@ int ReleaseSubMessage(CMessage* self, const FieldDescriptor* field_descriptor, CMessage* child_cmessage) { // Release the Message - shared_ptr<Message> released_message(ReleaseMessage( + CMessage::OwnerRef released_message(ReleaseMessage( self, child_cmessage->message->GetDescriptor(), field_descriptor)); child_cmessage->message = released_message.get(); child_cmessage->owner.swap(released_message); @@ -2329,7 +2330,9 @@ PyObject* InternalGetScalar(const Message* message, break; } case FieldDescriptor::CPPTYPE_STRING: { - string value = reflection->GetString(*message, field_descriptor); + string scratch; + const string& value = + reflection->GetStringReference(*message, field_descriptor, &scratch); result = ToStringObject(field_descriptor, value); break; } diff --git a/python/google/protobuf/pyext/message.h b/python/google/protobuf/pyext/message.h index 576d098c..7050f876 100644 --- a/python/google/protobuf/pyext/message.h +++ b/python/google/protobuf/pyext/message.h @@ -37,11 +37,11 @@ #include <Python.h> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <string> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/pyext/thread_unsafe_shared_ptr.h> + namespace google { namespace protobuf { @@ -71,7 +71,9 @@ typedef struct CMessage { // proto tree. Every Python CMessage holds a reference to it in // order to keep it alive as long as there's a Python object that // references any part of the tree. - shared_ptr<Message> owner; + + typedef ThreadUnsafeSharedPtr<Message> OwnerRef; + OwnerRef owner; // Weak reference to a parent CMessage object. This is NULL for any top-level // message and is set for any child message (i.e. a child submessage or a @@ -255,7 +257,7 @@ PyObject* FindInitializationErrors(CMessage* self); // Set the owner field of self and any children of self, recursively. // Used when self is being released and thus has a new owner (the // released Message.) -int SetOwner(CMessage* self, const shared_ptr<Message>& new_owner); +int SetOwner(CMessage* self, const CMessage::OwnerRef& new_owner); int AssureWritable(CMessage* self); @@ -336,7 +338,8 @@ bool CheckAndSetString( const Reflection* reflection, bool append, int index); -PyObject* ToStringObject(const FieldDescriptor* descriptor, string value); +PyObject* ToStringObject(const FieldDescriptor* descriptor, + const string& value); // Check if the passed field descriptor belongs to the given message. // If not, return false and set a Python exception (a KeyError) @@ -347,6 +350,15 @@ extern PyObject* PickleError_class; bool InitProto2MessageModule(PyObject *m); +#if LANG_CXX11 +// These are referenced by repeated_scalar_container, and must +// be explicitly instantiated. +extern template bool CheckAndGetInteger<int32>(PyObject*, int32*); +extern template bool CheckAndGetInteger<int64>(PyObject*, int64*); +extern template bool CheckAndGetInteger<uint32>(PyObject*, uint32*); +extern template bool CheckAndGetInteger<uint64>(PyObject*, uint64*); +#endif + } // namespace python } // namespace protobuf diff --git a/python/google/protobuf/pyext/message_factory.cc b/python/google/protobuf/pyext/message_factory.cc index 571bae2b..bacc76a6 100644 --- a/python/google/protobuf/pyext/message_factory.cc +++ b/python/google/protobuf/pyext/message_factory.cc @@ -100,7 +100,9 @@ PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { NewMessageFactory(type, reinterpret_cast<PyDescriptorPool*>(pool))); } -static void Dealloc(PyMessageFactory* self) { +static void Dealloc(PyObject* pself) { + PyMessageFactory* self = reinterpret_cast<PyMessageFactory*>(pself); + // TODO(amauryfa): When the MessageFactory is not created from the // DescriptorPool this reference should be owned, not borrowed. // Py_CLEAR(self->pool); @@ -111,7 +113,7 @@ static void Dealloc(PyMessageFactory* self) { } delete self->classes_by_descriptor; delete self->message_factory; - Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); + Py_TYPE(self)->tp_free(pself); } // Add a message class to our database. @@ -231,7 +233,7 @@ PyTypeObject PyMessageFactory_Type = { ".MessageFactory", // tp_name sizeof(PyMessageFactory), // tp_basicsize 0, // tp_itemsize - (destructor)message_factory::Dealloc, // tp_dealloc + message_factory::Dealloc, // tp_dealloc 0, // tp_print 0, // tp_getattr 0, // tp_setattr diff --git a/python/google/protobuf/pyext/repeated_composite_container.cc b/python/google/protobuf/pyext/repeated_composite_container.cc index 5ad71db5..5874d5de 100644 --- a/python/google/protobuf/pyext/repeated_composite_container.cc +++ b/python/google/protobuf/pyext/repeated_composite_container.cc @@ -34,9 +34,6 @@ #include <google/protobuf/pyext/repeated_composite_container.h> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> @@ -81,7 +78,10 @@ namespace repeated_composite_container { // --------------------------------------------------------------------- // len() -static Py_ssize_t Length(RepeatedCompositeContainer* self) { +static Py_ssize_t Length(PyObject* pself) { + RepeatedCompositeContainer* self = + reinterpret_cast<RepeatedCompositeContainer*>(pself); + Message* message = self->message; if (message != NULL) { return message->GetReflection()->FieldSize(*message, @@ -102,7 +102,7 @@ static int UpdateChildMessages(RepeatedCompositeContainer* self) { // A MergeFrom on a parent message could have caused extra messages to be // added in the underlying protobuf so add them to our list. They can never // be removed in such a way so there's no need to worry about that. - Py_ssize_t message_length = Length(self); + Py_ssize_t message_length = Length(reinterpret_cast<PyObject*>(self)); Py_ssize_t child_length = PyList_GET_SIZE(self->child_messages); Message* message = self->message; const Reflection* reflection = message->GetReflection(); @@ -191,6 +191,10 @@ PyObject* Add(RepeatedCompositeContainer* self, return AddToAttached(self, args, kwargs); } +static PyObject* AddMethod(PyObject* self, PyObject* args, PyObject* kwargs) { + return Add(reinterpret_cast<RepeatedCompositeContainer*>(self), args, kwargs); +} + // --------------------------------------------------------------------- // extend() @@ -226,6 +230,10 @@ PyObject* Extend(RepeatedCompositeContainer* self, PyObject* value) { Py_RETURN_NONE; } +static PyObject* ExtendMethod(PyObject* self, PyObject* value) { + return Extend(reinterpret_cast<RepeatedCompositeContainer*>(self), value); +} + PyObject* MergeFrom(RepeatedCompositeContainer* self, PyObject* other) { if (UpdateChildMessages(self) < 0) { return NULL; @@ -233,6 +241,10 @@ PyObject* MergeFrom(RepeatedCompositeContainer* self, PyObject* other) { return Extend(self, other); } +static PyObject* MergeFromMethod(PyObject* self, PyObject* other) { + return MergeFrom(reinterpret_cast<RepeatedCompositeContainer*>(self), other); +} + PyObject* Subscript(RepeatedCompositeContainer* self, PyObject* slice) { if (UpdateChildMessages(self) < 0) { return NULL; @@ -242,6 +254,10 @@ PyObject* Subscript(RepeatedCompositeContainer* self, PyObject* slice) { return PyObject_GetItem(self->child_messages, slice); } +static PyObject* SubscriptMethod(PyObject* self, PyObject* slice) { + return Subscript(reinterpret_cast<RepeatedCompositeContainer*>(self), slice); +} + int AssignSubscript(RepeatedCompositeContainer* self, PyObject* slice, PyObject* value) { @@ -265,7 +281,7 @@ int AssignSubscript(RepeatedCompositeContainer* self, Py_ssize_t from; Py_ssize_t to; Py_ssize_t step; - Py_ssize_t length = Length(self); + Py_ssize_t length = Length(reinterpret_cast<PyObject*>(self)); Py_ssize_t slicelength; if (PySlice_Check(slice)) { #if PY_MAJOR_VERSION >= 3 @@ -290,7 +306,16 @@ int AssignSubscript(RepeatedCompositeContainer* self, return 0; } -static PyObject* Remove(RepeatedCompositeContainer* self, PyObject* value) { +static int AssignSubscriptMethod(PyObject* self, PyObject* slice, + PyObject* value) { + return AssignSubscript(reinterpret_cast<RepeatedCompositeContainer*>(self), + slice, value); +} + +static PyObject* Remove(PyObject* pself, PyObject* value) { + RepeatedCompositeContainer* self = + reinterpret_cast<RepeatedCompositeContainer*>(pself); + if (UpdateChildMessages(self) < 0) { return NULL; } @@ -305,9 +330,10 @@ static PyObject* Remove(RepeatedCompositeContainer* self, PyObject* value) { Py_RETURN_NONE; } -static PyObject* RichCompare(RepeatedCompositeContainer* self, - PyObject* other, - int opid) { +static PyObject* RichCompare(PyObject* pself, PyObject* other, int opid) { + RepeatedCompositeContainer* self = + reinterpret_cast<RepeatedCompositeContainer*>(pself); + if (UpdateChildMessages(self) < 0) { return NULL; } @@ -340,12 +366,13 @@ static PyObject* RichCompare(RepeatedCompositeContainer* self, } } -static PyObject* ToStr(RepeatedCompositeContainer* self) { +static PyObject* ToStr(PyObject* pself) { ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); if (full_slice == NULL) { return NULL; } - ScopedPyObjectPtr list(Subscript(self, full_slice.get())); + ScopedPyObjectPtr list(Subscript( + reinterpret_cast<RepeatedCompositeContainer*>(pself), full_slice.get())); if (list == NULL) { return NULL; } @@ -359,7 +386,7 @@ static void ReorderAttached(RepeatedCompositeContainer* self) { Message* message = self->message; const Reflection* reflection = message->GetReflection(); const FieldDescriptor* descriptor = self->parent_field_descriptor; - const Py_ssize_t length = Length(self); + const Py_ssize_t length = Length(reinterpret_cast<PyObject*>(self)); // Since Python protobuf objects are never arena-allocated, adding and // removing message pointers to the underlying array is just updating @@ -390,9 +417,10 @@ static int SortPythonMessages(RepeatedCompositeContainer* self, return 0; } -static PyObject* Sort(RepeatedCompositeContainer* self, - PyObject* args, - PyObject* kwds) { +static PyObject* Sort(PyObject* pself, PyObject* args, PyObject* kwds) { + RepeatedCompositeContainer* self = + reinterpret_cast<RepeatedCompositeContainer*>(pself); + // Support the old sort_function argument for backwards // compatibility. if (kwds != NULL) { @@ -416,11 +444,14 @@ static PyObject* Sort(RepeatedCompositeContainer* self, // --------------------------------------------------------------------- -static PyObject* Item(RepeatedCompositeContainer* self, Py_ssize_t index) { +static PyObject* Item(PyObject* pself, Py_ssize_t index) { + RepeatedCompositeContainer* self = + reinterpret_cast<RepeatedCompositeContainer*>(pself); + if (UpdateChildMessages(self) < 0) { return NULL; } - Py_ssize_t length = Length(self); + Py_ssize_t length = Length(pself); if (index < 0) { index = length + index; } @@ -432,17 +463,17 @@ static PyObject* Item(RepeatedCompositeContainer* self, Py_ssize_t index) { return item; } -static PyObject* Pop(RepeatedCompositeContainer* self, - PyObject* args) { +static PyObject* Pop(PyObject* pself, PyObject* args) { + RepeatedCompositeContainer* self = + reinterpret_cast<RepeatedCompositeContainer*>(pself); + Py_ssize_t index = -1; if (!PyArg_ParseTuple(args, "|n", &index)) { return NULL; } - PyObject* item = Item(self, index); + PyObject* item = Item(pself, index); if (item == NULL) { - PyErr_Format(PyExc_IndexError, - "list index (%zd) out of range", - index); + PyErr_Format(PyExc_IndexError, "list index (%zd) out of range", index); return NULL; } ScopedPyObjectPtr py_index(PyLong_FromSsize_t(index)); @@ -460,7 +491,7 @@ void ReleaseLastTo(CMessage* parent, GOOGLE_CHECK_NOTNULL(field); GOOGLE_CHECK_NOTNULL(target); - shared_ptr<Message> released_message( + CMessage::OwnerRef released_message( parent->message->GetReflection()->ReleaseLast(parent->message, field)); // TODO(tibell): Deal with proto1. @@ -503,7 +534,10 @@ int Release(RepeatedCompositeContainer* self) { return 0; } -PyObject* DeepCopy(RepeatedCompositeContainer* self, PyObject* arg) { +PyObject* DeepCopy(PyObject* pself, PyObject* arg) { + RepeatedCompositeContainer* self = + reinterpret_cast<RepeatedCompositeContainer*>(pself); + ScopedPyObjectPtr cloneObj( PyType_GenericAlloc(&RepeatedCompositeContainer_Type, 0)); if (cloneObj == NULL) { @@ -530,7 +564,7 @@ PyObject* DeepCopy(RepeatedCompositeContainer* self, PyObject* arg) { } int SetOwner(RepeatedCompositeContainer* self, - const shared_ptr<Message>& new_owner) { + const CMessage::OwnerRef& new_owner) { GOOGLE_CHECK_ATTACHED(self); self->owner = new_owner; @@ -571,43 +605,46 @@ PyObject *NewContainer( return reinterpret_cast<PyObject*>(self); } -static void Dealloc(RepeatedCompositeContainer* self) { +static void Dealloc(PyObject* pself) { + RepeatedCompositeContainer* self = + reinterpret_cast<RepeatedCompositeContainer*>(pself); + Py_CLEAR(self->child_messages); Py_CLEAR(self->child_message_class); // TODO(tibell): Do we need to call delete on these objects to make // sure their destructors are called? self->owner.reset(); - Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); + Py_TYPE(self)->tp_free(pself); } static PySequenceMethods SqMethods = { - (lenfunc)Length, /* sq_length */ - 0, /* sq_concat */ - 0, /* sq_repeat */ - (ssizeargfunc)Item /* sq_item */ + Length, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + Item /* sq_item */ }; static PyMappingMethods MpMethods = { - (lenfunc)Length, /* mp_length */ - (binaryfunc)Subscript, /* mp_subscript */ - (objobjargproc)AssignSubscript,/* mp_ass_subscript */ + Length, /* mp_length */ + SubscriptMethod, /* mp_subscript */ + AssignSubscriptMethod, /* mp_ass_subscript */ }; static PyMethodDef Methods[] = { - { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS, + { "__deepcopy__", DeepCopy, METH_VARARGS, "Makes a deep copy of the class." }, - { "add", (PyCFunction) Add, METH_VARARGS | METH_KEYWORDS, + { "add", (PyCFunction)AddMethod, METH_VARARGS | METH_KEYWORDS, "Adds an object to the repeated container." }, - { "extend", (PyCFunction) Extend, METH_O, + { "extend", ExtendMethod, METH_O, "Adds objects to the repeated container." }, - { "pop", (PyCFunction)Pop, METH_VARARGS, + { "pop", Pop, METH_VARARGS, "Removes an object from the repeated container and returns it." }, - { "remove", (PyCFunction) Remove, METH_O, + { "remove", Remove, METH_O, "Removes an object from the repeated container." }, - { "sort", (PyCFunction) Sort, METH_VARARGS | METH_KEYWORDS, + { "sort", (PyCFunction)Sort, METH_VARARGS | METH_KEYWORDS, "Sorts the repeated container." }, - { "MergeFrom", (PyCFunction) MergeFrom, METH_O, + { "MergeFrom", MergeFromMethod, METH_O, "Adds objects to the repeated container." }, { NULL, NULL } }; @@ -619,12 +656,12 @@ PyTypeObject RepeatedCompositeContainer_Type = { FULL_MODULE_NAME ".RepeatedCompositeContainer", // tp_name sizeof(RepeatedCompositeContainer), // tp_basicsize 0, // tp_itemsize - (destructor)repeated_composite_container::Dealloc, // tp_dealloc + repeated_composite_container::Dealloc, // tp_dealloc 0, // tp_print 0, // tp_getattr 0, // tp_setattr 0, // tp_compare - (reprfunc)repeated_composite_container::ToStr, // tp_repr + repeated_composite_container::ToStr, // tp_repr 0, // tp_as_number &repeated_composite_container::SqMethods, // tp_as_sequence &repeated_composite_container::MpMethods, // tp_as_mapping @@ -638,7 +675,7 @@ PyTypeObject RepeatedCompositeContainer_Type = { "A Repeated scalar container", // tp_doc 0, // tp_traverse 0, // tp_clear - (richcmpfunc)repeated_composite_container::RichCompare, // tp_richcompare + repeated_composite_container::RichCompare, // tp_richcompare 0, // tp_weaklistoffset 0, // tp_iter 0, // tp_iternext diff --git a/python/google/protobuf/pyext/repeated_composite_container.h b/python/google/protobuf/pyext/repeated_composite_container.h index a7b56b61..e5e946aa 100644 --- a/python/google/protobuf/pyext/repeated_composite_container.h +++ b/python/google/protobuf/pyext/repeated_composite_container.h @@ -37,27 +37,19 @@ #include <Python.h> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <string> #include <vector> +#include <google/protobuf/pyext/message.h> + namespace google { namespace protobuf { class FieldDescriptor; class Message; -#ifdef _SHARED_PTR_H -using std::shared_ptr; -#else -using internal::shared_ptr; -#endif - namespace python { -struct CMessage; struct CMessageClass; // A RepeatedCompositeContainer can be in one of two states: attached @@ -77,7 +69,7 @@ typedef struct RepeatedCompositeContainer { // proto tree. Every Python RepeatedCompositeContainer holds a // reference to it in order to keep it alive as long as there's a // Python object that references any part of the tree. - shared_ptr<Message> owner; + CMessage::OwnerRef owner; // Weak reference to parent object. May be NULL. Used to make sure // the parent is writable before modifying the @@ -148,11 +140,6 @@ int AssignSubscript(RepeatedCompositeContainer* self, PyObject* slice, PyObject* value); -// Releases the messages in the container to the given message. -// -// Returns 0 on success, -1 on failure. -int ReleaseToMessage(RepeatedCompositeContainer* self, Message* new_message); - // Releases the messages in the container to a new message. // // Returns 0 on success, -1 on failure. @@ -160,7 +147,7 @@ int Release(RepeatedCompositeContainer* self); // Returns 0 on success, -1 on failure. int SetOwner(RepeatedCompositeContainer* self, - const shared_ptr<Message>& new_owner); + const CMessage::OwnerRef& new_owner); // Removes the last element of the repeated message field 'field' on // the Message 'parent', and transfers the ownership of the released diff --git a/python/google/protobuf/pyext/repeated_scalar_container.cc b/python/google/protobuf/pyext/repeated_scalar_container.cc index 5a7832cd..1517e654 100644 --- a/python/google/protobuf/pyext/repeated_scalar_container.cc +++ b/python/google/protobuf/pyext/repeated_scalar_container.cc @@ -34,9 +34,6 @@ #include <google/protobuf/pyext/repeated_scalar_container.h> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/logging.h> @@ -77,15 +74,18 @@ static int InternalAssignRepeatedField( return 0; } -static Py_ssize_t Len(RepeatedScalarContainer* self) { +static Py_ssize_t Len(PyObject* pself) { + RepeatedScalarContainer* self = + reinterpret_cast<RepeatedScalarContainer*>(pself); Message* message = self->message; return message->GetReflection()->FieldSize(*message, self->parent_field_descriptor); } -static int AssignItem(RepeatedScalarContainer* self, - Py_ssize_t index, - PyObject* arg) { +static int AssignItem(PyObject* pself, Py_ssize_t index, PyObject* arg) { + RepeatedScalarContainer* self = + reinterpret_cast<RepeatedScalarContainer*>(pself); + cmessage::AssureWritable(self->parent); Message* message = self->message; const FieldDescriptor* field_descriptor = self->parent_field_descriptor; @@ -188,7 +188,10 @@ static int AssignItem(RepeatedScalarContainer* self, return 0; } -static PyObject* Item(RepeatedScalarContainer* self, Py_ssize_t index) { +static PyObject* Item(PyObject* pself, Py_ssize_t index) { + RepeatedScalarContainer* self = + reinterpret_cast<RepeatedScalarContainer*>(pself); + Message* message = self->message; const FieldDescriptor* field_descriptor = self->parent_field_descriptor; const Reflection* reflection = message->GetReflection(); @@ -256,8 +259,9 @@ static PyObject* Item(RepeatedScalarContainer* self, Py_ssize_t index) { break; } case FieldDescriptor::CPPTYPE_STRING: { - string value = reflection->GetRepeatedString( - *message, field_descriptor, index); + string scratch; + const string& value = reflection->GetRepeatedStringReference( + *message, field_descriptor, index, &scratch); result = ToStringObject(field_descriptor, value); break; } @@ -271,7 +275,10 @@ static PyObject* Item(RepeatedScalarContainer* self, Py_ssize_t index) { return result; } -static PyObject* Subscript(RepeatedScalarContainer* self, PyObject* slice) { +static PyObject* Subscript(PyObject* pself, PyObject* slice) { + RepeatedScalarContainer* self = + reinterpret_cast<RepeatedScalarContainer*>(pself); + Py_ssize_t from; Py_ssize_t to; Py_ssize_t step; @@ -286,14 +293,13 @@ static PyObject* Subscript(RepeatedScalarContainer* self, PyObject* slice) { if (PyLong_Check(slice)) { from = to = PyLong_AsLong(slice); } else if (PySlice_Check(slice)) { - length = Len(self); + length = Len(pself); #if PY_MAJOR_VERSION >= 3 if (PySlice_GetIndicesEx(slice, length, &from, &to, &step, &slicelength) == -1) { #else if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject*>(slice), length, &from, &to, &step, &slicelength) == -1) { - #endif return NULL; } @@ -304,7 +310,7 @@ static PyObject* Subscript(RepeatedScalarContainer* self, PyObject* slice) { } if (!return_list) { - return Item(self, from); + return Item(pself, from); } PyObject* list = PyList_New(0); @@ -319,7 +325,7 @@ static PyObject* Subscript(RepeatedScalarContainer* self, PyObject* slice) { if (index < 0 || index >= length) { break; } - ScopedPyObjectPtr s(Item(self, index)); + ScopedPyObjectPtr s(Item(pself, index)); PyList_Append(list, s.get()); } } else { @@ -330,7 +336,7 @@ static PyObject* Subscript(RepeatedScalarContainer* self, PyObject* slice) { if (index < 0 || index >= length) { break; } - ScopedPyObjectPtr s(Item(self, index)); + ScopedPyObjectPtr s(Item(pself, index)); PyList_Append(list, s.get()); } } @@ -417,9 +423,14 @@ PyObject* Append(RepeatedScalarContainer* self, PyObject* item) { Py_RETURN_NONE; } -static int AssSubscript(RepeatedScalarContainer* self, - PyObject* slice, - PyObject* value) { +static PyObject* AppendMethod(PyObject* self, PyObject* item) { + return Append(reinterpret_cast<RepeatedScalarContainer*>(self), item); +} + +static int AssSubscript(PyObject* pself, PyObject* slice, PyObject* value) { + RepeatedScalarContainer* self = + reinterpret_cast<RepeatedScalarContainer*>(pself); + Py_ssize_t from; Py_ssize_t to; Py_ssize_t step; @@ -435,7 +446,7 @@ static int AssSubscript(RepeatedScalarContainer* self, #if PY_MAJOR_VERSION < 3 if (PyInt_Check(slice)) { from = to = PyInt_AsLong(slice); - } else + } else // NOLINT #endif if (PyLong_Check(slice)) { from = to = PyLong_AsLong(slice); @@ -463,14 +474,14 @@ static int AssSubscript(RepeatedScalarContainer* self, } if (!create_list) { - return AssignItem(self, from, value); + return AssignItem(pself, from, value); } ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); if (full_slice == NULL) { return -1; } - ScopedPyObjectPtr new_list(Subscript(self, full_slice.get())); + ScopedPyObjectPtr new_list(Subscript(pself, full_slice.get())); if (new_list == NULL) { return -1; } @@ -509,14 +520,17 @@ PyObject* Extend(RepeatedScalarContainer* self, PyObject* value) { Py_RETURN_NONE; } -static PyObject* Insert(RepeatedScalarContainer* self, PyObject* args) { +static PyObject* Insert(PyObject* pself, PyObject* args) { + RepeatedScalarContainer* self = + reinterpret_cast<RepeatedScalarContainer*>(pself); + Py_ssize_t index; PyObject* value; if (!PyArg_ParseTuple(args, "lO", &index, &value)) { return NULL; } ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); - ScopedPyObjectPtr new_list(Subscript(self, full_slice.get())); + ScopedPyObjectPtr new_list(Subscript(pself, full_slice.get())); if (PyList_Insert(new_list.get(), index, value) < 0) { return NULL; } @@ -527,10 +541,13 @@ static PyObject* Insert(RepeatedScalarContainer* self, PyObject* args) { Py_RETURN_NONE; } -static PyObject* Remove(RepeatedScalarContainer* self, PyObject* value) { +static PyObject* Remove(PyObject* pself, PyObject* value) { + RepeatedScalarContainer* self = + reinterpret_cast<RepeatedScalarContainer*>(pself); + Py_ssize_t match_index = -1; - for (Py_ssize_t i = 0; i < Len(self); ++i) { - ScopedPyObjectPtr elem(Item(self, i)); + for (Py_ssize_t i = 0; i < Len(pself); ++i) { + ScopedPyObjectPtr elem(Item(pself, i)); if (PyObject_RichCompareBool(elem.get(), value, Py_EQ)) { match_index = i; break; @@ -540,15 +557,20 @@ static PyObject* Remove(RepeatedScalarContainer* self, PyObject* value) { PyErr_SetString(PyExc_ValueError, "remove(x): x not in container"); return NULL; } - if (AssignItem(self, match_index, NULL) < 0) { + if (AssignItem(pself, match_index, NULL) < 0) { return NULL; } Py_RETURN_NONE; } -static PyObject* RichCompare(RepeatedScalarContainer* self, - PyObject* other, - int opid) { +static PyObject* ExtendMethod(PyObject* self, PyObject* value) { + return Extend(reinterpret_cast<RepeatedScalarContainer*>(self), value); +} + +static PyObject* RichCompare(PyObject* pself, PyObject* other, int opid) { + RepeatedScalarContainer* self = + reinterpret_cast<RepeatedScalarContainer*>(pself); + if (opid != Py_EQ && opid != Py_NE) { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; @@ -565,28 +587,25 @@ static PyObject* RichCompare(RepeatedScalarContainer* self, ScopedPyObjectPtr other_list_deleter; if (PyObject_TypeCheck(other, &RepeatedScalarContainer_Type)) { - other_list_deleter.reset(Subscript( - reinterpret_cast<RepeatedScalarContainer*>(other), full_slice.get())); + other_list_deleter.reset(Subscript(other, full_slice.get())); other = other_list_deleter.get(); } - ScopedPyObjectPtr list(Subscript(self, full_slice.get())); + ScopedPyObjectPtr list(Subscript(pself, full_slice.get())); if (list == NULL) { return NULL; } return PyObject_RichCompare(list.get(), other, opid); } -PyObject* Reduce(RepeatedScalarContainer* unused_self) { +PyObject* Reduce(PyObject* unused_self, PyObject* unused_other) { PyErr_Format( PickleError_class, "can't pickle repeated message fields, convert to list first"); return NULL; } -static PyObject* Sort(RepeatedScalarContainer* self, - PyObject* args, - PyObject* kwds) { +static PyObject* Sort(PyObject* pself, PyObject* args, PyObject* kwds) { // Support the old sort_function argument for backwards // compatibility. if (kwds != NULL) { @@ -605,7 +624,7 @@ static PyObject* Sort(RepeatedScalarContainer* self, if (full_slice == NULL) { return NULL; } - ScopedPyObjectPtr list(Subscript(self, full_slice.get())); + ScopedPyObjectPtr list(Subscript(pself, full_slice.get())); if (list == NULL) { return NULL; } @@ -617,38 +636,39 @@ static PyObject* Sort(RepeatedScalarContainer* self, if (res == NULL) { return NULL; } - int ret = InternalAssignRepeatedField(self, list.get()); + int ret = InternalAssignRepeatedField( + reinterpret_cast<RepeatedScalarContainer*>(pself), list.get()); if (ret < 0) { return NULL; } Py_RETURN_NONE; } -static PyObject* Pop(RepeatedScalarContainer* self, - PyObject* args) { +static PyObject* Pop(PyObject* pself, PyObject* args) { Py_ssize_t index = -1; if (!PyArg_ParseTuple(args, "|n", &index)) { return NULL; } - PyObject* item = Item(self, index); + PyObject* item = Item(pself, index); if (item == NULL) { - PyErr_Format(PyExc_IndexError, - "list index (%zd) out of range", - index); + PyErr_Format(PyExc_IndexError, "list index (%zd) out of range", index); return NULL; } - if (AssignItem(self, index, NULL) < 0) { + if (AssignItem(pself, index, NULL) < 0) { return NULL; } return item; } -static PyObject* ToStr(RepeatedScalarContainer* self) { +static PyObject* ToStr(PyObject* pself) { + RepeatedScalarContainer* self = + reinterpret_cast<RepeatedScalarContainer*>(pself); + ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); if (full_slice == NULL) { return NULL; } - ScopedPyObjectPtr list(Subscript(self, full_slice.get())); + ScopedPyObjectPtr list(Subscript(pself, full_slice.get())); if (list == NULL) { return NULL; } @@ -687,7 +707,8 @@ static int InitializeAndCopyToParentContainer( if (full_slice == NULL) { return -1; } - ScopedPyObjectPtr values(Subscript(from, full_slice.get())); + ScopedPyObjectPtr values( + Subscript(reinterpret_cast<PyObject*>(from), full_slice.get())); if (values == NULL) { return -1; } @@ -706,7 +727,10 @@ int Release(RepeatedScalarContainer* self) { return InitializeAndCopyToParentContainer(self, self); } -PyObject* DeepCopy(RepeatedScalarContainer* self, PyObject* arg) { +PyObject* DeepCopy(PyObject* pself, PyObject* arg) { + RepeatedScalarContainer* self = + reinterpret_cast<RepeatedScalarContainer*>(pself); + RepeatedScalarContainer* clone = reinterpret_cast<RepeatedScalarContainer*>( PyType_GenericAlloc(&RepeatedScalarContainer_Type, 0)); if (clone == NULL) { @@ -720,45 +744,47 @@ PyObject* DeepCopy(RepeatedScalarContainer* self, PyObject* arg) { return reinterpret_cast<PyObject*>(clone); } -static void Dealloc(RepeatedScalarContainer* self) { +static void Dealloc(PyObject* pself) { + RepeatedScalarContainer* self = + reinterpret_cast<RepeatedScalarContainer*>(pself); self->owner.reset(); - Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); + Py_TYPE(self)->tp_free(pself); } void SetOwner(RepeatedScalarContainer* self, - const shared_ptr<Message>& new_owner) { + const CMessage::OwnerRef& new_owner) { self->owner = new_owner; } static PySequenceMethods SqMethods = { - (lenfunc)Len, /* sq_length */ - 0, /* sq_concat */ - 0, /* sq_repeat */ - (ssizeargfunc)Item, /* sq_item */ - 0, /* sq_slice */ - (ssizeobjargproc)AssignItem /* sq_ass_item */ + Len, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + Item, /* sq_item */ + 0, /* sq_slice */ + AssignItem /* sq_ass_item */ }; static PyMappingMethods MpMethods = { - (lenfunc)Len, /* mp_length */ - (binaryfunc)Subscript, /* mp_subscript */ - (objobjargproc)AssSubscript, /* mp_ass_subscript */ + Len, /* mp_length */ + Subscript, /* mp_subscript */ + AssSubscript, /* mp_ass_subscript */ }; static PyMethodDef Methods[] = { - { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS, + { "__deepcopy__", DeepCopy, METH_VARARGS, "Makes a deep copy of the class." }, - { "__reduce__", (PyCFunction)Reduce, METH_NOARGS, + { "__reduce__", Reduce, METH_NOARGS, "Outputs picklable representation of the repeated field." }, - { "append", (PyCFunction)Append, METH_O, + { "append", AppendMethod, METH_O, "Appends an object to the repeated container." }, - { "extend", (PyCFunction)Extend, METH_O, - "Appends objects to the repeated container." }, - { "insert", (PyCFunction)Insert, METH_VARARGS, + { "extend", ExtendMethod, METH_O, "Appends objects to the repeated container." }, - { "pop", (PyCFunction)Pop, METH_VARARGS, + { "insert", Insert, METH_VARARGS, + "Inserts an object at the specified position in the container." }, + { "pop", Pop, METH_VARARGS, "Removes an object from the repeated container and returns it." }, - { "remove", (PyCFunction)Remove, METH_O, + { "remove", Remove, METH_O, "Removes an object from the repeated container." }, { "sort", (PyCFunction)Sort, METH_VARARGS | METH_KEYWORDS, "Sorts the repeated container."}, @@ -772,12 +798,12 @@ PyTypeObject RepeatedScalarContainer_Type = { FULL_MODULE_NAME ".RepeatedScalarContainer", // tp_name sizeof(RepeatedScalarContainer), // tp_basicsize 0, // tp_itemsize - (destructor)repeated_scalar_container::Dealloc, // tp_dealloc + repeated_scalar_container::Dealloc, // tp_dealloc 0, // tp_print 0, // tp_getattr 0, // tp_setattr 0, // tp_compare - (reprfunc)repeated_scalar_container::ToStr, // tp_repr + repeated_scalar_container::ToStr, // tp_repr 0, // tp_as_number &repeated_scalar_container::SqMethods, // tp_as_sequence &repeated_scalar_container::MpMethods, // tp_as_mapping @@ -791,7 +817,7 @@ PyTypeObject RepeatedScalarContainer_Type = { "A Repeated scalar container", // tp_doc 0, // tp_traverse 0, // tp_clear - (richcmpfunc)repeated_scalar_container::RichCompare, // tp_richcompare + repeated_scalar_container::RichCompare, // tp_richcompare 0, // tp_weaklistoffset 0, // tp_iter 0, // tp_iternext diff --git a/python/google/protobuf/pyext/repeated_scalar_container.h b/python/google/protobuf/pyext/repeated_scalar_container.h index 555e621c..559dec98 100644 --- a/python/google/protobuf/pyext/repeated_scalar_container.h +++ b/python/google/protobuf/pyext/repeated_scalar_container.h @@ -37,27 +37,14 @@ #include <Python.h> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <google/protobuf/descriptor.h> +#include <google/protobuf/pyext/message.h> namespace google { namespace protobuf { - -class Message; - -#ifdef _SHARED_PTR_H -using std::shared_ptr; -#else -using internal::shared_ptr; -#endif - namespace python { -struct CMessage; - typedef struct RepeatedScalarContainer { PyObject_HEAD; @@ -65,7 +52,7 @@ typedef struct RepeatedScalarContainer { // proto tree. Every Python RepeatedScalarContainer holds a // reference to it in order to keep it alive as long as there's a // Python object that references any part of the tree. - shared_ptr<Message> owner; + CMessage::OwnerRef owner; // Pointer to the C++ Message that contains this container. The // RepeatedScalarContainer does not own this pointer. @@ -112,7 +99,7 @@ PyObject* Extend(RepeatedScalarContainer* self, PyObject* value); // Set the owner field of self and any children of self. void SetOwner(RepeatedScalarContainer* self, - const shared_ptr<Message>& new_owner); + const CMessage::OwnerRef& new_owner); } // namespace repeated_scalar_container } // namespace python |