Skip to content

Commit 791a46e

Browse files
authored
[3.9] bpo-38964: Print correct filename on a SyntaxError in an fstring (GH-20399) (GH-20404)
When a `SyntaxError` in the expression part of a fstring is found, the filename attribute of the `SyntaxError` is always `<fstring>`. With this commit, it gets changed to always have the name of the file the fstring resides in. Co-authored-by: Pablo Galindo <[email protected]>. (cherry picked from commit f7b1e46)
1 parent 6cb0ad2 commit 791a46e

File tree

3 files changed

+16
-6
lines changed

3 files changed

+16
-6
lines changed

Lib/test/test_fstring.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
# Unicode identifiers in tests is allowed by PEP 3131.
99

1010
import ast
11+
import os
1112
import types
1213
import decimal
1314
import unittest
14-
from test.support import use_old_parser
15+
from test.support import temp_cwd, use_old_parser
16+
from test.support.script_helper import assert_python_failure
1517

1618
a_global = 'global variable'
1719

@@ -1050,6 +1052,16 @@ def test_errors(self):
10501052
r"f'{1000:j}'",
10511053
])
10521054

1055+
@unittest.skipIf(use_old_parser(), "The old parser only supports <fstring> as the filename")
1056+
def test_filename_in_syntaxerror(self):
1057+
# see issue 38964
1058+
with temp_cwd() as cwd:
1059+
file_path = os.path.join(cwd, 't.py')
1060+
with open(file_path, 'w') as f:
1061+
f.write('f"{a b}"') # This generates a SyntaxError
1062+
_, _, stderr = assert_python_failure(file_path)
1063+
self.assertIn(file_path, stderr.decode('utf-8'))
1064+
10531065
def test_loop(self):
10541066
for i in range(1000):
10551067
self.assertEqual(f'i:{i}', 'i:' + str(i))
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
When there's a :exc:`SyntaxError` in the expression part of an fstring, the filename attribute of the :exc:`SyntaxError` gets correctly set to the name of the file the fstring resides in.

Parser/pegen/parse_string.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -606,11 +606,8 @@ fstring_compile_expr(Parser *p, const char *expr_start, const char *expr_end,
606606
if (tok == NULL) {
607607
return NULL;
608608
}
609-
tok->filename = PyUnicode_FromString("<fstring>");
610-
if (!tok->filename) {
611-
PyTokenizer_Free(tok);
612-
return NULL;
613-
}
609+
Py_INCREF(p->tok->filename);
610+
tok->filename = p->tok->filename;
614611

615612
Parser *p2 = _PyPegen_Parser_New(tok, Py_fstring_input, p->flags, p->feature_version,
616613
NULL, p->arena);

0 commit comments

Comments
 (0)