New GitHub issue #92858 from wookie184:<br>

<hr>

<pre>
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:**
```python
   >>> 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:**
```python
   >>> 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:
```diff
--- 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!)


</pre>

<hr>

<a href="https://github.com/python/cpython/issues/92858">View on GitHub</a>
<p>Labels: type-bug</p>
<p>Assignee: </p>