[pypy-commit] pypy py3.6: (vxgmichel, arigo)

arigo pypy.commits at gmail.com
Sun Jul 16 05:07:58 EDT 2017


Author: Armin Rigo <arigo at 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]
+        """


More information about the pypy-commit mailing list