Home | History | Annotate | Download | only in test
      1 import inspect
      2 import sys
      3 import types
      4 import unittest
      5 
      6 from unittest import mock
      7 
      8 from test.support import import_module
      9 asyncio = import_module("asyncio")
     10 
     11 
     12 class AwaitException(Exception):
     13     pass
     14 
     15 
     16 @types.coroutine
     17 def awaitable(*, throw=False):
     18     if throw:
     19         yield ('throw',)
     20     else:
     21         yield ('result',)
     22 
     23 
     24 def run_until_complete(coro):
     25     exc = False
     26     while True:
     27         try:
     28             if exc:
     29                 exc = False
     30                 fut = coro.throw(AwaitException)
     31             else:
     32                 fut = coro.send(None)
     33         except StopIteration as ex:
     34             return ex.args[0]
     35 
     36         if fut == ('throw',):
     37             exc = True
     38 
     39 
     40 def to_list(gen):
     41     async def iterate():
     42         res = []
     43         async for i in gen:
     44             res.append(i)
     45         return res
     46 
     47     return run_until_complete(iterate())
     48 
     49 
     50 class AsyncGenSyntaxTest(unittest.TestCase):
     51 
     52     def test_async_gen_syntax_01(self):
     53         code = '''async def foo():
     54             await abc
     55             yield from 123
     56         '''
     57 
     58         with self.assertRaisesRegex(SyntaxError, 'yield from.*inside async'):
     59             exec(code, {}, {})
     60 
     61     def test_async_gen_syntax_02(self):
     62         code = '''async def foo():
     63             yield from 123
     64         '''
     65 
     66         with self.assertRaisesRegex(SyntaxError, 'yield from.*inside async'):
     67             exec(code, {}, {})
     68 
     69     def test_async_gen_syntax_03(self):
     70         code = '''async def foo():
     71             await abc
     72             yield
     73             return 123
     74         '''
     75 
     76         with self.assertRaisesRegex(SyntaxError, 'return.*value.*async gen'):
     77             exec(code, {}, {})
     78 
     79     def test_async_gen_syntax_04(self):
     80         code = '''async def foo():
     81             yield
     82             return 123
     83         '''
     84 
     85         with self.assertRaisesRegex(SyntaxError, 'return.*value.*async gen'):
     86             exec(code, {}, {})
     87 
     88     def test_async_gen_syntax_05(self):
     89         code = '''async def foo():
     90             if 0:
     91                 yield
     92             return 12
     93         '''
     94 
     95         with self.assertRaisesRegex(SyntaxError, 'return.*value.*async gen'):
     96             exec(code, {}, {})
     97 
     98 
     99 class AsyncGenTest(unittest.TestCase):
    100 
    101     def compare_generators(self, sync_gen, async_gen):
    102         def sync_iterate(g):
    103             res = []
    104             while True:
    105                 try:
    106                     res.append(g.__next__())
    107                 except StopIteration:
    108                     res.append('STOP')
    109                     break
    110                 except Exception as ex:
    111                     res.append(str(type(ex)))
    112             return res
    113 
    114         def async_iterate(g):
    115             res = []
    116             while True:
    117                 try:
    118                     g.__anext__().__next__()
    119                 except StopAsyncIteration:
    120                     res.append('STOP')
    121                     break
    122                 except StopIteration as ex:
    123                     if ex.args:
    124                         res.append(ex.args[0])
    125                     else:
    126                         res.append('EMPTY StopIteration')
    127                         break
    128                 except Exception as ex:
    129                     res.append(str(type(ex)))
    130             return res
    131 
    132         sync_gen_result = sync_iterate(sync_gen)
    133         async_gen_result = async_iterate(async_gen)
    134         self.assertEqual(sync_gen_result, async_gen_result)
    135         return async_gen_result
    136 
    137     def test_async_gen_iteration_01(self):
    138         async def gen():
    139             await awaitable()
    140             a = yield 123
    141             self.assertIs(a, None)
    142             await awaitable()
    143             yield 456
    144             await awaitable()
    145             yield 789
    146 
    147         self.assertEqual(to_list(gen()), [123, 456, 789])
    148 
    149     def test_async_gen_iteration_02(self):
    150         async def gen():
    151             await awaitable()
    152             yield 123
    153             await awaitable()
    154 
    155         g = gen()
    156         ai = g.__aiter__()
    157         self.assertEqual(ai.__anext__().__next__(), ('result',))
    158 
    159         try:
    160             ai.__anext__().__next__()
    161         except StopIteration as ex:
    162             self.assertEqual(ex.args[0], 123)
    163         else:
    164             self.fail('StopIteration was not raised')
    165 
    166         self.assertEqual(ai.__anext__().__next__(), ('result',))
    167 
    168         try:
    169             ai.__anext__().__next__()
    170         except StopAsyncIteration as ex:
    171             self.assertFalse(ex.args)
    172         else:
    173             self.fail('StopAsyncIteration was not raised')
    174 
    175     def test_async_gen_exception_03(self):
    176         async def gen():
    177             await awaitable()
    178             yield 123
    179             await awaitable(throw=True)
    180             yield 456
    181 
    182         with self.assertRaises(AwaitException):
    183             to_list(gen())
    184 
    185     def test_async_gen_exception_04(self):
    186         async def gen():
    187             await awaitable()
    188             yield 123
    189             1 / 0
    190 
    191         g = gen()
    192         ai = g.__aiter__()
    193         self.assertEqual(ai.__anext__().__next__(), ('result',))
    194 
    195         try:
    196             ai.__anext__().__next__()
    197         except StopIteration as ex:
    198             self.assertEqual(ex.args[0], 123)
    199         else:
    200             self.fail('StopIteration was not raised')
    201 
    202         with self.assertRaises(ZeroDivisionError):
    203             ai.__anext__().__next__()
    204 
    205     def test_async_gen_exception_05(self):
    206         async def gen():
    207             yield 123
    208             raise StopAsyncIteration
    209 
    210         with self.assertRaisesRegex(RuntimeError,
    211                                     'async generator.*StopAsyncIteration'):
    212             to_list(gen())
    213 
    214     def test_async_gen_exception_06(self):
    215         async def gen():
    216             yield 123
    217             raise StopIteration
    218 
    219         with self.assertRaisesRegex(RuntimeError,
    220                                     'async generator.*StopIteration'):
    221             to_list(gen())
    222 
    223     def test_async_gen_exception_07(self):
    224         def sync_gen():
    225             try:
    226                 yield 1
    227                 1 / 0
    228             finally:
    229                 yield 2
    230                 yield 3
    231 
    232             yield 100
    233 
    234         async def async_gen():
    235             try:
    236                 yield 1
    237                 1 / 0
    238             finally:
    239                 yield 2
    240                 yield 3
    241 
    242             yield 100
    243 
    244         self.compare_generators(sync_gen(), async_gen())
    245 
    246     def test_async_gen_exception_08(self):
    247         def sync_gen():
    248             try:
    249                 yield 1
    250             finally:
    251                 yield 2
    252                 1 / 0
    253                 yield 3
    254 
    255             yield 100
    256 
    257         async def async_gen():
    258             try:
    259                 yield 1
    260                 await awaitable()
    261             finally:
    262                 await awaitable()
    263                 yield 2
    264                 1 / 0
    265                 yield 3
    266 
    267             yield 100
    268 
    269         self.compare_generators(sync_gen(), async_gen())
    270 
    271     def test_async_gen_exception_09(self):
    272         def sync_gen():
    273             try:
    274                 yield 1
    275                 1 / 0
    276             finally:
    277                 yield 2
    278                 yield 3
    279 
    280             yield 100
    281 
    282         async def async_gen():
    283             try:
    284                 await awaitable()
    285                 yield 1
    286                 1 / 0
    287             finally:
    288                 yield 2
    289                 await awaitable()
    290                 yield 3
    291 
    292             yield 100
    293 
    294         self.compare_generators(sync_gen(), async_gen())
    295 
    296     def test_async_gen_exception_10(self):
    297         async def gen():
    298             yield 123
    299         with self.assertRaisesRegex(TypeError,
    300                                     "non-None value .* async generator"):
    301             gen().__anext__().send(100)
    302 
    303     def test_async_gen_api_01(self):
    304         async def gen():
    305             yield 123
    306 
    307         g = gen()
    308 
    309         self.assertEqual(g.__name__, 'gen')
    310         g.__name__ = '123'
    311         self.assertEqual(g.__name__, '123')
    312 
    313         self.assertIn('.gen', g.__qualname__)
    314         g.__qualname__ = '123'
    315         self.assertEqual(g.__qualname__, '123')
    316 
    317         self.assertIsNone(g.ag_await)
    318         self.assertIsInstance(g.ag_frame, types.FrameType)
    319         self.assertFalse(g.ag_running)
    320         self.assertIsInstance(g.ag_code, types.CodeType)
    321 
    322         self.assertTrue(inspect.isawaitable(g.aclose()))
    323 
    324 
    325 class AsyncGenAsyncioTest(unittest.TestCase):
    326 
    327     def setUp(self):
    328         self.loop = asyncio.new_event_loop()
    329         asyncio.set_event_loop(None)
    330 
    331     def tearDown(self):
    332         self.loop.close()
    333         self.loop = None
    334 
    335     async def to_list(self, gen):
    336         res = []
    337         async for i in gen:
    338             res.append(i)
    339         return res
    340 
    341     def test_async_gen_asyncio_01(self):
    342         async def gen():
    343             yield 1
    344             await asyncio.sleep(0.01, loop=self.loop)
    345             yield 2
    346             await asyncio.sleep(0.01, loop=self.loop)
    347             return
    348             yield 3
    349 
    350         res = self.loop.run_until_complete(self.to_list(gen()))
    351         self.assertEqual(res, [1, 2])
    352 
    353     def test_async_gen_asyncio_02(self):
    354         async def gen():
    355             yield 1
    356             await asyncio.sleep(0.01, loop=self.loop)
    357             yield 2
    358             1 / 0
    359             yield 3
    360 
    361         with self.assertRaises(ZeroDivisionError):
    362             self.loop.run_until_complete(self.to_list(gen()))
    363 
    364     def test_async_gen_asyncio_03(self):
    365         loop = self.loop
    366 
    367         class Gen:
    368             async def __aiter__(self):
    369                 yield 1
    370                 await asyncio.sleep(0.01, loop=loop)
    371                 yield 2
    372 
    373         res = loop.run_until_complete(self.to_list(Gen()))
    374         self.assertEqual(res, [1, 2])
    375 
    376     def test_async_gen_asyncio_anext_04(self):
    377         async def foo():
    378             yield 1
    379             await asyncio.sleep(0.01, loop=self.loop)
    380             try:
    381                 yield 2
    382                 yield 3
    383             except ZeroDivisionError:
    384                 yield 1000
    385             await asyncio.sleep(0.01, loop=self.loop)
    386             yield 4
    387 
    388         async def run1():
    389             it = foo().__aiter__()
    390 
    391             self.assertEqual(await it.__anext__(), 1)
    392             self.assertEqual(await it.__anext__(), 2)
    393             self.assertEqual(await it.__anext__(), 3)
    394             self.assertEqual(await it.__anext__(), 4)
    395             with self.assertRaises(StopAsyncIteration):
    396                 await it.__anext__()
    397             with self.assertRaises(StopAsyncIteration):
    398                 await it.__anext__()
    399 
    400         async def run2():
    401             it = foo().__aiter__()
    402 
    403             self.assertEqual(await it.__anext__(), 1)
    404             self.assertEqual(await it.__anext__(), 2)
    405             try:
    406                 it.__anext__().throw(ZeroDivisionError)
    407             except StopIteration as ex:
    408                 self.assertEqual(ex.args[0], 1000)
    409             else:
    410                 self.fail('StopIteration was not raised')
    411             self.assertEqual(await it.__anext__(), 4)
    412             with self.assertRaises(StopAsyncIteration):
    413                 await it.__anext__()
    414 
    415         self.loop.run_until_complete(run1())
    416         self.loop.run_until_complete(run2())
    417 
    418     def test_async_gen_asyncio_anext_05(self):
    419         async def foo():
    420             v = yield 1
    421             v = yield v
    422             yield v * 100
    423 
    424         async def run():
    425             it = foo().__aiter__()
    426 
    427             try:
    428                 it.__anext__().send(None)
    429             except StopIteration as ex:
    430                 self.assertEqual(ex.args[0], 1)
    431             else:
    432                 self.fail('StopIteration was not raised')
    433 
    434             try:
    435                 it.__anext__().send(10)
    436             except StopIteration as ex:
    437                 self.assertEqual(ex.args[0], 10)
    438             else:
    439                 self.fail('StopIteration was not raised')
    440 
    441             try:
    442                 it.__anext__().send(12)
    443             except StopIteration as ex:
    444                 self.assertEqual(ex.args[0], 1200)
    445             else:
    446                 self.fail('StopIteration was not raised')
    447 
    448             with self.assertRaises(StopAsyncIteration):
    449                 await it.__anext__()
    450 
    451         self.loop.run_until_complete(run())
    452 
    453     def test_async_gen_asyncio_anext_06(self):
    454         DONE = 0
    455 
    456         # test synchronous generators
    457         def foo():
    458             try:
    459                 yield
    460             except:
    461                 pass
    462         g = foo()
    463         g.send(None)
    464         with self.assertRaises(StopIteration):
    465             g.send(None)
    466 
    467         # now with asynchronous generators
    468 
    469         async def gen():
    470             nonlocal DONE
    471             try:
    472                 yield
    473             except:
    474                 pass
    475             DONE = 1
    476 
    477         async def run():
    478             nonlocal DONE
    479             g = gen()
    480             await g.asend(None)
    481             with self.assertRaises(StopAsyncIteration):
    482                 await g.asend(None)
    483             DONE += 10
    484 
    485         self.loop.run_until_complete(run())
    486         self.assertEqual(DONE, 11)
    487 
    488     def test_async_gen_asyncio_anext_tuple(self):
    489         async def foo():
    490             try:
    491                 yield (1,)
    492             except ZeroDivisionError:
    493                 yield (2,)
    494 
    495         async def run():
    496             it = foo().__aiter__()
    497 
    498             self.assertEqual(await it.__anext__(), (1,))
    499             with self.assertRaises(StopIteration) as cm:
    500                 it.__anext__().throw(ZeroDivisionError)
    501             self.assertEqual(cm.exception.args[0], (2,))
    502             with self.assertRaises(StopAsyncIteration):
    503                 await it.__anext__()
    504 
    505         self.loop.run_until_complete(run())
    506 
    507     def test_async_gen_asyncio_anext_stopiteration(self):
    508         async def foo():
    509             try:
    510                 yield StopIteration(1)
    511             except ZeroDivisionError:
    512                 yield StopIteration(3)
    513 
    514         async def run():
    515             it = foo().__aiter__()
    516 
    517             v = await it.__anext__()
    518             self.assertIsInstance(v, StopIteration)
    519             self.assertEqual(v.value, 1)
    520             with self.assertRaises(StopIteration) as cm:
    521                 it.__anext__().throw(ZeroDivisionError)
    522             v = cm.exception.args[0]
    523             self.assertIsInstance(v, StopIteration)
    524             self.assertEqual(v.value, 3)
    525             with self.assertRaises(StopAsyncIteration):
    526                 await it.__anext__()
    527 
    528         self.loop.run_until_complete(run())
    529 
    530     def test_async_gen_asyncio_aclose_06(self):
    531         async def foo():
    532             try:
    533                 yield 1
    534                 1 / 0
    535             finally:
    536                 await asyncio.sleep(0.01, loop=self.loop)
    537                 yield 12
    538 
    539         async def run():
    540             gen = foo()
    541             it = gen.__aiter__()
    542             await it.__anext__()
    543             await gen.aclose()
    544 
    545         with self.assertRaisesRegex(
    546                 RuntimeError,
    547                 "async generator ignored GeneratorExit"):
    548             self.loop.run_until_complete(run())
    549 
    550     def test_async_gen_asyncio_aclose_07(self):
    551         DONE = 0
    552 
    553         async def foo():
    554             nonlocal DONE
    555             try:
    556                 yield 1
    557                 1 / 0
    558             finally:
    559                 await asyncio.sleep(0.01, loop=self.loop)
    560                 await asyncio.sleep(0.01, loop=self.loop)
    561                 DONE += 1
    562             DONE += 1000
    563 
    564         async def run():
    565             gen = foo()
    566             it = gen.__aiter__()
    567             await it.__anext__()
    568             await gen.aclose()
    569 
    570         self.loop.run_until_complete(run())
    571         self.assertEqual(DONE, 1)
    572 
    573     def test_async_gen_asyncio_aclose_08(self):
    574         DONE = 0
    575 
    576         fut = asyncio.Future(loop=self.loop)
    577 
    578         async def foo():
    579             nonlocal DONE
    580             try:
    581                 yield 1
    582                 await fut
    583                 DONE += 1000
    584                 yield 2
    585             finally:
    586                 await asyncio.sleep(0.01, loop=self.loop)
    587                 await asyncio.sleep(0.01, loop=self.loop)
    588                 DONE += 1
    589             DONE += 1000
    590 
    591         async def run():
    592             gen = foo()
    593             it = gen.__aiter__()
    594             self.assertEqual(await it.__anext__(), 1)
    595             t = self.loop.create_task(it.__anext__())
    596             await asyncio.sleep(0.01, loop=self.loop)
    597             await gen.aclose()
    598             return t
    599 
    600         t = self.loop.run_until_complete(run())
    601         self.assertEqual(DONE, 1)
    602 
    603         # Silence ResourceWarnings
    604         fut.cancel()
    605         t.cancel()
    606         self.loop.run_until_complete(asyncio.sleep(0.01, loop=self.loop))
    607 
    608     def test_async_gen_asyncio_gc_aclose_09(self):
    609         DONE = 0
    610 
    611         async def gen():
    612             nonlocal DONE
    613             try:
    614                 while True:
    615                     yield 1
    616             finally:
    617                 await asyncio.sleep(0.01, loop=self.loop)
    618                 await asyncio.sleep(0.01, loop=self.loop)
    619                 DONE = 1
    620 
    621         async def run():
    622             g = gen()
    623             await g.__anext__()
    624             await g.__anext__()
    625             del g
    626 
    627             await asyncio.sleep(0.1, loop=self.loop)
    628 
    629         self.loop.run_until_complete(run())
    630         self.assertEqual(DONE, 1)
    631 
    632     def test_async_gen_asyncio_aclose_10(self):
    633         DONE = 0
    634 
    635         # test synchronous generators
    636         def foo():
    637             try:
    638                 yield
    639             except:
    640                 pass
    641         g = foo()
    642         g.send(None)
    643         g.close()
    644 
    645         # now with asynchronous generators
    646 
    647         async def gen():
    648             nonlocal DONE
    649             try:
    650                 yield
    651             except:
    652                 pass
    653             DONE = 1
    654 
    655         async def run():
    656             nonlocal DONE
    657             g = gen()
    658             await g.asend(None)
    659             await g.aclose()
    660             DONE += 10
    661 
    662         self.loop.run_until_complete(run())
    663         self.assertEqual(DONE, 11)
    664 
    665     def test_async_gen_asyncio_aclose_11(self):
    666         DONE = 0
    667 
    668         # test synchronous generators
    669         def foo():
    670             try:
    671                 yield
    672             except:
    673                 pass
    674             yield
    675         g = foo()
    676         g.send(None)
    677         with self.assertRaisesRegex(RuntimeError, 'ignored GeneratorExit'):
    678             g.close()
    679 
    680         # now with asynchronous generators
    681 
    682         async def gen():
    683             nonlocal DONE
    684             try:
    685                 yield
    686             except:
    687                 pass
    688             yield
    689             DONE += 1
    690 
    691         async def run():
    692             nonlocal DONE
    693             g = gen()
    694             await g.asend(None)
    695             with self.assertRaisesRegex(RuntimeError, 'ignored GeneratorExit'):
    696                 await g.aclose()
    697             DONE += 10
    698 
    699         self.loop.run_until_complete(run())
    700         self.assertEqual(DONE, 10)
    701 
    702     def test_async_gen_asyncio_asend_01(self):
    703         DONE = 0
    704 
    705         # Sanity check:
    706         def sgen():
    707             v = yield 1
    708             yield v * 2
    709         sg = sgen()
    710         v = sg.send(None)
    711         self.assertEqual(v, 1)
    712         v = sg.send(100)
    713         self.assertEqual(v, 200)
    714 
    715         async def gen():
    716             nonlocal DONE
    717             try:
    718                 await asyncio.sleep(0.01, loop=self.loop)
    719                 v = yield 1
    720                 await asyncio.sleep(0.01, loop=self.loop)
    721                 yield v * 2
    722                 await asyncio.sleep(0.01, loop=self.loop)
    723                 return
    724             finally:
    725                 await asyncio.sleep(0.01, loop=self.loop)
    726                 await asyncio.sleep(0.01, loop=self.loop)
    727                 DONE = 1
    728 
    729         async def run():
    730             g = gen()
    731 
    732             v = await g.asend(None)
    733             self.assertEqual(v, 1)
    734 
    735             v = await g.asend(100)
    736             self.assertEqual(v, 200)
    737 
    738             with self.assertRaises(StopAsyncIteration):
    739                 await g.asend(None)
    740 
    741         self.loop.run_until_complete(run())
    742         self.assertEqual(DONE, 1)
    743 
    744     def test_async_gen_asyncio_asend_02(self):
    745         DONE = 0
    746 
    747         async def sleep_n_crash(delay):
    748             await asyncio.sleep(delay, loop=self.loop)
    749             1 / 0
    750 
    751         async def gen():
    752             nonlocal DONE
    753             try:
    754                 await asyncio.sleep(0.01, loop=self.loop)
    755                 v = yield 1
    756                 await sleep_n_crash(0.01)
    757                 DONE += 1000
    758                 yield v * 2
    759             finally:
    760                 await asyncio.sleep(0.01, loop=self.loop)
    761                 await asyncio.sleep(0.01, loop=self.loop)
    762                 DONE = 1
    763 
    764         async def run():
    765             g = gen()
    766 
    767             v = await g.asend(None)
    768             self.assertEqual(v, 1)
    769 
    770             await g.asend(100)
    771 
    772         with self.assertRaises(ZeroDivisionError):
    773             self.loop.run_until_complete(run())
    774         self.assertEqual(DONE, 1)
    775 
    776     def test_async_gen_asyncio_asend_03(self):
    777         DONE = 0
    778 
    779         async def sleep_n_crash(delay):
    780             fut = asyncio.ensure_future(asyncio.sleep(delay, loop=self.loop),
    781                                         loop=self.loop)
    782             self.loop.call_later(delay / 2, lambda: fut.cancel())
    783             return await fut
    784 
    785         async def gen():
    786             nonlocal DONE
    787             try:
    788                 await asyncio.sleep(0.01, loop=self.loop)
    789                 v = yield 1
    790                 await sleep_n_crash(0.01)
    791                 DONE += 1000
    792                 yield v * 2
    793             finally:
    794                 await asyncio.sleep(0.01, loop=self.loop)
    795                 await asyncio.sleep(0.01, loop=self.loop)
    796                 DONE = 1
    797 
    798         async def run():
    799             g = gen()
    800 
    801             v = await g.asend(None)
    802             self.assertEqual(v, 1)
    803 
    804             await g.asend(100)
    805 
    806         with self.assertRaises(asyncio.CancelledError):
    807             self.loop.run_until_complete(run())
    808         self.assertEqual(DONE, 1)
    809 
    810     def test_async_gen_asyncio_athrow_01(self):
    811         DONE = 0
    812 
    813         class FooEr(Exception):
    814             pass
    815 
    816         # Sanity check:
    817         def sgen():
    818             try:
    819                 v = yield 1
    820             except FooEr:
    821                 v = 1000
    822             yield v * 2
    823         sg = sgen()
    824         v = sg.send(None)
    825         self.assertEqual(v, 1)
    826         v = sg.throw(FooEr)
    827         self.assertEqual(v, 2000)
    828         with self.assertRaises(StopIteration):
    829             sg.send(None)
    830 
    831         async def gen():
    832             nonlocal DONE
    833             try:
    834                 await asyncio.sleep(0.01, loop=self.loop)
    835                 try:
    836                     v = yield 1
    837                 except FooEr:
    838                     v = 1000
    839                     await asyncio.sleep(0.01, loop=self.loop)
    840                 yield v * 2
    841                 await asyncio.sleep(0.01, loop=self.loop)
    842                 # return
    843             finally:
    844                 await asyncio.sleep(0.01, loop=self.loop)
    845                 await asyncio.sleep(0.01, loop=self.loop)
    846                 DONE = 1
    847 
    848         async def run():
    849             g = gen()
    850 
    851             v = await g.asend(None)
    852             self.assertEqual(v, 1)
    853 
    854             v = await g.athrow(FooEr)
    855             self.assertEqual(v, 2000)
    856 
    857             with self.assertRaises(StopAsyncIteration):
    858                 await g.asend(None)
    859 
    860         self.loop.run_until_complete(run())
    861         self.assertEqual(DONE, 1)
    862 
    863     def test_async_gen_asyncio_athrow_02(self):
    864         DONE = 0
    865 
    866         class FooEr(Exception):
    867             pass
    868 
    869         async def sleep_n_crash(delay):
    870             fut = asyncio.ensure_future(asyncio.sleep(delay, loop=self.loop),
    871                                         loop=self.loop)
    872             self.loop.call_later(delay / 2, lambda: fut.cancel())
    873             return await fut
    874 
    875         async def gen():
    876             nonlocal DONE
    877             try:
    878                 await asyncio.sleep(0.01, loop=self.loop)
    879                 try:
    880                     v = yield 1
    881                 except FooEr:
    882                     await sleep_n_crash(0.01)
    883                 yield v * 2
    884                 await asyncio.sleep(0.01, loop=self.loop)
    885                 # return
    886             finally:
    887                 await asyncio.sleep(0.01, loop=self.loop)
    888                 await asyncio.sleep(0.01, loop=self.loop)
    889                 DONE = 1
    890 
    891         async def run():
    892             g = gen()
    893 
    894             v = await g.asend(None)
    895             self.assertEqual(v, 1)
    896 
    897             try:
    898                 await g.athrow(FooEr)
    899             except asyncio.CancelledError:
    900                 self.assertEqual(DONE, 1)
    901                 raise
    902             else:
    903                 self.fail('CancelledError was not raised')
    904 
    905         with self.assertRaises(asyncio.CancelledError):
    906             self.loop.run_until_complete(run())
    907         self.assertEqual(DONE, 1)
    908 
    909     def test_async_gen_asyncio_athrow_03(self):
    910         DONE = 0
    911 
    912         # test synchronous generators
    913         def foo():
    914             try:
    915                 yield
    916             except:
    917                 pass
    918         g = foo()
    919         g.send(None)
    920         with self.assertRaises(StopIteration):
    921             g.throw(ValueError)
    922 
    923         # now with asynchronous generators
    924 
    925         async def gen():
    926             nonlocal DONE
    927             try:
    928                 yield
    929             except:
    930                 pass
    931             DONE = 1
    932 
    933         async def run():
    934             nonlocal DONE
    935             g = gen()
    936             await g.asend(None)
    937             with self.assertRaises(StopAsyncIteration):
    938                 await g.athrow(ValueError)
    939             DONE += 10
    940 
    941         self.loop.run_until_complete(run())
    942         self.assertEqual(DONE, 11)
    943 
    944     def test_async_gen_asyncio_athrow_tuple(self):
    945         async def gen():
    946             try:
    947                 yield 1
    948             except ZeroDivisionError:
    949                 yield (2,)
    950 
    951         async def run():
    952             g = gen()
    953             v = await g.asend(None)
    954             self.assertEqual(v, 1)
    955             v = await g.athrow(ZeroDivisionError)
    956             self.assertEqual(v, (2,))
    957             with self.assertRaises(StopAsyncIteration):
    958                 await g.asend(None)
    959 
    960         self.loop.run_until_complete(run())
    961 
    962     def test_async_gen_asyncio_athrow_stopiteration(self):
    963         async def gen():
    964             try:
    965                 yield 1
    966             except ZeroDivisionError:
    967                 yield StopIteration(2)
    968 
    969         async def run():
    970             g = gen()
    971             v = await g.asend(None)
    972             self.assertEqual(v, 1)
    973             v = await g.athrow(ZeroDivisionError)
    974             self.assertIsInstance(v, StopIteration)
    975             self.assertEqual(v.value, 2)
    976             with self.assertRaises(StopAsyncIteration):
    977                 await g.asend(None)
    978 
    979         self.loop.run_until_complete(run())
    980 
    981     def test_async_gen_asyncio_shutdown_01(self):
    982         finalized = 0
    983 
    984         async def waiter(timeout):
    985             nonlocal finalized
    986             try:
    987                 await asyncio.sleep(timeout, loop=self.loop)
    988                 yield 1
    989             finally:
    990                 await asyncio.sleep(0, loop=self.loop)
    991                 finalized += 1
    992 
    993         async def wait():
    994             async for _ in waiter(1):
    995                 pass
    996 
    997         t1 = self.loop.create_task(wait())
    998         t2 = self.loop.create_task(wait())
    999 
   1000         self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop))
   1001 
   1002         self.loop.run_until_complete(self.loop.shutdown_asyncgens())
   1003         self.assertEqual(finalized, 2)
   1004 
   1005         # Silence warnings
   1006         t1.cancel()
   1007         t2.cancel()
   1008         self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop))
   1009 
   1010     def test_async_gen_asyncio_shutdown_02(self):
   1011         logged = 0
   1012 
   1013         def logger(loop, context):
   1014             nonlocal logged
   1015             self.assertIn('asyncgen', context)
   1016             expected = 'an error occurred during closing of asynchronous'
   1017             if expected in context['message']:
   1018                 logged += 1
   1019 
   1020         async def waiter(timeout):
   1021             try:
   1022                 await asyncio.sleep(timeout, loop=self.loop)
   1023                 yield 1
   1024             finally:
   1025                 1 / 0
   1026 
   1027         async def wait():
   1028             async for _ in waiter(1):
   1029                 pass
   1030 
   1031         t = self.loop.create_task(wait())
   1032         self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop))
   1033 
   1034         self.loop.set_exception_handler(logger)
   1035         self.loop.run_until_complete(self.loop.shutdown_asyncgens())
   1036 
   1037         self.assertEqual(logged, 1)
   1038 
   1039         # Silence warnings
   1040         t.cancel()
   1041         self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop))
   1042 
   1043 if __name__ == "__main__":
   1044     unittest.main()
   1045