From 5c71e35befb1fef5cdedcbca796b3e08cbb441c3 Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Tue, 23 Jun 2020 02:34:31 +0300 Subject: [PATCH 1/4] bpo-41084: Adjust message when an f-string expression causes a SyntaxError Prefix the error message with `fstring: `, when parsing an f-string expression throws a `SyntaxError`. --- Lib/test/test_fstring.py | 10 +++++++--- Parser/pegen.c | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index 9eb7ebe10559a4e..d015cc219637b53 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -524,7 +524,7 @@ def test_format_specifier_expressions(self): # This looks like a nested format spec. ]) - self.assertAllRaise(SyntaxError, "invalid syntax", + self.assertAllRaise(SyntaxError, "f-string: invalid syntax", [# Invalid syntax inside a nested spec. "f'{4:{/5}}'", ]) @@ -598,7 +598,7 @@ def test_parens_in_expressions(self): # are added around it. But we shouldn't go from an invalid # expression to a valid one. The added parens are just # supposed to allow whitespace (including newlines). - self.assertAllRaise(SyntaxError, 'invalid syntax', + self.assertAllRaise(SyntaxError, 'f-string: invalid syntax', ["f'{,}'", "f'{,}'", # this is (,), which is an error ]) @@ -716,7 +716,7 @@ def test_lambda(self): # lambda doesn't work without parens, because the colon # makes the parser think it's a format_spec - self.assertAllRaise(SyntaxError, 'invalid syntax', + self.assertAllRaise(SyntaxError, 'f-string: invalid syntax', ["f'{lambda x:x}'", ]) @@ -1193,6 +1193,10 @@ def test_walrus(self): self.assertEqual(f'{(x:=10)}', '10') self.assertEqual(x, 10) + def test_invalid_syntax_error_message(self): + with self.assertRaisesRegex(SyntaxError, "f-string: invalid syntax"): + compile("f'{a $ b}'", "?", "exec") + if __name__ == '__main__': unittest.main() diff --git a/Parser/pegen.c b/Parser/pegen.c index 594754cee5d5380..79fcd2f5999de17 100644 --- a/Parser/pegen.c +++ b/Parser/pegen.c @@ -391,6 +391,21 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, PyObject *tmp = NULL; p->error_indicator = 1; + if (p->start_rule == Py_fstring_input) { + const char *fstring_msg = "f-string: "; + Py_ssize_t len = strlen(fstring_msg) + strlen(errmsg); + + char *new_errmsg = PyMem_RawMalloc(len + 1); // Lengths of both strings plus NULL character + if (!new_errmsg) { + return (void *) PyErr_NoMemory(); + } + + // Copy both strings into new buffer + memcpy(new_errmsg, fstring_msg, strlen(fstring_msg)); + memcpy(new_errmsg + strlen(fstring_msg), errmsg, strlen(errmsg)); + new_errmsg[len] = 0; + errmsg = new_errmsg; + } errstr = PyUnicode_FromFormatV(errmsg, va); if (!errstr) { goto error; @@ -427,11 +442,17 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, Py_DECREF(errstr); Py_DECREF(value); + if (p->start_rule == Py_fstring_input) { + PyMem_RawFree((void *)errmsg); + } return NULL; error: Py_XDECREF(errstr); Py_XDECREF(error_line); + if (p->start_rule == Py_fstring_input) { + PyMem_RawFree((void *)errmsg); + } return NULL; } From d50dad01f5edd6c61a273ab2b97ee6be239720dc Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Tue, 23 Jun 2020 15:10:24 +0000 Subject: [PATCH 2/4] =?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-06-23-15-10-19.bpo-41084.pt3y7F.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-23-15-10-19.bpo-41084.pt3y7F.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-23-15-10-19.bpo-41084.pt3y7F.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-23-15-10-19.bpo-41084.pt3y7F.rst new file mode 100644 index 000000000000000..5064622c35bf7e3 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-23-15-10-19.bpo-41084.pt3y7F.rst @@ -0,0 +1 @@ +Prefix the error message with `fstring: `, when parsing an f-string expression throws a :exc:`SyntaxError`. \ No newline at end of file From 2367cdc3f58f7942ceb098eeb0c8735bb47418b4 Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Tue, 23 Jun 2020 19:47:09 +0300 Subject: [PATCH 3/4] Fix NEWS blurb --- .../Core and Builtins/2020-06-23-15-10-19.bpo-41084.pt3y7F.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-23-15-10-19.bpo-41084.pt3y7F.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-23-15-10-19.bpo-41084.pt3y7F.rst index 5064622c35bf7e3..d70e0df9c6ff5b9 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-23-15-10-19.bpo-41084.pt3y7F.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-23-15-10-19.bpo-41084.pt3y7F.rst @@ -1 +1 @@ -Prefix the error message with `fstring: `, when parsing an f-string expression throws a :exc:`SyntaxError`. \ No newline at end of file +Prefix the error message with 'f-string: ', when parsing an f-string expression throws a :exc:`SyntaxError`. From 368beeaa29f44004668b34410ae3a3cd7fc34153 Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Tue, 23 Jun 2020 19:51:19 +0300 Subject: [PATCH 4/4] Address Eric's feedback about the NEWS blurb text --- .../Core and Builtins/2020-06-23-15-10-19.bpo-41084.pt3y7F.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-23-15-10-19.bpo-41084.pt3y7F.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-23-15-10-19.bpo-41084.pt3y7F.rst index d70e0df9c6ff5b9..cd349af770bd078 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-23-15-10-19.bpo-41084.pt3y7F.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-23-15-10-19.bpo-41084.pt3y7F.rst @@ -1 +1 @@ -Prefix the error message with 'f-string: ', when parsing an f-string expression throws a :exc:`SyntaxError`. +Prefix the error message with 'f-string: ', when parsing an f-string expression which throws a :exc:`SyntaxError`.