[Python-checkins] bpo-44792: Improve syntax errors for if expressions (GH-27506) (GH-27565)

pablogsal webhook-mailer at python.org
Mon Aug 2 15:05:43 EDT 2021


https://github.com/python/cpython/commit/567176249ea95c074eb80199aaf19f3a55aa3954
commit: 567176249ea95c074eb80199aaf19f3a55aa3954
branch: 3.10
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: pablogsal <Pablogsal at gmail.com>
date: 2021-08-02T20:05:33+01:00
summary:

bpo-44792: Improve syntax errors for if expressions (GH-27506) (GH-27565)

(cherry picked from commit 28b6dc9dd5d1ce6f8aff7e06d4ef9afdc2bc8332)

Co-authored-by: Miguel Brito <5544985+miguendes at users.noreply.github.com>

files:
A Misc/NEWS.d/next/Core and Builtins/2021-07-31-12-12-57.bpo-44792.mOReTW.rst
M Grammar/python.gram
M Lib/test/test_syntax.py
M Misc/ACKS
M Parser/parser.c

diff --git a/Grammar/python.gram b/Grammar/python.gram
index 057bcb641a666..3e7475a3fa6f4 100644
--- a/Grammar/python.gram
+++ b/Grammar/python.gram
@@ -859,6 +859,7 @@ invalid_expression:
     # Soft keywords need to also be ignored because they can be parsed as NAME NAME
    | !(NAME STRING | SOFT_KEYWORD) a=disjunction b=expression_without_invalid {
         RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Perhaps you forgot a comma?") }
+   | a=disjunction 'if' b=disjunction !'else' { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "expected 'else' after 'if' expression") }
 
 invalid_named_expression:
     | a=expression ':=' expression {
diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py
index 6e1531e8b25fc..d5a52ba628a81 100644
--- a/Lib/test/test_syntax.py
+++ b/Lib/test/test_syntax.py
@@ -140,6 +140,18 @@
 Traceback (most recent call last):
 SyntaxError: cannot assign to conditional expression
 
+>>> a = 42 if True
+Traceback (most recent call last):
+SyntaxError: expected 'else' after 'if' expression
+
+>>> a = (42 if True)
+Traceback (most recent call last):
+SyntaxError: expected 'else' after 'if' expression
+
+>>> a = [1, 42 if True, 4]
+Traceback (most recent call last):
+SyntaxError: expected 'else' after 'if' expression
+
 >>> True = True = 3
 Traceback (most recent call last):
 SyntaxError: cannot assign to True
diff --git a/Misc/ACKS b/Misc/ACKS
index 385d7caf1775b..3f0506ecf758e 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -227,6 +227,7 @@ Tom Bridgman
 Anthony Briggs
 Keith Briggs
 Tobias Brink
+Miguel Brito
 Dillon Brock
 Richard Brodie
 Michael Broghton
diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-07-31-12-12-57.bpo-44792.mOReTW.rst b/Misc/NEWS.d/next/Core and Builtins/2021-07-31-12-12-57.bpo-44792.mOReTW.rst
new file mode 100644
index 0000000000000..2e9000d09ee44
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2021-07-31-12-12-57.bpo-44792.mOReTW.rst	
@@ -0,0 +1 @@
+Improve syntax errors for if expressions. Patch by Miguel Brito
diff --git a/Parser/parser.c b/Parser/parser.c
index c4a4eb651b3e7..b37e3d6855ce9 100644
--- a/Parser/parser.c
+++ b/Parser/parser.c
@@ -18229,6 +18229,7 @@ invalid_legacy_expression_rule(Parser *p)
 // invalid_expression:
 //     | invalid_legacy_expression
 //     | !(NAME STRING | SOFT_KEYWORD) disjunction expression_without_invalid
+//     | disjunction 'if' disjunction !'else'
 static void *
 invalid_expression_rule(Parser *p)
 {
@@ -18287,6 +18288,38 @@ invalid_expression_rule(Parser *p)
         D(fprintf(stderr, "%*c%s invalid_expression[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "!(NAME STRING | SOFT_KEYWORD) disjunction expression_without_invalid"));
     }
+    { // disjunction 'if' disjunction !'else'
+        if (p->error_indicator) {
+            D(p->level--);
+            return NULL;
+        }
+        D(fprintf(stderr, "%*c> invalid_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction !'else'"));
+        Token * _keyword;
+        expr_ty a;
+        expr_ty b;
+        if (
+            (a = disjunction_rule(p))  // disjunction
+            &&
+            (_keyword = _PyPegen_expect_token(p, 510))  // token='if'
+            &&
+            (b = disjunction_rule(p))  // disjunction
+            &&
+            _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 516)  // token='else'
+        )
+        {
+            D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction !'else'"));
+            _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "expected 'else' after 'if' expression" );
+            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_expression[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "disjunction 'if' disjunction !'else'"));
+    }
     _res = NULL;
   done:
     D(p->level--);



More information about the Python-checkins mailing list