From fd97d1f1af910a6222ea12aec42c456b64f9aee4 Mon Sep 17 00:00:00 2001 From: David Cuthbert Date: Fri, 21 Sep 2018 18:31:15 -0700 Subject: [PATCH] bpo-32117: Allow tuple unpacking in return and yield statements (gh-4509) Iterable unpacking is now allowed without parentheses in yield and return statements, e.g. ``yield 1, 2, 3, *rest``. Thanks to David Cuthbert for the change and jChapman for added tests. --- Grammar/Grammar | 4 ++-- Lib/test/test_grammar.py | 11 ++++++++++- .../2017-11-22-15-43-14.bpo-32117.-vloh8.rst | 3 +++ Python/graminit.c | 6 +++--- 4 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2017-11-22-15-43-14.bpo-32117.-vloh8.rst diff --git a/Grammar/Grammar b/Grammar/Grammar index 7d3dd0b86dc..e232df979e2 100644 --- a/Grammar/Grammar +++ b/Grammar/Grammar @@ -50,7 +50,7 @@ pass_stmt: 'pass' flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt break_stmt: 'break' continue_stmt: 'continue' -return_stmt: 'return' [testlist] +return_stmt: 'return' [testlist_star_expr] yield_stmt: yield_expr raise_stmt: 'raise' [test ['from' test]] import_stmt: import_name | import_from @@ -147,4 +147,4 @@ comp_if: 'if' test_nocond [comp_iter] encoding_decl: NAME yield_expr: 'yield' [yield_arg] -yield_arg: 'from' test | testlist +yield_arg: 'from' test | testlist_star_expr diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 78918ae250c..462e77a0be5 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -824,11 +824,17 @@ class GrammarTests(unittest.TestCase): test_inner() def test_return(self): - # 'return' [testlist] + # 'return' [testlist_star_expr] def g1(): return def g2(): return 1 + def g3(): + z = [2, 3] + return 1, *z + g1() x = g2() + y = g3() + self.assertEqual(y, (1, 2, 3), "unparenthesized star expr return") check_syntax_error(self, "class foo:return 1") def test_break_in_finally(self): @@ -981,6 +987,9 @@ class GrammarTests(unittest.TestCase): def g(): f((yield 1), 1) def g(): f((yield from ())) def g(): f((yield from ()), 1) + # Do not require parenthesis for tuple unpacking + def g(): rest = 4, 5, 6; yield 1, 2, 3, *rest + self.assertEquals(list(g()), [(1, 2, 3, 4, 5, 6)]) check_syntax_error(self, "def g(): f(yield 1)") check_syntax_error(self, "def g(): f(yield 1, 1)") check_syntax_error(self, "def g(): f(yield from ())") diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-11-22-15-43-14.bpo-32117.-vloh8.rst b/Misc/NEWS.d/next/Core and Builtins/2017-11-22-15-43-14.bpo-32117.-vloh8.rst new file mode 100644 index 00000000000..9685680ee53 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-11-22-15-43-14.bpo-32117.-vloh8.rst @@ -0,0 +1,3 @@ +Iterable unpacking is now allowed without parenthesis in yield and return +statements, e.g. ``yield 1, 2, 3, *rest``. Thanks to David Cuthbert for the +change and jChapman for added tests. diff --git a/Python/graminit.c b/Python/graminit.c index 5770e8f6a94..0a681f7b797 100644 --- a/Python/graminit.c +++ b/Python/graminit.c @@ -613,7 +613,7 @@ static arc arcs_25_0[1] = { {75, 1}, }; static arc arcs_25_1[2] = { - {9, 2}, + {47, 2}, {0, 1}, }; static arc arcs_25_2[1] = { @@ -1900,7 +1900,7 @@ static state states_85[3] = { }; static arc arcs_86_0[2] = { {77, 1}, - {9, 2}, + {47, 2}, }; static arc arcs_86_1[1] = { {26, 2}, @@ -2087,7 +2087,7 @@ static dfa dfas[87] = { {341, "yield_expr", 0, 3, states_85, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000"}, {342, "yield_arg", 0, 3, states_86, - "\000\040\200\000\000\000\000\000\000\040\010\000\000\000\020\002\000\300\220\050\037\000\000"}, + "\000\040\200\000\002\000\000\000\000\040\010\000\000\000\020\002\000\300\220\050\037\000\000"}, }; static label labels[177] = { {0, "EMPTY"},