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

Reply via email to