Implement PEP 380 - 'yield from' (closes #11682)
diff --git a/Lib/opcode.py b/Lib/opcode.py
index b631b25..6fe20c7 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -87,6 +87,7 @@
 
 def_op('PRINT_EXPR', 70)
 def_op('LOAD_BUILD_CLASS', 71)
+def_op('YIELD_FROM', 72)
 
 def_op('INPLACE_LSHIFT', 75)
 def_op('INPLACE_RSHIFT', 76)
diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py
index b1656bc..2022ee2 100644
--- a/Lib/test/test_ast.py
+++ b/Lib/test/test_ast.py
@@ -813,7 +813,8 @@
         self._check_comprehension(factory)
 
     def test_yield(self):
-        self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load")
+        self.expr(ast.Yield(0, ast.Name("x", ast.Store())), "must have Load")
+        self.expr(ast.Yield(1, ast.Name("x", ast.Store())), "must have Load")
 
     def test_compare(self):
         left = ast.Name("x", ast.Load())
diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py
index 5f47b3e..06f67c2 100644
--- a/Lib/test/test_generators.py
+++ b/Lib/test/test_generators.py
@@ -728,29 +728,6 @@
 
 syntax_tests = """
 
->>> def f():
-...     return 22
-...     yield 1
-Traceback (most recent call last):
-  ..
-SyntaxError: 'return' with argument inside generator
-
->>> def f():
-...     yield 1
-...     return 22
-Traceback (most recent call last):
-  ..
-SyntaxError: 'return' with argument inside generator
-
-"return None" is not the same as "return" in a generator:
-
->>> def f():
-...     yield 1
-...     return None
-Traceback (most recent call last):
-  ..
-SyntaxError: 'return' with argument inside generator
-
 These are fine:
 
 >>> def f():
@@ -866,20 +843,6 @@
 >>> type(f())
 <class 'generator'>
 
-
->>> def f():
-...     if 0:
-...         lambda x:  x        # shouldn't trigger here
-...         return              # or here
-...         def f(i):
-...             return 2*i      # or here
-...         if 0:
-...             return 3        # but *this* sucks (line 8)
-...     if 0:
-...         yield 2             # because it's a generator (line 10)
-Traceback (most recent call last):
-SyntaxError: 'return' with argument inside generator
-
 This one caused a crash (see SF bug 567538):
 
 >>> def f():
@@ -1566,11 +1529,6 @@
   ...
 SyntaxError: 'yield' outside function
 
->>> def f(): return lambda x=(yield): 1
-Traceback (most recent call last):
-  ...
-SyntaxError: 'return' with argument inside generator
-
 >>> def f(): x = yield = y
 Traceback (most recent call last):
   ...
diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py
index eff763e..6b326bd 100644
--- a/Lib/test/test_grammar.py
+++ b/Lib/test/test_grammar.py
@@ -458,7 +458,39 @@
         check_syntax_error(self, "class foo:return 1")
 
     def test_yield(self):
+        # Allowed as standalone statement
+        def g(): yield 1
+        def g(): yield from ()
+        # Allowed as RHS of assignment
+        def g(): x = yield 1
+        def g(): x = yield from ()
+        # Ordinary yield accepts implicit tuples
+        def g(): yield 1, 1
+        def g(): x = yield 1, 1
+        # 'yield from' does not
+        check_syntax_error(self, "def g(): yield from (), 1")
+        check_syntax_error(self, "def g(): x = yield from (), 1")
+        # Requires parentheses as subexpression
+        def g(): 1, (yield 1)
+        def g(): 1, (yield from ())
+        check_syntax_error(self, "def g(): 1, yield 1")
+        check_syntax_error(self, "def g(): 1, yield from ()")
+        # Requires parentheses as call argument
+        def g(): f((yield 1))
+        def g(): f((yield 1), 1)
+        def g(): f((yield from ()))
+        def g(): f((yield from ()), 1)
+        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 ())")
+        check_syntax_error(self, "def g(): f(yield from (), 1)")
+        # Not allowed at top level
+        check_syntax_error(self, "yield")
+        check_syntax_error(self, "yield from")
+        # Not allowed at class scope
         check_syntax_error(self, "class foo:yield 1")
+        check_syntax_error(self, "class foo:yield from ()")
+
 
     def test_raise(self):
         # 'raise' test [',' test]
diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py
index 2b50fca..b6f81fb 100644
--- a/Lib/test/test_parser.py
+++ b/Lib/test/test_parser.py
@@ -50,6 +50,10 @@
         self.check_suite("def f(): (yield 1)*2")
         self.check_suite("def f(): return; yield 1")
         self.check_suite("def f(): yield 1; return")
+        self.check_suite("def f(): yield from 1")
+        self.check_suite("def f(): x = yield from 1")
+        self.check_suite("def f(): f((yield from 1))")
+        self.check_suite("def f(): yield 1; return 1")
         self.check_suite("def f():\n"
                          "    for x in range(30):\n"
                          "        yield x\n")
@@ -621,7 +625,6 @@
         with self.assertRaises(TypeError):
             parser.expr("a", "b")
 
-
 def test_main():
     support.run_unittest(
         RoundtripLegalSyntaxTestCase,
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index f89514f..6dc0e42 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -727,7 +727,7 @@
         nfrees = len(x.f_code.co_freevars)
         extras = x.f_code.co_stacksize + x.f_code.co_nlocals +\
                   ncells + nfrees - 1
-        check(x, size(vh + '12P3i' + CO_MAXBLOCKS*'3i' + 'P' + extras*'P'))
+        check(x, size(vh + '13P3i' + CO_MAXBLOCKS*'3i' + 'P' + extras*'P'))
         # function
         def func(): pass
         check(func, size(h + '12P'))