@@ -174,6 +174,17 @@ get_signal_state(PyObject *module)
174174}
175175
176176
177+ static inline int
178+ compare_handler (PyObject * func , PyObject * dfl_ign_handler )
179+ {
180+ assert (PyLong_CheckExact (dfl_ign_handler ));
181+ if (!PyLong_CheckExact (func )) {
182+ return 0 ;
183+ }
184+ // Assume that comparison of two PyLong objects will never fail.
185+ return PyObject_RichCompareBool (func , dfl_ign_handler , Py_EQ ) == 1 ;
186+ }
187+
177188#ifdef HAVE_GETITIMER
178189/* auxiliary functions for setitimer */
179190static int
@@ -525,21 +536,18 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
525536 "signal number out of range" );
526537 return NULL ;
527538 }
528- if (handler == modstate -> ignore_handler ) {
539+ if (PyCallable_Check (handler )) {
540+ func = signal_handler ;
541+ } else if (compare_handler (handler , modstate -> ignore_handler )) {
529542 func = SIG_IGN ;
530- }
531- else if (handler == modstate -> default_handler ) {
543+ } else if (compare_handler (handler , modstate -> default_handler )) {
532544 func = SIG_DFL ;
533- }
534- else if (!PyCallable_Check (handler )) {
545+ } else {
535546 _PyErr_SetString (tstate , PyExc_TypeError ,
536547 "signal handler must be signal.SIG_IGN, "
537548 "signal.SIG_DFL, or a callable object" );
538549 return NULL ;
539550 }
540- else {
541- func = signal_handler ;
542- }
543551
544552 /* Check for pending signals before changing signal handler */
545553 if (_PyErr_CheckSignalsTstate (tstate )) {
@@ -1736,8 +1744,8 @@ _PySignal_Fini(void)
17361744 set_handler (signum , NULL );
17371745 if (func != NULL
17381746 && func != Py_None
1739- && func != state -> default_handler
1740- && func != state -> ignore_handler )
1747+ && ! compare_handler ( func , state -> default_handler )
1748+ && ! compare_handler ( func , state -> ignore_handler ) )
17411749 {
17421750 PyOS_setsig (signum , SIG_DFL );
17431751 }
@@ -1812,8 +1820,9 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate)
18121820 * (see bpo-43406).
18131821 */
18141822 PyObject * func = get_handler (i );
1815- if (func == NULL || func == Py_None || func == state -> ignore_handler ||
1816- func == state -> default_handler ) {
1823+ if (func == NULL || func == Py_None ||
1824+ compare_handler (func , state -> ignore_handler ) ||
1825+ compare_handler (func , state -> default_handler )) {
18171826 /* No Python signal handler due to aforementioned race condition.
18181827 * We can't call raise() as it would break the assumption
18191828 * that PyErr_SetInterrupt() only *simulates* an incoming
@@ -1873,7 +1882,8 @@ PyErr_SetInterruptEx(int signum)
18731882
18741883 signal_state_t * state = & signal_global_state ;
18751884 PyObject * func = get_handler (signum );
1876- if (func != state -> ignore_handler && func != state -> default_handler ) {
1885+ if (!compare_handler (func , state -> ignore_handler )
1886+ && !compare_handler (func , state -> default_handler )) {
18771887 trip_signal (signum );
18781888 }
18791889 return 0 ;
0 commit comments