From dc55479efe30402c345f696cad443774e2130d62 Mon Sep 17 00:00:00 2001
From: Mohamed Koubaa <koubaa.m@gmail.com>
Date: Mon, 10 Aug 2020 19:15:07 -0500
Subject: [PATCH 1/4] port signalmodule to multi-phase

---
 Modules/signalmodule.c | 159 +++++++++++++++++++++--------------------
 1 file changed, 80 insertions(+), 79 deletions(-)

diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index 7bc1b535e6e2ca..294d95920fd8a4 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -1365,33 +1365,16 @@ ITIMER_PROF -- decrements both when the process is executing and\n\
 A signal handler function is called with two arguments:\n\
 the first is the signal number, the second is the interrupted stack frame.");
 
-static struct PyModuleDef signalmodule = {
-    PyModuleDef_HEAD_INIT,
-    "_signal",
-    module_doc,
-    -1,
-    signal_methods,
-    NULL,
-    NULL,
-    NULL,
-    NULL
-};
-
-PyMODINIT_FUNC
-PyInit__signal(void)
-{
-    PyObject *m, *d;
-    int i;
 
-    /* Create the module and add the functions */
-    m = PyModule_Create(&signalmodule);
-    if (m == NULL)
-        return NULL;
 
+static int
+signal_exec(PyObject *m)
+{
+    /* add the functions */
 #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
     if (!initialized) {
         if (PyStructSequence_InitType2(&SiginfoType, &struct_siginfo_desc) < 0)
-            return NULL;
+            return -1;
     }
     Py_INCREF((PyObject*) &SiginfoType);
     PyModule_AddObject(m, "struct_siginfo", (PyObject*) &SiginfoType);
@@ -1399,43 +1382,43 @@ PyInit__signal(void)
 #endif
 
     /* Add some symbolic constants to the module */
-    d = PyModule_GetDict(m);
+    PyObject *d = PyModule_GetDict(m);
 
     DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL);
     if (!DefaultHandler ||
         PyDict_SetItemString(d, "SIG_DFL", DefaultHandler) < 0) {
-        goto finally;
+        return -1;
     }
 
     IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN);
     if (!IgnoreHandler ||
         PyDict_SetItemString(d, "SIG_IGN", IgnoreHandler) < 0) {
-        goto finally;
+        return -1;
     }
 
     if (PyModule_AddIntMacro(m, NSIG))
-        goto finally;
+        return -1;
 
 #ifdef SIG_BLOCK
     if (PyModule_AddIntMacro(m, SIG_BLOCK))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIG_UNBLOCK
     if (PyModule_AddIntMacro(m, SIG_UNBLOCK))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIG_SETMASK
     if (PyModule_AddIntMacro(m, SIG_SETMASK))
-         goto finally;
+         return -1;
 #endif
 
     IntHandler = PyDict_GetItemString(d, "default_int_handler");
     if (!IntHandler)
-        goto finally;
+        return -1;
     Py_INCREF(IntHandler);
 
     _Py_atomic_store_relaxed(&Handlers[0].tripped, 0);
-    for (i = 1; i < NSIG; i++) {
+    for (int i = 1; i < NSIG; i++) {
         void (*t)(int);
         t = PyOS_getsig(i);
         _Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
@@ -1456,168 +1439,168 @@ PyInit__signal(void)
 
 #ifdef SIGHUP
     if (PyModule_AddIntMacro(m, SIGHUP))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGINT
     if (PyModule_AddIntMacro(m, SIGINT))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGBREAK
     if (PyModule_AddIntMacro(m, SIGBREAK))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGQUIT
     if (PyModule_AddIntMacro(m, SIGQUIT))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGILL
     if (PyModule_AddIntMacro(m, SIGILL))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGTRAP
     if (PyModule_AddIntMacro(m, SIGTRAP))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGIOT
     if (PyModule_AddIntMacro(m, SIGIOT))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGABRT
     if (PyModule_AddIntMacro(m, SIGABRT))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGEMT
     if (PyModule_AddIntMacro(m, SIGEMT))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGFPE
     if (PyModule_AddIntMacro(m, SIGFPE))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGKILL
     if (PyModule_AddIntMacro(m, SIGKILL))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGBUS
     if (PyModule_AddIntMacro(m, SIGBUS))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGSEGV
     if (PyModule_AddIntMacro(m, SIGSEGV))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGSYS
     if (PyModule_AddIntMacro(m, SIGSYS))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGPIPE
     if (PyModule_AddIntMacro(m, SIGPIPE))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGALRM
     if (PyModule_AddIntMacro(m, SIGALRM))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGTERM
     if (PyModule_AddIntMacro(m, SIGTERM))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGUSR1
     if (PyModule_AddIntMacro(m, SIGUSR1))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGUSR2
     if (PyModule_AddIntMacro(m, SIGUSR2))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGCLD
     if (PyModule_AddIntMacro(m, SIGCLD))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGCHLD
     if (PyModule_AddIntMacro(m, SIGCHLD))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGPWR
     if (PyModule_AddIntMacro(m, SIGPWR))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGIO
     if (PyModule_AddIntMacro(m, SIGIO))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGURG
     if (PyModule_AddIntMacro(m, SIGURG))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGWINCH
     if (PyModule_AddIntMacro(m, SIGWINCH))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGPOLL
     if (PyModule_AddIntMacro(m, SIGPOLL))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGSTOP
     if (PyModule_AddIntMacro(m, SIGSTOP))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGTSTP
     if (PyModule_AddIntMacro(m, SIGTSTP))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGCONT
     if (PyModule_AddIntMacro(m, SIGCONT))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGTTIN
     if (PyModule_AddIntMacro(m, SIGTTIN))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGTTOU
     if (PyModule_AddIntMacro(m, SIGTTOU))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGVTALRM
     if (PyModule_AddIntMacro(m, SIGVTALRM))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGPROF
     if (PyModule_AddIntMacro(m, SIGPROF))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGXCPU
     if (PyModule_AddIntMacro(m, SIGXCPU))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGXFSZ
     if (PyModule_AddIntMacro(m, SIGXFSZ))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGRTMIN
     if (PyModule_AddIntMacro(m, SIGRTMIN))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGRTMAX
     if (PyModule_AddIntMacro(m, SIGRTMAX))
-         goto finally;
+         return -1;
 #endif
 #ifdef SIGINFO
     if (PyModule_AddIntMacro(m, SIGINFO))
-         goto finally;
+         return -1;
 #endif
 
 #ifdef ITIMER_REAL
     if (PyModule_AddIntMacro(m, ITIMER_REAL))
-         goto finally;
+         return -1;
 #endif
 #ifdef ITIMER_VIRTUAL
     if (PyModule_AddIntMacro(m, ITIMER_VIRTUAL))
-         goto finally;
+         return -1;
 #endif
 #ifdef ITIMER_PROF
     if (PyModule_AddIntMacro(m, ITIMER_PROF))
-         goto finally;
+         return -1;
 #endif
 
 #if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER)
@@ -1625,18 +1608,18 @@ PyInit__signal(void)
             PyExc_OSError, NULL);
     if (!ItimerError ||
         PyDict_SetItemString(d, "ItimerError", ItimerError) < 0) {
-        goto finally;
+        return -1;
     }
 #endif
 
 #ifdef CTRL_C_EVENT
     if (PyModule_AddIntMacro(m, CTRL_C_EVENT))
-         goto finally;
+         return -1;
 #endif
 
 #ifdef CTRL_BREAK_EVENT
     if (PyModule_AddIntMacro(m, CTRL_BREAK_EVENT))
-         goto finally;
+         return -1;
 #endif
 
 #ifdef MS_WINDOWS
@@ -1645,12 +1628,30 @@ PyInit__signal(void)
 #endif
 
     if (PyErr_Occurred()) {
-        Py_DECREF(m);
-        m = NULL;
+        return -1;
     }
 
-  finally:
-    return m;
+  return 0;
+}
+
+static PyModuleDef_Slot signal_slots[] = {
+    {Py_mod_exec, signal_exec},
+    {0, NULL}
+};
+
+static struct PyModuleDef signalmodule = {
+    PyModuleDef_HEAD_INIT,
+    "_signal",
+    .m_doc = module_doc,
+    .m_size = 0,
+    .m_methods = signal_methods,
+    .m_slots = signal_slots
+};
+
+PyMODINIT_FUNC
+PyInit__signal(void)
+{
+    return PyModuleDef_Init(&signalmodule);
 }
 
 static void

From c85ad8f5c93db740bdcc1156dffbdaaada9ad33f Mon Sep 17 00:00:00 2001
From: Mohamed Koubaa <koubaa.m@gmail.com>
Date: Tue, 1 Sep 2020 17:07:24 -0500
Subject: [PATCH 2/4] blurb

---
 .../2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst                  | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst

diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst
new file mode 100644
index 00000000000000..cbf0460525a821
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst	
@@ -0,0 +1,2 @@
+Port the :mod:`signalmodule` extension module to multi-phase initialization
+(:pep:`489`).

From 78b7f2c5cedd708fbaafc71b1e8d4f924a478b89 Mon Sep 17 00:00:00 2001
From: Mohamed Koubaa <koubaa.m@gmail.com>
Date: Wed, 2 Sep 2020 18:24:02 -0500
Subject: [PATCH 3/4] improvements

---
 .../2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst           | 3 +--
 Modules/signalmodule.c                                   | 9 ++++++---
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst
index cbf0460525a821..ff7cb352869a22 100644
--- a/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst	
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-01-17-07-20.bpo-1635741.7wSuCc.rst	
@@ -1,2 +1 @@
-Port the :mod:`signalmodule` extension module to multi-phase initialization
-(:pep:`489`).
+Port the :mod:`_signal` extension module to multi-phase initialization (:pep:`489`).
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index 294d95920fd8a4..da7304bd593367 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -1373,11 +1373,14 @@ signal_exec(PyObject *m)
     /* add the functions */
 #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
     if (!initialized) {
-        if (PyStructSequence_InitType2(&SiginfoType, &struct_siginfo_desc) < 0)
+        if (PyStructSequence_InitType2(&SiginfoType, &struct_siginfo_desc) < 0) {
             return -1;
+        }
+    }
+
+    if (PyModule_AddType(m, "struct_siginfo", &SiginfoType) < 0) {
+        return -1;
     }
-    Py_INCREF((PyObject*) &SiginfoType);
-    PyModule_AddObject(m, "struct_siginfo", (PyObject*) &SiginfoType);
     initialized = 1;
 #endif
 

From 748371d1469627551592e8cf817f094e6b5247b5 Mon Sep 17 00:00:00 2001
From: Mohamed Koubaa <koubaa.m@gmail.com>
Date: Wed, 2 Sep 2020 18:39:11 -0500
Subject: [PATCH 4/4] fix syntax issue

---
 Modules/signalmodule.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index da7304bd593367..2a7e5c6d692277 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -1378,7 +1378,7 @@ signal_exec(PyObject *m)
         }
     }
 
-    if (PyModule_AddType(m, "struct_siginfo", &SiginfoType) < 0) {
+    if (PyModule_AddType(m, &SiginfoType) < 0) {
         return -1;
     }
     initialized = 1;