Skip to content

Commit cb3e5ed

Browse files
authored
bpo-42374: Allow unparenthesized walrus in genexps (GH-23319)
This fixes a regression that was introduced by the new parser. Automerge-Triggered-By: GH:lysnikolaou
1 parent f62dad1 commit cb3e5ed

File tree

4 files changed

+18
-7
lines changed

4 files changed

+18
-7
lines changed

Grammar/python.gram

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ group[expr_ty]:
517517
| '(' a=(yield_expr | named_expression) ')' { a }
518518
| invalid_group
519519
genexp[expr_ty]:
520-
| '(' a=expression ~ b=for_if_clauses ')' { _Py_GeneratorExp(a, b, EXTRA) }
520+
| '(' a=named_expression ~ b=for_if_clauses ')' { _Py_GeneratorExp(a, b, EXTRA) }
521521
| invalid_comprehension
522522
set[expr_ty]: '{' a=expressions_list '}' { _Py_Set(a, EXTRA) }
523523
setcomp[expr_ty]:

Lib/test/test_named_expressions.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,15 @@ def g():
513513
self.assertEqual(nonlocal_var, None)
514514
f()
515515

516+
def test_named_expression_scope_in_genexp(self):
517+
a = 1
518+
b = [1, 2, 3, 4]
519+
genexp = (c := i + a for i in b)
520+
521+
self.assertNotIn("c", locals())
522+
for idx, elem in enumerate(genexp):
523+
self.assertEqual(elem, b[idx] + a)
524+
516525

517526
if __name__ == "__main__":
518527
unittest.main()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a regression introduced by the new parser, where an unparenthesized walrus operator
2+
was not allowed within generator expressions.

Parser/parser.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11357,7 +11357,7 @@ group_rule(Parser *p)
1135711357
return _res;
1135811358
}
1135911359

11360-
// genexp: '(' expression ~ for_if_clauses ')' | invalid_comprehension
11360+
// genexp: '(' named_expression ~ for_if_clauses ')' | invalid_comprehension
1136111361
static expr_ty
1136211362
genexp_rule(Parser *p)
1136311363
{
@@ -11377,12 +11377,12 @@ genexp_rule(Parser *p)
1137711377
UNUSED(_start_lineno); // Only used by EXTRA macro
1137811378
int _start_col_offset = p->tokens[_mark]->col_offset;
1137911379
UNUSED(_start_col_offset); // Only used by EXTRA macro
11380-
{ // '(' expression ~ for_if_clauses ')'
11380+
{ // '(' named_expression ~ for_if_clauses ')'
1138111381
if (p->error_indicator) {
1138211382
D(p->level--);
1138311383
return NULL;
1138411384
}
11385-
D(fprintf(stderr, "%*c> genexp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' expression ~ for_if_clauses ')'"));
11385+
D(fprintf(stderr, "%*c> genexp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' named_expression ~ for_if_clauses ')'"));
1138611386
int _cut_var = 0;
1138711387
Token * _literal;
1138811388
Token * _literal_1;
@@ -11391,7 +11391,7 @@ genexp_rule(Parser *p)
1139111391
if (
1139211392
(_literal = _PyPegen_expect_token(p, 7)) // token='('
1139311393
&&
11394-
(a = expression_rule(p)) // expression
11394+
(a = named_expression_rule(p)) // named_expression
1139511395
&&
1139611396
(_cut_var = 1)
1139711397
&&
@@ -11400,7 +11400,7 @@ genexp_rule(Parser *p)
1140011400
(_literal_1 = _PyPegen_expect_token(p, 8)) // token=')'
1140111401
)
1140211402
{
11403-
D(fprintf(stderr, "%*c+ genexp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' expression ~ for_if_clauses ')'"));
11403+
D(fprintf(stderr, "%*c+ genexp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' named_expression ~ for_if_clauses ')'"));
1140411404
Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
1140511405
if (_token == NULL) {
1140611406
D(p->level--);
@@ -11420,7 +11420,7 @@ genexp_rule(Parser *p)
1142011420
}
1142111421
p->mark = _mark;
1142211422
D(fprintf(stderr, "%*c%s genexp[%d-%d]: %s failed!\n", p->level, ' ',
11423-
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' expression ~ for_if_clauses ')'"));
11423+
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' named_expression ~ for_if_clauses ')'"));
1142411424
if (_cut_var) {
1142511425
D(p->level--);
1142611426
return NULL;

0 commit comments

Comments
 (0)