Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Confusing SyntaxError message for x for x if range(1) #111488

Closed
sobolevn opened this issue Oct 30, 2023 · 7 comments · Fixed by #113656
Closed

Confusing SyntaxError message for x for x if range(1) #111488

sobolevn opened this issue Oct 30, 2023 · 7 comments · Fixed by #113656
Labels
3.11 bug and security fixes 3.12 bugs and security fixes 3.13 new features, bugs and security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) topic-parser type-bug An unexpected behavior, bug, or error

Comments

@sobolevn
Copy link
Member

sobolevn commented Oct 30, 2023

Bug report

Today I made a typo: instead of in I wrote if.
I was quite interested to see the error message:

>>> [x for x if range(1)]
  File "<stdin>", line 1
    [x for x if range(1)]
           ^^^^^^^^^^^^^
SyntaxError: expected 'else' after 'if' expression

I don't think that this error message is correct. Why? Because even if we follow the rabbit hole and use else, we won't be ever correct:

>>> [x for (x if range(1) else y) in range(1)]
  File "<stdin>", line 1
    [x for (x if range(1) else y) in range(1)]
            ^^^^^^^^^^^^^^^^^^^^
SyntaxError: cannot assign to conditional expression

So, maybe we should change it to be something like:

>>> [x for x if range(1)]
  File "<stdin>", line 1
    [x for x if range(1)]
             ^^
SyntaxError: expected 'in', got 'if'

Suggestions about wording are welcome :)

If others agree, I would like to work on this.

Linked PRs

@sobolevn sobolevn added type-bug An unexpected behavior, bug, or error interpreter-core (Objects, Python, Grammar, and Parser dirs) topic-parser labels Oct 30, 2023
@sobolevn
Copy link
Member Author

cc @pablogsal @lysnikolaou

@pablogsal
Copy link
Member

Thanks for the issue! Will take a bite at this today at night

@furkanonder furkanonder added 3.12 bugs and security fixes 3.13 new features, bugs and security fixes 3.11 bug and security fixes labels Oct 30, 2023
@skirpichev
Copy link
Contributor

This works for me:

diff --git a/Grammar/python.gram b/Grammar/python.gram
index ec964d6783..98270fe77f 100644
--- a/Grammar/python.gram
+++ b/Grammar/python.gram
@@ -1282,6 +1282,8 @@ invalid_with_item:
         RAISE_SYNTAX_ERROR_INVALID_TARGET(STAR_TARGETS, a) }
 
 invalid_for_target:
+    | 'async'? 'for' star_targets !'in' {
+        RAISE_SYNTAX_ERROR("'in' expected after for-loop variables") }
     | 'async'? 'for' a=star_expressions {
         RAISE_SYNTAX_ERROR_INVALID_TARGET(FOR_TARGETS, a) }
Python 3.13.0a1+ (heads/main-dirty:4a929d432b, Oct 31 2023, 15:32:48) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> [x for x if range(1)]
  File "<stdin>", line 1
    [x for x if range(1)]
             ^^
SyntaxError: 'in' expected after for-loop variables

Let me know if this worth a PR.

@pablogsal
Copy link
Member

pablogsal commented Oct 31, 2023

This sort of works, but it breaks other error messages, for instance this one:

 for a, b, (c + 1, d()): pass

That used to be: SyntaxError: cannot assign to expression but now will show 'in' expected after for-loop variables which is not correct. What is worse, adding in produces this:

>>> for a, b, (c + 1, d()) in P:
  File "<stdin>", line 1
    for a, b, (c + 1, d()) in P:
                           ^^
SyntaxError: 'in' expected after for-loop variables

which is hilariously incorrect. This happens as well with function calls:

for a, b() in c: pass

now shows:

        for a, b() in c: pass
                   ^^
    SyntaxError: 'in' expected after for-loop variable

instead of cannot assign to function call

@skirpichev
Copy link
Contributor

Yep, wrong place, this should be restricted to comprehensions. test_syntax.py pass with this alternative at the end of for_if_clause[comprehension_ty].

@pablogsal
Copy link
Member

this should be restricted to comprehensions.

You have the same problem in list comprehensions, is just that there are no tests for that:

>>> [x for x() in a]
  File "<stdin>", line 1
    [x for x() in a]
               ^^
SyntaxError: 'in' expected after for-loop variables

this currently shows:

>>> [x for x() in a]
  File "<stdin>", line 1
    [x for x() in a]
           ^^^
SyntaxError: cannot assign to function call

@pablogsal
Copy link
Member

@skirpichev If you want a quick PR, you can add tests that cover this case for list/set/dict comprehensions in test_syntax

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.11 bug and security fixes 3.12 bugs and security fixes 3.13 new features, bugs and security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) topic-parser type-bug An unexpected behavior, bug, or error
Projects
None yet
4 participants