aboutsummaryrefslogtreecommitdiffhomepage
path: root/python/google/protobuf/pyext
diff options
context:
space:
mode:
authorGravatar Adam Cozzette <acozzette@google.com>2018-03-13 16:37:29 -0700
committerGravatar Adam Cozzette <acozzette@google.com>2018-03-13 16:37:29 -0700
commit0400cca3236de1ca303af38bf81eab332d042b7c (patch)
treea8a9b19853f64567c96750a1c7d253926471daa5 /python/google/protobuf/pyext
parent96b535cc2f4f7b7e22a1b8622149f7c26a5a3f63 (diff)
Integrated internal changes from Google
Diffstat (limited to 'python/google/protobuf/pyext')
-rw-r--r--python/google/protobuf/pyext/descriptor.cc80
-rw-r--r--python/google/protobuf/pyext/descriptor_pool.cc122
-rw-r--r--python/google/protobuf/pyext/extension_dict.cc3
-rw-r--r--python/google/protobuf/pyext/extension_dict.h15
-rw-r--r--python/google/protobuf/pyext/map_container.cc29
-rw-r--r--python/google/protobuf/pyext/map_container.h17
-rw-r--r--python/google/protobuf/pyext/message.cc29
-rw-r--r--python/google/protobuf/pyext/message.h24
-rw-r--r--python/google/protobuf/pyext/message_factory.cc8
-rw-r--r--python/google/protobuf/pyext/repeated_composite_container.cc129
-rw-r--r--python/google/protobuf/pyext/repeated_composite_container.h21
-rw-r--r--python/google/protobuf/pyext/repeated_scalar_container.cc174
-rw-r--r--python/google/protobuf/pyext/repeated_scalar_container.h19
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