Skip to content

Commit

Permalink
bpo-44792: Improve syntax errors for if expressions (GH-27506)
Browse files Browse the repository at this point in the history
  • Loading branch information
miguendes committed Aug 2, 2021
1 parent aa0894b commit 28b6dc9
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 0 deletions.
1 change: 1 addition & 0 deletions Grammar/python.gram
Expand Up @@ -1083,6 +1083,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 {
Expand Down
12 changes: 12 additions & 0 deletions Lib/test/test_syntax.py
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions Misc/ACKS
Expand Up @@ -227,6 +227,7 @@ Tom Bridgman
Anthony Briggs
Keith Briggs
Tobias Brink
Miguel Brito
Dillon Brock
Richard Brodie
Michael Broghton
Expand Down
@@ -0,0 +1 @@
Improve syntax errors for if expressions. Patch by Miguel Brito
33 changes: 33 additions & 0 deletions Parser/parser.c
Expand Up @@ -18207,6 +18207,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)
{
Expand Down Expand Up @@ -18265,6 +18266,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, 518) // 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--);
Expand Down

0 comments on commit 28b6dc9

Please sign in to comment.