From 75c0e9e418bc6b7dd8b14f9b71c58c88be04b4a5 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 26 Aug 2018 16:25:43 +0100 Subject: [PATCH 1/3] Issue 34508: Allow unparenthesized star-unpacking expressions in a return statement. --- Grammar/Grammar | 2 +- Lib/lib2to3/Grammar.txt | 2 +- Lib/lib2to3/tests/data/py3_test_grammar.py | 5 ++++- Lib/test/test_grammar.py | 5 ++++- Lib/test/test_parser.py | 3 +++ Python/ast.c | 2 +- Python/graminit.c | 2 +- 7 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Grammar/Grammar b/Grammar/Grammar index 7d3dd0b86dc69a..7befa9abf17cc6 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 diff --git a/Lib/lib2to3/Grammar.txt b/Lib/lib2to3/Grammar.txt index a7ddad3cf322c5..6c81173432b0fe 100644 --- a/Lib/lib2to3/Grammar.txt +++ b/Lib/lib2to3/Grammar.txt @@ -49,7 +49,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 | ',' test [',' test]]] import_stmt: import_name | import_from diff --git a/Lib/lib2to3/tests/data/py3_test_grammar.py b/Lib/lib2to3/tests/data/py3_test_grammar.py index e0b682837e1d89..1fa35292043809 100644 --- a/Lib/lib2to3/tests/data/py3_test_grammar.py +++ b/Lib/lib2to3/tests/data/py3_test_grammar.py @@ -473,12 +473,15 @@ def test_inner(extra_burning_oil = 1, count=0): test_inner() def testReturn(self): - # 'return' [testlist] + # 'return' [testlist_star_expr] def g1(): return def g2(): return 1 + def g3(): return *(1, 2), 3 g1() x = g2() + g3() check_syntax_error(self, "class foo:return 1") + check_syntax_error(self, "def f(): return *(1, 2, 3)") def testYield(self): check_syntax_error(self, "class foo:yield 1") diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 78918ae250c4a3..a3df200f4d1f35 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -824,12 +824,15 @@ 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(): return *(1, 2), 3 g1() x = g2() + g3() check_syntax_error(self, "class foo:return 1") + check_syntax_error(self, "def f(): return *(1, 2, 3)") def test_break_in_finally(self): count = 0 diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py index 274e26061a1991..bd80bfc85ea073 100644 --- a/Lib/test/test_parser.py +++ b/Lib/test/test_parser.py @@ -41,6 +41,9 @@ def test_flags_passed(self): def check_suite(self, s): self.roundtrip(parser.suite, s) + def test_return_statement(self): + self.check_suite("def f(): return *(1, 2), 3") + def test_yield_statement(self): self.check_suite("def f(): yield 1") self.check_suite("def f(): yield") diff --git a/Python/ast.c b/Python/ast.c index a91c075dae6684..74f6d39454a547 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -3096,7 +3096,7 @@ ast_for_flow_stmt(struct compiling *c, const node *n) | yield_stmt break_stmt: 'break' continue_stmt: 'continue' - return_stmt: 'return' [testlist] + return_stmt: 'return' [testlist_star_expr] yield_stmt: yield_expr yield_expr: 'yield' testlist | 'yield' 'from' test raise_stmt: 'raise' [test [',' test [',' test]]] diff --git a/Python/graminit.c b/Python/graminit.c index 8e89ccea3bab6a..61fdb762fae4a2 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] = { From 45940615f023c89af77ef5f31d996373ebb51446 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 26 Aug 2018 16:53:14 +0100 Subject: [PATCH 2/3] Add NEWS entry. --- .../Core and Builtins/2018-08-26-16-31-34.bpo-34508.o_gpUi.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2018-08-26-16-31-34.bpo-34508.o_gpUi.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-08-26-16-31-34.bpo-34508.o_gpUi.rst b/Misc/NEWS.d/next/Core and Builtins/2018-08-26-16-31-34.bpo-34508.o_gpUi.rst new file mode 100644 index 00000000000000..1380563c4f333c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-08-26-16-31-34.bpo-34508.o_gpUi.rst @@ -0,0 +1 @@ +Allow unparenthesized star-unpacking expressions in return statements. From 19d3683f328abb911b162c92bc174e06caeed0c3 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 26 Aug 2018 16:53:27 +0100 Subject: [PATCH 3/3] Update documentation. --- Doc/reference/simple_stmts.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index bb1eea66f98bbc..46402ff0b63a61 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -471,12 +471,12 @@ The :keyword:`return` statement pair: class; definition .. productionlist:: - return_stmt: "return" [`expression_list`] + return_stmt: "return" [`starred_expression`] :keyword:`return` may only occur syntactically nested in a function definition, not within a nested class definition. -If an expression list is present, it is evaluated, else ``None`` is substituted. +If an expression is present, it is evaluated, else ``None`` is substituted. :keyword:`return` leaves the current function call with the expression list (or ``None``) as return value.