]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-152132: Enhance Py_RunMain() and fix bugs (#153461)
authorVictor Stinner <vstinner@python.org>
Thu, 9 Jul 2026 23:29:53 +0000 (01:29 +0200)
committerGitHub <noreply@github.com>
Thu, 9 Jul 2026 23:29:53 +0000 (01:29 +0200)
* 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.
* Add pymain_error() and pyrun_error(): write the error message to
  sys.stderr instead of the C stream stderr.
* Convert _PyPathConfig_UpdateGlobal() PyStatus error to an
  exception.
* Simplify pymain_run_startup(): avoid strerror() which is decoded
  from the wrong encoding. Instead display the exception, Py_fopen()
  raises an OSError with the path object (and can raise other exceptions).
* Add pymain_set_path0() function.
* Add _PySys_FormatV() function.

Include/internal/pycore_sysmodule.h
Lib/test/test_cmd_line.py
Modules/main.c
Python/pythonrun.c
Python/sysmodule.c

index 347b0a7a790c0669872125a6c52246b78240946f..d86599cbc3a0452d7377f44397fcbd3557194189 100644 (file)
@@ -21,6 +21,12 @@ extern int _PySys_SetIntMaxStrDigits(int maxdigits);
 
 extern int _PySysRemoteDebug_SendExec(int pid, int tid, const char *debugger_script_path);
 
+extern void _PySys_FormatV(
+    PyObject *key,
+    FILE *fp,
+    const char *format,
+    va_list va);
+
 #ifdef __cplusplus
 }
 #endif
index a8645af26b25d87d1883e0e64ab998291d152437..7640e50f19b7839c4c0b7c7df8ef76157ea1c46f 100644 (file)
@@ -314,7 +314,7 @@ class CmdLineTest(unittest.TestCase):
             # decodable from ASCII) and run_command() failed on
             # PyUnicode_AsUTF8String(). This is the expected behaviour on
             # Linux.
-            pattern = b"Unable to decode the command from the command line:"
+            pattern = b"python: Unable to decode the command from the command line:"
         elif p.returncode == 0:
             # _Py_char2wchar() decoded b'\xff' as '\xff' even if the locale is
             # C and the locale encoding is ASCII. It occurs on FreeBSD, Solaris
index a65247dc1e5c61756e601495e0875d1a4a59288f..ef22331760906cee4b8f86205b761d14ab12d8a0 100644 (file)
@@ -11,6 +11,7 @@
 #include "pycore_pylifecycle.h"   // _Py_PreInitializeFromPyArgv()
 #include "pycore_pystate.h"       // _PyInterpreterState_GET()
 #include "pycore_pythonrun.h"     // _PyRun_AnyFile()
+#include "pycore_sysmodule.h"     // _PySys_FormatV()
 #include "pycore_tuple.h"         // _PyTuple_FromPair
 #include "pycore_unicodeobject.h" // _PyUnicode_Dedent()
 
@@ -80,6 +81,32 @@ done:
 
 /* --- pymain_run_python() ---------------------------------------- */
 
+static void
+pymain_error_format(const char *format, ...)
+{
+    va_list vargs;
+    va_start(vargs, format);
+
+    PySys_WriteStderr("python: ");
+    _PySys_FormatV(&_Py_ID(stderr), stderr, format, vargs);
+    PySys_WriteStderr("\n");
+
+    va_end(vargs);
+}
+
+// See also pyrun_error()
+static void
+pymain_error(const char *msg)
+{
+    PySys_FormatStderr("python: %s\n", msg);
+}
+
+static int
+pymain_check_signals(void)
+{
+    return Py_MakePendingCalls();
+}
+
 /* Non-zero if filename, command (-c) or module (-m) is set
    on the command line */
 static inline int config_run_code(const PyConfig *config)
@@ -122,19 +149,29 @@ pymain_exit_err_print(void)
 }
 
 
-/* Write an exitcode into *exitcode and return 1 if we have to exit Python.
-   Return 0 otherwise. */
+// If filename is a package (ex: directory or ZIP file) which contains
+// __main__.py, main_importer_path is set to filename and will be prepended to
+// sys.path.
+//
+// Otherwise, main_importer_path is left unchanged.
+//
+// Write an exitcode into *exitcode and return 1 if we have to exit Python.
+// Return 0 otherwise.
 static int
-pymain_get_importer(const wchar_t *filename, PyObject **importer_p, int *exitcode)
+pymain_get_importer(const PyConfig *config, PyObject **importer_p,
+                    int *exitcode)
 {
-    PyObject *sys_path0 = NULL, *importer;
+    const wchar_t *filename = config->run_filename;
+    if (filename == NULL) {
+        return 0;
+    }
 
-    sys_path0 = PyUnicode_FromWideChar(filename, -1);
+    PyObject *sys_path0 = PyUnicode_FromWideChar(filename, -1);
     if (sys_path0 == NULL) {
         goto error;
     }
 
-    importer = PyImport_GetImporter(sys_path0);
+    PyObject *importer = PyImport_GetImporter(sys_path0);
     if (importer == NULL) {
         goto error;
     }
@@ -152,15 +189,16 @@ pymain_get_importer(const wchar_t *filename, PyObject **importer_p, int *exitcod
 error:
     Py_XDECREF(sys_path0);
 
-    PySys_WriteStderr("Failed checking if argv[0] is an import path entry\n");
+    pymain_error("Failed checking if argv[0] is an import path entry:");
     return pymain_err_print(exitcode);
 }
 
 
 static int
-pymain_sys_path_add_path0(PyInterpreterState *interp, PyObject *path0)
+pymain_sys_path_add_path0(PyObject *path0)
 {
     PyObject *sys_path;
+    PyInterpreterState *interp = _PyInterpreterState_GET();
     PyObject *sysdict = interp->sysdict;
     if (sysdict != NULL) {
         sys_path = PyDict_GetItemWithError(sysdict, &_Py_ID(path));
@@ -201,17 +239,21 @@ pymain_header(const PyConfig *config)
 }
 
 
-static void
+static int
 pymain_import_readline(const PyConfig *config)
 {
+    if (pymain_check_signals() < 0) {
+        return -1;
+    }
+
     if (config->isolated) {
-        return;
+        return 0;
     }
     if (!config->inspect && config_run_code(config)) {
-        return;
+        return 0;
     }
     if (!isatty(fileno(stdin))) {
-        return;
+        return 0;
     }
 
     PyObject *mod = PyImport_ImportModule("readline");
@@ -221,6 +263,7 @@ pymain_import_readline(const PyConfig *config)
     else {
         Py_DECREF(mod);
     }
+
     mod = PyImport_ImportModule("rlcompleter");
     if (mod == NULL) {
         PyErr_Clear();
@@ -228,6 +271,7 @@ pymain_import_readline(const PyConfig *config)
     else {
         Py_DECREF(mod);
     }
+    return 0;
 }
 
 
@@ -272,7 +316,7 @@ pymain_run_command(wchar_t *command)
     return 0;
 
 error:
-    PySys_WriteStderr("Unable to decode the command from the command line:\n");
+    pymain_error("Unable to decode the command from the command line:");
     return pymain_exit_err_print();
 }
 
@@ -289,13 +333,13 @@ pymain_run_pyrepl(int pythonstartup)
 
     PyObject *pyrepl = PyImport_ImportModule("_pyrepl.main");
     if (pyrepl == NULL) {
-        fprintf(stderr, "Could not import _pyrepl.main\n");
+        pymain_error("Could not import _pyrepl.main");
         goto error;
     }
 
     console = PyObject_GetAttrString(pyrepl, "interactive_console");
     if (console == NULL) {
-        fprintf(stderr, "Could not access _pyrepl.main.interactive_console\n");
+        pymain_error("Could not access _pyrepl.main.interactive_console");
         goto error;
     }
 
@@ -343,45 +387,56 @@ error:
 static int
 pymain_run_module(const wchar_t *modname, int set_argv0)
 {
-    PyObject *module, *runmodule, *runargs, *result;
+    int exitcode = 0;
+    PyObject *module = NULL;
+    PyObject *runmodule = NULL;
+    PyObject *runargs = NULL;
+    PyObject *result = NULL;
+
     if (PySys_Audit("cpython.run_module", "u", modname) < 0) {
-        return pymain_exit_err_print();
+        goto error;
     }
+
     runmodule = PyImport_ImportModuleAttrString("runpy",
                                                 "_run_module_as_main");
     if (runmodule == NULL) {
-        fprintf(stderr, "Could not import runpy._run_module_as_main\n");
-        return pymain_exit_err_print();
+        pymain_error("Could not import runpy._run_module_as_main");
+        goto error;
     }
+
     module = PyUnicode_FromWideChar(modname, -1);
     if (module == NULL) {
-        fprintf(stderr, "Could not convert module name to unicode\n");
-        Py_DECREF(runmodule);
-        return pymain_exit_err_print();
+        pymain_error("Could not convert module name to unicode");
+        goto error;
     }
+
     runargs = _PyTuple_FromPair(module, set_argv0 ? Py_True : Py_False);
     if (runargs == NULL) {
-        fprintf(stderr,
-            "Could not create arguments for runpy._run_module_as_main\n");
-        Py_DECREF(runmodule);
-        Py_DECREF(module);
-        return pymain_exit_err_print();
+        pymain_error("Could not create arguments "
+                     "for runpy._run_module_as_main");
+        goto error;
     }
+
     result = PyObject_Call(runmodule, runargs, NULL);
-    Py_DECREF(runmodule);
-    Py_DECREF(module);
-    Py_DECREF(runargs);
     if (result == NULL) {
-        return pymain_exit_err_print();
+        goto error;
     }
-    Py_DECREF(result);
-    return 0;
+
+done:
+    Py_XDECREF(module);
+    Py_XDECREF(runmodule);
+    Py_XDECREF(runargs);
+    Py_XDECREF(result);
+    return exitcode;
+
+error:
+    exitcode = pymain_exit_err_print();
+    goto done;
 }
 
 
 static int
-pymain_run_file_obj(PyObject *program_name, PyObject *filename,
-                    int skip_source_first_line)
+pymain_run_file_obj(PyObject *filename, int skip_source_first_line)
 {
     if (PySys_Audit("cpython.run_file", "O", filename) < 0) {
         return pymain_exit_err_print();
@@ -389,11 +444,8 @@ pymain_run_file_obj(PyObject *program_name, PyObject *filename,
 
     FILE *fp = Py_fopen(filename, "rb");
     if (fp == NULL) {
-        // Ignore the OSError
-        PyErr_Clear();
-        // TODO(picnixz): strerror() is locale dependent but not PySys_FormatStderr().
-        PySys_FormatStderr("%S: can't open file %R: [Errno %d] %s\n",
-                           program_name, filename, errno, strerror(errno));
+        pymain_error_format("can't open file %R:", filename);
+        pymain_exit_err_print();
         return 2;
     }
 
@@ -410,14 +462,13 @@ pymain_run_file_obj(PyObject *program_name, PyObject *filename,
 
     struct _Py_stat_struct sb;
     if (_Py_fstat_noraise(fileno(fp), &sb) == 0 && S_ISDIR(sb.st_mode)) {
-        PySys_FormatStderr("%S: %R is a directory, cannot continue\n",
-                           program_name, filename);
+        pymain_error_format("%R is a directory, cannot continue",
+                            filename);
         fclose(fp);
         return 1;
     }
 
-    // Call pending calls like signal handlers (SIGINT)
-    if (Py_MakePendingCalls() == -1) {
+    if (pymain_check_signals() < 0) {
         fclose(fp);
         return pymain_exit_err_print();
     }
@@ -439,16 +490,9 @@ pymain_run_file(const PyConfig *config)
     if (filename == NULL) {
         return pymain_exit_err_print();
     }
-    PyObject *program_name = PyUnicode_FromWideChar(config->program_name, -1);
-    if (program_name == NULL) {
-        Py_DECREF(filename);
-        return pymain_exit_err_print();
-    }
 
-    int exitcode = pymain_run_file_obj(program_name, filename,
-                                       config->skip_source_first_line);
-    Py_DECREF(filename);
-    Py_DECREF(program_name);
+    int exitcode = pymain_run_file_obj(filename, config->skip_source_first_line);
+    Py_XDECREF(filename);
     return exitcode;
 }
 
@@ -457,15 +501,17 @@ static int
 pymain_run_startup(PyConfig *config, int *exitcode)
 {
     int ret = 0;
+    PyObject *startup = NULL;
+
     if (!config->use_environment) {
-        return 0;
+        goto done;
     }
-    PyObject *startup = NULL;
 #ifdef MS_WINDOWS
     const wchar_t *env = _wgetenv(L"PYTHONSTARTUP");
     if (env == NULL || env[0] == L'\0') {
-        return 0;
+        goto done;
     }
+
     startup = PyUnicode_FromWideChar(env, -1);
     if (startup == NULL) {
         goto error;
@@ -473,8 +519,9 @@ pymain_run_startup(PyConfig *config, int *exitcode)
 #else
     const char *env = _Py_GetEnv(config->use_environment, "PYTHONSTARTUP");
     if (env == NULL) {
-        return 0;
+        goto done;
     }
+
     startup = PyUnicode_DecodeFSDefault(env);
     if (startup == NULL) {
         goto error;
@@ -486,12 +533,7 @@ pymain_run_startup(PyConfig *config, int *exitcode)
 
     FILE *fp = Py_fopen(startup, "r");
     if (fp == NULL) {
-        int save_errno = errno;
-        PyErr_Clear();
-        PySys_WriteStderr("Could not open PYTHONSTARTUP\n");
-
-        errno = save_errno;
-        PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, startup, NULL);
+        pymain_error("Could not open PYTHONSTARTUP");
         goto error;
     }
 
@@ -537,53 +579,55 @@ pymain_run_interactive_hook(int *exitcode)
         goto error;
     }
     Py_DECREF(result);
-
     return 0;
 
 error:
-    PySys_WriteStderr("Failed calling sys.__interactivehook__\n");
+    pymain_error("Failed calling sys.__interactivehook__:");
     return pymain_err_print(exitcode);
 }
 
 
-static void
-pymain_set_inspect(PyConfig *config, int inspect)
+static int
+pymain_set_inspect(PyConfig *config, int inspect, int *exitcode)
 {
     PyObject *value = PyLong_FromLong(inspect);
     if (value == NULL || PyConfig_Set("inspect", value) < 0) {
-        fprintf(stderr, "Could not set the inspect flag\n");
-        PyErr_Print();
+        Py_XDECREF(value);
+        pymain_error("Could not set the inspect flag");
+        return pymain_err_print(exitcode);
     }
     else {
         assert(config->inspect == inspect);
     }
     Py_XDECREF(value);
+    return 0;
 }
 
 
 static int
 _pymain_run_repl(PyConfig *config, int startup)
 {
-    /* call pending calls like signal handlers (SIGINT) */
-    if (Py_MakePendingCalls() == -1) {
-        return pymain_exit_err_print();
+    if (pymain_check_signals() < 0) {
+        goto error;
     }
 
     if (PySys_Audit("cpython.run_stdin", NULL) < 0) {
-        return pymain_exit_err_print();
+        goto error;
     }
 
     if (isatty(fileno(stdin))
-        && !_Py_GetEnv(config->use_environment, "PYTHON_BASIC_REPL")) {
+        && !_Py_GetEnv(config->use_environment, "PYTHON_BASIC_REPL"))
+    {
         PyObject *pyrepl = PyImport_ImportModule("_pyrepl");
         if (pyrepl != NULL) {
             int exitcode = pymain_run_pyrepl(startup);
             Py_DECREF(pyrepl);
             return exitcode;
         }
+
         if (!PyErr_ExceptionMatches(PyExc_ModuleNotFoundError)) {
-            fprintf(stderr, "Could not import _pyrepl.main\n");
-            return pymain_exit_err_print();
+            pymain_error("Could not import _pyrepl.main");
+            goto error;
         }
         PyErr_Clear();
     }
@@ -596,10 +640,13 @@ _pymain_run_repl(PyConfig *config, int startup)
         Py_DECREF(stdin_obj);
     }
     if (result == NULL) {
-        return pymain_exit_err_print();
+        goto error;
     }
     Py_DECREF(result);
     return 0;
+
+error:
+    return pymain_exit_err_print();
 }
 
 static int
@@ -607,9 +654,11 @@ pymain_run_stdin(PyConfig *config)
 {
     if (stdin_is_interactive(config)) {
         // do exit on SystemExit
-        pymain_set_inspect(config, 0);
-
         int exitcode;
+        if (pymain_set_inspect(config, 0, &exitcode)) {
+            return exitcode;
+        }
+
         if (pymain_run_startup(config, &exitcode)) {
             return exitcode;
         }
@@ -629,14 +678,18 @@ pymain_repl(PyConfig *config, int *exitcode)
     /* Check this environment variable at the end, to give programs the
        opportunity to set it from Python. */
     if (!config->inspect && _Py_GetEnv(config->use_environment, "PYTHONINSPECT")) {
-        pymain_set_inspect(config, 1);
+        if (pymain_set_inspect(config, 1, exitcode)) {
+            return;
+        }
     }
 
     if (!(config->inspect && stdin_is_interactive(config) && config_run_code(config))) {
         return;
     }
 
-    pymain_set_inspect(config, 0);
+    if (pymain_set_inspect(config, 0, exitcode)) {
+        return;
+    }
     if (pymain_run_interactive_hook(exitcode)) {
         return;
     }
@@ -645,16 +698,68 @@ pymain_repl(PyConfig *config, int *exitcode)
 }
 
 
+static int
+pymain_set_path0(PyObject *main_importer_path)
+{
+    PyConfig *config = (PyConfig *)_Py_GetConfig();
+
+    PyObject *path0 = NULL;
+    if (main_importer_path != NULL) {
+        path0 = Py_NewRef(main_importer_path);
+    }
+    else if (!config->safe_path) {
+        int res = _PyPathConfig_ComputeSysPath0(&config->argv, &path0);
+        if (res < 0) {
+            return -1;
+        }
+        else if (res == 0) {
+            Py_CLEAR(path0);
+        }
+    }
+
+    if (path0 == NULL) {
+        return 0;
+    }
+
+    // XXX Apply config->sys_path_0 in init_interp_main().  We have
+    // to be sure to get readline/rlcompleter imported at the correct time.
+    wchar_t *wstr = PyUnicode_AsWideCharString(path0, NULL);
+    if (wstr == NULL) {
+        goto error;
+    }
+
+    PyStatus status = PyConfig_SetString(config, &config->sys_path_0, wstr);
+    PyMem_Free(wstr);
+    if (_PyStatus_EXCEPTION(status)) {
+        _PyErr_SetFromPyStatus(status);
+        goto error;
+    }
+
+    int res = pymain_sys_path_add_path0(path0);
+    Py_DECREF(path0);
+
+    return res;
+
+error:
+    Py_DECREF(path0);
+    return -1;
+}
+
+
 static void
 pymain_run_python(int *exitcode)
 {
+    int set_running_main = 0;
+
     PyObject *main_importer_path = NULL;
     PyInterpreterState *interp = _PyInterpreterState_GET();
     /* pymain_repl() and pymain_run_stdin() modify the config */
     PyConfig *config = (PyConfig*)_PyInterpreterState_GetConfig(interp);
 
     /* ensure path config is written into global variables */
-    if (_PyStatus_EXCEPTION(_PyPathConfig_UpdateGlobal(config))) {
+    PyStatus status = _PyPathConfig_UpdateGlobal(config);
+    if (_PyStatus_EXCEPTION(status)) {
+        _PyErr_SetFromPyStatus(status);
         goto error;
     }
 
@@ -663,60 +768,29 @@ pymain_run_python(int *exitcode)
     // at that point.
     assert(config->sys_path_0 == NULL);
 
-    if (config->run_filename != NULL) {
-        /* If filename is a package (ex: directory or ZIP file) which contains
-           __main__.py, main_importer_path is set to filename and will be
-           prepended to sys.path.
-
-           Otherwise, main_importer_path is left unchanged. */
-        if (pymain_get_importer(config->run_filename, &main_importer_path,
-                                exitcode)) {
-            return;
-        }
+    if (pymain_get_importer(config, &main_importer_path, exitcode)) {
+        return;
     }
 
     // import readline and rlcompleter before script dir is added to sys.path
-    pymain_import_readline(config);
-
-    PyObject *path0 = NULL;
-    if (main_importer_path != NULL) {
-        path0 = Py_NewRef(main_importer_path);
-    }
-    else if (!config->safe_path) {
-        int res = _PyPathConfig_ComputeSysPath0(&config->argv, &path0);
-        if (res < 0) {
-            goto error;
-        }
-        else if (res == 0) {
-            Py_CLEAR(path0);
-        }
+    if (pymain_import_readline(config) < 0) {
+        goto error;
     }
-    // XXX Apply config->sys_path_0 in init_interp_main().  We have
-    // to be sure to get readline/rlcompleter imported at the correct time.
-    if (path0 != NULL) {
-        wchar_t *wstr = PyUnicode_AsWideCharString(path0, NULL);
-        if (wstr == NULL) {
-            Py_DECREF(path0);
-            goto error;
-        }
-        config->sys_path_0 = _PyMem_RawWcsdup(wstr);
-        PyMem_Free(wstr);
-        if (config->sys_path_0 == NULL) {
-            Py_DECREF(path0);
-            goto error;
-        }
-        int res = pymain_sys_path_add_path0(interp, path0);
-        Py_DECREF(path0);
-        if (res < 0) {
-            goto error;
-        }
+
+    if (pymain_set_path0(main_importer_path) < 0) {
+        goto error;
     }
 
     pymain_header(config);
 
     _PyInterpreterState_SetRunningMain(interp);
+    set_running_main = 1;
     assert(!PyErr_Occurred());
 
+    if (pymain_check_signals() < 0) {
+        goto error;
+    }
+
     if (config->run_command) {
         *exitcode = pymain_run_command(config->run_command);
     }
@@ -733,6 +807,10 @@ pymain_run_python(int *exitcode)
         *exitcode = pymain_run_stdin(config);
     }
 
+    if (pymain_check_signals() < 0) {
+        goto error;
+    }
+
     pymain_repl(config, exitcode);
     goto done;
 
@@ -740,7 +818,9 @@ error:
     *exitcode = pymain_exit_err_print();
 
 done:
-    _PyInterpreterState_SetNotRunningMain(interp);
+    if (set_running_main) {
+        _PyInterpreterState_SetNotRunningMain(interp);
+    }
     Py_XDECREF(main_importer_path);
 }
 
index e0a752720dfcc2debea27212b82ee68a19a665f2..5abfdc04538c369dfff59e2b2f0f48f773576ab0 100644 (file)
@@ -60,6 +60,14 @@ _PyRun_File(FILE *fp, PyObject *filename, int start, PyObject *globals,
             PyObject *locals, int closeit, PyCompilerFlags *flags);
 
 
+// See also pymain_error()
+static void
+pyrun_error(const char *msg)
+{
+    PySys_FormatStderr("python: %s\n", msg);
+}
+
+
 PyObject*
 _PyRun_AnyFile(FILE *fp, PyObject *filename, int closeit,
                PyCompilerFlags *flags)
@@ -496,7 +504,7 @@ _PyRun_SimpleFile(FILE *fp, PyObject *filename, int closeit,
     }
     if (!has_file) {
         if (PyDict_SetItemString(dict, "__file__", filename) < 0) {
-            fprintf(stderr, "python: failed to set __main__.__file__\n");
+            pyrun_error("failed to set __main__.__file__");
             goto done;
         }
         set_file_name = 1;
@@ -516,12 +524,12 @@ _PyRun_SimpleFile(FILE *fp, PyObject *filename, int closeit,
 
         pyc_fp = Py_fopen(filename, "rb");
         if (pyc_fp == NULL) {
-            fprintf(stderr, "python: Can't reopen .pyc file\n");
+            pyrun_error("Can't reopen .pyc file");
             goto done;
         }
 
         if (set_main_loader(dict, filename, "SourcelessFileLoader") < 0) {
-            fprintf(stderr, "python: failed to set __main__.__loader__\n");
+            pyrun_error("failed to set __main__.__loader__");
             fclose(pyc_fp);
             goto done;
         }
@@ -530,7 +538,7 @@ _PyRun_SimpleFile(FILE *fp, PyObject *filename, int closeit,
         /* When running from stdin, leave __main__.__loader__ alone */
         if ((!PyUnicode_Check(filename) || !PyUnicode_EqualToUTF8(filename, "<stdin>")) &&
             set_main_loader(dict, filename, "SourceFileLoader") < 0) {
-            fprintf(stderr, "python: failed to set __main__.__loader__\n");
+            pyrun_error("failed to set __main__.__loader__");
             goto done;
         }
         res = _PyRun_File(fp, filename, Py_file_input, dict, dict,
@@ -541,7 +549,7 @@ _PyRun_SimpleFile(FILE *fp, PyObject *filename, int closeit,
   done:
     if (set_file_name) {
         if (PyDict_PopString(dict, "__file__", NULL) < 0) {
-            fprintf(stderr, "python: failed to delete __main__.__file__\n");
+            pyrun_error("failed to delete __main__.__file__");
             Py_CLEAR(res);
         }
     }
index d9f7b9c449cfb9487fdf7429b62b013eb33109f0..9442472b53abbe1d8d5659df107462c871cb98c2 100644 (file)
@@ -4641,8 +4641,8 @@ PySys_WriteStderr(const char *format, ...)
     va_end(va);
 }
 
-static void
-sys_format(PyObject *key, FILE *fp, const char *format, va_list va)
+void
+_PySys_FormatV(PyObject *key, FILE *fp, const char *format, va_list va)
 {
     PyObject *file, *message;
     const char *utf8;
@@ -4664,13 +4664,14 @@ sys_format(PyObject *key, FILE *fp, const char *format, va_list va)
     _PyErr_SetRaisedException(tstate, exc);
 }
 
+
 void
 PySys_FormatStdout(const char *format, ...)
 {
     va_list va;
 
     va_start(va, format);
-    sys_format(&_Py_ID(stdout), stdout, format, va);
+    _PySys_FormatV(&_Py_ID(stdout), stdout, format, va);
     va_end(va);
 }
 
@@ -4680,7 +4681,7 @@ PySys_FormatStderr(const char *format, ...)
     va_list va;
 
     va_start(va, format);
-    sys_format(&_Py_ID(stderr), stderr, format, va);
+    _PySys_FormatV(&_Py_ID(stderr), stderr, format, va);
     va_end(va);
 }