]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-41713: Port _signal module to multi-phase init (GH-23355)
authorVictor Stinner <vstinner@python.org>
Tue, 17 Nov 2020 22:28:25 +0000 (23:28 +0100)
committerGitHub <noreply@github.com>
Tue, 17 Nov 2020 22:28:25 +0000 (23:28 +0100)
Port the _signal extension module to the multi-phase initialization
API (PEP 489).

Co-Authored-By: Mohamed Koubaa <koubaa.m@gmail.com>
Misc/NEWS.d/next/Library/2020-11-17-23-00-27.bpo-41713.-Us0tf.rst [new file with mode: 0644]
Modules/signalmodule.c

diff --git a/Misc/NEWS.d/next/Library/2020-11-17-23-00-27.bpo-41713.-Us0tf.rst b/Misc/NEWS.d/next/Library/2020-11-17-23-00-27.bpo-41713.-Us0tf.rst
new file mode 100644 (file)
index 0000000..4b297d9
--- /dev/null
@@ -0,0 +1,2 @@
+Port the ``_signal`` extension module to the multi-phase initialization API
+(:pep:`489`). Patch by Victor Stinner and Mohamed Koubaa.
index acaaafe89d1242cda2ac082d52cba8ee5d92342e..fcc8f1cbda227ed0ab92a4d0b80f982809becf36 100644 (file)
@@ -1538,7 +1538,7 @@ signal_add_constants(PyObject *module)
 
 
 static int
-signal_exec(PyObject *m)
+signal_module_exec(PyObject *m)
 {
     assert(!PyErr_Occurred());
 
@@ -1568,15 +1568,19 @@ signal_exec(PyObject *m)
     // Get signal handlers
     for (int signum = 1; signum < NSIG; signum++) {
         void (*c_handler)(int) = PyOS_getsig(signum);
+        PyObject *func;
         if (c_handler == SIG_DFL) {
-            Handlers[signum].func = Py_NewRef(DefaultHandler);
+            func = DefaultHandler;
         }
         else if (c_handler == SIG_IGN) {
-            Handlers[signum].func = Py_NewRef(IgnoreHandler);
+            func = IgnoreHandler;
         }
         else {
-            Handlers[signum].func = Py_NewRef(Py_None); // None of our business
+            func = Py_None; // None of our business
         }
+        // If signal_module_exec() is called more than one, we must
+        // clear the strong reference to the previous function.
+        Py_XSETREF(Handlers[signum].func, Py_NewRef(func));
     }
 
     // Instal Python SIGINT handler which raises KeyboardInterrupt
@@ -1595,28 +1599,25 @@ signal_exec(PyObject *m)
 }
 
 
-static struct PyModuleDef signalmodule = {
+static PyModuleDef_Slot signal_slots[] = {
+    {Py_mod_exec, signal_module_exec},
+    {0, NULL}
+};
+
+static struct PyModuleDef signal_module = {
     PyModuleDef_HEAD_INIT,
     "_signal",
     .m_doc = module_doc,
-    .m_size = -1,
+    .m_size = 0,
     .m_methods = signal_methods,
+    .m_slots = signal_slots,
 };
 
 
 PyMODINIT_FUNC
 PyInit__signal(void)
 {
-    PyObject *mod = PyModule_Create(&signalmodule);
-    if (mod == NULL) {
-        return NULL;
-    }
-
-    if (signal_exec(mod) < 0) {
-        Py_DECREF(mod);
-        return NULL;
-    }
-    return mod;
+    return PyModuleDef_Init(&signal_module);
 }