Author: Raffael Tfirst <[email protected]>
Branch: py3.5-async
Changeset: r85729:dbdd4a20233f
Date: 2016-07-16 23:15 +0200
http://bitbucket.org/pypy/pypy/changeset/dbdd4a20233f/
Log: Implement close, finalize, throw in coroutine (adapted from
generator)
diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -326,7 +326,7 @@
(code_name, addrstring))
def descr_close(self):
- """x.close(arg) -> raise GeneratorExit inside generator."""
+ """x.close(arg) -> raise GeneratorExit inside coroutine."""
space = self.space
try:
w_retval = self.throw(space.w_GeneratorExit, space.w_None,
@@ -342,8 +342,8 @@
"coroutine ignored GeneratorExit")
def descr_throw(self, w_type, w_val=None, w_tb=None):
- """x.throw(typ[,val[,tb]]) -> raise exception in generator,
-return next yielded value or raise StopIteration."""
+ """x.throw(typ[,val[,tb]]) -> raise exception in coroutine,
+return next iterated value or raise StopIteration."""
if w_val is None:
w_val = self.space.w_None
return self.throw(w_type, w_val, w_tb)
@@ -443,7 +443,7 @@
def _send_ex(self, w_arg, operr):
space = self.space
if self.running:
- raise oefmt(space.w_ValueError, "generator already executing")
+ raise oefmt(space.w_ValueError, "coroutine already executing")
frame = self.frame
if frame is None:
# xxx a bit ad-hoc, but we don't want to go inside
@@ -457,7 +457,7 @@
if w_arg and not space.is_w(w_arg, space.w_None):
raise oefmt(space.w_TypeError,
"can't send non-None value to a just-started "
- "generator")
+ "coroutine")
else:
if not w_arg:
w_arg = space.w_None
@@ -483,6 +483,36 @@
finally:
frame.f_backref = jit.vref_None
self.running = False
+
+ def descr_gi_frame(self, space):
+ if self.frame is not None and not self.frame.frame_finished_execution:
+ return self.frame
+ else:
+ return space.w_None
+
+ def descr_gi_code(self, space):
+ return self.pycode
+
+ def descr__name__(self, space):
+ if self.pycode is None:
+ code_name = '<finished>'
+ else:
+ code_name = self.pycode.co_name
+ return space.wrap(code_name)
+
+ def _finalize_(self):
+ # This is only called if the CO_YIELD_INSIDE_TRY flag is set
+ # on the code object. If the frame is still not finished and
+ # finally or except blocks are present at the current
+ # position, then raise a GeneratorExit. Otherwise, there is
+ # no point.
+ if self.frame is not None:
+ block = self.frame.lastblock
+ while block is not None:
+ if not isinstance(block, LoopBlock):
+ self.descr_close()
+ break
+ block = block.previous
def get_printable_location_genentry(bytecode):
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -805,17 +805,17 @@
descrmismatch='__next__'),
send = interp2app(GeneratorIterator.descr_send,
descrmismatch='send'),
- throw = interp2app(GeneratorIterator.descr_throw,
+ throw = interp2app(Coroutine.descr_throw,
descrmismatch='throw'),
close = interp2app(Coroutine.descr_close,
descrmismatch='close'),
__iter__ = interp2app(GeneratorIterator.descr__iter__,
descrmismatch='__iter__'),
- gi_running = interp_attrproperty('running', cls=GeneratorIterator),
- gi_frame = GetSetProperty(GeneratorIterator.descr_gi_frame),
- gi_code = GetSetProperty(GeneratorIterator.descr_gi_code),
- __name__ = GetSetProperty(GeneratorIterator.descr__name__),
- __weakref__ = make_weakref_descr(GeneratorIterator),
+ gi_running = interp_attrproperty('running', cls=Coroutine),
+ gi_frame = GetSetProperty(Coroutine.descr_gi_frame),
+ gi_code = GetSetProperty(Coroutine.descr_gi_code),
+ __name__ = GetSetProperty(Coroutine.descr__name__),
+ __weakref__ = make_weakref_descr(Coroutine),
)
assert not Coroutine.typedef.acceptable_as_base_class # no __new__
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit