Skip to content

Commit 1034e73

Browse files
gh-153171: Produce specialized syntax errors for 'not' after an operator in more positions (GH-153175)
Move the invalid_factor rule from term to factor and the invalid_arithmetic rule from shift_expr to sum, so that they are tried at all positions where the invalid construct can occur. Previously a generic "invalid syntax" error was reported for constructs like "1 << 2 + not x" or "1 * + not x". Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 8bee2a3 commit 1034e73

4 files changed

Lines changed: 64 additions & 45 deletions

File tree

Grammar/python.gram

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,6 @@ bitwise_and[expr_ty]:
835835
shift_expr[expr_ty]:
836836
| a=shift_expr '<<' b=sum { _PyAST_BinOp(a, LShift, b, EXTRA) }
837837
| a=shift_expr '>>' b=sum { _PyAST_BinOp(a, RShift, b, EXTRA) }
838-
| invalid_arithmetic
839838
| sum
840839

841840
# Arithmetic operators
@@ -844,6 +843,7 @@ shift_expr[expr_ty]:
844843
sum[expr_ty]:
845844
| a=sum '+' b=term { _PyAST_BinOp(a, Add, b, EXTRA) }
846845
| a=sum '-' b=term { _PyAST_BinOp(a, Sub, b, EXTRA) }
846+
| invalid_arithmetic
847847
| term
848848

849849
term[expr_ty]:
@@ -852,14 +852,14 @@ term[expr_ty]:
852852
| a=term '//' b=factor { _PyAST_BinOp(a, FloorDiv, b, EXTRA) }
853853
| a=term '%' b=factor { _PyAST_BinOp(a, Mod, b, EXTRA) }
854854
| a=term '@' b=factor { CHECK_VERSION(expr_ty, 5, "The '@' operator is", _PyAST_BinOp(a, MatMult, b, EXTRA)) }
855-
| invalid_factor
856855
| factor
857856

858857
factor[expr_ty] (memo):
859858
| '+' a=factor { _PyAST_UnaryOp(UAdd, a, EXTRA) }
860859
| '-' a=factor { _PyAST_UnaryOp(USub, a, EXTRA) }
861860
| '~' a=factor { _PyAST_UnaryOp(Invert, a, EXTRA) }
862861
| power
862+
| invalid_factor
863863

864864
power[expr_ty]:
865865
| a=await_primary '**' b=factor { _PyAST_BinOp(a, Pow, b, EXTRA) }

Lib/test/test_syntax.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2268,6 +2268,22 @@
22682268
Traceback (most recent call last):
22692269
SyntaxError: 'not' after an operator must be parenthesized
22702270
2271+
>>> 1 << 2 + not 3
2272+
Traceback (most recent call last):
2273+
SyntaxError: 'not' after an operator must be parenthesized
2274+
2275+
>>> 1 >> 2 * not 3
2276+
Traceback (most recent call last):
2277+
SyntaxError: 'not' after an operator must be parenthesized
2278+
2279+
>>> 3 * + not 3
2280+
Traceback (most recent call last):
2281+
SyntaxError: 'not' after an operator must be parenthesized
2282+
2283+
>>> 3 ** - not 3
2284+
Traceback (most recent call last):
2285+
SyntaxError: 'not' after an operator must be parenthesized
2286+
22712287
# Check that we don't introduce misleading errors
22722288
>>> not 1 */ 2
22732289
Traceback (most recent call last):
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Improve syntax error messages for misplaced ``not`` after an operator
2+
in contexts where a generic "invalid syntax" error was previously reported,
3+
such as ``1 << 2 + not x`` and ``1 * + not x``.

Parser/parser.c

Lines changed: 43 additions & 43 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)