From e0a2f53d96549d55be139268b1da661bdbb63515 Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Tue, 26 May 2020 00:40:46 +0300 Subject: [PATCH 1/5] bpo-38964: Print correct filename on a SyntaxError in an fstring When a `SyntaxError` in the expression part of an fstring is found, the filename attribute of the `SyntaxError` is always ``. With this PR it gets changed to always have the name of the file the fstring resides in. --- Lib/test/test_fstring.py | 12 ++++++++++++ Parser/pegen/parse_string.c | 7 ++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index e0bb5b56b2614f..d22dd4c444d28d 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -8,9 +8,12 @@ # Unicode identifiers in tests is allowed by PEP 3131. import ast +import os import types import decimal import unittest +from test.support import temp_cwd +from test.support.script_helper import assert_python_failure a_global = 'global variable' @@ -1044,6 +1047,15 @@ def test_errors(self): r"f'{1000:j}'", ]) + def test_filename_in_syntaxerror(self): + # see issue 38964 + with temp_cwd() as cwd: + filename = os.path.join(cwd, 't.py') + with open(filename, 'w') as f: + f.write('f"{a b}"') # This generates a SyntaxError + _, _, stderr = assert_python_failure(filename) + self.assertIn(filename, stderr.decode('utf-8')) + def test_loop(self): for i in range(1000): self.assertEqual(f'i:{i}', 'i:' + str(i)) diff --git a/Parser/pegen/parse_string.c b/Parser/pegen/parse_string.c index ca4b733c153b57..a0ec698fa56a24 100644 --- a/Parser/pegen/parse_string.c +++ b/Parser/pegen/parse_string.c @@ -606,11 +606,8 @@ fstring_compile_expr(Parser *p, const char *expr_start, const char *expr_end, if (tok == NULL) { return NULL; } - tok->filename = PyUnicode_FromString(""); - if (!tok->filename) { - PyTokenizer_Free(tok); - return NULL; - } + Py_INCREF(p->tok->filename); + tok->filename = p->tok->filename; Parser *p2 = _PyPegen_Parser_New(tok, Py_fstring_input, p->flags, p->feature_version, NULL, p->arena); From f44d71f1819c01da325fe2c28ee60e7144d8876e Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 25 May 2020 21:49:15 +0000 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Core and Builtins/2020-05-25-21-49-11.bpo-38964.lrml90.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-05-25-21-49-11.bpo-38964.lrml90.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-25-21-49-11.bpo-38964.lrml90.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-25-21-49-11.bpo-38964.lrml90.rst new file mode 100644 index 00000000000000..12007643069466 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-05-25-21-49-11.bpo-38964.lrml90.rst @@ -0,0 +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. \ No newline at end of file From 2cde8f9e2b928d1423388b6cacb57c94718939e0 Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Tue, 26 May 2020 01:16:04 +0300 Subject: [PATCH 3/5] Skip the test with the old parser --- Lib/test/test_fstring.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index d22dd4c444d28d..dcedcad3fc3063 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -12,7 +12,7 @@ import types import decimal import unittest -from test.support import temp_cwd +from test.support import temp_cwd, use_old_parser from test.support.script_helper import assert_python_failure a_global = 'global variable' @@ -1047,6 +1047,7 @@ def test_errors(self): r"f'{1000:j}'", ]) + @unittest.skipIf(use_old_parser(), "This is not supported by the old parser") def test_filename_in_syntaxerror(self): # see issue 38964 with temp_cwd() as cwd: From 817b693ac05b56fbfc76a6e59e6a960bc9cc7d6b Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Tue, 26 May 2020 01:19:01 +0300 Subject: [PATCH 4/5] Rename filename to file_path --- Lib/test/test_fstring.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index dcedcad3fc3063..53ff2e97c4b307 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -1051,11 +1051,11 @@ def test_errors(self): def test_filename_in_syntaxerror(self): # see issue 38964 with temp_cwd() as cwd: - filename = os.path.join(cwd, 't.py') - with open(filename, 'w') as f: + file_path = os.path.join(cwd, 't.py') + with open(file_path, 'w') as f: f.write('f"{a b}"') # This generates a SyntaxError - _, _, stderr = assert_python_failure(filename) - self.assertIn(filename, stderr.decode('utf-8')) + _, _, stderr = assert_python_failure(file_path) + self.assertIn(file_path, stderr.decode('utf-8')) def test_loop(self): for i in range(1000): From 0371cc6cb8e1df7b2b75815171a204b1ba737607 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Mon, 25 May 2020 23:31:01 +0100 Subject: [PATCH 5/5] Update Lib/test/test_fstring.py --- Lib/test/test_fstring.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index 53ff2e97c4b307..ea4e589929e7ec 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -1047,7 +1047,7 @@ def test_errors(self): r"f'{1000:j}'", ]) - @unittest.skipIf(use_old_parser(), "This is not supported by the old parser") + @unittest.skipIf(use_old_parser(), "The old parser only supports as the filename") def test_filename_in_syntaxerror(self): # see issue 38964 with temp_cwd() as cwd: