Skip to content

gh-151303 : Improve SyntaxError suggestions for common operator typos and cross-language mistakes#151375

Open
Aniketsy wants to merge 13 commits into
python:mainfrom
Aniketsy:fix-151303
Open

gh-151303 : Improve SyntaxError suggestions for common operator typos and cross-language mistakes#151375
Aniketsy wants to merge 13 commits into
python:mainfrom
Aniketsy:fix-151303

Conversation

@Aniketsy

@Aniketsy Aniketsy commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

@skirpichev

This comment was marked as resolved.

Comment thread Grammar/python.gram Outdated
Comment thread Misc/NEWS.d/next/Core_and_Builtins/2026-06-12-03-41-39.gh-issue-151303.mzlJxi.rst Outdated
Comment thread Grammar/python.gram Outdated
| invalid_eqeqeq

invalid_diamond_op:
| a='<' b='>' { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Maybe you meant '!=' instead of '<>'?") }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this break when __future__.CO_FUTURE_BARRY_AS_BDFL is true?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm , yes

aniket@DESKTOP-074O80J:/mnt/d/cpython/cpython$ ./python.exe -c "
__futu> from __future__ import barry_as_FLUFL
> 1 < > 2
> "
  File "<string>", line 3
    1 < > 2
      ^^^
SyntaxError: invalid syntax.  Maybe you meant '!=' instead of '<>'?

please let me know your thoughts on this ...

aniket@DESKTOP-074O80J:/mnt/d/cpython/cpython$ git diff Grammar/python.gram
diff --git a/Grammar/python.gram b/Grammar/python.gram
index 61a6d5ea90..19ef406437 100644
--- a/Grammar/python.gram
+++ b/Grammar/python.gram
@@ -805,7 +805,11 @@ compare_op_bitwise_or_pair[CmpopExprPair*]:
     | invalid_eqeqeq

 invalid_diamond_op:
-    | a='<' b='>' { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax.  Maybe you meant '!=' instead of '<>'?") }
+    | a='<' b='>' {
+        (p->flags & PyPARSE_BARRY_AS_BDFL)
+        ? RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax.  Maybe you meant '<>' instead of '< >'?")
+        : RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax.  Maybe you meant '!=' instead of '<>'?")
+    }
 eq_bitwise_or[CmpopExprPair*]: '==' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, Eq, a) }
 invalid_eqeqeq:
     | a='==' b='=' { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax.  Maybe you meant '==' instead of '==='?") }

output:

aniket@DESKTOP-074O80J:/mnt/d/cpython/cpython$ ./python.exe -c "1 < > 2"
  File "<string>", line 1
    1 < > 2
      ^^^
SyntaxError: invalid syntax.  Maybe you meant '!=' instead of '<>'?
aniket@DESKTOP-074O80J:/mnt/d/cpython/cpython$ ./python.exe -c "
__futu> from __future__ import barry_as_FLUFL
> 1 < > 2
> "
  File "<string>", line 3
    1 < > 2
      ^^^
SyntaxError: invalid syntax.  Maybe you meant '<>' instead of '< >'?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, yes

No, this example doesn't break __future__ import. But I suspect, that __future__.CO_FUTURE_BARRY_AS_BDFL is the reason that your code doesn't work without spaces. This can be "fixed" by this patch:

diff --git a/Tools/build/generate_token.py b/Tools/build/generate_token.py
index 9ee5ec86e75..28a0ce1ff78 100755
--- a/Tools/build/generate_token.py
+++ b/Tools/build/generate_token.py
@@ -178,7 +178,7 @@ def generate_chars_to_token(mapping, n=1):
 
 def make_c(infile, outfile='Parser/token.c'):
     tok_names, ERRORTOKEN, string_to_tok = load_tokens(infile)
-    string_to_tok['<>'] = string_to_tok['!=']
+#   string_to_tok['<>'] = string_to_tok['!=']
     chars_to_token = {}
     for string, value in string_to_tok.items():
         assert 1 <= len(string) <= 3

Look at the difference:

$ cat a.py
1 =! 2
$ cat a.py | ./python -m tokenize
1,0-1,1:            NUMBER         '1'            
1,2-1,3:            OP             '='            
1,3-1,4:            OP             '!'            
1,5-1,6:            NUMBER         '2'            
1,6-1,7:            NEWLINE        '\n'           
2,0-2,0:            ENDMARKER      ''             

vs

$ cat a.py
1 <> 2
$ cat a.py | ./python -m tokenize
1,0-1,1:            NUMBER         '1'            
1,2-1,4:            OP             '<>'           
1,5-1,6:            NUMBER         '2'            
1,6-1,7:            NEWLINE        '\n'           
2,0-2,0:            ENDMARKER      ''             

Regardless on a joke, it looks as a tokenizer bug. I'll open a separate issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for looking into this, i'll revert the changes

@StanFromIreland StanFromIreland Jun 14, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this example doesn't break future import.

It still does break it, we're suggesting != for < > which is invalid syntax when __future__.CO_FUTURE_BARRY_AS_BDFL is true.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is wrong, see my comment below. But nothing to do with __future__.barry_as_FLUFL.

Currently, we have a hidden token (<> is alias for !=) in the grammar. So, this patch will not produce an error without a space between. See #151464.

Comment thread Grammar/python.gram Outdated
@skirpichev

This comment was marked as resolved.

@serhiy-storchaka serhiy-storchaka left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like in the previous PR, check that there is no gap between tokens.

Comment thread Grammar/python.gram Outdated
Comment thread Lib/test/test_syntax.py Outdated

def test_diamond_operator(self):
self._check_error(
"1 < > 2",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should not be space in the middle.

Comment thread Grammar/python.gram Outdated
Comment thread Grammar/python.gram Outdated
Comment thread Grammar/python.gram Outdated
Comment thread Lib/test/test_syntax.py
Comment thread Lib/test/test_syntax.py
Comment thread Misc/NEWS.d/next/Core_and_Builtins/2026-06-12-03-41-39.gh-issue-151303.mzlJxi.rst Outdated
@Aniketsy

Copy link
Copy Markdown
Contributor Author

@skirpichev thanks for the review, i've updated with helper function

Comment thread Lib/test/test_syntax.py
Comment thread Parser/action_helpers.c Outdated
Comment on lines +934 to +937
if (strcmp(tok_str, "<>") == 0) {
RAISE_SYNTAX_ERROR("invalid syntax. Are you trying to overthrow the SC? Use operator \"!=\"!");
return -1;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer not use this workaround for #151464. Leave "<>" case for another PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should i revert the changes for this case ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is my suggestion, yes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer not use this workaround for #151464. Leave "<>" case for another PR.

@skirpichev are you planning to work on this PR as issue was assigned to you, or i can open a follow up pr after this . please let me know 😊

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to do this.

I'm waiting for opinion of core developers. Beware that posted patch is only a partial solution. Proper support of this easter egg will require much more work. Do we need this? I'm not sure. Other options:

  1. call this not a bug
  2. remove joke.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm waiting for opinion of core developers.

in that case i think i should also wait for the opinion.

Beware that posted patch is only a partial solution. Proper support of this easter egg will require much more work.

and meanwhile, i'll explore this, and will update you in the issue ... Thanks :)

@serhiy-storchaka

Copy link
Copy Markdown
Member

We wait for other PR to be merged first.

@serhiy-storchaka

Copy link
Copy Markdown
Member

For future -- never use rebase, amend and force-push. This forces us to review the entire PR from the beginning, instead of just the new changes.

@Aniketsy

Copy link
Copy Markdown
Contributor Author

For future -- never use rebase, amend and force-push. This forces us to review the entire PR from the beginning, instead of just the new changes.

sorry for creating extra works, i didn't know we can solve conflicts without rebase, i'll keep in mind and i always wanted to never use rebase as i used to mess with this in past and this leads to creating my PR dirty that's the reason i built grebase(https://github.com/Aniketsy/grebase) But now i think i got alternative way to do . Thanks!

@Aniketsy

Copy link
Copy Markdown
Contributor Author

gentle ping, i've resolved the conflict in parser.c, i think it would be great if we can move forward with this . Thanks :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve SyntaxError suggestions for common operator typos and cross-language mistakes

4 participants