Author: Armin Rigo <ar...@tunes.org>
Branch: py3.6
Changeset: r91883:68e743f6f11e
Date: 2017-07-16 11:07 +0200
http://bitbucket.org/pypy/pypy/changeset/68e743f6f11e/

Log:    (vxgmichel, arigo)

        Handle exhausted async generators correctly

diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -43,7 +43,7 @@
     def descr__repr__(self, space):
         addrstring = self.getaddrstring(space)
         return space.newunicode(u"<%s object %s at 0x%s>" %
-                          (unicode(self.KIND),
+                          (self.KIND_U,
                            self.get_qualname(),
                            unicode(addrstring)))
 
@@ -80,6 +80,8 @@
             # execute_frame() if the frame is actually finished
             if isinstance(w_arg_or_err, SApplicationException):
                 operr = w_arg_or_err.operr
+            elif isinstance(self, AsyncGenerator):
+                operr = OperationError(space.w_StopAsyncIteration, 
space.w_None)
             else:
                 operr = OperationError(space.w_StopIteration, space.w_None)
             raise operr
@@ -345,6 +347,7 @@
 class GeneratorIterator(GeneratorOrCoroutine):
     "An iterator created by a generator."
     KIND = "generator"
+    KIND_U = u"generator"
 
     def descr__iter__(self):
         """Implement iter(self)."""
@@ -393,6 +396,7 @@
 class Coroutine(GeneratorOrCoroutine):
     "A coroutine object."
     KIND = "coroutine"
+    KIND_U = u"coroutine"
 
     def descr__await__(self, space):
         return CoroutineWrapper(self)
@@ -571,7 +575,8 @@
 
 class AsyncGenerator(GeneratorOrCoroutine):
     "An async generator (i.e. a coroutine with a 'yield')"
-    KIND = "async_generator"
+    KIND = "async generator"
+    KIND_U = u"async_generator"
 
     def descr__aiter__(self):
         """Return an asynchronous iterator."""
diff --git a/pypy/interpreter/test/test_coroutine.py 
b/pypy/interpreter/test/test_coroutine.py
--- a/pypy/interpreter/test/test_coroutine.py
+++ b/pypy/interpreter/test/test_coroutine.py
@@ -222,3 +222,25 @@
             pass
         assert result == [5]
         """
+
+    def test_async_yield_already_finished(self): """
+        class Done(Exception): pass
+
+        async def mygen():
+            yield 5
+
+        result = []
+        async def foo():
+            g = mygen()
+            async for i in g:
+                result.append(i)
+            async for i in g:
+                assert False   # should not be reached
+            raise Done
+
+        try:
+            foo().send(None)
+        except Done:
+            pass
+        assert result == [5]
+        """
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to