bpo-30858: Improve error location for expressions with assignments (GH-23753)

Co-authored-by: Lysandros Nikolaou <lisandrosnik@gmail.com>
This commit is contained in:
Pablo Galindo 2020-12-13 16:46:48 +00:00 committed by GitHub
parent da431f789b
commit 43c4fb6c90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 15 additions and 6 deletions

View File

@ -646,7 +646,7 @@ invalid_arguments:
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "Generator expression must be parenthesized") } RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "Generator expression must be parenthesized") }
| a=args ',' args { _PyPegen_arguments_parsing_error(p, a) } | a=args ',' args { _PyPegen_arguments_parsing_error(p, a) }
invalid_kwarg: invalid_kwarg:
| a=expression '=' { | expression a='=' {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION( RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
a, "expression cannot contain assignment, perhaps you meant \"==\"?") } a, "expression cannot contain assignment, perhaps you meant \"==\"?") }
invalid_named_expression: invalid_named_expression:

View File

@ -252,7 +252,7 @@ class ExceptionTests(unittest.TestCase):
check('from __future__ import doesnt_exist', 1, 1) check('from __future__ import doesnt_exist', 1, 1)
check('from __future__ import braces', 1, 1) check('from __future__ import braces', 1, 1)
check('x=1\nfrom __future__ import division', 2, 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('def f():\n x, y: int', 2, 3)
check('[*x for x in xs]', 1, 2) check('[*x for x in xs]', 1, 2)
check('foo(x for x in range(10), 100)', 1, 5) check('foo(x for x in range(10), 100)', 1, 5)

View File

@ -802,6 +802,13 @@ class SyntaxTestCase(unittest.TestCase):
else: else:
self.fail("compile() did not raise SyntaxError") 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): def test_curly_brace_after_primary_raises_immediately(self):
self._check_error("f{", "invalid syntax", mode="single") self._check_error("f{", "invalid syntax", mode="single")

View File

@ -0,0 +1,2 @@
Improve error location in expressions that contain assignments. Patch by
Pablo Galindo and Lysandros Nikolaou.

View File

@ -14562,12 +14562,12 @@ invalid_kwarg_rule(Parser *p)
return NULL; return NULL;
} }
D(fprintf(stderr, "%*c> invalid_kwarg[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression '='")); D(fprintf(stderr, "%*c> invalid_kwarg[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression '='"));
Token * _literal; Token * a;
expr_ty a; expr_ty expression_var;
if ( 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 '='")); D(fprintf(stderr, "%*c+ invalid_kwarg[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression '='"));