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