From: Pablo Galindo Date: Sun, 13 Dec 2020 16:46:48 +0000 (+0000) Subject: bpo-30858: Improve error location for expressions with assignments (GH-23753) X-Git-Tag: v3.10.0a4~191 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=43c4fb6c90c013a00cb820cb61e4990cd8ec7f5e;p=thirdparty%2FPython%2Fcpython.git bpo-30858: Improve error location for expressions with assignments (GH-23753) Co-authored-by: Lysandros Nikolaou --- diff --git a/Grammar/python.gram b/Grammar/python.gram index 9f4709491469..4915cc43e84a 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -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: diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 1bdd3f2ce599..e752ab72ccff 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -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) diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 91ca1db43a74..d8255607dcfd 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -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 index 000000000000..f2d06c3009ca --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-12-13-15-23-09.bpo-30858.-f9G4z.rst @@ -0,0 +1,2 @@ +Improve error location in expressions that contain assignments. Patch by +Pablo Galindo and Lysandros Nikolaou. diff --git a/Parser/parser.c b/Parser/parser.c index b6c04953c899..2559969f86e5 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -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 '='"));