Skip to content

Commit 99c765a

Browse files
[3.13] gh-152132: Fix bugs in Py_RunMain() (GH-153461) (GH-153466) (#153468)
[3.15] gh-152132: Fix bugs in Py_RunMain() (GH-153461) (GH-153466) * Check for signals more often. Previously, a pending exception could be removed by PyErr_Clear(). * Only call _PyInterpreterState_SetNotRunningMain() if _PyInterpreterState_SetRunningMain() has been called. * Convert _PyPathConfig_UpdateGlobal() PyStatus error to an exception. (cherry picked from commit cecafeb) Co-authored-by: Victor Stinner <vstinner@python.org>
1 parent 3d9a420 commit 99c765a

1 file changed

Lines changed: 37 additions & 11 deletions

File tree

Modules/main.c

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ pymain_init(const _PyArgv *args)
7676

7777
/* --- pymain_run_python() ---------------------------------------- */
7878

79+
static int
80+
pymain_check_signals(void)
81+
{
82+
return Py_MakePendingCalls();
83+
}
84+
7985
/* Non-zero if filename, command (-c) or module (-m) is set
8086
on the command line */
8187
static inline int config_run_code(const PyConfig *config)
@@ -197,17 +203,21 @@ pymain_header(const PyConfig *config)
197203
}
198204

199205

200-
static void
206+
static int
201207
pymain_import_readline(const PyConfig *config)
202208
{
209+
if (pymain_check_signals() < 0) {
210+
return -1;
211+
}
212+
203213
if (config->isolated) {
204-
return;
214+
return 0;
205215
}
206216
if (!config->inspect && config_run_code(config)) {
207-
return;
217+
return 0;
208218
}
209219
if (!isatty(fileno(stdin))) {
210-
return;
220+
return 0;
211221
}
212222

213223
PyObject *mod = PyImport_ImportModule("readline");
@@ -224,6 +234,7 @@ pymain_import_readline(const PyConfig *config)
224234
else {
225235
Py_DECREF(mod);
226236
}
237+
return 0;
227238
}
228239

229240

@@ -418,8 +429,7 @@ pymain_run_file_obj(PyObject *program_name, PyObject *filename,
418429
return 1;
419430
}
420431

421-
// Call pending calls like signal handlers (SIGINT)
422-
if (Py_MakePendingCalls() == -1) {
432+
if (pymain_check_signals() < 0) {
423433
fclose(fp);
424434
return pymain_exit_err_print();
425435
}
@@ -567,8 +577,7 @@ _Py_COMP_DIAG_POP
567577
static int
568578
_pymain_run_repl(PyConfig *config, int startup)
569579
{
570-
/* call pending calls like signal handlers (SIGINT) */
571-
if (Py_MakePendingCalls() == -1) {
580+
if (pymain_check_signals() < 0) {
572581
return pymain_exit_err_print();
573582
}
574583

@@ -647,13 +656,17 @@ pymain_repl(PyConfig *config, int *exitcode)
647656
static void
648657
pymain_run_python(int *exitcode)
649658
{
659+
int set_running_main = 0;
660+
650661
PyObject *main_importer_path = NULL;
651662
PyInterpreterState *interp = _PyInterpreterState_GET();
652663
/* pymain_run_stdin() modify the config */
653664
PyConfig *config = (PyConfig*)_PyInterpreterState_GetConfig(interp);
654665

655666
/* ensure path config is written into global variables */
656-
if (_PyStatus_EXCEPTION(_PyPathConfig_UpdateGlobal(config))) {
667+
PyStatus status = _PyPathConfig_UpdateGlobal(config);
668+
if (_PyStatus_EXCEPTION(status)) {
669+
_PyErr_SetFromPyStatus(status);
657670
goto error;
658671
}
659672

@@ -675,7 +688,9 @@ pymain_run_python(int *exitcode)
675688
}
676689

677690
// import readline and rlcompleter before script dir is added to sys.path
678-
pymain_import_readline(config);
691+
if (pymain_import_readline(config) < 0) {
692+
goto error;
693+
}
679694

680695
PyObject *path0 = NULL;
681696
if (main_importer_path != NULL) {
@@ -714,8 +729,13 @@ pymain_run_python(int *exitcode)
714729
pymain_header(config);
715730

716731
_PyInterpreterState_SetRunningMain(interp);
732+
set_running_main = 1;
717733
assert(!PyErr_Occurred());
718734

735+
if (pymain_check_signals() < 0) {
736+
goto error;
737+
}
738+
719739
if (config->run_command) {
720740
*exitcode = pymain_run_command(config->run_command);
721741
}
@@ -732,14 +752,20 @@ pymain_run_python(int *exitcode)
732752
*exitcode = pymain_run_stdin(config);
733753
}
734754

755+
if (pymain_check_signals() < 0) {
756+
goto error;
757+
}
758+
735759
pymain_repl(config, exitcode);
736760
goto done;
737761

738762
error:
739763
*exitcode = pymain_exit_err_print();
740764

741765
done:
742-
_PyInterpreterState_SetNotRunningMain(interp);
766+
if (set_running_main) {
767+
_PyInterpreterState_SetNotRunningMain(interp);
768+
}
743769
Py_XDECREF(main_importer_path);
744770
}
745771

0 commit comments

Comments
 (0)