diff --git a/Grammar/python.gram b/Grammar/python.gram index ae5e4b5d4ca64d..9ed885696ebf43 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -491,7 +491,7 @@ slices[expr_ty]: | a[asdl_expr_seq*]=','.slice+ [','] { _Py_Tuple(a, Load, EXTRA) } slice[expr_ty]: | a=[expression] ':' b=[expression] c=[':' d=[expression] { d }] { _Py_Slice(a, b, c, EXTRA) } - | a=expression { a } + | a=named_expression { a } atom[expr_ty]: | NAME | 'True' { _Py_Constant(Py_True, NULL, EXTRA) } diff --git a/Lib/test/test_named_expressions.py b/Lib/test/test_named_expressions.py index c813830ce6d3cf..67617ee4a584b5 100644 --- a/Lib/test/test_named_expressions.py +++ b/Lib/test/test_named_expressions.py @@ -271,6 +271,27 @@ def test_named_expression_assignment_16(self): fib = {(c := a): (a := b) + (b := a + c) - b for __ in range(6)} self.assertEqual(fib, {1: 2, 2: 3, 3: 5, 5: 8, 8: 13, 13: 21}) + def test_named_expression_assignment_17(self): + a = [1] + element = a[b:=0] + self.assertEqual(b, 0) + self.assertEqual(element, a[0]) + + def test_named_expression_assignment_18(self): + class TwoDimensionalList: + def __init__(self, two_dimensional_list): + self.two_dimensional_list = two_dimensional_list + + def __getitem__(self, index): + return self.two_dimensional_list[index[0]][index[1]] + + a = TwoDimensionalList([[1], [2]]) + element = a[b:=0, c:=0] + self.assertEqual(b, 0) + self.assertEqual(c, 0) + self.assertEqual(element, a.two_dimensional_list[b][c]) + + class NamedExpressionScopeTest(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-11-16-17-30-03.bpo-42316._DdmpQ.rst b/Misc/NEWS.d/next/Core and Builtins/2020-11-16-17-30-03.bpo-42316._DdmpQ.rst new file mode 100644 index 00000000000000..77eb6662ba827e --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-11-16-17-30-03.bpo-42316._DdmpQ.rst @@ -0,0 +1 @@ +Allow an unparenthesized walrus in subscript indexes. \ No newline at end of file diff --git a/Parser/parser.c b/Parser/parser.c index 48ebfe65aedafa..8bf0a53d5c8acf 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -10639,7 +10639,7 @@ slices_rule(Parser *p) return _res; } -// slice: expression? ':' expression? [':' expression?] | expression +// slice: expression? ':' expression? [':' expression?] | named_expression static expr_ty slice_rule(Parser *p) { @@ -10701,18 +10701,18 @@ slice_rule(Parser *p) D(fprintf(stderr, "%*c%s slice[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression? ':' expression? [':' expression?]")); } - { // expression + { // named_expression if (p->error_indicator) { D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> slice[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression")); + D(fprintf(stderr, "%*c> slice[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression")); expr_ty a; if ( - (a = expression_rule(p)) // expression + (a = named_expression_rule(p)) // named_expression ) { - D(fprintf(stderr, "%*c+ slice[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression")); + D(fprintf(stderr, "%*c+ slice[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "named_expression")); _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -10723,7 +10723,7 @@ slice_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s slice[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "named_expression")); } _res = NULL; done: