]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-40985: Show correct SyntaxError text when last line has a LINECONT (GH-20888)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 16 Jun 2020 00:46:44 +0000 (17:46 -0700)
committerGitHub <noreply@github.com>
Tue, 16 Jun 2020 00:46:44 +0000 (17:46 -0700)
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.
(cherry picked from commit 113e2b0a07c72c0d5e3489076afb14f6b3ad1049)

Co-authored-by: Lysandros Nikolaou <lisandrosnik@gmail.com>
Lib/test/test_eof.py
Misc/NEWS.d/next/Core and Builtins/2020-06-15-16-29-55.bpo-40985.IIN_xX.rst [new file with mode: 0644]
Python/errors.c

index bebad3106119ecf530d1b70bb55614ccf4df9852..51cbbd8eed664fa22b0f526c603f6adea3755e3b 100644 (file)
@@ -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 (file)
index 0000000..e07134c
--- /dev/null
@@ -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.
index 5d1725679c4bdc25b39de7583c919989cc7acb62..87af39d527a512668dfc16ab44baf0da01e3a6af 100644 (file)
@@ -1648,16 +1648,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,
@@ -1665,6 +1667,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;