[pypy-svn] r76767 - in pypy/trunk/pypy/interpreter: . test

arigo at codespeak.net arigo at codespeak.net
Sat Aug 28 17:44:36 CEST 2010


Author: arigo
Date: Sat Aug 28 17:44:32 2010
New Revision: 76767

Modified:
   pypy/trunk/pypy/interpreter/generator.py
   pypy/trunk/pypy/interpreter/pyframe.py
   pypy/trunk/pypy/interpreter/test/test_generator.py
Log:
Test and fix about generator.throw().


Modified: pypy/trunk/pypy/interpreter/generator.py
==============================================================================
--- pypy/trunk/pypy/interpreter/generator.py	(original)
+++ pypy/trunk/pypy/interpreter/generator.py	Sat Aug 28 17:44:32 2010
@@ -1,7 +1,6 @@
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.gateway import NoneNotWrapped
-from pypy.rlib.rarithmetic import intmask
 from pypy.rlib import jit
 from pypy.interpreter.pyopcode import LoopBlock
 
@@ -37,7 +36,7 @@
 return next yielded value or raise StopIteration."""
         return self.send_ex(w_arg)
 
-    def send_ex(self, w_arg, exc=False):
+    def send_ex(self, w_arg, operr=None):
         space = self.space
         if self.running:
             raise OperationError(space.w_ValueError,
@@ -57,7 +56,7 @@
         self.running = True
         try:
             try:
-                w_result = self.frame.execute_generator_frame(w_arg, exc)
+                w_result = self.frame.execute_generator_frame(w_arg, operr)
             except OperationError:
                 # errors finish a frame
                 self.frame.frame_finished_execution = True
@@ -89,12 +88,7 @@
        
         operr = OperationError(w_type, w_val, tb)
         operr.normalize_exception(space)
-        
-        ec = space.getexecutioncontext()
-        next_instr = self.frame.handle_operation_error(ec, operr)
-        self.frame.last_instr = intmask(next_instr - 1)
-
-        return self.send_ex(space.w_None, True)
+        return self.send_ex(space.w_None, operr)
              
     def descr_next(self):
         """next() -> the next value, or raise StopIteration"""

Modified: pypy/trunk/pypy/interpreter/pyframe.py
==============================================================================
--- pypy/trunk/pypy/interpreter/pyframe.py	(original)
+++ pypy/trunk/pypy/interpreter/pyframe.py	Sat Aug 28 17:44:32 2010
@@ -10,6 +10,7 @@
 from pypy.rlib.objectmodel import we_are_translated, instantiate
 from pypy.rlib.jit import hint
 from pypy.rlib.debug import make_sure_not_resized
+from pypy.rlib.rarithmetic import intmask
 from pypy.rlib import jit, rstack
 from pypy.tool import stdlib_opcode
 
@@ -125,8 +126,12 @@
         else:
             return self.execute_frame()
 
-    def execute_generator_frame(self, w_inputvalue, ex=False):
-        if self.last_instr != -1 and not ex:
+    def execute_generator_frame(self, w_inputvalue, operr=None):
+        if operr is not None:
+            ec = self.space.getexecutioncontext()
+            next_instr = self.handle_operation_error(ec, operr)
+            self.last_instr = intmask(next_instr - 1)
+        elif self.last_instr != -1:
             self.pushvalue(w_inputvalue)
         return self.execute_frame()
 

Modified: pypy/trunk/pypy/interpreter/test/test_generator.py
==============================================================================
--- pypy/trunk/pypy/interpreter/test/test_generator.py	(original)
+++ pypy/trunk/pypy/interpreter/test/test_generator.py	Sat Aug 28 17:44:32 2010
@@ -126,6 +126,16 @@
         raises(ValueError, g.throw, ValueError)
         assert g.gi_frame is None
 
+    def test_throw_bug(self):
+        def f():
+            try:
+                x.throw(IndexError)     # => "generator already executing"
+            except ValueError:
+                yield 1
+        x = f()
+        res = list(x)
+        assert res == [1]
+
     def test_close(self):
         def f():
             yield 1



More information about the Pypy-commit mailing list