Issue #20182: converted the signal module to use Argument Clinic
diff --git a/Modules/clinic/signalmodule.c.h b/Modules/clinic/signalmodule.c.h
new file mode 100644
index 0000000..30dc745
--- /dev/null
+++ b/Modules/clinic/signalmodule.c.h
@@ -0,0 +1,432 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+#if defined(HAVE_ALARM)
+
+PyDoc_STRVAR(signal_alarm__doc__,
+"alarm($module, seconds, /)\n"
+"--\n"
+"\n"
+"Arrange for SIGALRM to arrive after the given number of seconds.");
+
+#define SIGNAL_ALARM_METHODDEF    \
+    {"alarm", (PyCFunction)signal_alarm, METH_O, signal_alarm__doc__},
+
+static long
+signal_alarm_impl(PyModuleDef *module, int seconds);
+
+static PyObject *
+signal_alarm(PyModuleDef *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    int seconds;
+    long _return_value;
+
+    if (!PyArg_Parse(arg, "i:alarm", &seconds))
+        goto exit;
+    _return_value = signal_alarm_impl(module, seconds);
+    if ((_return_value == -1) && PyErr_Occurred())
+        goto exit;
+    return_value = PyLong_FromLong(_return_value);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(HAVE_ALARM) */
+
+#if defined(HAVE_PAUSE)
+
+PyDoc_STRVAR(signal_pause__doc__,
+"pause($module, /)\n"
+"--\n"
+"\n"
+"Wait until a signal arrives.");
+
+#define SIGNAL_PAUSE_METHODDEF    \
+    {"pause", (PyCFunction)signal_pause, METH_NOARGS, signal_pause__doc__},
+
+static PyObject *
+signal_pause_impl(PyModuleDef *module);
+
+static PyObject *
+signal_pause(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
+{
+    return signal_pause_impl(module);
+}
+
+#endif /* defined(HAVE_PAUSE) */
+
+PyDoc_STRVAR(signal_signal__doc__,
+"signal($module, signalnum, handler, /)\n"
+"--\n"
+"\n"
+"Set the action for the given signal.\n"
+"\n"
+"The action can be SIG_DFL, SIG_IGN, or a callable Python object.\n"
+"The previous action is returned.  See getsignal() for possible return values.\n"
+"\n"
+"*** IMPORTANT NOTICE ***\n"
+"A signal handler function is called with two arguments:\n"
+"the first is the signal number, the second is the interrupted stack frame.");
+
+#define SIGNAL_SIGNAL_METHODDEF    \
+    {"signal", (PyCFunction)signal_signal, METH_VARARGS, signal_signal__doc__},
+
+static PyObject *
+signal_signal_impl(PyModuleDef *module, int signalnum, PyObject *handler);
+
+static PyObject *
+signal_signal(PyModuleDef *module, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    int signalnum;
+    PyObject *handler;
+
+    if (!PyArg_ParseTuple(args, "iO:signal",
+        &signalnum, &handler))
+        goto exit;
+    return_value = signal_signal_impl(module, signalnum, handler);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(signal_getsignal__doc__,
+"getsignal($module, signalnum, /)\n"
+"--\n"
+"\n"
+"Return the current action for the given signal.\n"
+"\n"
+"The return value can be:\n"
+"  SIG_IGN -- if the signal is being ignored\n"
+"  SIG_DFL -- if the default action for the signal is in effect\n"
+"  None    -- if an unknown handler is in effect\n"
+"  anything else -- the callable Python object used as a handler");
+
+#define SIGNAL_GETSIGNAL_METHODDEF    \
+    {"getsignal", (PyCFunction)signal_getsignal, METH_O, signal_getsignal__doc__},
+
+static PyObject *
+signal_getsignal_impl(PyModuleDef *module, int signalnum);
+
+static PyObject *
+signal_getsignal(PyModuleDef *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    int signalnum;
+
+    if (!PyArg_Parse(arg, "i:getsignal", &signalnum))
+        goto exit;
+    return_value = signal_getsignal_impl(module, signalnum);
+
+exit:
+    return return_value;
+}
+
+#if defined(HAVE_SIGINTERRUPT)
+
+PyDoc_STRVAR(signal_siginterrupt__doc__,
+"siginterrupt($module, signalnum, flag, /)\n"
+"--\n"
+"\n"
+"Change system call restart behaviour.\n"
+"\n"
+"If flag is False, system calls will be restarted when interrupted by\n"
+"signal sig, else system calls will be interrupted.");
+
+#define SIGNAL_SIGINTERRUPT_METHODDEF    \
+    {"siginterrupt", (PyCFunction)signal_siginterrupt, METH_VARARGS, signal_siginterrupt__doc__},
+
+static PyObject *
+signal_siginterrupt_impl(PyModuleDef *module, int signalnum, int flag);
+
+static PyObject *
+signal_siginterrupt(PyModuleDef *module, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    int signalnum;
+    int flag;
+
+    if (!PyArg_ParseTuple(args, "ii:siginterrupt",
+        &signalnum, &flag))
+        goto exit;
+    return_value = signal_siginterrupt_impl(module, signalnum, flag);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(HAVE_SIGINTERRUPT) */
+
+#if defined(HAVE_SETITIMER)
+
+PyDoc_STRVAR(signal_setitimer__doc__,
+"setitimer($module, which, seconds, interval=0.0, /)\n"
+"--\n"
+"\n"
+"Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF).\n"
+"\n"
+"The timer will fire after value seconds and after that every interval seconds.\n"
+"The itimer can be cleared by setting seconds to zero.\n"
+"\n"
+"Returns old values as a tuple: (delay, interval).");
+
+#define SIGNAL_SETITIMER_METHODDEF    \
+    {"setitimer", (PyCFunction)signal_setitimer, METH_VARARGS, signal_setitimer__doc__},
+
+static PyObject *
+signal_setitimer_impl(PyModuleDef *module, int which, double seconds,
+                      double interval);
+
+static PyObject *
+signal_setitimer(PyModuleDef *module, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    int which;
+    double seconds;
+    double interval = 0.0;
+
+    if (!PyArg_ParseTuple(args, "id|d:setitimer",
+        &which, &seconds, &interval))
+        goto exit;
+    return_value = signal_setitimer_impl(module, which, seconds, interval);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(HAVE_SETITIMER) */
+
+#if defined(HAVE_GETITIMER)
+
+PyDoc_STRVAR(signal_getitimer__doc__,
+"getitimer($module, which, /)\n"
+"--\n"
+"\n"
+"Returns current value of given itimer.");
+
+#define SIGNAL_GETITIMER_METHODDEF    \
+    {"getitimer", (PyCFunction)signal_getitimer, METH_O, signal_getitimer__doc__},
+
+static PyObject *
+signal_getitimer_impl(PyModuleDef *module, int which);
+
+static PyObject *
+signal_getitimer(PyModuleDef *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    int which;
+
+    if (!PyArg_Parse(arg, "i:getitimer", &which))
+        goto exit;
+    return_value = signal_getitimer_impl(module, which);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(HAVE_GETITIMER) */
+
+#if defined(PYPTHREAD_SIGMASK)
+
+PyDoc_STRVAR(signal_pthread_sigmask__doc__,
+"pthread_sigmask($module, how, mask, /)\n"
+"--\n"
+"\n"
+"Fetch and/or change the signal mask of the calling thread.");
+
+#define SIGNAL_PTHREAD_SIGMASK_METHODDEF    \
+    {"pthread_sigmask", (PyCFunction)signal_pthread_sigmask, METH_VARARGS, signal_pthread_sigmask__doc__},
+
+static PyObject *
+signal_pthread_sigmask_impl(PyModuleDef *module, int how, PyObject *mask);
+
+static PyObject *
+signal_pthread_sigmask(PyModuleDef *module, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    int how;
+    PyObject *mask;
+
+    if (!PyArg_ParseTuple(args, "iO:pthread_sigmask",
+        &how, &mask))
+        goto exit;
+    return_value = signal_pthread_sigmask_impl(module, how, mask);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(PYPTHREAD_SIGMASK) */
+
+#if defined(HAVE_SIGPENDING)
+
+PyDoc_STRVAR(signal_sigpending__doc__,
+"sigpending($module, /)\n"
+"--\n"
+"\n"
+"Examine pending signals.\n"
+"\n"
+"Returns a set of signal numbers that are pending for delivery to\n"
+"the calling thread.");
+
+#define SIGNAL_SIGPENDING_METHODDEF    \
+    {"sigpending", (PyCFunction)signal_sigpending, METH_NOARGS, signal_sigpending__doc__},
+
+static PyObject *
+signal_sigpending_impl(PyModuleDef *module);
+
+static PyObject *
+signal_sigpending(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
+{
+    return signal_sigpending_impl(module);
+}
+
+#endif /* defined(HAVE_SIGPENDING) */
+
+#if defined(HAVE_SIGWAIT)
+
+PyDoc_STRVAR(signal_sigwait__doc__,
+"sigwait($module, sigset, /)\n"
+"--\n"
+"\n"
+"Wait for a signal.\n"
+"\n"
+"Suspend execution of the calling thread until the delivery of one of the\n"
+"signals specified in the signal set sigset.  The function accepts the signal\n"
+"and returns the signal number.");
+
+#define SIGNAL_SIGWAIT_METHODDEF    \
+    {"sigwait", (PyCFunction)signal_sigwait, METH_O, signal_sigwait__doc__},
+
+#endif /* defined(HAVE_SIGWAIT) */
+
+#if defined(HAVE_SIGWAITINFO)
+
+PyDoc_STRVAR(signal_sigwaitinfo__doc__,
+"sigwaitinfo($module, sigset, /)\n"
+"--\n"
+"\n"
+"Wait synchronously until one of the signals in *sigset* is delivered.\n"
+"\n"
+"Returns a struct_siginfo containing information about the signal.");
+
+#define SIGNAL_SIGWAITINFO_METHODDEF    \
+    {"sigwaitinfo", (PyCFunction)signal_sigwaitinfo, METH_O, signal_sigwaitinfo__doc__},
+
+#endif /* defined(HAVE_SIGWAITINFO) */
+
+#if defined(HAVE_SIGTIMEDWAIT)
+
+PyDoc_STRVAR(signal_sigtimedwait__doc__,
+"sigtimedwait($module, sigset, timeout, /)\n"
+"--\n"
+"\n"
+"Like sigwaitinfo(), but with a timeout.\n"
+"\n"
+"The timeout is specified in seconds, with floating point numbers allowed.");
+
+#define SIGNAL_SIGTIMEDWAIT_METHODDEF    \
+    {"sigtimedwait", (PyCFunction)signal_sigtimedwait, METH_VARARGS, signal_sigtimedwait__doc__},
+
+static PyObject *
+signal_sigtimedwait_impl(PyModuleDef *module, PyObject *sigset,
+                         PyObject *timeout);
+
+static PyObject *
+signal_sigtimedwait(PyModuleDef *module, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    PyObject *sigset;
+    PyObject *timeout;
+
+    if (!PyArg_UnpackTuple(args, "sigtimedwait",
+        2, 2,
+        &sigset, &timeout))
+        goto exit;
+    return_value = signal_sigtimedwait_impl(module, sigset, timeout);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(HAVE_SIGTIMEDWAIT) */
+
+#if (defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD))
+
+PyDoc_STRVAR(signal_pthread_kill__doc__,
+"pthread_kill($module, thread_id, signalnum, /)\n"
+"--\n"
+"\n"
+"Send a signal to a thread.");
+
+#define SIGNAL_PTHREAD_KILL_METHODDEF    \
+    {"pthread_kill", (PyCFunction)signal_pthread_kill, METH_VARARGS, signal_pthread_kill__doc__},
+
+static PyObject *
+signal_pthread_kill_impl(PyModuleDef *module, long thread_id, int signalnum);
+
+static PyObject *
+signal_pthread_kill(PyModuleDef *module, PyObject *args)
+{
+    PyObject *return_value = NULL;
+    long thread_id;
+    int signalnum;
+
+    if (!PyArg_ParseTuple(args, "li:pthread_kill",
+        &thread_id, &signalnum))
+        goto exit;
+    return_value = signal_pthread_kill_impl(module, thread_id, signalnum);
+
+exit:
+    return return_value;
+}
+
+#endif /* (defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD)) */
+
+#ifndef SIGNAL_ALARM_METHODDEF
+    #define SIGNAL_ALARM_METHODDEF
+#endif /* !defined(SIGNAL_ALARM_METHODDEF) */
+
+#ifndef SIGNAL_PAUSE_METHODDEF
+    #define SIGNAL_PAUSE_METHODDEF
+#endif /* !defined(SIGNAL_PAUSE_METHODDEF) */
+
+#ifndef SIGNAL_SIGINTERRUPT_METHODDEF
+    #define SIGNAL_SIGINTERRUPT_METHODDEF
+#endif /* !defined(SIGNAL_SIGINTERRUPT_METHODDEF) */
+
+#ifndef SIGNAL_SETITIMER_METHODDEF
+    #define SIGNAL_SETITIMER_METHODDEF
+#endif /* !defined(SIGNAL_SETITIMER_METHODDEF) */
+
+#ifndef SIGNAL_GETITIMER_METHODDEF
+    #define SIGNAL_GETITIMER_METHODDEF
+#endif /* !defined(SIGNAL_GETITIMER_METHODDEF) */
+
+#ifndef SIGNAL_PTHREAD_SIGMASK_METHODDEF
+    #define SIGNAL_PTHREAD_SIGMASK_METHODDEF
+#endif /* !defined(SIGNAL_PTHREAD_SIGMASK_METHODDEF) */
+
+#ifndef SIGNAL_SIGPENDING_METHODDEF
+    #define SIGNAL_SIGPENDING_METHODDEF
+#endif /* !defined(SIGNAL_SIGPENDING_METHODDEF) */
+
+#ifndef SIGNAL_SIGWAIT_METHODDEF
+    #define SIGNAL_SIGWAIT_METHODDEF
+#endif /* !defined(SIGNAL_SIGWAIT_METHODDEF) */
+
+#ifndef SIGNAL_SIGWAITINFO_METHODDEF
+    #define SIGNAL_SIGWAITINFO_METHODDEF
+#endif /* !defined(SIGNAL_SIGWAITINFO_METHODDEF) */
+
+#ifndef SIGNAL_SIGTIMEDWAIT_METHODDEF
+    #define SIGNAL_SIGTIMEDWAIT_METHODDEF
+#endif /* !defined(SIGNAL_SIGTIMEDWAIT_METHODDEF) */
+
+#ifndef SIGNAL_PTHREAD_KILL_METHODDEF
+    #define SIGNAL_PTHREAD_KILL_METHODDEF
+#endif /* !defined(SIGNAL_PTHREAD_KILL_METHODDEF) */
+/*[clinic end generated code: output=65ca7b83632eda99 input=a9049054013a1b77]*/
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index cc13194..d7b44f6 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -52,6 +52,13 @@
 # endif
 #endif
 
+#include "clinic/signalmodule.c.h"
+
+/*[clinic input]
+module signal
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b0301a3bde5fe9d3]*/
+
 
 /*
    NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS
@@ -322,25 +329,37 @@
 
 
 #ifdef HAVE_ALARM
-static PyObject *
-signal_alarm(PyObject *self, PyObject *args)
+
+/*[clinic input]
+signal.alarm -> long
+
+    seconds: int
+    /
+
+Arrange for SIGALRM to arrive after the given number of seconds.
+[clinic start generated code]*/
+
+static long
+signal_alarm_impl(PyModuleDef *module, int seconds)
+/*[clinic end generated code: output=f5f9badaab25d3e7 input=0d5e97e0e6f39e86]*/
 {
-    int t;
-    if (!PyArg_ParseTuple(args, "i:alarm", &t))
-        return NULL;
     /* alarm() returns the number of seconds remaining */
-    return PyLong_FromLong((long)alarm(t));
+    return (long)alarm(seconds);
 }
 
-PyDoc_STRVAR(alarm_doc,
-"alarm(seconds)\n\
-\n\
-Arrange for SIGALRM to arrive after the given number of seconds.");
 #endif
 
 #ifdef HAVE_PAUSE
+
+/*[clinic input]
+signal.pause
+
+Wait until a signal arrives.
+[clinic start generated code]*/
+
 static PyObject *
-signal_pause(PyObject *self)
+signal_pause_impl(PyModuleDef *module)
+/*[clinic end generated code: output=9245704caa63bbe9 input=f03de0f875752062]*/
 {
     Py_BEGIN_ALLOW_THREADS
     (void)pause();
@@ -351,29 +370,38 @@
     if (PyErr_CheckSignals())
         return NULL;
 
-    Py_INCREF(Py_None);
-    return Py_None;
+    Py_RETURN_NONE;
 }
-PyDoc_STRVAR(pause_doc,
-"pause()\n\
-\n\
-Wait until a signal arrives.");
 
 #endif
 
 
+/*[clinic input]
+signal.signal
+
+    signalnum: int
+    handler:   object
+    /
+
+Set the action for the given signal.
+
+The action can be SIG_DFL, SIG_IGN, or a callable Python object.
+The previous action is returned.  See getsignal() for possible return values.
+
+*** IMPORTANT NOTICE ***
+A signal handler function is called with two arguments:
+the first is the signal number, the second is the interrupted stack frame.
+[clinic start generated code]*/
+
 static PyObject *
-signal_signal(PyObject *self, PyObject *args)
+signal_signal_impl(PyModuleDef *module, int signalnum, PyObject *handler)
+/*[clinic end generated code: output=622d7d0beebea546 input=deee84af5fa0432c]*/
 {
-    PyObject *obj;
-    int sig_num;
     PyObject *old_handler;
     void (*func)(int);
-    if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj))
-        return NULL;
 #ifdef MS_WINDOWS
-    /* Validate that sig_num is one of the allowable signals */
-    switch (sig_num) {
+    /* Validate that signalnum is one of the allowable signals */
+    switch (signalnum) {
         case SIGABRT: break;
 #ifdef SIGBREAK
         /* Issue #10003: SIGBREAK is not documented as permitted, but works
@@ -397,61 +425,63 @@
         return NULL;
     }
 #endif
-    if (sig_num < 1 || sig_num >= NSIG) {
+    if (signalnum < 1 || signalnum >= NSIG) {
         PyErr_SetString(PyExc_ValueError,
                         "signal number out of range");
         return NULL;
     }
-    if (obj == IgnoreHandler)
+    if (handler == IgnoreHandler)
         func = SIG_IGN;
-    else if (obj == DefaultHandler)
+    else if (handler == DefaultHandler)
         func = SIG_DFL;
-    else if (!PyCallable_Check(obj)) {
+    else if (!PyCallable_Check(handler)) {
         PyErr_SetString(PyExc_TypeError,
 "signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object");
                 return NULL;
     }
     else
         func = signal_handler;
-    if (PyOS_setsig(sig_num, func) == SIG_ERR) {
+    if (PyOS_setsig(signalnum, func) == SIG_ERR) {
         PyErr_SetFromErrno(PyExc_OSError);
         return NULL;
     }
-    old_handler = Handlers[sig_num].func;
-    Handlers[sig_num].tripped = 0;
-    Py_INCREF(obj);
-    Handlers[sig_num].func = obj;
+    old_handler = Handlers[signalnum].func;
+    Handlers[signalnum].tripped = 0;
+    Py_INCREF(handler);
+    Handlers[signalnum].func = handler;
     if (old_handler != NULL)
         return old_handler;
     else
         Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(signal_doc,
-"signal(sig, action) -> action\n\
-\n\
-Set the action for the given signal.  The action can be SIG_DFL,\n\
-SIG_IGN, or a callable Python object.  The previous action is\n\
-returned.  See getsignal() for possible return values.\n\
-\n\
-*** IMPORTANT NOTICE ***\n\
-A signal handler function is called with two arguments:\n\
-the first is the signal number, the second is the interrupted stack frame.");
 
+/*[clinic input]
+signal.getsignal
+
+    signalnum: int
+    /
+
+Return the current action for the given signal.
+
+The return value can be:
+  SIG_IGN -- if the signal is being ignored
+  SIG_DFL -- if the default action for the signal is in effect
+  None    -- if an unknown handler is in effect
+  anything else -- the callable Python object used as a handler
+[clinic start generated code]*/
 
 static PyObject *
-signal_getsignal(PyObject *self, PyObject *args)
+signal_getsignal_impl(PyModuleDef *module, int signalnum)
+/*[clinic end generated code: output=d50ec355757e360c input=ac23a00f19dfa509]*/
 {
-    int sig_num;
     PyObject *old_handler;
-    if (!PyArg_ParseTuple(args, "i:getsignal", &sig_num))
-        return NULL;
-    if (sig_num < 1 || sig_num >= NSIG) {
+    if (signalnum < 1 || signalnum >= NSIG) {
         PyErr_SetString(PyExc_ValueError,
                         "signal number out of range");
         return NULL;
     }
-    old_handler = Handlers[sig_num].func;
+    old_handler = Handlers[signalnum].func;
     if (old_handler != NULL) {
         Py_INCREF(old_handler);
         return old_handler;
@@ -461,47 +491,41 @@
     }
 }
 
-PyDoc_STRVAR(getsignal_doc,
-"getsignal(sig) -> action\n\
-\n\
-Return the current action for the given signal.  The return value can be:\n\
-SIG_IGN -- if the signal is being ignored\n\
-SIG_DFL -- if the default action for the signal is in effect\n\
-None -- if an unknown handler is in effect\n\
-anything else -- the callable Python object used as a handler");
-
 #ifdef HAVE_SIGINTERRUPT
-PyDoc_STRVAR(siginterrupt_doc,
-"siginterrupt(sig, flag) -> None\n\
-change system call restart behaviour: if flag is False, system calls\n\
-will be restarted when interrupted by signal sig, else system calls\n\
-will be interrupted.");
+
+/*[clinic input]
+signal.siginterrupt
+
+    signalnum: int
+    flag:      int
+    /
+
+Change system call restart behaviour.
+
+If flag is False, system calls will be restarted when interrupted by
+signal sig, else system calls will be interrupted.
+[clinic start generated code]*/
 
 static PyObject *
-signal_siginterrupt(PyObject *self, PyObject *args)
+signal_siginterrupt_impl(PyModuleDef *module, int signalnum, int flag)
+/*[clinic end generated code: output=5dcf8b031b0e8044 input=4160acacca3e2099]*/
 {
-    int sig_num;
-    int flag;
-
-    if (!PyArg_ParseTuple(args, "ii:siginterrupt", &sig_num, &flag))
-        return NULL;
-    if (sig_num < 1 || sig_num >= NSIG) {
+    if (signalnum < 1 || signalnum >= NSIG) {
         PyErr_SetString(PyExc_ValueError,
                         "signal number out of range");
         return NULL;
     }
-    if (siginterrupt(sig_num, flag)<0) {
+    if (siginterrupt(signalnum, flag)<0) {
         PyErr_SetFromErrno(PyExc_OSError);
         return NULL;
     }
-
-    Py_INCREF(Py_None);
-    return Py_None;
+    Py_RETURN_NONE;
 }
 
 #endif
 
-static PyObject *
+
+static PyObject*
 signal_set_wakeup_fd(PyObject *self, PyObject *args)
 {
     struct _Py_stat_struct status;
@@ -640,62 +664,69 @@
 
 
 #ifdef HAVE_SETITIMER
+
+/*[clinic input]
+signal.setitimer
+
+    which:    int
+    seconds:  double
+    interval: double = 0.0
+    /
+
+Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF).
+
+The timer will fire after value seconds and after that every interval seconds.
+The itimer can be cleared by setting seconds to zero.
+
+Returns old values as a tuple: (delay, interval).
+[clinic start generated code]*/
+
 static PyObject *
-signal_setitimer(PyObject *self, PyObject *args)
+signal_setitimer_impl(PyModuleDef *module, int which, double seconds,
+                      double interval)
+/*[clinic end generated code: output=9a9227a27bd05988 input=0d27d417cfcbd51a]*/
 {
-    double first;
-    double interval = 0;
-    int which;
     struct itimerval new, old;
 
-    if(!PyArg_ParseTuple(args, "id|d:setitimer", &which, &first, &interval))
-    return NULL;
-
-    timeval_from_double(first, &new.it_value);
+    timeval_from_double(seconds, &new.it_value);
     timeval_from_double(interval, &new.it_interval);
     /* Let OS check "which" value */
     if (setitimer(which, &new, &old) != 0) {
-    PyErr_SetFromErrno(ItimerError);
-    return NULL;
+        PyErr_SetFromErrno(ItimerError);
+        return NULL;
     }
 
     return itimer_retval(&old);
 }
 
-PyDoc_STRVAR(setitimer_doc,
-"setitimer(which, seconds[, interval])\n\
-\n\
-Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL\n\
-or ITIMER_PROF) to fire after value seconds and after\n\
-that every interval seconds.\n\
-The itimer can be cleared by setting seconds to zero.\n\
-\n\
-Returns old values as a tuple: (delay, interval).");
 #endif
 
 
 #ifdef HAVE_GETITIMER
+
+/*[clinic input]
+signal.getitimer
+
+    which:    int
+    /
+
+Returns current value of given itimer.
+[clinic start generated code]*/
+
 static PyObject *
-signal_getitimer(PyObject *self, PyObject *args)
+signal_getitimer_impl(PyModuleDef *module, int which)
+/*[clinic end generated code: output=d1349ab18aadc569 input=f7d21d38f3490627]*/
 {
-    int which;
     struct itimerval old;
 
-    if (!PyArg_ParseTuple(args, "i:getitimer", &which))
-    return NULL;
-
     if (getitimer(which, &old) != 0) {
-    PyErr_SetFromErrno(ItimerError);
-    return NULL;
+        PyErr_SetFromErrno(ItimerError);
+        return NULL;
     }
 
     return itimer_retval(&old);
 }
 
-PyDoc_STRVAR(getitimer_doc,
-"getitimer(which)\n\
-\n\
-Returns current value of given itimer.");
 #endif
 
 #if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) || \
@@ -786,21 +817,28 @@
 #endif
 
 #ifdef PYPTHREAD_SIGMASK
+
+/*[clinic input]
+signal.pthread_sigmask
+
+    how:  int
+    mask: object
+    /
+
+Fetch and/or change the signal mask of the calling thread.
+[clinic start generated code]*/
+
 static PyObject *
-signal_pthread_sigmask(PyObject *self, PyObject *args)
+signal_pthread_sigmask_impl(PyModuleDef *module, int how, PyObject *mask)
+/*[clinic end generated code: output=b043a9f0eeb1e075 input=f3b7d7a61b7b8283]*/
 {
-    int how;
-    PyObject *signals;
-    sigset_t mask, previous;
+    sigset_t newmask, previous;
     int err;
 
-    if (!PyArg_ParseTuple(args, "iO:pthread_sigmask", &how, &signals))
+    if (iterable_to_sigset(mask, &newmask))
         return NULL;
 
-    if (iterable_to_sigset(signals, &mask))
-        return NULL;
-
-    err = pthread_sigmask(how, &mask, &previous);
+    err = pthread_sigmask(how, &newmask, &previous);
     if (err != 0) {
         errno = err;
         PyErr_SetFromErrno(PyExc_OSError);
@@ -814,16 +852,23 @@
     return sigset_to_set(previous);
 }
 
-PyDoc_STRVAR(signal_pthread_sigmask_doc,
-"pthread_sigmask(how, mask) -> old mask\n\
-\n\
-Fetch and/or change the signal mask of the calling thread.");
 #endif   /* #ifdef PYPTHREAD_SIGMASK */
 
 
 #ifdef HAVE_SIGPENDING
+
+/*[clinic input]
+signal.sigpending
+
+Examine pending signals.
+
+Returns a set of signal numbers that are pending for delivery to
+the calling thread.
+[clinic start generated code]*/
+
 static PyObject *
-signal_sigpending(PyObject *self)
+signal_sigpending_impl(PyModuleDef *module)
+/*[clinic end generated code: output=bf4ced803e7e51dd input=e0036c016f874e29]*/
 {
     int err;
     sigset_t mask;
@@ -833,25 +878,32 @@
     return sigset_to_set(mask);
 }
 
-PyDoc_STRVAR(signal_sigpending_doc,
-"sigpending() -> list\n\
-\n\
-Examine pending signals.");
 #endif   /* #ifdef HAVE_SIGPENDING */
 
 
 #ifdef HAVE_SIGWAIT
+
+/*[clinic input]
+signal.sigwait
+
+    sigset: object
+    /
+
+Wait for a signal.
+
+Suspend execution of the calling thread until the delivery of one of the
+signals specified in the signal set sigset.  The function accepts the signal
+and returns the signal number.
+[clinic start generated code]*/
+
 static PyObject *
-signal_sigwait(PyObject *self, PyObject *args)
+signal_sigwait(PyModuleDef *module, PyObject *sigset)
+/*[clinic end generated code: output=dae53048b0336a5c input=11af2d82d83c2e94]*/
 {
-    PyObject *signals;
     sigset_t set;
     int err, signum;
 
-    if (!PyArg_ParseTuple(args, "O:sigwait", &signals))
-        return NULL;
-
-    if (iterable_to_sigset(signals, &set))
+    if (iterable_to_sigset(sigset, &set))
         return NULL;
 
     Py_BEGIN_ALLOW_THREADS
@@ -865,11 +917,8 @@
     return PyLong_FromLong(signum);
 }
 
-PyDoc_STRVAR(signal_sigwait_doc,
-"sigwait(sigset) -> signum\n\
-\n\
-Wait a signal.");
-#endif   /* #ifdef HAVE_SIGPENDING */
+#endif   /* #ifdef HAVE_SIGWAIT */
+
 
 #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
 static int initialized;
@@ -924,19 +973,28 @@
 #endif
 
 #ifdef HAVE_SIGWAITINFO
+
+/*[clinic input]
+signal.sigwaitinfo
+
+    sigset: object
+    /
+
+Wait synchronously until one of the signals in *sigset* is delivered.
+
+Returns a struct_siginfo containing information about the signal.
+[clinic start generated code]*/
+
 static PyObject *
-signal_sigwaitinfo(PyObject *self, PyObject *args)
+signal_sigwaitinfo(PyModuleDef *module, PyObject *sigset)
+/*[clinic end generated code: output=0bb53b07e5e926b5 input=f3779a74a991e171]*/
 {
-    PyObject *signals;
     sigset_t set;
     siginfo_t si;
     int err;
     int async_err = 0;
 
-    if (!PyArg_ParseTuple(args, "O:sigwaitinfo", &signals))
-        return NULL;
-
-    if (iterable_to_sigset(signals, &set))
+    if (iterable_to_sigset(sigset, &set))
         return NULL;
 
     do {
@@ -951,29 +1009,33 @@
     return fill_siginfo(&si);
 }
 
-PyDoc_STRVAR(signal_sigwaitinfo_doc,
-"sigwaitinfo(sigset) -> struct_siginfo\n\
-\n\
-Wait synchronously for a signal until one of the signals in *sigset* is\n\
-delivered.\n\
-Returns a struct_siginfo containing information about the signal.");
 #endif   /* #ifdef HAVE_SIGWAITINFO */
 
 #ifdef HAVE_SIGTIMEDWAIT
+
+/*[clinic input]
+signal.sigtimedwait
+
+    sigset:  object
+    timeout: object
+    /
+
+Like sigwaitinfo(), but with a timeout.
+
+The timeout is specified in seconds, with floating point numbers allowed.
+[clinic start generated code]*/
+
 static PyObject *
-signal_sigtimedwait(PyObject *self, PyObject *args)
+signal_sigtimedwait_impl(PyModuleDef *module, PyObject *sigset,
+                         PyObject *timeout)
+/*[clinic end generated code: output=e6e049f2bddea688 input=036bbab9b15cb8de]*/
 {
-    PyObject *signals, *timeout_obj;
     struct timespec ts;
     sigset_t set;
     siginfo_t si;
     int res;
     _PyTime_t timeout, deadline, monotonic;
 
-    if (!PyArg_ParseTuple(args, "OO:sigtimedwait",
-                          &signals, &timeout_obj))
-        return NULL;
-
     if (_PyTime_FromSecondsObject(&timeout,
                                   timeout_obj, _PyTime_ROUND_CEILING) < 0)
         return NULL;
@@ -983,7 +1045,7 @@
         return NULL;
     }
 
-    if (iterable_to_sigset(signals, &set))
+    if (iterable_to_sigset(sigset, &set))
         return NULL;
 
     deadline = _PyTime_GetMonotonicClock() + timeout;
@@ -1019,26 +1081,28 @@
     return fill_siginfo(&si);
 }
 
-PyDoc_STRVAR(signal_sigtimedwait_doc,
-"sigtimedwait(sigset, (timeout_sec, timeout_nsec)) -> struct_siginfo\n\
-\n\
-Like sigwaitinfo(), but with a timeout specified as a tuple of (seconds,\n\
-nanoseconds).");
 #endif   /* #ifdef HAVE_SIGTIMEDWAIT */
 
 
 #if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD)
+
+/*[clinic input]
+signal.pthread_kill
+
+    thread_id:  long
+    signalnum:  int
+    /
+
+Send a signal to a thread.
+[clinic start generated code]*/
+
 static PyObject *
-signal_pthread_kill(PyObject *self, PyObject *args)
+signal_pthread_kill_impl(PyModuleDef *module, long thread_id, int signalnum)
+/*[clinic end generated code: output=35aed2713c756d7a input=77ed6a3b6f2a8122]*/
 {
-    long tid;
-    int signum;
     int err;
 
-    if (!PyArg_ParseTuple(args, "li:pthread_kill", &tid, &signum))
-        return NULL;
-
-    err = pthread_kill((pthread_t)tid, signum);
+    err = pthread_kill((pthread_t)thread_id, signalnum);
     if (err != 0) {
         errno = err;
         PyErr_SetFromErrno(PyExc_OSError);
@@ -1052,62 +1116,29 @@
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(signal_pthread_kill_doc,
-"pthread_kill(thread_id, signum)\n\
-\n\
-Send a signal to a thread.");
 #endif   /* #if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD) */
 
 
 
-/* List of functions defined in the module */
+/* List of functions defined in the module -- some of the methoddefs are
+   defined to nothing if the corresponding C function is not available. */
 static PyMethodDef signal_methods[] = {
-#ifdef HAVE_ALARM
-    {"alarm",                   signal_alarm, METH_VARARGS, alarm_doc},
-#endif
-#ifdef HAVE_SETITIMER
-    {"setitimer",       signal_setitimer, METH_VARARGS, setitimer_doc},
-#endif
-#ifdef HAVE_GETITIMER
-    {"getitimer",       signal_getitimer, METH_VARARGS, getitimer_doc},
-#endif
-    {"signal",                  signal_signal, METH_VARARGS, signal_doc},
-    {"getsignal",               signal_getsignal, METH_VARARGS, getsignal_doc},
+    {"default_int_handler", signal_default_int_handler, METH_VARARGS, default_int_handler_doc},
+    SIGNAL_ALARM_METHODDEF
+    SIGNAL_SETITIMER_METHODDEF
+    SIGNAL_GETITIMER_METHODDEF
+    SIGNAL_SIGNAL_METHODDEF
+    SIGNAL_GETSIGNAL_METHODDEF
     {"set_wakeup_fd",           signal_set_wakeup_fd, METH_VARARGS, set_wakeup_fd_doc},
-#ifdef HAVE_SIGINTERRUPT
-    {"siginterrupt",            signal_siginterrupt, METH_VARARGS, siginterrupt_doc},
-#endif
-#ifdef HAVE_PAUSE
-    {"pause",                   (PyCFunction)signal_pause,
-     METH_NOARGS, pause_doc},
-#endif
-    {"default_int_handler", signal_default_int_handler,
-     METH_VARARGS, default_int_handler_doc},
-#if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD)
-    {"pthread_kill",            (PyCFunction)signal_pthread_kill,
-     METH_VARARGS, signal_pthread_kill_doc},
-#endif
-#ifdef PYPTHREAD_SIGMASK
-    {"pthread_sigmask",         (PyCFunction)signal_pthread_sigmask,
-     METH_VARARGS, signal_pthread_sigmask_doc},
-#endif
-#ifdef HAVE_SIGPENDING
-    {"sigpending",              (PyCFunction)signal_sigpending,
-     METH_NOARGS, signal_sigpending_doc},
-#endif
-#ifdef HAVE_SIGWAIT
-    {"sigwait",                 (PyCFunction)signal_sigwait,
-     METH_VARARGS, signal_sigwait_doc},
-#endif
-#ifdef HAVE_SIGWAITINFO
-    {"sigwaitinfo",             (PyCFunction)signal_sigwaitinfo,
-     METH_VARARGS, signal_sigwaitinfo_doc},
-#endif
-#ifdef HAVE_SIGTIMEDWAIT
-    {"sigtimedwait",            (PyCFunction)signal_sigtimedwait,
-     METH_VARARGS, signal_sigtimedwait_doc},
-#endif
-    {NULL,                      NULL}           /* sentinel */
+    SIGNAL_SIGINTERRUPT_METHODDEF
+    SIGNAL_PAUSE_METHODDEF
+    SIGNAL_PTHREAD_KILL_METHODDEF
+    SIGNAL_PTHREAD_SIGMASK_METHODDEF
+    SIGNAL_SIGPENDING_METHODDEF
+    SIGNAL_SIGWAIT_METHODDEF
+    SIGNAL_SIGWAITINFO_METHODDEF
+    SIGNAL_SIGTIMEDWAIT_METHODDEF
+    {NULL, NULL}           /* sentinel */
 };