Author: Manuel Jacob <m...@manueljacob.de>
Branch: py3.6
Changeset: r91918:a52d37ceba11
Date: 2017-07-18 19:35 +0200
http://bitbucket.org/pypy/pypy/changeset/a52d37ceba11/

Log:    Add first test for aclose() on async generator and make it pass.

diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -602,7 +602,7 @@
         return AsyncGenAThrow(self, w_type, w_val, w_tb)
 
     def descr_aclose(self):
-        XXX
+        return AsyncGenAThrow(self, None, None, None)
 
 
 class AsyncGenValueWrapper(W_Root):
@@ -709,14 +709,30 @@
 
         try:
             if throwing:
-                w_value = self.async_gen.throw(self.w_exc_type,
-                                               self.w_exc_value,
-                                               self.w_exc_tb)
+                if self.w_exc_type is None:
+                    w_value = self.async_gen.throw(space.w_GeneratorExit,
+                                                   None, None)
+                    if w_value is not None:
+                        XXX
+                else:
+                    w_value = self.async_gen.throw(self.w_exc_type,
+                                                   self.w_exc_value,
+                                                   self.w_exc_tb)
             else:
                 w_value = self.async_gen.send_ex(w_arg_or_err)
             return self.unwrap_value(w_value)
         except OperationError as e:
-            self.state = self.ST_CLOSED
+            if e.match(space, space.w_StopAsyncIteration):
+                self.state = self.ST_CLOSED
+                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.
+                    raise OperationError(space.w_StopIteration, space.w_None)
+            if e.match(space, space.w_GeneratorExit):
+                self.state = self.ST_CLOSED
+                # Ignore this error.
+                raise OperationError(space.w_StopIteration, space.w_None)
             raise
 
     def descr_throw(self, w_type, w_val=None, w_tb=None):
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
@@ -448,3 +448,25 @@
         except StopIteration:
             assert values == [42]
     """
+
+    def test_async_aclose(self): """
+        raises_generator_exit = False
+        async def ag():
+            nonlocal raises_generator_exit
+            try:
+                yield
+            except GeneratorExit:
+                raises_generator_exit = True
+                raise
+
+        async def run():
+            a = ag()
+            async for i in a:
+                break
+            await a.aclose()
+        try:
+            run().send(None)
+        except StopIteration:
+            pass
+        assert raises_generator_exit
+    """
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to