Skip to content

Commit 65ed8b4

Browse files
pablogsalwookie184
andauthored
[3.11] gh-92858: Improve error message for some suites with syntax error before ':' (GH-92894) (#94180)
(cherry picked from commit 2fc83ac) Co-authored-by: wookie184 <wookie1840@gmail.com> Co-authored-by: wookie184 <wookie1840@gmail.com>
1 parent ee82f0f commit 65ed8b4

File tree

4 files changed

+542
-380
lines changed

4 files changed

+542
-380
lines changed

Grammar/python.gram

+10-8
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ class_def[stmt_ty]:
249249

250250
class_def_raw[stmt_ty]:
251251
| invalid_class_def_raw
252-
| 'class' a=NAME b=['(' z=[arguments] ')' { z }] &&':' c=block {
252+
| 'class' a=NAME b=['(' z=[arguments] ')' { z }] ':' c=block {
253253
_PyAST_ClassDef(a->v.Name.id,
254254
(b) ? ((expr_ty) b)->v.Call.args : NULL,
255255
(b) ? ((expr_ty) b)->v.Call.keywords : NULL,
@@ -379,9 +379,9 @@ while_stmt[stmt_ty]:
379379

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

@@ -1231,8 +1231,8 @@ invalid_import_from_targets:
12311231
RAISE_SYNTAX_ERROR("trailing comma not allowed without surrounding parentheses") }
12321232

12331233
invalid_with_stmt:
1234-
| [ASYNC] 'with' ','.(expression ['as' star_target])+ &&':'
1235-
| [ASYNC] 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' &&':'
1234+
| [ASYNC] 'with' ','.(expression ['as' star_target])+ NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
1235+
| [ASYNC] 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
12361236
invalid_with_stmt_indent:
12371237
| [ASYNC] a='with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT {
12381238
RAISE_INDENTATION_ERROR("expected an indented block after 'with' statement on line %d", a->lineno) }
@@ -1262,11 +1262,11 @@ invalid_except_star_stmt_indent:
12621262
| a='except' '*' expression ['as' NAME ] ':' NEWLINE !INDENT {
12631263
RAISE_INDENTATION_ERROR("expected an indented block after 'except*' statement on line %d", a->lineno) }
12641264
invalid_match_stmt:
1265-
| "match" subject_expr !':' { CHECK_VERSION(void*, 10, "Pattern matching is", RAISE_SYNTAX_ERROR("expected ':'") ) }
1265+
| "match" subject_expr NEWLINE { CHECK_VERSION(void*, 10, "Pattern matching is", RAISE_SYNTAX_ERROR("expected ':'") ) }
12661266
| a="match" subject=subject_expr ':' NEWLINE !INDENT {
12671267
RAISE_INDENTATION_ERROR("expected an indented block after 'match' statement on line %d", a->lineno) }
12681268
invalid_case_block:
1269-
| "case" patterns guard? !':' { RAISE_SYNTAX_ERROR("expected ':'") }
1269+
| "case" patterns guard? NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
12701270
| a="case" patterns guard? ':' NEWLINE !INDENT {
12711271
RAISE_INDENTATION_ERROR("expected an indented block after 'case' statement on line %d", a->lineno) }
12721272
invalid_as_pattern:
@@ -1295,13 +1295,15 @@ invalid_while_stmt:
12951295
| a='while' named_expression ':' NEWLINE !INDENT {
12961296
RAISE_INDENTATION_ERROR("expected an indented block after 'while' statement on line %d", a->lineno) }
12971297
invalid_for_stmt:
1298+
| [ASYNC] 'for' star_targets 'in' star_expressions NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
12981299
| [ASYNC] a='for' star_targets 'in' star_expressions ':' NEWLINE !INDENT {
12991300
RAISE_INDENTATION_ERROR("expected an indented block after 'for' statement on line %d", a->lineno) }
13001301
invalid_def_raw:
13011302
| [ASYNC] a='def' NAME '(' [params] ')' ['->' expression] ':' NEWLINE !INDENT {
13021303
RAISE_INDENTATION_ERROR("expected an indented block after function definition on line %d", a->lineno) }
13031304
invalid_class_def_raw:
1304-
| a='class' NAME ['('[arguments] ')'] ':' NEWLINE !INDENT {
1305+
| 'class' NAME ['(' [arguments] ')'] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
1306+
| a='class' NAME ['(' [arguments] ')'] ':' NEWLINE !INDENT {
13051307
RAISE_INDENTATION_ERROR("expected an indented block after class definition on line %d", a->lineno) }
13061308

13071309
invalid_double_starred_kvpairs:

Lib/test/test_syntax.py

+31-10
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@
607607
>>> class C(x for x in L):
608608
... pass
609609
Traceback (most recent call last):
610-
SyntaxError: expected ':'
610+
SyntaxError: invalid syntax
611611
612612
>>> def g(*args, **kwargs):
613613
... print(args, sorted(kwargs.items()))
@@ -963,17 +963,22 @@
963963
...
964964
SyntaxError: cannot assign to function call here. Maybe you meant '==' instead of '='?
965965
966-
Missing ':' before suites:
966+
Missing ':' before suites:
967967
968-
>>> def f()
969-
... pass
970-
Traceback (most recent call last):
971-
SyntaxError: expected ':'
968+
>>> def f()
969+
... pass
970+
Traceback (most recent call last):
971+
SyntaxError: expected ':'
972972
973-
>>> class A
974-
... pass
975-
Traceback (most recent call last):
976-
SyntaxError: expected ':'
973+
>>> class A
974+
... pass
975+
Traceback (most recent call last):
976+
SyntaxError: expected ':'
977+
978+
>>> class R&D:
979+
... pass
980+
Traceback (most recent call last):
981+
SyntaxError: invalid syntax
977982
978983
>>> if 1
979984
... pass
@@ -1007,6 +1012,11 @@
10071012
Traceback (most recent call last):
10081013
SyntaxError: expected ':'
10091014
1015+
>>> for x in range 10:
1016+
... pass
1017+
Traceback (most recent call last):
1018+
SyntaxError: invalid syntax
1019+
10101020
>>> while True
10111021
... pass
10121022
Traceback (most recent call last):
@@ -1052,6 +1062,11 @@
10521062
Traceback (most recent call last):
10531063
SyntaxError: expected ':'
10541064
1065+
>>> with block ad something:
1066+
... pass
1067+
Traceback (most recent call last):
1068+
SyntaxError: invalid syntax
1069+
10551070
>>> try
10561071
... pass
10571072
Traceback (most recent call last):
@@ -1070,6 +1085,12 @@
10701085
Traceback (most recent call last):
10711086
SyntaxError: expected ':'
10721087
1088+
>>> match x x:
1089+
... case list():
1090+
... pass
1091+
Traceback (most recent call last):
1092+
SyntaxError: invalid syntax
1093+
10731094
>>> match x:
10741095
... case list()
10751096
... pass
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve error message for some suites with syntax error before ':'

0 commit comments

Comments
 (0)