Minor improvement to errors with (no) missing colon
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!)