From 113e2b0a07c72c0d5e3489076afb14f6b3ad1049 Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Tue, 16 Jun 2020 03:27:33 +0300 Subject: [PATCH] bpo-40985: Show correct SyntaxError text when last line has a LINECONT (GH-20888) When a file ends with a line that contains a line continuation character the text of the emitted SyntaxError is empty, contrary to the old parser, where the error text contained the text of the last line. --- Lib/test/test_eof.py | 4 ++++ .../2020-06-15-16-29-55.bpo-40985.IIN_xX.rst | 1 + Python/errors.c | 12 ++++++++---- 3 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-15-16-29-55.bpo-40985.IIN_xX.rst diff --git a/Lib/test/test_eof.py b/Lib/test/test_eof.py index bebad310611..51cbbd8eed6 100644 --- a/Lib/test/test_eof.py +++ b/Lib/test/test_eof.py @@ -52,10 +52,14 @@ class EOFTestCase(unittest.TestCase): file_name = script_helper.make_script(temp_dir, 'foo', '\\') rc, out, err = script_helper.assert_python_failure(file_name) self.assertIn(b'unexpected EOF while parsing', err) + self.assertIn(b'line 2', err) + self.assertIn(b'\\', err) file_name = script_helper.make_script(temp_dir, 'foo', 'y = 6\\') rc, out, err = script_helper.assert_python_failure(file_name) self.assertIn(b'unexpected EOF while parsing', err) + self.assertIn(b'line 2', err) + self.assertIn(b'y = 6\\', err) if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-15-16-29-55.bpo-40985.IIN_xX.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-15-16-29-55.bpo-40985.IIN_xX.rst new file mode 100644 index 00000000000..e07134c7166 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-15-16-29-55.bpo-40985.IIN_xX.rst @@ -0,0 +1 @@ +Fix a bug that caused the :exc:`SyntaxError` text to be empty when a file ends with a line ending in a line continuation character (i.e. backslash). The error text should contain the text of the last line. diff --git a/Python/errors.c b/Python/errors.c index cc00ae4a540..720f18bc224 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -1646,16 +1646,18 @@ err_programtext(PyThreadState *tstate, FILE *fp, int lineno) { int i; char linebuf[1000]; - - if (fp == NULL) + if (fp == NULL) { return NULL; + } + for (i = 0; i < lineno; i++) { char *pLastChar = &linebuf[sizeof(linebuf) - 2]; do { *pLastChar = '\0'; if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf, - fp, NULL) == NULL) - break; + fp, NULL) == NULL) { + goto after_loop; + } /* fgets read *something*; if it didn't get as far as pLastChar, it must have found a newline or hit the end of the file; if pLastChar is \n, @@ -1663,6 +1665,8 @@ err_programtext(PyThreadState *tstate, FILE *fp, int lineno) yet seen a newline, so must continue */ } while (*pLastChar != '\0' && *pLastChar != '\n'); } + +after_loop: fclose(fp); if (i == lineno) { PyObject *res;