]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-30858: Improve error location for expressions with assignments (GH-23753)
authorPablo Galindo <Pablogsal@gmail.com>
Sun, 13 Dec 2020 16:46:48 +0000 (16:46 +0000)
committerGitHub <noreply@github.com>
Sun, 13 Dec 2020 16:46:48 +0000 (16:46 +0000)
Co-authored-by: Lysandros Nikolaou <lisandrosnik@gmail.com>
Grammar/python.gram
Lib/test/test_exceptions.py
Lib/test/test_syntax.py
Misc/NEWS.d/next/Core and Builtins/2020-12-13-15-23-09.bpo-30858.-f9G4z.rst [new file with mode: 0644]
Parser/parser.c

index 9f4709491469d8afe5a23108851fbb8ef5e70636..4915cc43e84adcfefc0219c76105e1f436012077 100644 (file)
@@ -646,7 +646,7 @@ invalid_arguments:
         RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "Generator expression must be parenthesized") }
     | a=args ',' args { _PyPegen_arguments_parsing_error(p, a) }
 invalid_kwarg:
-    | a=expression '=' {
+    | expression a='=' {
         RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
             a, "expression cannot contain assignment, perhaps you meant \"==\"?") }
 invalid_named_expression:
index 1bdd3f2ce59934d2dde2ca3339229de0ecad086d..e752ab72ccff3370cc8f747cd304f04d4322e198 100644 (file)
@@ -252,7 +252,7 @@ class ExceptionTests(unittest.TestCase):
         check('from __future__ import doesnt_exist', 1, 1)
         check('from __future__ import braces', 1, 1)
         check('x=1\nfrom __future__ import division', 2, 1)
-        check('foo(1=2)', 1, 5)
+        check('foo(1=2)', 1, 6)
         check('def f():\n  x, y: int', 2, 3)
         check('[*x for x in xs]', 1, 2)
         check('foo(x for x in range(10), 100)', 1, 5)
index 91ca1db43a74f23ffc1b37e856f768100d65da71..d8255607dcfd5c8cd88724bdc7509eb9604a9133 100644 (file)
@@ -802,6 +802,13 @@ class SyntaxTestCase(unittest.TestCase):
         else:
             self.fail("compile() did not raise SyntaxError")
 
+    def test_expression_with_assignment(self):
+        self._check_error(
+            "print(end1 + end2 = ' ')",
+            'expression cannot contain assignment, perhaps you meant "=="?',
+            offset=19
+        )
+
     def test_curly_brace_after_primary_raises_immediately(self):
         self._check_error("f{", "invalid syntax", mode="single")
 
diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-12-13-15-23-09.bpo-30858.-f9G4z.rst b/Misc/NEWS.d/next/Core and Builtins/2020-12-13-15-23-09.bpo-30858.-f9G4z.rst
new file mode 100644 (file)
index 0000000..f2d06c3
--- /dev/null
@@ -0,0 +1,2 @@
+Improve error location in expressions that contain assignments. Patch by
+Pablo Galindo and Lysandros Nikolaou.
index b6c04953c899e0ea604fd015ded1b6b0570cd3ed..2559969f86e516cac738751ccd0f0a404163e149 100644 (file)
@@ -14562,12 +14562,12 @@ invalid_kwarg_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_kwarg[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression '='"));
-        Token * _literal;
-        expr_ty a;
+        Token * a;
+        expr_ty expression_var;
         if (
-            (a = expression_rule(p))  // expression
+            (expression_var = expression_rule(p))  // expression
             &&
-            (_literal = _PyPegen_expect_token(p, 22))  // token='='
+            (a = _PyPegen_expect_token(p, 22))  // token='='
         )
         {
             D(fprintf(stderr, "%*c+ invalid_kwarg[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression '='"));