@@ -177,6 +177,17 @@ get_signal_state(PyObject *module)
177177}
178178
179179
180+ static inline int
181+ compare_handler (PyObject * func , PyObject * dfl_ign_handler )
182+ {
183+ assert (PyLong_CheckExact (dfl_ign_handler ));
184+ if (!PyLong_CheckExact (func )) {
185+ return 0 ;
186+ }
187+ // Assume that comparison of two PyLong objects will never fail.
188+ return PyObject_RichCompareBool (func , dfl_ign_handler , Py_EQ ) == 1 ;
189+ }
190+
180191#ifdef HAVE_GETITIMER
181192/* auxiliary functions for setitimer */
182193static int
@@ -528,21 +539,18 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
528539 "signal number out of range" );
529540 return NULL ;
530541 }
531- if (handler == modstate -> ignore_handler ) {
542+ if (PyCallable_Check (handler )) {
543+ func = signal_handler ;
544+ } else if (compare_handler (handler , modstate -> ignore_handler )) {
532545 func = SIG_IGN ;
533- }
534- else if (handler == modstate -> default_handler ) {
546+ } else if (compare_handler (handler , modstate -> default_handler )) {
535547 func = SIG_DFL ;
536- }
537- else if (!PyCallable_Check (handler )) {
548+ } else {
538549 _PyErr_SetString (tstate , PyExc_TypeError ,
539550 "signal handler must be signal.SIG_IGN, "
540551 "signal.SIG_DFL, or a callable object" );
541552 return NULL ;
542553 }
543- else {
544- func = signal_handler ;
545- }
546554
547555 /* Check for pending signals before changing signal handler */
548556 if (_PyErr_CheckSignalsTstate (tstate )) {
@@ -1752,8 +1760,8 @@ _PySignal_Fini(void)
17521760 set_handler (signum , NULL );
17531761 if (func != NULL
17541762 && func != Py_None
1755- && func != state -> default_handler
1756- && func != state -> ignore_handler )
1763+ && ! compare_handler ( func , state -> default_handler )
1764+ && ! compare_handler ( func , state -> ignore_handler ) )
17571765 {
17581766 PyOS_setsig (signum , SIG_DFL );
17591767 }
@@ -1824,8 +1832,9 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate)
18241832 * (see bpo-43406).
18251833 */
18261834 PyObject * func = get_handler (i );
1827- if (func == NULL || func == Py_None || func == state -> ignore_handler ||
1828- func == state -> default_handler ) {
1835+ if (func == NULL || func == Py_None ||
1836+ compare_handler (func , state -> ignore_handler ) ||
1837+ compare_handler (func , state -> default_handler )) {
18291838 /* No Python signal handler due to aforementioned race condition.
18301839 * We can't call raise() as it would break the assumption
18311840 * that PyErr_SetInterrupt() only *simulates* an incoming
@@ -1893,7 +1902,8 @@ PyErr_SetInterruptEx(int signum)
18931902
18941903 signal_state_t * state = & signal_global_state ;
18951904 PyObject * func = get_handler (signum );
1896- if (func != state -> ignore_handler && func != state -> default_handler ) {
1905+ if (!compare_handler (func , state -> ignore_handler )
1906+ && !compare_handler (func , state -> default_handler )) {
18971907 trip_signal (signum );
18981908 }
18991909 return 0 ;
0 commit comments