From e1abdf2c762cdddfbbd2c916cbc663914e858a01 Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Tue, 22 Dec 2015 11:13:03 -0800 Subject: [PATCH] Fixed compile for Python 3. There are still some crashes though. --- python/google/protobuf/pyext/map_container.cc | 229 +++++++++++------- python/google/protobuf/pyext/map_container.h | 12 +- python/setup.py | 2 +- 3 files changed, 152 insertions(+), 91 deletions(-) diff --git a/python/google/protobuf/pyext/map_container.cc b/python/google/protobuf/pyext/map_container.cc index c39f7b8395..516662ee00 100644 --- a/python/google/protobuf/pyext/map_container.cc +++ b/python/google/protobuf/pyext/map_container.cc @@ -395,7 +395,12 @@ PyObject *NewScalarMapContainer( return NULL; } +#if PY_MAJOR_VERSION >= 3 + ScopedPyObjectPtr obj(PyType_GenericAlloc( + reinterpret_cast(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."); @@ -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." }, @@ -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 ////////////////////////////////////////////////////////////////// @@ -613,7 +639,12 @@ PyObject* NewMessageMapContainer( return NULL; } +#if PY_MAJOR_VERSION >= 3 + PyObject* obj = PyType_GenericAlloc( + reinterpret_cast(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."); @@ -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."}, @@ -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 ///////////////////////////////////////////////////////////////// diff --git a/python/google/protobuf/pyext/map_container.h b/python/google/protobuf/pyext/map_container.h index 2de611875d..ddf94be71b 100644 --- a/python/google/protobuf/pyext/map_container.h +++ b/python/google/protobuf/pyext/map_container.h @@ -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 diff --git a/python/setup.py b/python/setup.py index 2a5513b717..1223775ce5 100755 --- a/python/setup.py +++ b/python/setup.py @@ -162,7 +162,7 @@ if __name__ == '__main__': 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: