Skip to content

Commit 53a2483

Browse files
[3.14] gh-152132: Fix bugs in Py_RunMain() (GH-153461) (GH-153466) (#153467)
[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 7a7da86 commit 53a2483

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
@@ -79,6 +79,12 @@ pymain_init(const _PyArgv *args)
7979

8080
/* --- pymain_run_python() ---------------------------------------- */
8181

82+
static int
83+
pymain_check_signals(void)
84+
{
85+
return Py_MakePendingCalls();
86+
}
87+
8288
/* Non-zero if filename, command (-c) or module (-m) is set
8389
on the command line */
8490
static inline int config_run_code(const PyConfig *config)
@@ -200,17 +206,21 @@ pymain_header(const PyConfig *config)
200206
}
201207

202208

203-
static void
209+
static int
204210
pymain_import_readline(const PyConfig *config)
205211
{
212+
if (pymain_check_signals() < 0) {
213+
return -1;
214+
}
215+
206216
if (config->isolated) {
207-
return;
217+
return 0;
208218
}
209219
if (!config->inspect && config_run_code(config)) {
210-
return;
220+
return 0;
211221
}
212222
if (!isatty(fileno(stdin))) {
213-
return;
223+
return 0;
214224
}
215225

216226
PyObject *mod = PyImport_ImportModule("readline");
@@ -227,6 +237,7 @@ pymain_import_readline(const PyConfig *config)
227237
else {
228238
Py_DECREF(mod);
229239
}
240+
return 0;
230241
}
231242

232243

@@ -415,8 +426,7 @@ pymain_run_file_obj(PyObject *program_name, PyObject *filename,
415426
return 1;
416427
}
417428

418-
// Call pending calls like signal handlers (SIGINT)
419-
if (Py_MakePendingCalls() == -1) {
429+
if (pymain_check_signals() < 0) {
420430
fclose(fp);
421431
return pymain_exit_err_print();
422432
}
@@ -566,8 +576,7 @@ pymain_set_inspect(PyConfig *config, int inspect)
566576
static int
567577
_pymain_run_repl(PyConfig *config, int startup)
568578
{
569-
/* call pending calls like signal handlers (SIGINT) */
570-
if (Py_MakePendingCalls() == -1) {
579+
if (pymain_check_signals() < 0) {
571580
return pymain_exit_err_print();
572581
}
573582

@@ -650,13 +659,17 @@ pymain_repl(PyConfig *config, int *exitcode)
650659
static void
651660
pymain_run_python(int *exitcode)
652661
{
662+
int set_running_main = 0;
663+
653664
PyObject *main_importer_path = NULL;
654665
PyInterpreterState *interp = _PyInterpreterState_GET();
655666
/* pymain_repl() and pymain_run_stdin() modify the config */
656667
PyConfig *config = (PyConfig*)_PyInterpreterState_GetConfig(interp);
657668

658669
/* ensure path config is written into global variables */
659-
if (_PyStatus_EXCEPTION(_PyPathConfig_UpdateGlobal(config))) {
670+
PyStatus status = _PyPathConfig_UpdateGlobal(config);
671+
if (_PyStatus_EXCEPTION(status)) {
672+
_PyErr_SetFromPyStatus(status);
660673
goto error;
661674
}
662675

@@ -678,7 +691,9 @@ pymain_run_python(int *exitcode)
678691
}
679692

680693
// import readline and rlcompleter before script dir is added to sys.path
681-
pymain_import_readline(config);
694+
if (pymain_import_readline(config) < 0) {
695+
goto error;
696+
}
682697

683698
PyObject *path0 = NULL;
684699
if (main_importer_path != NULL) {
@@ -717,8 +732,13 @@ pymain_run_python(int *exitcode)
717732
pymain_header(config);
718733

719734
_PyInterpreterState_SetRunningMain(interp);
735+
set_running_main = 1;
720736
assert(!PyErr_Occurred());
721737

738+
if (pymain_check_signals() < 0) {
739+
goto error;
740+
}
741+
722742
if (config->run_command) {
723743
*exitcode = pymain_run_command(config->run_command);
724744
}
@@ -735,14 +755,20 @@ pymain_run_python(int *exitcode)
735755
*exitcode = pymain_run_stdin(config);
736756
}
737757

758+
if (pymain_check_signals() < 0) {
759+
goto error;
760+
}
761+
738762
pymain_repl(config, exitcode);
739763
goto done;
740764

741765
error:
742766
*exitcode = pymain_exit_err_print();
743767

744768
done:
745-
_PyInterpreterState_SetNotRunningMain(interp);
769+
if (set_running_main) {
770+
_PyInterpreterState_SetNotRunningMain(interp);
771+
}
746772
Py_XDECREF(main_importer_path);
747773
}
748774

0 commit comments

Comments
 (0)