Skip to content

Commit

Permalink
[3.10] gh-92858: Improve error message for some suites with syntax er…
Browse files Browse the repository at this point in the history
…ror before ':' (GH-92894). (#94183)

(cherry picked from commit 2fc83ac)

Co-authored-by: wookie184 <[email protected]>

Co-authored-by: wookie184 <[email protected]>
  • Loading branch information
pablogsal and wookie184 authored Jun 23, 2022
1 parent 34be807 commit 05cae26
Show file tree
Hide file tree
Showing 4 changed files with 472 additions and 310 deletions.
16 changes: 9 additions & 7 deletions Grammar/python.gram
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,9 @@ while_stmt[stmt_ty]:

for_stmt[stmt_ty]:
| invalid_for_stmt
| 'for' t=star_targets 'in' ~ ex=star_expressions &&':' tc=[TYPE_COMMENT] b=block el=[else_block] {
| 'for' t=star_targets 'in' ~ ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] {
_PyAST_For(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA) }
| ASYNC 'for' t=star_targets 'in' ~ ex=star_expressions &&':' tc=[TYPE_COMMENT] b=block el=[else_block] {
| ASYNC 'for' t=star_targets 'in' ~ ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] {
CHECK_VERSION(stmt_ty, 5, "Async for loops are", _PyAST_AsyncFor(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
| invalid_for_target

Expand Down Expand Up @@ -488,7 +488,7 @@ class_def[stmt_ty]:
| class_def_raw
class_def_raw[stmt_ty]:
| invalid_class_def_raw
| 'class' a=NAME b=['(' z=[arguments] ')' { z }] &&':' c=block {
| 'class' a=NAME b=['(' z=[arguments] ')' { z }] ':' c=block {
_PyAST_ClassDef(a->v.Name.id,
(b) ? ((expr_ty) b)->v.Call.args : NULL,
(b) ? ((expr_ty) b)->v.Call.keywords : NULL,
Expand Down Expand Up @@ -954,8 +954,8 @@ invalid_import_from_targets:
RAISE_SYNTAX_ERROR("trailing comma not allowed without surrounding parentheses") }

invalid_with_stmt:
| [ASYNC] 'with' ','.(expression ['as' star_target])+ &&':'
| [ASYNC] 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' &&':'
| [ASYNC] 'with' ','.(expression ['as' star_target])+ NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
| [ASYNC] 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
invalid_with_stmt_indent:
| [ASYNC] a='with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT {
RAISE_INDENTATION_ERROR("expected an indented block after 'with' statement on line %d", a->lineno) }
Expand All @@ -979,11 +979,11 @@ invalid_except_stmt_indent:
RAISE_INDENTATION_ERROR("expected an indented block after 'except' statement on line %d", a->lineno) }
| a='except' ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'except' statement on line %d", a->lineno) }
invalid_match_stmt:
| "match" subject_expr !':' { CHECK_VERSION(void*, 10, "Pattern matching is", RAISE_SYNTAX_ERROR("expected ':'") ) }
| "match" subject_expr NEWLINE { CHECK_VERSION(void*, 10, "Pattern matching is", RAISE_SYNTAX_ERROR("expected ':'") ) }
| a="match" subject=subject_expr ':' NEWLINE !INDENT {
RAISE_INDENTATION_ERROR("expected an indented block after 'match' statement on line %d", a->lineno) }
invalid_case_block:
| "case" patterns guard? !':' { RAISE_SYNTAX_ERROR("expected ':'") }
| "case" patterns guard? NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
| a="case" patterns guard? ':' NEWLINE !INDENT {
RAISE_INDENTATION_ERROR("expected an indented block after 'case' statement on line %d", a->lineno) }
invalid_as_pattern:
Expand Down Expand Up @@ -1012,12 +1012,14 @@ invalid_while_stmt:
| a='while' named_expression ':' NEWLINE !INDENT {
RAISE_INDENTATION_ERROR("expected an indented block after 'while' statement on line %d", a->lineno) }
invalid_for_stmt:
| [ASYNC] 'for' star_targets 'in' star_expressions NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
| [ASYNC] a='for' star_targets 'in' star_expressions ':' NEWLINE !INDENT {
RAISE_INDENTATION_ERROR("expected an indented block after 'for' statement on line %d", a->lineno) }
invalid_def_raw:
| [ASYNC] a='def' NAME '(' [params] ')' ['->' expression] ':' NEWLINE !INDENT {
RAISE_INDENTATION_ERROR("expected an indented block after function definition on line %d", a->lineno) }
invalid_class_def_raw:
| 'class' NAME ['(' [arguments] ')'] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
| a='class' NAME ['('[arguments] ')'] ':' NEWLINE !INDENT {
RAISE_INDENTATION_ERROR("expected an indented block after class definition on line %d", a->lineno) }

Expand Down
41 changes: 31 additions & 10 deletions Lib/test/test_syntax.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@
>>> class C(x for x in L):
... pass
Traceback (most recent call last):
SyntaxError: expected ':'
SyntaxError: invalid syntax
>>> def g(*args, **kwargs):
... print(args, sorted(kwargs.items()))
Expand Down Expand Up @@ -759,17 +759,22 @@
...
SyntaxError: cannot assign to function call here. Maybe you meant '==' instead of '='?
Missing ':' before suites:
Missing ':' before suites:
>>> def f()
... pass
Traceback (most recent call last):
SyntaxError: expected ':'
>>> def f()
... pass
Traceback (most recent call last):
SyntaxError: expected ':'
>>> class A
... pass
Traceback (most recent call last):
SyntaxError: expected ':'
>>> class A
... pass
Traceback (most recent call last):
SyntaxError: expected ':'
>>> class R&D:
... pass
Traceback (most recent call last):
SyntaxError: invalid syntax
>>> if 1
... pass
Expand Down Expand Up @@ -803,6 +808,11 @@
Traceback (most recent call last):
SyntaxError: expected ':'
>>> for x in range 10:
... pass
Traceback (most recent call last):
SyntaxError: invalid syntax
>>> while True
... pass
Traceback (most recent call last):
Expand Down Expand Up @@ -848,6 +858,11 @@
Traceback (most recent call last):
SyntaxError: expected ':'
>>> with block ad something:
... pass
Traceback (most recent call last):
SyntaxError: invalid syntax
>>> try
... pass
Traceback (most recent call last):
Expand All @@ -866,6 +881,12 @@
Traceback (most recent call last):
SyntaxError: expected ':'
>>> match x x:
... case list():
... pass
Traceback (most recent call last):
SyntaxError: invalid syntax
>>> match x:
... case list()
... pass
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Improve error message for some suites with syntax error before ':'
Loading

0 comments on commit 05cae26

Please sign in to comment.