[Python-checkins] bpo-32117: Allow tuple unpacking in return and yield statements (gh-4509)

Guido van Rossum webhook-mailer at python.org
Fri Sep 21 21:31:20 EDT 2018


https://github.com/python/cpython/commit/fd97d1f1af910a6222ea12aec42c456b64f9aee4
commit: fd97d1f1af910a6222ea12aec42c456b64f9aee4
branch: master
author: David Cuthbert <dacut at kanga.org>
committer: Guido van Rossum <guido at python.org>
date: 2018-09-21T18:31:15-07:00
summary:

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.

files:
A Misc/NEWS.d/next/Core and Builtins/2017-11-22-15-43-14.bpo-32117.-vloh8.rst
M Grammar/Grammar
M Lib/test/test_grammar.py
M Python/graminit.c

diff --git a/Grammar/Grammar b/Grammar/Grammar
index 7d3dd0b86dc6..e232df979e2d 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 78918ae250c4..462e77a0be55 100644
--- a/Lib/test/test_grammar.py
+++ b/Lib/test/test_grammar.py
@@ -824,11 +824,17 @@ def test_inner(extra_burning_oil = 1, count=0):
         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 @@ def g(): f((yield 1))
         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 000000000000..9685680ee53e
--- /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 5770e8f6a941..0a681f7b797f 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"},



More information about the Python-checkins mailing list