diff options
author | Victor Stinner <vstinner@python.org> | 2020-12-15 15:25:27 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-15 15:25:27 (GMT) |
commit | ceb420251c1d635520049fbb7b5269a73d63fb58 (patch) | |
tree | f42f9ef03f9e783bff9f9b13d52819704e1c8b65 /Modules/main.c | |
parent | f7049b5fb680c774e4950d10be62859a749f4e79 (diff) | |
download | cpython-ceb420251c1d635520049fbb7b5269a73d63fb58.zip cpython-ceb420251c1d635520049fbb7b5269a73d63fb58.tar.gz cpython-ceb420251c1d635520049fbb7b5269a73d63fb58.tar.bz2 |
bpo-32381: pymain_run_file() uses PySys_FormatStderr() (GH-23778)
If config->run_filename doesn't exist, log the error into sys.stderr
using "%R" format, to escape properly unencodable characters (usually
with backslashreplace).
Diffstat (limited to 'Modules/main.c')
-rw-r--r-- | Modules/main.c | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/Modules/main.c b/Modules/main.c index 7ffcb07..b97034e 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -305,20 +305,23 @@ pymain_run_module(const wchar_t *modname, int set_argv0) static int -pymain_run_file(const PyConfig *config, PyCompilerFlags *cf) +pymain_run_file_obj(PyObject *program_name, PyObject *filename, + int skip_source_first_line, PyCompilerFlags *cf) { - const wchar_t *filename = config->run_filename; - if (PySys_Audit("cpython.run_file", "u", filename) < 0) { + if (PySys_Audit("cpython.run_file", "O", filename) < 0) { return pymain_exit_err_print(); } - FILE *fp = _Py_wfopen(filename, L"rb"); + + FILE *fp = _Py_fopen_obj(filename, "rb"); if (fp == NULL) { - fprintf(stderr, "%ls: can't open file '%ls': [Errno %d] %s\n", - config->program_name, filename, errno, strerror(errno)); + // Ignore the OSError + PyErr_Clear(); + PySys_FormatStderr("%S: can't open file %R: [Errno %d] %s\n", + program_name, filename, errno, strerror(errno)); return 2; } - if (config->skip_source_first_line) { + if (skip_source_first_line) { int ch; /* Push back first newline so line numbers remain the same */ while ((ch = getc(fp)) != EOF) { @@ -331,29 +334,43 @@ pymain_run_file(const PyConfig *config, PyCompilerFlags *cf) struct _Py_stat_struct sb; if (_Py_fstat_noraise(fileno(fp), &sb) == 0 && S_ISDIR(sb.st_mode)) { - fprintf(stderr, - "%ls: '%ls' is a directory, cannot continue\n", - config->program_name, filename); + PySys_FormatStderr("%S: %R is a directory, cannot continue\n", + program_name, filename); fclose(fp); return 1; } - /* call pending calls like signal handlers (SIGINT) */ + // Call pending calls like signal handlers (SIGINT) if (Py_MakePendingCalls() == -1) { fclose(fp); return pymain_exit_err_print(); } - PyObject *filename_obj = PyUnicode_FromWideChar(filename, -1); - if (filename_obj == NULL) { + /* PyRun_AnyFileExFlags(closeit=1) calls fclose(fp) before running code */ + int run = _PyRun_AnyFileObject(fp, filename, 1, cf); + return (run != 0); +} + +static int +pymain_run_file(const PyConfig *config, PyCompilerFlags *cf) +{ + PyObject *filename = PyUnicode_FromWideChar(config->run_filename, -1); + if (filename == NULL) { + PyErr_Print(); + return -1; + } + PyObject *program_name = PyUnicode_FromWideChar(config->program_name, -1); + if (program_name == NULL) { + Py_DECREF(filename); PyErr_Print(); return -1; } - /* PyRun_AnyFileExFlags(closeit=1) calls fclose(fp) before running code */ - int run = _PyRun_AnyFileObject(fp, filename_obj, 1, cf); - Py_XDECREF(filename_obj); - return (run != 0); + int res = pymain_run_file_obj(program_name, filename, + config->skip_source_first_line, cf); + Py_DECREF(filename); + Py_DECREF(program_name); + return res; } |