Author: Carl Friedrich Bolz-Tereick <cfb...@gmx.de>
Branch: py3.7
Changeset: r98622:7a0cdcf24b94
Date: 2020-01-31 23:01 +0100
http://bitbucket.org/pypy/pypy/changeset/7a0cdcf24b94/

Log:    gah! turning StopIteration to RuntimeError in generators broke the
        applevel implementation of iter with sentinel!

diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -163,6 +163,7 @@
         self.frame.w_yielding_from = w_delegate
 
     def _leak_stopiteration(self, e):
+        import pdb; pdb.set_trace()
         # turn a leaking StopIteration into RuntimeError (with its cause set
         # appropriately).
         space = self.space
diff --git a/pypy/interpreter/test/apptest_generator.py 
b/pypy/interpreter/test/apptest_generator.py
--- a/pypy/interpreter/test/apptest_generator.py
+++ b/pypy/interpreter/test/apptest_generator.py
@@ -803,6 +803,21 @@
     with raises(RuntimeError):
         next(badgenerator(5))
 
+def test_stopiteration_can_be_caught():
+    def g():
+        raise StopIteration
+    def finegenerator(x):
+        yield x
+        if x == 5:
+            try:
+                g()
+            except StopIteration:
+                pass
+        yield x
+    gen = finegenerator(5)
+    next(gen) # fine
+    next(gen) # fine
+
 def test_generator_stop_cause():
     def gen1():
         yield 42
diff --git a/pypy/module/__builtin__/operation.py 
b/pypy/module/__builtin__/operation.py
--- a/pypy/module/__builtin__/operation.py
+++ b/pypy/module/__builtin__/operation.py
@@ -126,7 +126,10 @@
 
     def iter_generator(callable_, sentinel):
         while 1:
-            result = callable_()
+            try:
+                result = callable_()
+            except StopIteration:
+                return
             if result == sentinel:
                 return
             yield result
diff --git a/pypy/module/__builtin__/test/test_builtin.py 
b/pypy/module/__builtin__/test/test_builtin.py
--- a/pypy/module/__builtin__/test/test_builtin.py
+++ b/pypy/module/__builtin__/test/test_builtin.py
@@ -286,17 +286,20 @@
                 self.value = 0
             def __call__(self):
                 self.value += 1
+                if self.value > 10:
+                    raise StopIteration
                 return self.value
-        # XXX Raising errors is quite slow --
-        #            uncomment these lines when fixed
-        #self.assertRaises(TypeError,iter,3,5)
-        #self.assertRaises(TypeError,iter,[],5)
-        #self.assertRaises(TypeError,iter,{},5)
+        with raises(TypeError):
+            iter(3, 5)
+
         x = iter(count(),3)
         assert next(x) ==1
         assert next(x) ==2
         raises(StopIteration, next, x)
 
+        # a case that runs till the end
+        assert list(iter(count(), 100)) == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+
     def test_enumerate(self):
         import sys
         seq = range(2,4)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to