Skip to content

Commit

Permalink
bpo-40985: Show correct SyntaxError text when last line has a LINECONT (
Browse files Browse the repository at this point in the history
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.
(cherry picked from commit 113e2b0)

Co-authored-by: Lysandros Nikolaou <lisandrosnik@gmail.com>
  • Loading branch information
miss-islington and lysnikolaou committed Jun 16, 2020
1 parent bc996c6 commit 097b8b6
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 4 deletions.
4 changes: 4 additions & 0 deletions Lib/test/test_eof.py
Expand Up @@ -52,10 +52,14 @@ def test_line_continuation_EOF_from_file_bpo2180(self):
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()
@@ -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.
12 changes: 8 additions & 4 deletions Python/errors.c
Expand Up @@ -1648,23 +1648,27 @@ 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,
it obviously found a newline; else we haven't
yet seen a newline, so must continue */
} while (*pLastChar != '\0' && *pLastChar != '\n');
}

after_loop:
fclose(fp);
if (i == lineno) {
PyObject *res;
Expand Down

0 comments on commit 097b8b6

Please sign in to comment.