@@ -589,8 +589,13 @@ parse_exit_code(PyObject *code, int *exitcode_p)
589589}
590590
591591int
592- _Py_HandleSystemExit (int * exitcode_p )
592+ _Py_HandleSystemExitAndKeyboardInterrupt (int * exitcode_p )
593593{
594+ if (PyErr_ExceptionMatches (PyExc_KeyboardInterrupt )) {
595+ _Py_atomic_store_int (& _PyRuntime .signals .unhandled_keyboard_interrupt , 1 );
596+ return 0 ;
597+ }
598+
594599 int inspect = _Py_GetConfig ()-> inspect ;
595600 if (inspect ) {
596601 /* Don't exit if -i flag was given. This flag is set to 0
@@ -646,7 +651,7 @@ static void
646651handle_system_exit (void )
647652{
648653 int exitcode ;
649- if (_Py_HandleSystemExit (& exitcode )) {
654+ if (_Py_HandleSystemExitAndKeyboardInterrupt (& exitcode )) {
650655 Py_Exit (exitcode );
651656 }
652657}
@@ -1105,8 +1110,6 @@ _PyErr_Display(PyObject *file, PyObject *unused, PyObject *value, PyObject *tb)
11051110 }
11061111 }
11071112
1108- int unhandled_keyboard_interrupt = _PyRuntime .signals .unhandled_keyboard_interrupt ;
1109-
11101113 // Try first with the stdlib traceback module
11111114 PyObject * print_exception_fn = PyImport_ImportModuleAttrString (
11121115 "traceback" ,
@@ -1120,11 +1123,9 @@ _PyErr_Display(PyObject *file, PyObject *unused, PyObject *value, PyObject *tb)
11201123 Py_XDECREF (print_exception_fn );
11211124 if (result ) {
11221125 Py_DECREF (result );
1123- _PyRuntime .signals .unhandled_keyboard_interrupt = unhandled_keyboard_interrupt ;
11241126 return ;
11251127 }
11261128fallback :
1127- _PyRuntime .signals .unhandled_keyboard_interrupt = unhandled_keyboard_interrupt ;
11281129#ifdef Py_DEBUG
11291130 if (PyErr_Occurred ()) {
11301131 PyErr_FormatUnraisable (
@@ -1297,20 +1298,6 @@ flush_io(void)
12971298static PyObject *
12981299run_eval_code_obj (PyThreadState * tstate , PyCodeObject * co , PyObject * globals , PyObject * locals )
12991300{
1300- PyObject * v ;
1301- /*
1302- * We explicitly re-initialize _Py_UnhandledKeyboardInterrupt every eval
1303- * _just in case_ someone is calling into an embedded Python where they
1304- * don't care about an uncaught KeyboardInterrupt exception (why didn't they
1305- * leave config.install_signal_handlers set to 0?!?) but then later call
1306- * Py_Main() itself (which _checks_ this flag and dies with a signal after
1307- * its interpreter exits). We don't want a previous embedded interpreter's
1308- * uncaught exception to trigger an unexplained signal exit from a future
1309- * Py_Main() based one.
1310- */
1311- // XXX Isn't this dealt with by the move to _PyRuntimeState?
1312- _PyRuntime .signals .unhandled_keyboard_interrupt = 0 ;
1313-
13141301 /* Set globals['__builtins__'] if it doesn't exist */
13151302 if (!globals || !PyDict_Check (globals )) {
13161303 PyErr_SetString (PyExc_SystemError , "globals must be a real dict" );
@@ -1328,11 +1315,7 @@ run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, Py
13281315 }
13291316 }
13301317
1331- v = PyEval_EvalCode ((PyObject * )co , globals , locals );
1332- if (!v && _PyErr_Occurred (tstate ) == PyExc_KeyboardInterrupt ) {
1333- _PyRuntime .signals .unhandled_keyboard_interrupt = 1 ;
1334- }
1335- return v ;
1318+ return PyEval_EvalCode ((PyObject * )co , globals , locals );
13361319}
13371320
13381321static PyObject *
0 commit comments