[pypy-commit] pypy py3.5-async: Implement GET_YIELD_FROM_ITER pyopcode, 'yield from' works, write test for 'yield from'

raffael_t pypy.commits at gmail.com
Tue Jul 12 16:39:56 EDT 2016


Author: Raffael Tfirst <raffael.tfirst at gmail.com>
Branch: py3.5-async
Changeset: r85672:74022d9a4bbc
Date: 2016-07-12 22:39 +0200
http://bitbucket.org/pypy/pypy/changeset/74022d9a4bbc/

Log:	Implement GET_YIELD_FROM_ITER pyopcode, 'yield from' works, write
	test for 'yield from'

diff --git a/pypy/interpreter/astcompiler/assemble.py b/pypy/interpreter/astcompiler/assemble.py
--- a/pypy/interpreter/astcompiler/assemble.py
+++ b/pypy/interpreter/astcompiler/assemble.py
@@ -646,6 +646,7 @@
     ops.BEFORE_ASYNC_WITH: 1,
     ops.GET_AITER: 0,
     ops.GET_ANEXT: 1,
+    ops.GET_YIELD_FROM_ITER: 0,
 
     ops.LOAD_CONST: 1,
 
diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -1022,7 +1022,7 @@
     def visit_YieldFrom(self, yfr):
         self.update_position(yfr.lineno)
         yfr.value.walkabout(self)
-        self.emit_op(ops.GET_ITER)
+        self.emit_op(ops.GET_YIELD_FROM_ITER)
         self.load_const(self.space.w_None)
         self.emit_op(ops.YIELD_FROM)
     
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -418,6 +418,18 @@
                 self.YIELD_VALUE(oparg, next_instr)
             elif opcode == opcodedesc.YIELD_FROM.index:
                 self.YIELD_FROM(oparg, next_instr)
+            elif opcode == opcodedesc.GET_YIELD_FROM_ITER.index:
+                self.GET_YIELD_FROM_ITER(oparg, next_instr)
+            elif opcode == opcodedesc.GET_AWAITABLE.index:
+                self.GET_AWAITABLE(oparg, next_instr)
+            elif opcode == opcodedesc.SETUP_ASYNC_WITH.index:
+                self.SETUP_ASYNC_WITH(oparg, next_instr)
+            elif opcode == opcodedesc.BEFORE_ASYNC_WITH.index:
+                self.BEFORE_ASYNC_WITH(oparg, next_instr)
+            elif opcode == opcodedesc.GET_AITER.index:
+                self.GET_AITER(oparg, next_instr)
+            elif opcode == opcodedesc.GET_ANEXT.index:
+                self.GET_ANEXT(oparg, next_instr)
             else:
                 self.MISSING_OPCODE(oparg, next_instr)
 
@@ -1403,19 +1415,24 @@
             itemcount -= 1
         self.pushvalue(w_dict)
     
-    def GET_AWAITABLE(self):
+    def GET_YIELD_FROM_ITER(self, oparg, next_instr):
+        w_iterable = self.popvalue()
+        w_iterator = self.space.iter(w_iterable)
+        self.pushvalue(w_iterator)
+    
+    def GET_AWAITABLE(self, oparg, next_instr):
         pass
     
-    def SETUP_ASYNC_WITH(self):
+    def SETUP_ASYNC_WITH(self, oparg, next_instr):
         pass
     
-    def BEFORE_ASYNC_WITH(self):
+    def BEFORE_ASYNC_WITH(self, oparg, next_instr):
         pass
     
-    def GET_AITER(self):
+    def GET_AITER(self, oparg, next_instr):
         pass
     
-    def GET_ANEXT(self):
+    def GET_ANEXT(self, oparg, next_instr):
         pass
         
 ### ____________________________________________________________ ###
diff --git a/pypy/interpreter/test/test_compiler.py b/pypy/interpreter/test/test_compiler.py
--- a/pypy/interpreter/test/test_compiler.py
+++ b/pypy/interpreter/test/test_compiler.py
@@ -612,6 +612,24 @@
         space.exec_(code, w_d, w_d)
         w_res = space.getitem(w_d, space.wrap('res'))
         assert space.eq_w(w_res, space.wrap("var"))
+    
+    def test_(self):
+        space = self.space
+        snippet = str(py.code.Source(r'''
+            def f():
+                def generator2():
+                    yield 8
+                def generator():
+                    yield from generator2()
+                for i in generator(): return i
+            res = f()
+        '''))
+        code = self.compiler.compile(snippet, '<tmp>', 'exec', 0)
+        space = self.space
+        w_d = space.newdict()
+        space.exec_(code, w_d, w_d)
+        w_res = space.getitem(w_d, space.wrap('res'))
+        assert space.eq_w(w_res, space.wrap("8"))
 
     def test_dont_inherit_flag(self):
         # this test checks that compile() don't inherit the __future__ flags


More information about the pypy-commit mailing list