[pypy-commit] pypy py3.5-async: Implement missing coroutine functions and adapt typedef, add object serialization for coroutines

raffael_t pypy.commits at gmail.com
Mon Jul 18 14:22:58 EDT 2016


Author: Raffael Tfirst <raffael.tfirst at gmail.com>
Branch: py3.5-async
Changeset: r85763:1eff44f9dc2e
Date: 2016-07-18 18:44 +0200
http://bitbucket.org/pypy/pypy/changeset/1eff44f9dc2e/

Log:	Implement missing coroutine functions and adapt typedef, add object
	serialization for coroutines

diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -315,6 +315,48 @@
         self.running = False
         if self.pycode.co_flags & CO_YIELD_INSIDE_TRY:
             self.register_finalizer(self.space)
+    
+    def descr__reduce__(self, space):
+        from pypy.interpreter.mixedmodule import MixedModule
+        w_mod    = space.getbuiltinmodule('_pickle_support')
+        mod      = space.interp_w(MixedModule, w_mod)
+        new_inst = mod.get('coroutine_new')
+        w        = space.wrap
+        if self.frame:
+            w_frame = self.frame._reduce_state(space)
+        else:
+            w_frame = space.w_None
+
+        tup = [
+            w_frame,
+            w(self.running),
+            ]
+
+        return space.newtuple([new_inst, space.newtuple([]),
+                               space.newtuple(tup)])
+
+    def descr__setstate__(self, space, w_args):
+        from rpython.rlib.objectmodel import instantiate
+        args_w = space.unpackiterable(w_args)
+        w_framestate, w_running = args_w
+        if space.is_w(w_framestate, space.w_None):
+            self.frame = None
+            self.space = space
+            self.pycode = None
+        else:
+            frame = instantiate(space.FrameClass)   # XXX fish
+            frame.descr__setstate__(space, w_framestate)
+            Coroutine.__init__(self, frame)
+        self.running = self.space.is_true(w_running)
+
+    def descr__iter__(self):
+        """x.__iter__() <==> iter(x)"""
+        return self.space.wrap(self)
+
+    def descr_send(self, w_arg=None):
+        """send(arg) -> send 'arg' into coroutine,
+return next yielded value or raise StopIteration."""
+        return self.send_ex(w_arg)
 
     def descr__repr__(self, space):
         if self.pycode is None:
@@ -325,6 +367,10 @@
         return space.wrap("<coroutine object %s at 0x%s>" %
                           (code_name, addrstring))
     
+    def descr_next(self):
+        """x.__next__() <==> next(x)"""
+        return self.send_ex(self.space.w_None)
+    
     def descr_close(self):
         """x.close(arg) -> raise GeneratorExit inside coroutine."""
         space = self.space
@@ -509,7 +555,7 @@
         # If coroutine was never awaited on issue a RuntimeWarning.
         if self.pycode is not None:
             if self.frame is not None:
-                if self.frame.fget_f_lasti(frame).int_w(frame.space) == -1:
+                if self.frame.fget_f_lasti(self.frame).int_w(self.space) == -1:
                     raise oefmt(space.w_RuntimeWarning,
                                 "coroutine '%s' was never awaited",
                                 self.pycode.co_name)
@@ -520,6 +566,8 @@
                     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
@@ -799,17 +799,17 @@
 
 Coroutine.typedef = TypeDef("coroutine",
     __repr__   = interp2app(Coroutine.descr__repr__),
-    __reduce__   = interp2app(GeneratorIterator.descr__reduce__),
-    __setstate__ = interp2app(GeneratorIterator.descr__setstate__),
-    __next__   = interp2app(GeneratorIterator.descr_next,
+    __reduce__   = interp2app(Coroutine.descr__reduce__),
+    __setstate__ = interp2app(Coroutine.descr__setstate__),
+    __next__   = interp2app(Coroutine.descr_next,
                             descrmismatch='__next__'),
-    send       = interp2app(GeneratorIterator.descr_send,
+    send       = interp2app(Coroutine.descr_send,
                             descrmismatch='send'),
     throw      = interp2app(Coroutine.descr_throw,
                             descrmismatch='throw'),
     close      = interp2app(Coroutine.descr_close,
                             descrmismatch='close'),
-    __iter__   = interp2app(GeneratorIterator.descr__iter__,
+    __iter__   = interp2app(Coroutine.descr__iter__,
                             descrmismatch='__iter__'),
     gi_running = interp_attrproperty('running', cls=Coroutine),
     gi_frame   = GetSetProperty(Coroutine.descr_gi_frame),
diff --git a/pypy/module/_pickle_support/__init__.py b/pypy/module/_pickle_support/__init__.py
--- a/pypy/module/_pickle_support/__init__.py
+++ b/pypy/module/_pickle_support/__init__.py
@@ -19,6 +19,7 @@
         'frame_new'    : 'maker.frame_new',
         'traceback_new' : 'maker.traceback_new',
         'generator_new' : 'maker.generator_new',
+        'coroutine_new' : 'maker.coroutine_new',
         'longrangeiter_new': 'maker.longrangeiter_new',
         'intrangeiter_new': 'maker.intrangeiter_new',
         'builtin_code': 'maker.builtin_code',
diff --git a/pypy/module/_pickle_support/maker.py b/pypy/module/_pickle_support/maker.py
--- a/pypy/module/_pickle_support/maker.py
+++ b/pypy/module/_pickle_support/maker.py
@@ -4,7 +4,7 @@
 from pypy.interpreter.function import Function, Method
 from pypy.interpreter.module import Module
 from pypy.interpreter.pytraceback import PyTraceback
-from pypy.interpreter.generator import GeneratorIterator
+from pypy.interpreter.generator import GeneratorIterator, Coroutine
 from rpython.rlib.objectmodel import instantiate
 from pypy.interpreter.gateway import unwrap_spec
 from pypy.objspace.std.iterobject import W_SeqIterObject, W_ReverseSeqIterObject
@@ -62,6 +62,10 @@
     new_generator = instantiate(GeneratorIterator)
     return space.wrap(new_generator)
 
+def coroutine_new(space):
+    new_coroutine = instantiate(Coroutine)
+    return space.wrap(new_coroutine)
+
 def longrangeiter_new(space, w_start, w_step, w_len, w_index):
     from pypy.module.__builtin__.functional import W_LongRangeIterator
     new_iter = W_LongRangeIterator(space, w_start, w_step, w_len, w_index)


More information about the pypy-commit mailing list