Skip to content

Commit

Permalink
Fixed compile for Python 3. There are still some crashes though.
Browse files Browse the repository at this point in the history
  • Loading branch information
haberman committed Dec 31, 2015
1 parent d5fb408 commit e1abdf2
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 91 deletions.
229 changes: 141 additions & 88 deletions python/google/protobuf/pyext/map_container.cc
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,12 @@ PyObject *NewScalarMapContainer(
return NULL;
}

#if PY_MAJOR_VERSION >= 3
ScopedPyObjectPtr obj(PyType_GenericAlloc(
reinterpret_cast<PyTypeObject *>(ScalarMapContainer_Type), 0));
#else
ScopedPyObjectPtr obj(PyType_GenericAlloc(&ScalarMapContainer_Type, 0));
#endif
if (obj.get() == NULL) {
return PyErr_Format(PyExc_RuntimeError,
"Could not allocate new container.");
Expand Down Expand Up @@ -510,12 +515,6 @@ static void ScalarMapDealloc(PyObject* _self) {
Py_TYPE(_self)->tp_free(_self);
}

static PyMappingMethods ScalarMapMappingMethods = {
MapReflectionFriend::Length, // mp_length
MapReflectionFriend::ScalarMapGetItem, // mp_subscript
MapReflectionFriend::ScalarMapSetItem, // mp_ass_subscript
};

static PyMethodDef ScalarMapMethods[] = {
{ "__contains__", MapReflectionFriend::Contains, METH_O,
"Tests whether a key is a member of the map." },
Expand All @@ -532,44 +531,71 @@ static PyMethodDef ScalarMapMethods[] = {
{NULL, NULL},
};

PyTypeObject ScalarMapContainer_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
FULL_MODULE_NAME ".ScalarMapContainer", // tp_name
sizeof(MapContainer), // tp_basicsize
0, // tp_itemsize
ScalarMapDealloc, // tp_dealloc
0, // tp_print
0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
&ScalarMapMappingMethods, // tp_as_mapping
0, // tp_hash
0, // tp_call
0, // tp_str
0, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT, // tp_flags
"A scalar map container", // tp_doc
0, // tp_traverse
0, // tp_clear
0, // tp_richcompare
0, // tp_weaklistoffset
MapReflectionFriend::GetIterator, // tp_iter
0, // tp_iternext
ScalarMapMethods, // tp_methods
0, // tp_members
0, // tp_getset
0, // tp_base
0, // tp_dict
0, // tp_descr_get
0, // tp_descr_set
0, // tp_dictoffset
0, // tp_init
};
#if PY_MAJOR_VERSION >= 3
static PyType_Slot ScalarMapContainer_Type_slots[] = {
{Py_tp_dealloc, (void *)ScalarMapDealloc},
{Py_mp_length, (void *)MapReflectionFriend::Length},
{Py_mp_subscript, (void *)MapReflectionFriend::ScalarMapGetItem},
{Py_mp_ass_subscript, (void *)MapReflectionFriend::ScalarMapSetItem},
{Py_tp_methods, (void *)ScalarMapMethods},
{Py_tp_iter, (void *)MapReflectionFriend::GetIterator},
{0, 0},
};

PyType_Spec ScalarMapContainer_Type_spec = {
FULL_MODULE_NAME ".ScalarMapContainer",
sizeof(MapContainer),
0,
Py_TPFLAGS_DEFAULT,
ScalarMapContainer_Type_slots
};
PyObject *ScalarMapContainer_Type;
#else
static PyMappingMethods ScalarMapMappingMethods = {
MapReflectionFriend::Length, // mp_length
MapReflectionFriend::ScalarMapGetItem, // mp_subscript
MapReflectionFriend::ScalarMapSetItem, // mp_ass_subscript
};

PyTypeObject ScalarMapContainer_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
FULL_MODULE_NAME ".ScalarMapContainer", // tp_name
sizeof(MapContainer), // tp_basicsize
0, // tp_itemsize
ScalarMapDealloc, // tp_dealloc
0, // tp_print
0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
&ScalarMapMappingMethods, // tp_as_mapping
0, // tp_hash
0, // tp_call
0, // tp_str
0, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT, // tp_flags
"A scalar map container", // tp_doc
0, // tp_traverse
0, // tp_clear
0, // tp_richcompare
0, // tp_weaklistoffset
MapReflectionFriend::GetIterator, // tp_iter
0, // tp_iternext
ScalarMapMethods, // tp_methods
0, // tp_members
0, // tp_getset
0, // tp_base
0, // tp_dict
0, // tp_descr_get
0, // tp_descr_set
0, // tp_dictoffset
0, // tp_init
};
#endif


// MessageMap //////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -613,7 +639,12 @@ PyObject* NewMessageMapContainer(
return NULL;
}

#if PY_MAJOR_VERSION >= 3
PyObject* obj = PyType_GenericAlloc(
reinterpret_cast<PyTypeObject *>(MessageMapContainer_Type), 0);
#else
PyObject* obj = PyType_GenericAlloc(&MessageMapContainer_Type, 0);
#endif
if (obj == NULL) {
return PyErr_Format(PyExc_RuntimeError,
"Could not allocate new container.");
Expand Down Expand Up @@ -735,12 +766,6 @@ static void MessageMapDealloc(PyObject* _self) {
Py_TYPE(_self)->tp_free(_self);
}

static PyMappingMethods MessageMapMappingMethods = {
MapReflectionFriend::Length, // mp_length
MapReflectionFriend::MessageMapGetItem, // mp_subscript
MapReflectionFriend::MessageMapSetItem, // mp_ass_subscript
};

static PyMethodDef MessageMapMethods[] = {
{ "__contains__", (PyCFunction)MapReflectionFriend::Contains, METH_O,
"Tests whether the map contains this element."},
Expand All @@ -759,44 +784,72 @@ static PyMethodDef MessageMapMethods[] = {
{NULL, NULL},
};

PyTypeObject MessageMapContainer_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
FULL_MODULE_NAME ".MessageMapContainer", // tp_name
sizeof(MessageMapContainer), // tp_basicsize
0, // tp_itemsize
MessageMapDealloc, // tp_dealloc
0, // tp_print
0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
&MessageMapMappingMethods, // tp_as_mapping
0, // tp_hash
0, // tp_call
0, // tp_str
0, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT, // tp_flags
"A map container for message", // tp_doc
0, // tp_traverse
0, // tp_clear
0, // tp_richcompare
0, // tp_weaklistoffset
MapReflectionFriend::GetIterator, // tp_iter
0, // tp_iternext
MessageMapMethods, // tp_methods
0, // tp_members
0, // tp_getset
0, // tp_base
0, // tp_dict
0, // tp_descr_get
0, // tp_descr_set
0, // tp_dictoffset
0, // tp_init
};
#if PY_MAJOR_VERSION >= 3
static PyType_Slot MessageMapContainer_Type_slots[] = {
{Py_tp_dealloc, (void *)MessageMapDealloc},
{Py_mp_length, (void *)MapReflectionFriend::Length},
{Py_mp_subscript, (void *)MapReflectionFriend::MessageMapGetItem},
{Py_mp_ass_subscript, (void *)MapReflectionFriend::MessageMapSetItem},
{Py_tp_methods, (void *)MessageMapMethods},
{Py_tp_iter, (void *)MapReflectionFriend::GetIterator},
{0, 0}
};

PyType_Spec MessageMapContainer_Type_spec = {
FULL_MODULE_NAME ".MessageMapContainer",
sizeof(MapContainer),
0,
Py_TPFLAGS_DEFAULT,
MessageMapContainer_Type_slots
};

PyObject *MessageMapContainer_Type;
#else
static PyMappingMethods MessageMapMappingMethods = {
MapReflectionFriend::Length, // mp_length
MapReflectionFriend::MessageMapGetItem, // mp_subscript
MapReflectionFriend::MessageMapSetItem, // mp_ass_subscript
};

PyTypeObject MessageMapContainer_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
FULL_MODULE_NAME ".MessageMapContainer", // tp_name
sizeof(MessageMapContainer), // tp_basicsize
0, // tp_itemsize
MessageMapDealloc, // tp_dealloc
0, // tp_print
0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
&MessageMapMappingMethods, // tp_as_mapping
0, // tp_hash
0, // tp_call
0, // tp_str
0, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT, // tp_flags
"A map container for message", // tp_doc
0, // tp_traverse
0, // tp_clear
0, // tp_richcompare
0, // tp_weaklistoffset
MapReflectionFriend::GetIterator, // tp_iter
0, // tp_iternext
MessageMapMethods, // tp_methods
0, // tp_members
0, // tp_getset
0, // tp_base
0, // tp_dict
0, // tp_descr_get
0, // tp_descr_set
0, // tp_dictoffset
0, // tp_init
};
#endif

// MapIterator /////////////////////////////////////////////////////////////////

Expand Down
12 changes: 10 additions & 2 deletions python/google/protobuf/pyext/map_container.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,16 @@ struct MessageMapContainer : public MapContainer {
PyObject* message_dict;
};

extern PyTypeObject ScalarMapContainer_Type;
extern PyTypeObject MessageMapContainer_Type;
#if PY_MAJOR_VERSION >= 3
extern PyObject *MessageMapContainer_Type;
extern PyType_Spec MessageMapContainer_Type_spec;
extern PyObject *ScalarMapContainer_Type;
extern PyType_Spec ScalarMapContainer_Type_spec;
#else
extern PyTypeObject MessageMapContainer_Type;
extern PyTypeObject ScalarMapContainer_Type;
#endif

extern PyTypeObject MapIterator_Type; // Both map types use the same iterator.

// Builds a MapContainer object, from a parent message and a
Expand Down
2 changes: 1 addition & 1 deletion python/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def run(self):
extra_compile_args = ['-Wno-write-strings', '-Wno-invalid-offsetof']
test_conformance.target = 'test_python_cpp'

if "clang" in os.popen('$CC --version').read():
if "clang" in os.popen('$CC --version 2> /dev/null').read():
extra_compile_args.append('-Wno-shorten-64-to-32')

if warnings_as_errors in sys.argv:
Expand Down

0 comments on commit e1abdf2

Please sign in to comment.