Closed
Description
Some invalid for
statements currently give the specific error expected ':'
even if there is a colon on the line. I think it would be a slight improvement to raise a more general error in these cases. This is how while
and if
already behave.
Current behaviour:
>>> for x in range(10)
... pass
Traceback (most recent call last):
SyntaxError: expected ':'
>>> for x in range 10:
... pass
Traceback (most recent call last):
SyntaxError: expected ':'
>>> for x in range 10
... pass
Traceback (most recent call last):
SyntaxError: expected ':'
Proposed behaviour:
>>> for x in range(10)
... pass
Traceback (most recent call last):
SyntaxError: expected ':'
>>> for x in range 10:
... pass
Traceback (most recent call last):
SyntaxError: invalid syntax
>>> for x in range 10
... pass
Traceback (most recent call last):
SyntaxError: invalid syntax
Proposed Implementation:
Would do it the same way while
and if
do it. For the for loop example it would be something like this:
--- a/Grammar/python.gram
+++ b/Grammar/python.gram
@@ -379,7 +379,7 @@ 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] {
CHECK_VERSION(stmt_ty, 5, "Async for loops are", _PyAST_AsyncFor(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
@@ -1295,6 +1295,7 @@ 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:
+ | '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:
I'd also apply this to other suites where it makes sense (e.g. with
, match/case
, and try
)
Would it be OK for me to submit a PR making these changes? (this is my first time looking into the CPython parser so apologies if I made any obvious mistakes!)