Skip to content

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

Open
Aniketsy wants to merge 10 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 10 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

Copy link
Copy Markdown
Member

Sorry, this doesn't look right for me, just as in another your PR: #150906 (comment)

@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

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 Outdated
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 on lines +3528 to +3531
compile(
"from __future__ import barry_as_FLUFL\n1<>2",
"<test>", "exec",
)

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.

Check error for 'a < > b' in this case.

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.

 File "<test>", line 3
    a < > b
        ^
SyntaxError: invalid syntax

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 meant, please add a test.

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.

ahh 😿 my bad, i'll add 👍

Comment thread Parser/action_helpers.c
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.

@serhiy-storchaka

Copy link
Copy Markdown
Member

We wait for other PR to be merged first.

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