Author: Matti Picus <[email protected]>
Branch: py3.6
Changeset: r97382:585e24d5f093
Date: 2019-09-05 21:45 +0200
http://bitbucket.org/pypy/pypy/changeset/585e24d5f093/

Log:    test, fix for bpo-33786: handle generator exit in athrow()

diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -777,13 +777,12 @@
     def handle_error(self, e):
         space = self.space
         self.state = self.ST_CLOSED
-        if e.match(space, space.w_StopAsyncIteration):
+        if (e.match(space, space.w_StopAsyncIteration) or
+                    e.match(space, space.w_StopIteration)):
             if self.w_exc_type is None:
                 # When aclose() is called we don't want to propagate
-                # StopAsyncIteration; just raise StopIteration, signalling
-                # that 'aclose()' is done.
+                # StopAsyncIteration or GeneratorExit; just raise
+                # StopIteration, signalling that this 'aclose()' await
+                # is done.
                 raise OperationError(space.w_StopIteration, space.w_None)
-        if e.match(space, space.w_GeneratorExit):
-            # Ignore this error.
-            raise OperationError(space.w_StopIteration, space.w_None)
         raise e
diff --git a/pypy/interpreter/test/test_generator.py 
b/pypy/interpreter/test/test_generator.py
--- a/pypy/interpreter/test/test_generator.py
+++ b/pypy/interpreter/test/test_generator.py
@@ -539,6 +539,104 @@
         raises(TypeError, g.send, 2)
 
 
+class AppTestAsyncGenerator(object):
+
+    def test_async_gen_exception_11(self):
+        """
+        # bpo-33786
+        def compare_generators(sync_gen, async_gen):
+            def sync_iterate(g):
+                res = []
+                while True:
+                    try:
+                        res.append(g.__next__())
+                    except StopIteration:
+                        res.append('STOP')
+                        break
+                    except Exception as ex:
+                        res.append(str(type(ex)))
+                return res
+
+            def async_iterate(g):
+                res = []
+                while True:
+                    an = g.__anext__()
+                    try:
+                        while True:
+                            try:
+                                an.__next__()
+                            except StopIteration as ex:
+                                if ex.args:
+                                    res.append(ex.args[0])
+                                    break
+                                else:
+                                    res.append('EMPTY StopIteration')
+                                    break
+                            except StopAsyncIteration:
+                                raise
+                            except Exception as ex:
+                                res.append(str(type(ex)))
+                                break
+                    except StopAsyncIteration:
+                        res.append('STOP')
+                        break
+                return res
+
+            def async_iterate(g):
+                res = []
+                while True:
+                    try:
+                        g.__anext__().__next__()
+                    except StopAsyncIteration:
+                        res.append('STOP')
+                        break
+                    except StopIteration as ex:
+                        if ex.args:
+                            res.append(ex.args[0])
+                        else:
+                            res.append('EMPTY StopIteration')
+                            break
+                    except Exception as ex:
+                        res.append(str(type(ex)))
+                return res
+
+            sync_gen_result = sync_iterate(sync_gen)
+            async_gen_result = async_iterate(async_gen)
+            assert sync_gen_result == async_gen_result, "%s != %s" % 
(str(sync_gen_result), str(async_gen_result))
+            return async_gen_result
+
+        def sync_gen():
+            yield 10
+            yield 20
+
+        def sync_gen_wrapper():
+            yield 1
+            sg = sync_gen()
+            sg.send(None)
+            try:
+                sg.throw(GeneratorExit())
+            except GeneratorExit:
+                yield 2
+            yield 3
+
+        async def async_gen():
+            yield 10
+            yield 20
+
+        async def async_gen_wrapper():
+            yield 1
+            asg = async_gen()
+            await asg.asend(None)
+            try:
+                await asg.athrow(GeneratorExit())
+            except GeneratorExit:
+                yield 2
+            yield 3
+
+        compare_generators(sync_gen_wrapper(), async_gen_wrapper())
+        """
+
+
 def test_should_not_inline(space):
     from pypy.interpreter.generator import should_not_inline
     w_co = space.appexec([], '''():
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to