@@ -174,6 +174,17 @@ get_signal_state(PyObject *module)
174
174
}
175
175
176
176
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
+
177
188
#ifdef HAVE_GETITIMER
178
189
/* auxiliary functions for setitimer */
179
190
static int
@@ -525,21 +536,18 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
525
536
"signal number out of range" );
526
537
return NULL ;
527
538
}
528
- if (handler == modstate -> ignore_handler ) {
539
+ if (PyCallable_Check (handler )) {
540
+ func = signal_handler ;
541
+ } else if (compare_handler (handler , modstate -> ignore_handler )) {
529
542
func = SIG_IGN ;
530
- }
531
- else if (handler == modstate -> default_handler ) {
543
+ } else if (compare_handler (handler , modstate -> default_handler )) {
532
544
func = SIG_DFL ;
533
- }
534
- else if (!PyCallable_Check (handler )) {
545
+ } else {
535
546
_PyErr_SetString (tstate , PyExc_TypeError ,
536
547
"signal handler must be signal.SIG_IGN, "
537
548
"signal.SIG_DFL, or a callable object" );
538
549
return NULL ;
539
550
}
540
- else {
541
- func = signal_handler ;
542
- }
543
551
544
552
/* Check for pending signals before changing signal handler */
545
553
if (_PyErr_CheckSignalsTstate (tstate )) {
@@ -1736,8 +1744,8 @@ _PySignal_Fini(void)
1736
1744
set_handler (signum , NULL );
1737
1745
if (func != NULL
1738
1746
&& 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 ) )
1741
1749
{
1742
1750
PyOS_setsig (signum , SIG_DFL );
1743
1751
}
@@ -1812,8 +1820,9 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate)
1812
1820
* (see bpo-43406).
1813
1821
*/
1814
1822
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 )) {
1817
1826
/* No Python signal handler due to aforementioned race condition.
1818
1827
* We can't call raise() as it would break the assumption
1819
1828
* that PyErr_SetInterrupt() only *simulates* an incoming
@@ -1873,7 +1882,8 @@ PyErr_SetInterruptEx(int signum)
1873
1882
1874
1883
signal_state_t * state = & signal_global_state ;
1875
1884
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 )) {
1877
1887
trip_signal (signum );
1878
1888
}
1879
1889
return 0 ;
0 commit comments