Author: Armin Rigo <ar...@tunes.org>
Branch: py3.5-corowrapper
Changeset: r87145:7a673159303f
Date: 2016-09-16 19:02 +0200
http://bitbucket.org/pypy/pypy/changeset/7a673159303f/

Log:    in-progress

diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -4,13 +4,13 @@
 from pypy.interpreter.pycode import CO_YIELD_INSIDE_TRY
 from pypy.interpreter.astcompiler import consts
 from rpython.rlib import jit
+from rpython.rlib.objectmodel import specialize
 
 
 class GeneratorOrCoroutine(W_Root):
     _immutable_fields_ = ['pycode']
 
     w_yielded_from = None
-    thrown_operr = None
 
     def __init__(self, frame, name=None, qualname=None):
         self.space = frame.space
@@ -113,18 +113,17 @@
             raise operr
 
         w_result = self._invoke_execute_frame(frame, w_arg_or_err)
+        assert w_result is not None
 
         # if the frame is now marked as finished, it was RETURNed from
         if frame.frame_finished_execution:
             self.frame = None
-            if space.is_none(w_result):
-                # Delay exception instantiation if we can
+            if space.is_w(w_result, space.w_None):
                 raise OperationError(space.w_StopIteration, space.w_None)
             else:
                 raise OperationError(space.w_StopIteration,
-                                     space.newtuple([w_result]))
+                        space.call_function(space.w_StopIteration, w_result))
         else:
-            assert w_result is not None
             return w_result     # YIELDed
 
     def _invoke_execute_frame(self, frame, w_arg_or_err):
@@ -186,9 +185,10 @@
             elif space.is_w(w_inputvalue_or_err, space.w_None):
                 w_retval = space.next(w_yf)
             elif isinstance(w_inputvalue_or_err, SApplicationException):
-                raise w_inputvalue_or_err.operr
+                operr = w_inputvalue_or_err.operr
+                XXXXX
             else:
-                w_retval = space.call_method(w_gen, "send", 
w_inputvalue_or_err)
+                w_retval = space.call_method(w_yf, "send", w_inputvalue_or_err)
         except OperationError as e:
             self.w_yielded_from = None
             if not e.match(space, space.w_StopIteration):
@@ -229,13 +229,11 @@
     def descr_throw(self, w_type, w_val=None, w_tb=None):
         """throw(typ[,val[,tb]]) -> raise exception in generator/coroutine,
 return next yielded value or raise StopIteration."""
+        from pypy.interpreter.pytraceback import check_traceback
+
+        space = self.space
         if w_val is None:
-            w_val = self.space.w_None
-        return self.throw(w_type, w_val, w_tb)
-
-    def throw(self, w_type, w_val, w_tb):
-        from pypy.interpreter.pytraceback import check_traceback
-        space = self.space
+            w_val = space.w_None
 
         msg = "throw() third argument must be a traceback object"
         if space.is_none(w_tb):
@@ -244,6 +242,15 @@
             tb = check_traceback(space, w_tb, msg)
 
         operr = OperationError(w_type, w_val, tb)
+        w_yf = self.w_yielded_from
+        if (w_yf is not None and
+                    operr.match(space, space.w_GeneratorExit)):
+            self.w_yielded_from = None
+            try:
+                gen_close_iter(space, w_yf)
+            except OperationError as e:
+                return self.send_error(e)
+
         operr.normalize_exception(space)
         if tb is None:
             tb = space.getattr(operr.get_w_value(space),
@@ -257,18 +264,14 @@
         if self.frame is None:
             return     # nothing to do in this case
         space = self.space
-        operr = OperationError(space.w_GeneratorExit,
-                               space.call_function(space.w_GeneratorExit))
+        operr = get_generator_exit(space)
         w_yf = self.w_yielded_from
         if w_yf is not None:
-            XXX
-            self.running = True
+            self.w_yielded_from = None
             try:
                 gen_close_iter(space, w_yf)
             except OperationError as e:
                 operr = e
-            finally:
-                self.running = False
         try:
             self.send_error(operr)
         except OperationError as e:
@@ -402,6 +405,11 @@
         return self
 
 
+@specialize.memo()
+def get_generator_exit(space):
+    return OperationError(space.w_GeneratorExit,
+                          space.call_function(space.w_GeneratorExit))
+
 def gen_close_iter(space, w_yf):
     # This helper function is used by close() and throw() to
     # close a subiterator being delegated to by yield-from.
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to