Skip to content

Commit 113e2b0

Browse files
authored
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.
1 parent 8666356 commit 113e2b0

File tree

3 files changed

+13
-4
lines changed

3 files changed

+13
-4
lines changed

Lib/test/test_eof.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,14 @@ def test_line_continuation_EOF_from_file_bpo2180(self):
5252
file_name = script_helper.make_script(temp_dir, 'foo', '\\')
5353
rc, out, err = script_helper.assert_python_failure(file_name)
5454
self.assertIn(b'unexpected EOF while parsing', err)
55+
self.assertIn(b'line 2', err)
56+
self.assertIn(b'\\', err)
5557

5658
file_name = script_helper.make_script(temp_dir, 'foo', 'y = 6\\')
5759
rc, out, err = script_helper.assert_python_failure(file_name)
5860
self.assertIn(b'unexpected EOF while parsing', err)
61+
self.assertIn(b'line 2', err)
62+
self.assertIn(b'y = 6\\', err)
5963

6064
if __name__ == "__main__":
6165
unittest.main()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
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.

Python/errors.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1646,23 +1646,27 @@ err_programtext(PyThreadState *tstate, FILE *fp, int lineno)
16461646
{
16471647
int i;
16481648
char linebuf[1000];
1649-
1650-
if (fp == NULL)
1649+
if (fp == NULL) {
16511650
return NULL;
1651+
}
1652+
16521653
for (i = 0; i < lineno; i++) {
16531654
char *pLastChar = &linebuf[sizeof(linebuf) - 2];
16541655
do {
16551656
*pLastChar = '\0';
16561657
if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf,
1657-
fp, NULL) == NULL)
1658-
break;
1658+
fp, NULL) == NULL) {
1659+
goto after_loop;
1660+
}
16591661
/* fgets read *something*; if it didn't get as
16601662
far as pLastChar, it must have found a newline
16611663
or hit the end of the file; if pLastChar is \n,
16621664
it obviously found a newline; else we haven't
16631665
yet seen a newline, so must continue */
16641666
} while (*pLastChar != '\0' && *pLastChar != '\n');
16651667
}
1668+
1669+
after_loop:
16661670
fclose(fp);
16671671
if (i == lineno) {
16681672
PyObject *res;

0 commit comments

Comments
 (0)