[Python-checkins] bpo-41064: Improve syntax error for invalid usage of '**' in f-strings (GH-25006)

pablogsal webhook-mailer at python.org
Wed Mar 24 15:34:43 EDT 2021


https://github.com/python/cpython/commit/8efad61963809d239cac986e3f3bc4cb505ab8fe
commit: 8efad61963809d239cac986e3f3bc4cb505ab8fe
branch: master
author: Pablo Galindo <Pablogsal at gmail.com>
committer: pablogsal <Pablogsal at gmail.com>
date: 2021-03-24T19:34:17Z
summary:

bpo-41064: Improve syntax error for invalid usage of '**' in f-strings (GH-25006)

files:
A Misc/NEWS.d/next/Core and Builtins/2021-03-24-00-32-20.bpo-41064._H0K_g.rst
M Grammar/python.gram
M Lib/test/test_fstring.py
M Parser/parser.c

diff --git a/Grammar/python.gram b/Grammar/python.gram
index 7247962d3b971..4f3b649f9d57e 100644
--- a/Grammar/python.gram
+++ b/Grammar/python.gram
@@ -842,6 +842,8 @@ invalid_for_target:
 invalid_group:
     | '(' a=starred_expression ')' {
         RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "can't use starred expression here") }
+    | '(' a='**' expression ')' {
+        RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "can't use double starred expression here") }
 invalid_import_from_targets:
     | import_from_as_names ',' {
         RAISE_SYNTAX_ERROR("trailing comma not allowed without surrounding parentheses") }
diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py
index d7143d154a1bc..79e123f4b8cec 100644
--- a/Lib/test/test_fstring.py
+++ b/Lib/test/test_fstring.py
@@ -1275,5 +1275,14 @@ def test_with_an_underscore_and_a_comma_in_format_specifier(self):
         with self.assertRaisesRegex(ValueError, error_msg):
             f'{1:_,}'
 
+    def test_syntax_error_for_starred_expressions(self):
+        error_msg = re.escape("can't use starred expression here")
+        with self.assertRaisesRegex(SyntaxError, error_msg):
+            compile("f'{*a}'", "?", "exec")
+
+        error_msg = re.escape("can't use double starred expression here")
+        with self.assertRaisesRegex(SyntaxError, error_msg):
+            compile("f'{**a}'", "?", "exec")
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-03-24-00-32-20.bpo-41064._H0K_g.rst b/Misc/NEWS.d/next/Core and Builtins/2021-03-24-00-32-20.bpo-41064._H0K_g.rst
new file mode 100644
index 0000000000000..f6ea4d0bda6a0
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2021-03-24-00-32-20.bpo-41064._H0K_g.rst	
@@ -0,0 +1,2 @@
+Improve the syntax error for invalid usage of double starred elements ('**')
+in f-strings. Patch by Pablo Galindo.
diff --git a/Parser/parser.c b/Parser/parser.c
index 6efaebe179b9c..de90c87db38e6 100644
--- a/Parser/parser.c
+++ b/Parser/parser.c
@@ -18285,7 +18285,7 @@ invalid_for_target_rule(Parser *p)
     return _res;
 }
 
-// invalid_group: '(' starred_expression ')'
+// invalid_group: '(' starred_expression ')' | '(' '**' expression ')'
 static void *
 invalid_group_rule(Parser *p)
 {
@@ -18326,6 +18326,39 @@ invalid_group_rule(Parser *p)
         D(fprintf(stderr, "%*c%s invalid_group[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' starred_expression ')'"));
     }
+    { // '(' '**' expression ')'
+        if (p->error_indicator) {
+            D(p->level--);
+            return NULL;
+        }
+        D(fprintf(stderr, "%*c> invalid_group[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' '**' expression ')'"));
+        Token * _literal;
+        Token * _literal_1;
+        Token * a;
+        expr_ty expression_var;
+        if (
+            (_literal = _PyPegen_expect_token(p, 7))  // token='('
+            &&
+            (a = _PyPegen_expect_token(p, 35))  // token='**'
+            &&
+            (expression_var = expression_rule(p))  // expression
+            &&
+            (_literal_1 = _PyPegen_expect_token(p, 8))  // token=')'
+        )
+        {
+            D(fprintf(stderr, "%*c+ invalid_group[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' '**' expression ')'"));
+            _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "can't use double starred expression here" );
+            if (_res == NULL && PyErr_Occurred()) {
+                p->error_indicator = 1;
+                D(p->level--);
+                return NULL;
+            }
+            goto done;
+        }
+        p->mark = _mark;
+        D(fprintf(stderr, "%*c%s invalid_group[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' '**' expression ')'"));
+    }
     _res = NULL;
   done:
     D(p->level--);



More information about the Python-checkins mailing list