Author: Raffael Tfirst <raffael.tfi...@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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit