From 7a6dea106164537af8e96a32e3bede90c33f613d Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Wed, 18 Nov 2020 20:11:49 +0100 Subject: [PATCH 1/2] bpo-1635741: Port _queue to multiphase initialization Signed-off-by: Christian Heimes --- ...2020-11-18-20-11-13.bpo-1635741.fe3iRb.rst | 1 + Modules/_queuemodule.c | 75 ++++++++++--------- 2 files changed, 39 insertions(+), 37 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2020-11-18-20-11-13.bpo-1635741.fe3iRb.rst diff --git a/Misc/NEWS.d/next/C API/2020-11-18-20-11-13.bpo-1635741.fe3iRb.rst b/Misc/NEWS.d/next/C API/2020-11-18-20-11-13.bpo-1635741.fe3iRb.rst new file mode 100644 index 00000000000000..78df4fe0432266 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-11-18-20-11-13.bpo-1635741.fe3iRb.rst @@ -0,0 +1 @@ +Port _queue extension module to multiphase initialization (:pep:`489`) diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index 7cf73992795c6b..39a68eb4310c8b 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -381,55 +381,56 @@ PyDoc_STRVAR(queue_module_doc, "C implementation of the Python queue module.\n\ This module is an implementation detail, please do not use it directly."); -static struct PyModuleDef queuemodule = { - .m_base = PyModuleDef_HEAD_INIT, - .m_name = "_queue", - .m_doc = queue_module_doc, - .m_size = sizeof(simplequeue_state), - .m_traverse = queue_traverse, - .m_clear = queue_clear, - .m_free = queue_free, -}; - - -PyMODINIT_FUNC -PyInit__queue(void) +static int +queuemodule_exec(PyObject *module) { - PyObject *m; - simplequeue_state *state; - - /* Create the module */ - m = PyModule_Create(&queuemodule); - if (m == NULL) - return NULL; - - state = simplequeue_get_state(m); + simplequeue_state *state = simplequeue_get_state(module); state->EmptyError = PyErr_NewExceptionWithDoc( "_queue.Empty", "Exception raised by Queue.get(block=0)/get_nowait().", NULL, NULL); - if (state->EmptyError == NULL) - goto error; + if (state->EmptyError == NULL) { + return -1; + } Py_INCREF(state->EmptyError); - if (PyModule_AddObject(m, "Empty", state->EmptyError) < 0) { - Py_DECREF(state->EmptyError); - goto error; + if (PyModule_AddObject(module, "Empty", state->EmptyError) < 0) { + Py_CLEAR(state->EmptyError); + return -1; } - state->SimpleQueueType = (PyTypeObject *)PyType_FromModuleAndSpec(m, - &simplequeue_spec, - NULL); + state->SimpleQueueType = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &simplequeue_spec, NULL); if (state->SimpleQueueType == NULL) { - goto error; + return -1; } - if (PyModule_AddType(m, state->SimpleQueueType) < 0) { - goto error; + if (PyModule_AddType(module, state->SimpleQueueType) < 0) { + return -1; } - return m; + return 0; +} + +static PyModuleDef_Slot queuemodule_slots[] = { + {Py_mod_exec, queuemodule_exec}, + {0, NULL} +}; + + +static struct PyModuleDef queuemodule = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "_queue", + .m_doc = queue_module_doc, + .m_size = sizeof(simplequeue_state), + .m_slots = queuemodule_slots, + .m_traverse = queue_traverse, + .m_clear = queue_clear, + .m_free = queue_free, +}; -error: - Py_DECREF(m); - return NULL; + +PyMODINIT_FUNC +PyInit__queue(void) +{ + return PyModuleDef_Init(&queuemodule); } From c620a616514eb37bc46a6f5829d6a7bef9391e6c Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Thu, 19 Nov 2020 08:51:21 +0100 Subject: [PATCH 2/2] Use PyModule_AddObjectRef --- Modules/_queuemodule.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index 39a68eb4310c8b..a2b6ac87a72ebf 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -385,6 +385,7 @@ static int queuemodule_exec(PyObject *module) { simplequeue_state *state = simplequeue_get_state(module); + state->EmptyError = PyErr_NewExceptionWithDoc( "_queue.Empty", "Exception raised by Queue.get(block=0)/get_nowait().", @@ -392,10 +393,7 @@ queuemodule_exec(PyObject *module) if (state->EmptyError == NULL) { return -1; } - - Py_INCREF(state->EmptyError); - if (PyModule_AddObject(module, "Empty", state->EmptyError) < 0) { - Py_CLEAR(state->EmptyError); + if (PyModule_AddObjectRef(module, "Empty", state->EmptyError) < 0) { return -1; }