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