# HG changeset patch # User Pablo Galindo <Pablogsal@gmail.com> # Date 1618332681 -3600 # Tue Apr 13 17:51:21 2021 +0100 # Node ID 8c1ed915d32a303fa380240182e0802318dab183 # Parent d4917a0c968fcc0931e31209e5f431942fffd3a8 bpo-43797: Handle correctly invalid assignments inside function calls and generators (GH-25390) diff --git a/Grammar/python.gram b/Grammar/python.gram --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -638,7 +638,7 @@ | '(' a=(yield_expr | named_expression) ')' { a } | invalid_group genexp[expr_ty]: - | '(' a=named_expression b=for_if_clauses ')' { _PyAST_GeneratorExp(a, b, EXTRA) } + | '(' a=direct_named_expression b=for_if_clauses ')' { _PyAST_GeneratorExp(a, b, EXTRA) } | invalid_comprehension set[expr_ty]: '{' a=star_named_expressions '}' { _PyAST_Set(a, EXTRA) } setcomp[expr_ty]: diff --git a/Lib/test/test_genexps.py b/Lib/test/test_genexps.py --- a/Lib/test/test_genexps.py +++ b/Lib/test/test_genexps.py @@ -103,7 +103,7 @@ >>> dict(a = i for i in range(10)) Traceback (most recent call last): ... - SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='? + SyntaxError: invalid syntax Verify that parenthesis are required when used as a keyword argument value diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -868,6 +868,18 @@ Traceback (most recent call last): SyntaxError: invalid syntax + >>> dict(x=34); x $ y + Traceback (most recent call last): + SyntaxError: invalid syntax + + >>> dict(x=34, (x for x in range 10), 1); x $ y + Traceback (most recent call last): + SyntaxError: invalid syntax + + >>> dict(x=34, x=1, y=2); x $ y + Traceback (most recent call last): + SyntaxError: invalid syntax + Make sure that the old "raise X, Y[, Z]" form is gone: >>> raise X, Y Traceback (most recent call last): @@ -1013,7 +1025,7 @@ def test_expression_with_assignment(self): self._check_error( "print(end1 + end2 = ' ')", - "cannot assign to expression here. Maybe you meant '==' instead of '='?", + 'expression cannot contain assignment, perhaps you meant "=="?', offset=19 ) diff --git a/Parser/parser.c b/Parser/parser.c --- a/Parser/parser.c +++ b/Parser/parser.c @@ -14015,7 +14015,7 @@ return _res; } -// genexp: '(' named_expression for_if_clauses ')' | invalid_comprehension +// genexp: '(' direct_named_expression for_if_clauses ')' | invalid_comprehension static expr_ty genexp_rule(Parser *p) { @@ -14035,12 +14035,12 @@ UNUSED(_start_lineno); // Only used by EXTRA macro int _start_col_offset = p->tokens[_mark]->col_offset; UNUSED(_start_col_offset); // Only used by EXTRA macro - { // '(' named_expression for_if_clauses ')' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> genexp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' named_expression for_if_clauses ')'")); + { // '(' direct_named_expression for_if_clauses ')' + if (p->error_indicator) { + D(p->level--); + return NULL; + } + D(fprintf(stderr, "%*c> genexp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' direct_named_expression for_if_clauses ')'")); Token * _literal; Token * _literal_1; expr_ty a; @@ -14048,14 +14048,14 @@ if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = named_expression_rule(p)) // named_expression + (a = direct_named_expression_rule(p)) // direct_named_expression && (b = for_if_clauses_rule(p)) // for_if_clauses && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ genexp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' named_expression for_if_clauses ')'")); + D(fprintf(stderr, "%*c+ genexp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' direct_named_expression for_if_clauses ')'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { D(p->level--); @@ -14075,7 +14075,7 @@ } p->mark = _mark; D(fprintf(stderr, "%*c%s genexp[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' named_expression for_if_clauses ')'")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' direct_named_expression for_if_clauses ')'")); } if (p->call_invalid_rules) { // invalid_comprehension if (p->error_indicator) {