1import contextlib 2import copy 3import inspect 4import pickle 5import sys 6import types 7import unittest 8import warnings 9from test import support 10from test.support import import_helper 11from test.support import warnings_helper 12from test.support.script_helper import assert_python_ok 13 14 15class AsyncYieldFrom: 16 def __init__(self, obj): 17 self.obj = obj 18 19 def __await__(self): 20 yield from self.obj 21 22 23class AsyncYield: 24 def __init__(self, value): 25 self.value = value 26 27 def __await__(self): 28 yield self.value 29 30 31def run_async(coro): 32 assert coro.__class__ in {types.GeneratorType, types.CoroutineType} 33 34 buffer = [] 35 result = None 36 while True: 37 try: 38 buffer.append(coro.send(None)) 39 except StopIteration as ex: 40 result = ex.args[0] if ex.args else None 41 break 42 return buffer, result 43 44 45def run_async__await__(coro): 46 assert coro.__class__ is types.CoroutineType 47 aw = coro.__await__() 48 buffer = [] 49 result = None 50 i = 0 51 while True: 52 try: 53 if i % 2: 54 buffer.append(next(aw)) 55 else: 56 buffer.append(aw.send(None)) 57 i += 1 58 except StopIteration as ex: 59 result = ex.args[0] if ex.args else None 60 break 61 return buffer, result 62 63 64@contextlib.contextmanager 65def silence_coro_gc(): 66 with warnings.catch_warnings(): 67 warnings.simplefilter("ignore") 68 yield 69 support.gc_collect() 70 71 72class AsyncBadSyntaxTest(unittest.TestCase): 73 74 def test_badsyntax_1(self): 75 samples = [ 76 """def foo(): 77 await something() 78 """, 79 80 """await something()""", 81 82 """async def foo(): 83 yield from [] 84 """, 85 86 """async def foo(): 87 await await fut 88 """, 89 90 """async def foo(a=await something()): 91 pass 92 """, 93 94 """async def foo(a:await something()): 95 pass 96 """, 97 98 """async def foo(): 99 def bar(): 100 [i async for i in els] 101 """, 102 103 """async def foo(): 104 def bar(): 105 [await i for i in els] 106 """, 107 108 """async def foo(): 109 def bar(): 110 [i for i in els 111 async for b in els] 112 """, 113 114 """async def foo(): 115 def bar(): 116 [i for i in els 117 for c in b 118 async for b in els] 119 """, 120 121 """async def foo(): 122 def bar(): 123 [i for i in els 124 async for b in els 125 for c in b] 126 """, 127 128 """async def foo(): 129 def bar(): 130 [i for i in els 131 for b in await els] 132 """, 133 134 """async def foo(): 135 def bar(): 136 [i for i in els 137 for b in els 138 if await b] 139 """, 140 141 """async def foo(): 142 def bar(): 143 [i for i in await els] 144 """, 145 146 """async def foo(): 147 def bar(): 148 [i for i in els if await i] 149 """, 150 151 """def bar(): 152 [i async for i in els] 153 """, 154 155 """def bar(): 156 {i: i async for i in els} 157 """, 158 159 """def bar(): 160 {i async for i in els} 161 """, 162 163 """def bar(): 164 [await i for i in els] 165 """, 166 167 """def bar(): 168 [i for i in els 169 async for b in els] 170 """, 171 172 """def bar(): 173 [i for i in els 174 for c in b 175 async for b in els] 176 """, 177 178 """def bar(): 179 [i for i in els 180 async for b in els 181 for c in b] 182 """, 183 184 """def bar(): 185 [i for i in els 186 for b in await els] 187 """, 188 189 """def bar(): 190 [i for i in els 191 for b in els 192 if await b] 193 """, 194 195 """def bar(): 196 [i for i in await els] 197 """, 198 199 """def bar(): 200 [i for i in els if await i] 201 """, 202 203 """async def foo(): 204 await 205 """, 206 207 """async def foo(): 208 def bar(): pass 209 await = 1 210 """, 211 212 """async def foo(): 213 214 def bar(): pass 215 await = 1 216 """, 217 218 """async def foo(): 219 def bar(): pass 220 if 1: 221 await = 1 222 """, 223 224 """def foo(): 225 async def bar(): pass 226 if 1: 227 await a 228 """, 229 230 """def foo(): 231 async def bar(): pass 232 await a 233 """, 234 235 """def foo(): 236 def baz(): pass 237 async def bar(): pass 238 await a 239 """, 240 241 """def foo(): 242 def baz(): pass 243 # 456 244 async def bar(): pass 245 # 123 246 await a 247 """, 248 249 """async def foo(): 250 def baz(): pass 251 # 456 252 async def bar(): pass 253 # 123 254 await = 2 255 """, 256 257 """def foo(): 258 259 def baz(): pass 260 261 async def bar(): pass 262 263 await a 264 """, 265 266 """async def foo(): 267 268 def baz(): pass 269 270 async def bar(): pass 271 272 await = 2 273 """, 274 275 """async def foo(): 276 def async(): pass 277 """, 278 279 """async def foo(): 280 def await(): pass 281 """, 282 283 """async def foo(): 284 def bar(): 285 await 286 """, 287 288 """async def foo(): 289 return lambda async: await 290 """, 291 292 """async def foo(): 293 return lambda a: await 294 """, 295 296 """await a()""", 297 298 """async def foo(a=await b): 299 pass 300 """, 301 302 """async def foo(a:await b): 303 pass 304 """, 305 306 """def baz(): 307 async def foo(a=await b): 308 pass 309 """, 310 311 """async def foo(async): 312 pass 313 """, 314 315 """async def foo(): 316 def bar(): 317 def baz(): 318 async = 1 319 """, 320 321 """async def foo(): 322 def bar(): 323 def baz(): 324 pass 325 async = 1 326 """, 327 328 """def foo(): 329 async def bar(): 330 331 async def baz(): 332 pass 333 334 def baz(): 335 42 336 337 async = 1 338 """, 339 340 """async def foo(): 341 def bar(): 342 def baz(): 343 pass\nawait foo() 344 """, 345 346 """def foo(): 347 def bar(): 348 async def baz(): 349 pass\nawait foo() 350 """, 351 352 """async def foo(await): 353 pass 354 """, 355 356 """def foo(): 357 358 async def bar(): pass 359 360 await a 361 """, 362 363 """def foo(): 364 async def bar(): 365 pass\nawait a 366 """, 367 """def foo(): 368 async for i in arange(2): 369 pass 370 """, 371 """def foo(): 372 async with resource: 373 pass 374 """, 375 """async with resource: 376 pass 377 """, 378 """async for i in arange(2): 379 pass 380 """, 381 ] 382 383 for code in samples: 384 with self.subTest(code=code), self.assertRaises(SyntaxError): 385 compile(code, "<test>", "exec") 386 387 def test_badsyntax_2(self): 388 samples = [ 389 """def foo(): 390 await = 1 391 """, 392 393 """class Bar: 394 def async(): pass 395 """, 396 397 """class Bar: 398 async = 1 399 """, 400 401 """class async: 402 pass 403 """, 404 405 """class await: 406 pass 407 """, 408 409 """import math as await""", 410 411 """def async(): 412 pass""", 413 414 """def foo(*, await=1): 415 pass""" 416 417 """async = 1""", 418 419 """print(await=1)""" 420 ] 421 422 for code in samples: 423 with self.subTest(code=code), self.assertRaises(SyntaxError): 424 compile(code, "<test>", "exec") 425 426 def test_badsyntax_3(self): 427 with self.assertRaises(SyntaxError): 428 compile("async = 1", "<test>", "exec") 429 430 def test_badsyntax_4(self): 431 samples = [ 432 '''def foo(await): 433 async def foo(): pass 434 async def foo(): 435 pass 436 return await + 1 437 ''', 438 439 '''def foo(await): 440 async def foo(): pass 441 async def foo(): pass 442 return await + 1 443 ''', 444 445 '''def foo(await): 446 447 async def foo(): pass 448 449 async def foo(): pass 450 451 return await + 1 452 ''', 453 454 '''def foo(await): 455 """spam""" 456 async def foo(): \ 457 pass 458 # 123 459 async def foo(): pass 460 # 456 461 return await + 1 462 ''', 463 464 '''def foo(await): 465 def foo(): pass 466 def foo(): pass 467 async def bar(): return await_ 468 await_ = await 469 try: 470 bar().send(None) 471 except StopIteration as ex: 472 return ex.args[0] + 1 473 ''' 474 ] 475 476 for code in samples: 477 with self.subTest(code=code), self.assertRaises(SyntaxError): 478 compile(code, "<test>", "exec") 479 480 481class TokenizerRegrTest(unittest.TestCase): 482 483 def test_oneline_defs(self): 484 buf = [] 485 for i in range(500): 486 buf.append('def i{i}(): return {i}'.format(i=i)) 487 buf = '\n'.join(buf) 488 489 # Test that 500 consequent, one-line defs is OK 490 ns = {} 491 exec(buf, ns, ns) 492 self.assertEqual(ns['i499'](), 499) 493 494 # Test that 500 consequent, one-line defs *and* 495 # one 'async def' following them is OK 496 buf += '\nasync def foo():\n return' 497 ns = {} 498 exec(buf, ns, ns) 499 self.assertEqual(ns['i499'](), 499) 500 self.assertTrue(inspect.iscoroutinefunction(ns['foo'])) 501 502 503class CoroutineTest(unittest.TestCase): 504 505 def test_gen_1(self): 506 def gen(): yield 507 self.assertFalse(hasattr(gen, '__await__')) 508 509 def test_func_1(self): 510 async def foo(): 511 return 10 512 513 f = foo() 514 self.assertIsInstance(f, types.CoroutineType) 515 self.assertTrue(bool(foo.__code__.co_flags & inspect.CO_COROUTINE)) 516 self.assertFalse(bool(foo.__code__.co_flags & inspect.CO_GENERATOR)) 517 self.assertTrue(bool(f.cr_code.co_flags & inspect.CO_COROUTINE)) 518 self.assertFalse(bool(f.cr_code.co_flags & inspect.CO_GENERATOR)) 519 self.assertEqual(run_async(f), ([], 10)) 520 521 self.assertEqual(run_async__await__(foo()), ([], 10)) 522 523 def bar(): pass 524 self.assertFalse(bool(bar.__code__.co_flags & inspect.CO_COROUTINE)) 525 526 def test_func_2(self): 527 async def foo(): 528 raise StopIteration 529 530 with self.assertRaisesRegex( 531 RuntimeError, "coroutine raised StopIteration"): 532 533 run_async(foo()) 534 535 def test_func_3(self): 536 async def foo(): 537 raise StopIteration 538 539 coro = foo() 540 self.assertRegex(repr(coro), '^<coroutine object.* at 0x.*>$') 541 coro.close() 542 543 def test_func_4(self): 544 async def foo(): 545 raise StopIteration 546 coro = foo() 547 548 check = lambda: self.assertRaisesRegex( 549 TypeError, "'coroutine' object is not iterable") 550 551 with check(): 552 list(coro) 553 554 with check(): 555 tuple(coro) 556 557 with check(): 558 sum(coro) 559 560 with check(): 561 iter(coro) 562 563 with check(): 564 for i in coro: 565 pass 566 567 with check(): 568 [i for i in coro] 569 570 coro.close() 571 572 def test_func_5(self): 573 @types.coroutine 574 def bar(): 575 yield 1 576 577 async def foo(): 578 await bar() 579 580 check = lambda: self.assertRaisesRegex( 581 TypeError, "'coroutine' object is not iterable") 582 583 coro = foo() 584 with check(): 585 for el in coro: 586 pass 587 coro.close() 588 589 # the following should pass without an error 590 for el in bar(): 591 self.assertEqual(el, 1) 592 self.assertEqual([el for el in bar()], [1]) 593 self.assertEqual(tuple(bar()), (1,)) 594 self.assertEqual(next(iter(bar())), 1) 595 596 def test_func_6(self): 597 @types.coroutine 598 def bar(): 599 yield 1 600 yield 2 601 602 async def foo(): 603 await bar() 604 605 f = foo() 606 self.assertEqual(f.send(None), 1) 607 self.assertEqual(f.send(None), 2) 608 with self.assertRaises(StopIteration): 609 f.send(None) 610 611 def test_func_7(self): 612 async def bar(): 613 return 10 614 coro = bar() 615 616 def foo(): 617 yield from coro 618 619 with self.assertRaisesRegex( 620 TypeError, 621 "cannot 'yield from' a coroutine object in " 622 "a non-coroutine generator"): 623 list(foo()) 624 625 coro.close() 626 627 def test_func_8(self): 628 @types.coroutine 629 def bar(): 630 return (yield from coro) 631 632 async def foo(): 633 return 'spam' 634 635 coro = foo() 636 self.assertEqual(run_async(bar()), ([], 'spam')) 637 coro.close() 638 639 def test_func_9(self): 640 async def foo(): 641 pass 642 643 with self.assertWarnsRegex( 644 RuntimeWarning, 645 r"coroutine '.*test_func_9.*foo' was never awaited"): 646 647 foo() 648 support.gc_collect() 649 650 with self.assertWarnsRegex( 651 RuntimeWarning, 652 r"coroutine '.*test_func_9.*foo' was never awaited"): 653 654 with self.assertRaises(TypeError): 655 # See bpo-32703. 656 for _ in foo(): 657 pass 658 659 support.gc_collect() 660 661 def test_func_10(self): 662 N = 0 663 664 @types.coroutine 665 def gen(): 666 nonlocal N 667 try: 668 a = yield 669 yield (a ** 2) 670 except ZeroDivisionError: 671 N += 100 672 raise 673 finally: 674 N += 1 675 676 async def foo(): 677 await gen() 678 679 coro = foo() 680 aw = coro.__await__() 681 self.assertIs(aw, iter(aw)) 682 next(aw) 683 self.assertEqual(aw.send(10), 100) 684 685 self.assertEqual(N, 0) 686 aw.close() 687 self.assertEqual(N, 1) 688 689 coro = foo() 690 aw = coro.__await__() 691 next(aw) 692 with self.assertRaises(ZeroDivisionError): 693 aw.throw(ZeroDivisionError, None, None) 694 self.assertEqual(N, 102) 695 696 def test_func_11(self): 697 async def func(): pass 698 coro = func() 699 # Test that PyCoro_Type and _PyCoroWrapper_Type types were properly 700 # initialized 701 self.assertIn('__await__', dir(coro)) 702 self.assertIn('__iter__', dir(coro.__await__())) 703 self.assertIn('coroutine_wrapper', repr(coro.__await__())) 704 coro.close() # avoid RuntimeWarning 705 706 def test_func_12(self): 707 async def g(): 708 i = me.send(None) 709 await foo 710 me = g() 711 with self.assertRaisesRegex(ValueError, 712 "coroutine already executing"): 713 me.send(None) 714 715 def test_func_13(self): 716 async def g(): 717 pass 718 719 coro = g() 720 with self.assertRaisesRegex( 721 TypeError, 722 "can't send non-None value to a just-started coroutine"): 723 coro.send('spam') 724 725 coro.close() 726 727 def test_func_14(self): 728 @types.coroutine 729 def gen(): 730 yield 731 async def coro(): 732 try: 733 await gen() 734 except GeneratorExit: 735 await gen() 736 c = coro() 737 c.send(None) 738 with self.assertRaisesRegex(RuntimeError, 739 "coroutine ignored GeneratorExit"): 740 c.close() 741 742 def test_func_15(self): 743 # See http://bugs.python.org/issue25887 for details 744 745 async def spammer(): 746 return 'spam' 747 async def reader(coro): 748 return await coro 749 750 spammer_coro = spammer() 751 752 with self.assertRaisesRegex(StopIteration, 'spam'): 753 reader(spammer_coro).send(None) 754 755 with self.assertRaisesRegex(RuntimeError, 756 'cannot reuse already awaited coroutine'): 757 reader(spammer_coro).send(None) 758 759 def test_func_16(self): 760 # See http://bugs.python.org/issue25887 for details 761 762 @types.coroutine 763 def nop(): 764 yield 765 async def send(): 766 await nop() 767 return 'spam' 768 async def read(coro): 769 await nop() 770 return await coro 771 772 spammer = send() 773 774 reader = read(spammer) 775 reader.send(None) 776 reader.send(None) 777 with self.assertRaisesRegex(Exception, 'ham'): 778 reader.throw(Exception('ham')) 779 780 reader = read(spammer) 781 reader.send(None) 782 with self.assertRaisesRegex(RuntimeError, 783 'cannot reuse already awaited coroutine'): 784 reader.send(None) 785 786 with self.assertRaisesRegex(RuntimeError, 787 'cannot reuse already awaited coroutine'): 788 reader.throw(Exception('wat')) 789 790 def test_func_17(self): 791 # See http://bugs.python.org/issue25887 for details 792 793 async def coroutine(): 794 return 'spam' 795 796 coro = coroutine() 797 with self.assertRaisesRegex(StopIteration, 'spam'): 798 coro.send(None) 799 800 with self.assertRaisesRegex(RuntimeError, 801 'cannot reuse already awaited coroutine'): 802 coro.send(None) 803 804 with self.assertRaisesRegex(RuntimeError, 805 'cannot reuse already awaited coroutine'): 806 coro.throw(Exception('wat')) 807 808 # Closing a coroutine shouldn't raise any exception even if it's 809 # already closed/exhausted (similar to generators) 810 coro.close() 811 coro.close() 812 813 def test_func_18(self): 814 # See http://bugs.python.org/issue25887 for details 815 816 async def coroutine(): 817 return 'spam' 818 819 coro = coroutine() 820 await_iter = coro.__await__() 821 it = iter(await_iter) 822 823 with self.assertRaisesRegex(StopIteration, 'spam'): 824 it.send(None) 825 826 with self.assertRaisesRegex(RuntimeError, 827 'cannot reuse already awaited coroutine'): 828 it.send(None) 829 830 with self.assertRaisesRegex(RuntimeError, 831 'cannot reuse already awaited coroutine'): 832 # Although the iterator protocol requires iterators to 833 # raise another StopIteration here, we don't want to do 834 # that. In this particular case, the iterator will raise 835 # a RuntimeError, so that 'yield from' and 'await' 836 # expressions will trigger the error, instead of silently 837 # ignoring the call. 838 next(it) 839 840 with self.assertRaisesRegex(RuntimeError, 841 'cannot reuse already awaited coroutine'): 842 it.throw(Exception('wat')) 843 844 with self.assertRaisesRegex(RuntimeError, 845 'cannot reuse already awaited coroutine'): 846 it.throw(Exception('wat')) 847 848 # Closing a coroutine shouldn't raise any exception even if it's 849 # already closed/exhausted (similar to generators) 850 it.close() 851 it.close() 852 853 def test_func_19(self): 854 CHK = 0 855 856 @types.coroutine 857 def foo(): 858 nonlocal CHK 859 yield 860 try: 861 yield 862 except GeneratorExit: 863 CHK += 1 864 865 async def coroutine(): 866 await foo() 867 868 coro = coroutine() 869 870 coro.send(None) 871 coro.send(None) 872 873 self.assertEqual(CHK, 0) 874 coro.close() 875 self.assertEqual(CHK, 1) 876 877 for _ in range(3): 878 # Closing a coroutine shouldn't raise any exception even if it's 879 # already closed/exhausted (similar to generators) 880 coro.close() 881 self.assertEqual(CHK, 1) 882 883 def test_coro_wrapper_send_tuple(self): 884 async def foo(): 885 return (10,) 886 887 result = run_async__await__(foo()) 888 self.assertEqual(result, ([], (10,))) 889 890 def test_coro_wrapper_send_stop_iterator(self): 891 async def foo(): 892 return StopIteration(10) 893 894 result = run_async__await__(foo()) 895 self.assertIsInstance(result[1], StopIteration) 896 self.assertEqual(result[1].value, 10) 897 898 def test_cr_await(self): 899 @types.coroutine 900 def a(): 901 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_RUNNING) 902 self.assertIsNone(coro_b.cr_await) 903 yield 904 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_RUNNING) 905 self.assertIsNone(coro_b.cr_await) 906 907 async def c(): 908 await a() 909 910 async def b(): 911 self.assertIsNone(coro_b.cr_await) 912 await c() 913 self.assertIsNone(coro_b.cr_await) 914 915 coro_b = b() 916 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_CREATED) 917 self.assertIsNone(coro_b.cr_await) 918 919 coro_b.send(None) 920 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_SUSPENDED) 921 self.assertEqual(coro_b.cr_await.cr_await.gi_code.co_name, 'a') 922 923 with self.assertRaises(StopIteration): 924 coro_b.send(None) # complete coroutine 925 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_CLOSED) 926 self.assertIsNone(coro_b.cr_await) 927 928 def test_corotype_1(self): 929 ct = types.CoroutineType 930 self.assertIn('into coroutine', ct.send.__doc__) 931 self.assertIn('inside coroutine', ct.close.__doc__) 932 self.assertIn('in coroutine', ct.throw.__doc__) 933 self.assertIn('of the coroutine', ct.__dict__['__name__'].__doc__) 934 self.assertIn('of the coroutine', ct.__dict__['__qualname__'].__doc__) 935 self.assertEqual(ct.__name__, 'coroutine') 936 937 async def f(): pass 938 c = f() 939 self.assertIn('coroutine object', repr(c)) 940 c.close() 941 942 def test_await_1(self): 943 944 async def foo(): 945 await 1 946 with self.assertRaisesRegex(TypeError, "object int can.t.*await"): 947 run_async(foo()) 948 949 def test_await_2(self): 950 async def foo(): 951 await [] 952 with self.assertRaisesRegex(TypeError, "object list can.t.*await"): 953 run_async(foo()) 954 955 def test_await_3(self): 956 async def foo(): 957 await AsyncYieldFrom([1, 2, 3]) 958 959 self.assertEqual(run_async(foo()), ([1, 2, 3], None)) 960 self.assertEqual(run_async__await__(foo()), ([1, 2, 3], None)) 961 962 def test_await_4(self): 963 async def bar(): 964 return 42 965 966 async def foo(): 967 return await bar() 968 969 self.assertEqual(run_async(foo()), ([], 42)) 970 971 def test_await_5(self): 972 class Awaitable: 973 def __await__(self): 974 return 975 976 async def foo(): 977 return (await Awaitable()) 978 979 with self.assertRaisesRegex( 980 TypeError, "__await__.*returned non-iterator of type"): 981 982 run_async(foo()) 983 984 def test_await_6(self): 985 class Awaitable: 986 def __await__(self): 987 return iter([52]) 988 989 async def foo(): 990 return (await Awaitable()) 991 992 self.assertEqual(run_async(foo()), ([52], None)) 993 994 def test_await_7(self): 995 class Awaitable: 996 def __await__(self): 997 yield 42 998 return 100 999 1000 async def foo(): 1001 return (await Awaitable()) 1002 1003 self.assertEqual(run_async(foo()), ([42], 100)) 1004 1005 def test_await_8(self): 1006 class Awaitable: 1007 pass 1008 1009 async def foo(): return await Awaitable() 1010 1011 with self.assertRaisesRegex( 1012 TypeError, "object Awaitable can't be used in 'await' expression"): 1013 1014 run_async(foo()) 1015 1016 def test_await_9(self): 1017 def wrap(): 1018 return bar 1019 1020 async def bar(): 1021 return 42 1022 1023 async def foo(): 1024 db = {'b': lambda: wrap} 1025 1026 class DB: 1027 b = wrap 1028 1029 return (await bar() + await wrap()() + await db['b']()()() + 1030 await bar() * 1000 + await DB.b()()) 1031 1032 async def foo2(): 1033 return -await bar() 1034 1035 self.assertEqual(run_async(foo()), ([], 42168)) 1036 self.assertEqual(run_async(foo2()), ([], -42)) 1037 1038 def test_await_10(self): 1039 async def baz(): 1040 return 42 1041 1042 async def bar(): 1043 return baz() 1044 1045 async def foo(): 1046 return await (await bar()) 1047 1048 self.assertEqual(run_async(foo()), ([], 42)) 1049 1050 def test_await_11(self): 1051 def ident(val): 1052 return val 1053 1054 async def bar(): 1055 return 'spam' 1056 1057 async def foo(): 1058 return ident(val=await bar()) 1059 1060 async def foo2(): 1061 return await bar(), 'ham' 1062 1063 self.assertEqual(run_async(foo2()), ([], ('spam', 'ham'))) 1064 1065 def test_await_12(self): 1066 async def coro(): 1067 return 'spam' 1068 c = coro() 1069 1070 class Awaitable: 1071 def __await__(self): 1072 return c 1073 1074 async def foo(): 1075 return await Awaitable() 1076 1077 with self.assertRaisesRegex( 1078 TypeError, r"__await__\(\) returned a coroutine"): 1079 run_async(foo()) 1080 1081 c.close() 1082 1083 def test_await_13(self): 1084 class Awaitable: 1085 def __await__(self): 1086 return self 1087 1088 async def foo(): 1089 return await Awaitable() 1090 1091 with self.assertRaisesRegex( 1092 TypeError, "__await__.*returned non-iterator of type"): 1093 1094 run_async(foo()) 1095 1096 def test_await_14(self): 1097 class Wrapper: 1098 # Forces the interpreter to use CoroutineType.__await__ 1099 def __init__(self, coro): 1100 assert coro.__class__ is types.CoroutineType 1101 self.coro = coro 1102 def __await__(self): 1103 return self.coro.__await__() 1104 1105 class FutureLike: 1106 def __await__(self): 1107 return (yield) 1108 1109 class Marker(Exception): 1110 pass 1111 1112 async def coro1(): 1113 try: 1114 return await FutureLike() 1115 except ZeroDivisionError: 1116 raise Marker 1117 async def coro2(): 1118 return await Wrapper(coro1()) 1119 1120 c = coro2() 1121 c.send(None) 1122 with self.assertRaisesRegex(StopIteration, 'spam'): 1123 c.send('spam') 1124 1125 c = coro2() 1126 c.send(None) 1127 with self.assertRaises(Marker): 1128 c.throw(ZeroDivisionError) 1129 1130 def test_await_15(self): 1131 @types.coroutine 1132 def nop(): 1133 yield 1134 1135 async def coroutine(): 1136 await nop() 1137 1138 async def waiter(coro): 1139 await coro 1140 1141 coro = coroutine() 1142 coro.send(None) 1143 1144 with self.assertRaisesRegex(RuntimeError, 1145 "coroutine is being awaited already"): 1146 waiter(coro).send(None) 1147 1148 def test_await_16(self): 1149 # See https://bugs.python.org/issue29600 for details. 1150 1151 async def f(): 1152 return ValueError() 1153 1154 async def g(): 1155 try: 1156 raise KeyError 1157 except: 1158 return await f() 1159 1160 _, result = run_async(g()) 1161 self.assertIsNone(result.__context__) 1162 1163 def test_with_1(self): 1164 class Manager: 1165 def __init__(self, name): 1166 self.name = name 1167 1168 async def __aenter__(self): 1169 await AsyncYieldFrom(['enter-1-' + self.name, 1170 'enter-2-' + self.name]) 1171 return self 1172 1173 async def __aexit__(self, *args): 1174 await AsyncYieldFrom(['exit-1-' + self.name, 1175 'exit-2-' + self.name]) 1176 1177 if self.name == 'B': 1178 return True 1179 1180 1181 async def foo(): 1182 async with Manager("A") as a, Manager("B") as b: 1183 await AsyncYieldFrom([('managers', a.name, b.name)]) 1184 1/0 1185 1186 f = foo() 1187 result, _ = run_async(f) 1188 1189 self.assertEqual( 1190 result, ['enter-1-A', 'enter-2-A', 'enter-1-B', 'enter-2-B', 1191 ('managers', 'A', 'B'), 1192 'exit-1-B', 'exit-2-B', 'exit-1-A', 'exit-2-A'] 1193 ) 1194 1195 async def foo(): 1196 async with Manager("A") as a, Manager("C") as c: 1197 await AsyncYieldFrom([('managers', a.name, c.name)]) 1198 1/0 1199 1200 with self.assertRaises(ZeroDivisionError): 1201 run_async(foo()) 1202 1203 def test_with_2(self): 1204 class CM: 1205 def __aenter__(self): 1206 pass 1207 1208 body_executed = None 1209 async def foo(): 1210 nonlocal body_executed 1211 body_executed = False 1212 async with CM(): 1213 body_executed = True 1214 1215 with self.assertRaisesRegex(AttributeError, '__aexit__'): 1216 run_async(foo()) 1217 self.assertIs(body_executed, False) 1218 1219 def test_with_3(self): 1220 class CM: 1221 def __aexit__(self): 1222 pass 1223 1224 body_executed = None 1225 async def foo(): 1226 nonlocal body_executed 1227 body_executed = False 1228 async with CM(): 1229 body_executed = True 1230 1231 with self.assertRaisesRegex(AttributeError, '__aenter__'): 1232 run_async(foo()) 1233 self.assertIs(body_executed, False) 1234 1235 def test_with_4(self): 1236 class CM: 1237 pass 1238 1239 body_executed = None 1240 async def foo(): 1241 nonlocal body_executed 1242 body_executed = False 1243 async with CM(): 1244 body_executed = True 1245 1246 with self.assertRaisesRegex(AttributeError, '__aenter__'): 1247 run_async(foo()) 1248 self.assertIs(body_executed, False) 1249 1250 def test_with_5(self): 1251 # While this test doesn't make a lot of sense, 1252 # it's a regression test for an early bug with opcodes 1253 # generation 1254 1255 class CM: 1256 async def __aenter__(self): 1257 return self 1258 1259 async def __aexit__(self, *exc): 1260 pass 1261 1262 async def func(): 1263 async with CM(): 1264 assert (1, ) == 1 1265 1266 with self.assertRaises(AssertionError): 1267 run_async(func()) 1268 1269 def test_with_6(self): 1270 class CM: 1271 def __aenter__(self): 1272 return 123 1273 1274 def __aexit__(self, *e): 1275 return 456 1276 1277 async def foo(): 1278 async with CM(): 1279 pass 1280 1281 with self.assertRaisesRegex( 1282 TypeError, 1283 "'async with' received an object from __aenter__ " 1284 "that does not implement __await__: int"): 1285 # it's important that __aexit__ wasn't called 1286 run_async(foo()) 1287 1288 def test_with_7(self): 1289 class CM: 1290 async def __aenter__(self): 1291 return self 1292 1293 def __aexit__(self, *e): 1294 return 444 1295 1296 # Exit with exception 1297 async def foo(): 1298 async with CM(): 1299 1/0 1300 1301 try: 1302 run_async(foo()) 1303 except TypeError as exc: 1304 self.assertRegex( 1305 exc.args[0], 1306 "'async with' received an object from __aexit__ " 1307 "that does not implement __await__: int") 1308 self.assertTrue(exc.__context__ is not None) 1309 self.assertTrue(isinstance(exc.__context__, ZeroDivisionError)) 1310 else: 1311 self.fail('invalid asynchronous context manager did not fail') 1312 1313 1314 def test_with_8(self): 1315 CNT = 0 1316 1317 class CM: 1318 async def __aenter__(self): 1319 return self 1320 1321 def __aexit__(self, *e): 1322 return 456 1323 1324 # Normal exit 1325 async def foo(): 1326 nonlocal CNT 1327 async with CM(): 1328 CNT += 1 1329 with self.assertRaisesRegex( 1330 TypeError, 1331 "'async with' received an object from __aexit__ " 1332 "that does not implement __await__: int"): 1333 run_async(foo()) 1334 self.assertEqual(CNT, 1) 1335 1336 # Exit with 'break' 1337 async def foo(): 1338 nonlocal CNT 1339 for i in range(2): 1340 async with CM(): 1341 CNT += 1 1342 break 1343 with self.assertRaisesRegex( 1344 TypeError, 1345 "'async with' received an object from __aexit__ " 1346 "that does not implement __await__: int"): 1347 run_async(foo()) 1348 self.assertEqual(CNT, 2) 1349 1350 # Exit with 'continue' 1351 async def foo(): 1352 nonlocal CNT 1353 for i in range(2): 1354 async with CM(): 1355 CNT += 1 1356 continue 1357 with self.assertRaisesRegex( 1358 TypeError, 1359 "'async with' received an object from __aexit__ " 1360 "that does not implement __await__: int"): 1361 run_async(foo()) 1362 self.assertEqual(CNT, 3) 1363 1364 # Exit with 'return' 1365 async def foo(): 1366 nonlocal CNT 1367 async with CM(): 1368 CNT += 1 1369 return 1370 with self.assertRaisesRegex( 1371 TypeError, 1372 "'async with' received an object from __aexit__ " 1373 "that does not implement __await__: int"): 1374 run_async(foo()) 1375 self.assertEqual(CNT, 4) 1376 1377 1378 def test_with_9(self): 1379 CNT = 0 1380 1381 class CM: 1382 async def __aenter__(self): 1383 return self 1384 1385 async def __aexit__(self, *e): 1386 1/0 1387 1388 async def foo(): 1389 nonlocal CNT 1390 async with CM(): 1391 CNT += 1 1392 1393 with self.assertRaises(ZeroDivisionError): 1394 run_async(foo()) 1395 1396 self.assertEqual(CNT, 1) 1397 1398 def test_with_10(self): 1399 CNT = 0 1400 1401 class CM: 1402 async def __aenter__(self): 1403 return self 1404 1405 async def __aexit__(self, *e): 1406 1/0 1407 1408 async def foo(): 1409 nonlocal CNT 1410 async with CM(): 1411 async with CM(): 1412 raise RuntimeError 1413 1414 try: 1415 run_async(foo()) 1416 except ZeroDivisionError as exc: 1417 self.assertTrue(exc.__context__ is not None) 1418 self.assertTrue(isinstance(exc.__context__, ZeroDivisionError)) 1419 self.assertTrue(isinstance(exc.__context__.__context__, 1420 RuntimeError)) 1421 else: 1422 self.fail('exception from __aexit__ did not propagate') 1423 1424 def test_with_11(self): 1425 CNT = 0 1426 1427 class CM: 1428 async def __aenter__(self): 1429 raise NotImplementedError 1430 1431 async def __aexit__(self, *e): 1432 1/0 1433 1434 async def foo(): 1435 nonlocal CNT 1436 async with CM(): 1437 raise RuntimeError 1438 1439 try: 1440 run_async(foo()) 1441 except NotImplementedError as exc: 1442 self.assertTrue(exc.__context__ is None) 1443 else: 1444 self.fail('exception from __aenter__ did not propagate') 1445 1446 def test_with_12(self): 1447 CNT = 0 1448 1449 class CM: 1450 async def __aenter__(self): 1451 return self 1452 1453 async def __aexit__(self, *e): 1454 return True 1455 1456 async def foo(): 1457 nonlocal CNT 1458 async with CM() as cm: 1459 self.assertIs(cm.__class__, CM) 1460 raise RuntimeError 1461 1462 run_async(foo()) 1463 1464 def test_with_13(self): 1465 CNT = 0 1466 1467 class CM: 1468 async def __aenter__(self): 1469 1/0 1470 1471 async def __aexit__(self, *e): 1472 return True 1473 1474 async def foo(): 1475 nonlocal CNT 1476 CNT += 1 1477 async with CM(): 1478 CNT += 1000 1479 CNT += 10000 1480 1481 with self.assertRaises(ZeroDivisionError): 1482 run_async(foo()) 1483 self.assertEqual(CNT, 1) 1484 1485 def test_for_1(self): 1486 aiter_calls = 0 1487 1488 class AsyncIter: 1489 def __init__(self): 1490 self.i = 0 1491 1492 def __aiter__(self): 1493 nonlocal aiter_calls 1494 aiter_calls += 1 1495 return self 1496 1497 async def __anext__(self): 1498 self.i += 1 1499 1500 if not (self.i % 10): 1501 await AsyncYield(self.i * 10) 1502 1503 if self.i > 100: 1504 raise StopAsyncIteration 1505 1506 return self.i, self.i 1507 1508 1509 buffer = [] 1510 async def test1(): 1511 async for i1, i2 in AsyncIter(): 1512 buffer.append(i1 + i2) 1513 1514 yielded, _ = run_async(test1()) 1515 # Make sure that __aiter__ was called only once 1516 self.assertEqual(aiter_calls, 1) 1517 self.assertEqual(yielded, [i * 100 for i in range(1, 11)]) 1518 self.assertEqual(buffer, [i*2 for i in range(1, 101)]) 1519 1520 1521 buffer = [] 1522 async def test2(): 1523 nonlocal buffer 1524 async for i in AsyncIter(): 1525 buffer.append(i[0]) 1526 if i[0] == 20: 1527 break 1528 else: 1529 buffer.append('what?') 1530 buffer.append('end') 1531 1532 yielded, _ = run_async(test2()) 1533 # Make sure that __aiter__ was called only once 1534 self.assertEqual(aiter_calls, 2) 1535 self.assertEqual(yielded, [100, 200]) 1536 self.assertEqual(buffer, [i for i in range(1, 21)] + ['end']) 1537 1538 1539 buffer = [] 1540 async def test3(): 1541 nonlocal buffer 1542 async for i in AsyncIter(): 1543 if i[0] > 20: 1544 continue 1545 buffer.append(i[0]) 1546 else: 1547 buffer.append('what?') 1548 buffer.append('end') 1549 1550 yielded, _ = run_async(test3()) 1551 # Make sure that __aiter__ was called only once 1552 self.assertEqual(aiter_calls, 3) 1553 self.assertEqual(yielded, [i * 100 for i in range(1, 11)]) 1554 self.assertEqual(buffer, [i for i in range(1, 21)] + 1555 ['what?', 'end']) 1556 1557 def test_for_2(self): 1558 tup = (1, 2, 3) 1559 refs_before = sys.getrefcount(tup) 1560 1561 async def foo(): 1562 async for i in tup: 1563 print('never going to happen') 1564 1565 with self.assertRaisesRegex( 1566 TypeError, "async for' requires an object.*__aiter__.*tuple"): 1567 1568 run_async(foo()) 1569 1570 self.assertEqual(sys.getrefcount(tup), refs_before) 1571 1572 def test_for_3(self): 1573 class I: 1574 def __aiter__(self): 1575 return self 1576 1577 aiter = I() 1578 refs_before = sys.getrefcount(aiter) 1579 1580 async def foo(): 1581 async for i in aiter: 1582 print('never going to happen') 1583 1584 with self.assertRaisesRegex( 1585 TypeError, 1586 r"that does not implement __anext__"): 1587 1588 run_async(foo()) 1589 1590 self.assertEqual(sys.getrefcount(aiter), refs_before) 1591 1592 def test_for_4(self): 1593 class I: 1594 def __aiter__(self): 1595 return self 1596 1597 def __anext__(self): 1598 return () 1599 1600 aiter = I() 1601 refs_before = sys.getrefcount(aiter) 1602 1603 async def foo(): 1604 async for i in aiter: 1605 print('never going to happen') 1606 1607 with self.assertRaisesRegex( 1608 TypeError, 1609 "async for' received an invalid object.*__anext__.*tuple"): 1610 1611 run_async(foo()) 1612 1613 self.assertEqual(sys.getrefcount(aiter), refs_before) 1614 1615 def test_for_6(self): 1616 I = 0 1617 1618 class Manager: 1619 async def __aenter__(self): 1620 nonlocal I 1621 I += 10000 1622 1623 async def __aexit__(self, *args): 1624 nonlocal I 1625 I += 100000 1626 1627 class Iterable: 1628 def __init__(self): 1629 self.i = 0 1630 1631 def __aiter__(self): 1632 return self 1633 1634 async def __anext__(self): 1635 if self.i > 10: 1636 raise StopAsyncIteration 1637 self.i += 1 1638 return self.i 1639 1640 ############## 1641 1642 manager = Manager() 1643 iterable = Iterable() 1644 mrefs_before = sys.getrefcount(manager) 1645 irefs_before = sys.getrefcount(iterable) 1646 1647 async def main(): 1648 nonlocal I 1649 1650 async with manager: 1651 async for i in iterable: 1652 I += 1 1653 I += 1000 1654 1655 with warnings.catch_warnings(): 1656 warnings.simplefilter("error") 1657 # Test that __aiter__ that returns an asynchronous iterator 1658 # directly does not throw any warnings. 1659 run_async(main()) 1660 self.assertEqual(I, 111011) 1661 1662 self.assertEqual(sys.getrefcount(manager), mrefs_before) 1663 self.assertEqual(sys.getrefcount(iterable), irefs_before) 1664 1665 ############## 1666 1667 async def main(): 1668 nonlocal I 1669 1670 async with Manager(): 1671 async for i in Iterable(): 1672 I += 1 1673 I += 1000 1674 1675 async with Manager(): 1676 async for i in Iterable(): 1677 I += 1 1678 I += 1000 1679 1680 run_async(main()) 1681 self.assertEqual(I, 333033) 1682 1683 ############## 1684 1685 async def main(): 1686 nonlocal I 1687 1688 async with Manager(): 1689 I += 100 1690 async for i in Iterable(): 1691 I += 1 1692 else: 1693 I += 10000000 1694 I += 1000 1695 1696 async with Manager(): 1697 I += 100 1698 async for i in Iterable(): 1699 I += 1 1700 else: 1701 I += 10000000 1702 I += 1000 1703 1704 run_async(main()) 1705 self.assertEqual(I, 20555255) 1706 1707 def test_for_7(self): 1708 CNT = 0 1709 class AI: 1710 def __aiter__(self): 1711 1/0 1712 async def foo(): 1713 nonlocal CNT 1714 async for i in AI(): 1715 CNT += 1 1716 CNT += 10 1717 with self.assertRaises(ZeroDivisionError): 1718 run_async(foo()) 1719 self.assertEqual(CNT, 0) 1720 1721 def test_for_8(self): 1722 CNT = 0 1723 class AI: 1724 def __aiter__(self): 1725 1/0 1726 async def foo(): 1727 nonlocal CNT 1728 async for i in AI(): 1729 CNT += 1 1730 CNT += 10 1731 with self.assertRaises(ZeroDivisionError): 1732 with warnings.catch_warnings(): 1733 warnings.simplefilter("error") 1734 # Test that if __aiter__ raises an exception it propagates 1735 # without any kind of warning. 1736 run_async(foo()) 1737 self.assertEqual(CNT, 0) 1738 1739 def test_for_11(self): 1740 class F: 1741 def __aiter__(self): 1742 return self 1743 def __anext__(self): 1744 return self 1745 def __await__(self): 1746 1 / 0 1747 1748 async def main(): 1749 async for _ in F(): 1750 pass 1751 1752 with self.assertRaisesRegex(TypeError, 1753 'an invalid object from __anext__') as c: 1754 main().send(None) 1755 1756 err = c.exception 1757 self.assertIsInstance(err.__cause__, ZeroDivisionError) 1758 1759 def test_for_tuple(self): 1760 class Done(Exception): pass 1761 1762 class AIter(tuple): 1763 i = 0 1764 def __aiter__(self): 1765 return self 1766 async def __anext__(self): 1767 if self.i >= len(self): 1768 raise StopAsyncIteration 1769 self.i += 1 1770 return self[self.i - 1] 1771 1772 result = [] 1773 async def foo(): 1774 async for i in AIter([42]): 1775 result.append(i) 1776 raise Done 1777 1778 with self.assertRaises(Done): 1779 foo().send(None) 1780 self.assertEqual(result, [42]) 1781 1782 def test_for_stop_iteration(self): 1783 class Done(Exception): pass 1784 1785 class AIter(StopIteration): 1786 i = 0 1787 def __aiter__(self): 1788 return self 1789 async def __anext__(self): 1790 if self.i: 1791 raise StopAsyncIteration 1792 self.i += 1 1793 return self.value 1794 1795 result = [] 1796 async def foo(): 1797 async for i in AIter(42): 1798 result.append(i) 1799 raise Done 1800 1801 with self.assertRaises(Done): 1802 foo().send(None) 1803 self.assertEqual(result, [42]) 1804 1805 def test_comp_1(self): 1806 async def f(i): 1807 return i 1808 1809 async def run_list(): 1810 return [await c for c in [f(1), f(41)]] 1811 1812 async def run_set(): 1813 return {await c for c in [f(1), f(41)]} 1814 1815 async def run_dict1(): 1816 return {await c: 'a' for c in [f(1), f(41)]} 1817 1818 async def run_dict2(): 1819 return {i: await c for i, c in enumerate([f(1), f(41)])} 1820 1821 self.assertEqual(run_async(run_list()), ([], [1, 41])) 1822 self.assertEqual(run_async(run_set()), ([], {1, 41})) 1823 self.assertEqual(run_async(run_dict1()), ([], {1: 'a', 41: 'a'})) 1824 self.assertEqual(run_async(run_dict2()), ([], {0: 1, 1: 41})) 1825 1826 def test_comp_2(self): 1827 async def f(i): 1828 return i 1829 1830 async def run_list(): 1831 return [s for c in [f(''), f('abc'), f(''), f(['de', 'fg'])] 1832 for s in await c] 1833 1834 self.assertEqual( 1835 run_async(run_list()), 1836 ([], ['a', 'b', 'c', 'de', 'fg'])) 1837 1838 async def run_set(): 1839 return {d 1840 for c in [f([f([10, 30]), 1841 f([20])])] 1842 for s in await c 1843 for d in await s} 1844 1845 self.assertEqual( 1846 run_async(run_set()), 1847 ([], {10, 20, 30})) 1848 1849 async def run_set2(): 1850 return {await s 1851 for c in [f([f(10), f(20)])] 1852 for s in await c} 1853 1854 self.assertEqual( 1855 run_async(run_set2()), 1856 ([], {10, 20})) 1857 1858 def test_comp_3(self): 1859 async def f(it): 1860 for i in it: 1861 yield i 1862 1863 async def run_list(): 1864 return [i + 1 async for i in f([10, 20])] 1865 self.assertEqual( 1866 run_async(run_list()), 1867 ([], [11, 21])) 1868 1869 async def run_set(): 1870 return {i + 1 async for i in f([10, 20])} 1871 self.assertEqual( 1872 run_async(run_set()), 1873 ([], {11, 21})) 1874 1875 async def run_dict(): 1876 return {i + 1: i + 2 async for i in f([10, 20])} 1877 self.assertEqual( 1878 run_async(run_dict()), 1879 ([], {11: 12, 21: 22})) 1880 1881 async def run_gen(): 1882 gen = (i + 1 async for i in f([10, 20])) 1883 return [g + 100 async for g in gen] 1884 self.assertEqual( 1885 run_async(run_gen()), 1886 ([], [111, 121])) 1887 1888 def test_comp_4(self): 1889 async def f(it): 1890 for i in it: 1891 yield i 1892 1893 async def run_list(): 1894 return [i + 1 async for i in f([10, 20]) if i > 10] 1895 self.assertEqual( 1896 run_async(run_list()), 1897 ([], [21])) 1898 1899 async def run_set(): 1900 return {i + 1 async for i in f([10, 20]) if i > 10} 1901 self.assertEqual( 1902 run_async(run_set()), 1903 ([], {21})) 1904 1905 async def run_dict(): 1906 return {i + 1: i + 2 async for i in f([10, 20]) if i > 10} 1907 self.assertEqual( 1908 run_async(run_dict()), 1909 ([], {21: 22})) 1910 1911 async def run_gen(): 1912 gen = (i + 1 async for i in f([10, 20]) if i > 10) 1913 return [g + 100 async for g in gen] 1914 self.assertEqual( 1915 run_async(run_gen()), 1916 ([], [121])) 1917 1918 def test_comp_4_2(self): 1919 async def f(it): 1920 for i in it: 1921 yield i 1922 1923 async def run_list(): 1924 return [i + 10 async for i in f(range(5)) if 0 < i < 4] 1925 self.assertEqual( 1926 run_async(run_list()), 1927 ([], [11, 12, 13])) 1928 1929 async def run_set(): 1930 return {i + 10 async for i in f(range(5)) if 0 < i < 4} 1931 self.assertEqual( 1932 run_async(run_set()), 1933 ([], {11, 12, 13})) 1934 1935 async def run_dict(): 1936 return {i + 10: i + 100 async for i in f(range(5)) if 0 < i < 4} 1937 self.assertEqual( 1938 run_async(run_dict()), 1939 ([], {11: 101, 12: 102, 13: 103})) 1940 1941 async def run_gen(): 1942 gen = (i + 10 async for i in f(range(5)) if 0 < i < 4) 1943 return [g + 100 async for g in gen] 1944 self.assertEqual( 1945 run_async(run_gen()), 1946 ([], [111, 112, 113])) 1947 1948 def test_comp_5(self): 1949 async def f(it): 1950 for i in it: 1951 yield i 1952 1953 async def run_list(): 1954 return [i + 1 for pair in ([10, 20], [30, 40]) if pair[0] > 10 1955 async for i in f(pair) if i > 30] 1956 self.assertEqual( 1957 run_async(run_list()), 1958 ([], [41])) 1959 1960 def test_comp_6(self): 1961 async def f(it): 1962 for i in it: 1963 yield i 1964 1965 async def run_list(): 1966 return [i + 1 async for seq in f([(10, 20), (30,)]) 1967 for i in seq] 1968 1969 self.assertEqual( 1970 run_async(run_list()), 1971 ([], [11, 21, 31])) 1972 1973 def test_comp_7(self): 1974 async def f(): 1975 yield 1 1976 yield 2 1977 raise Exception('aaa') 1978 1979 async def run_list(): 1980 return [i async for i in f()] 1981 1982 with self.assertRaisesRegex(Exception, 'aaa'): 1983 run_async(run_list()) 1984 1985 def test_comp_8(self): 1986 async def f(): 1987 return [i for i in [1, 2, 3]] 1988 1989 self.assertEqual( 1990 run_async(f()), 1991 ([], [1, 2, 3])) 1992 1993 def test_comp_9(self): 1994 async def gen(): 1995 yield 1 1996 yield 2 1997 async def f(): 1998 l = [i async for i in gen()] 1999 return [i for i in l] 2000 2001 self.assertEqual( 2002 run_async(f()), 2003 ([], [1, 2])) 2004 2005 def test_comp_10(self): 2006 async def f(): 2007 xx = {i for i in [1, 2, 3]} 2008 return {x: x for x in xx} 2009 2010 self.assertEqual( 2011 run_async(f()), 2012 ([], {1: 1, 2: 2, 3: 3})) 2013 2014 def test_copy(self): 2015 async def func(): pass 2016 coro = func() 2017 with self.assertRaises(TypeError): 2018 copy.copy(coro) 2019 2020 aw = coro.__await__() 2021 try: 2022 with self.assertRaises(TypeError): 2023 copy.copy(aw) 2024 finally: 2025 aw.close() 2026 2027 def test_pickle(self): 2028 async def func(): pass 2029 coro = func() 2030 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 2031 with self.assertRaises((TypeError, pickle.PicklingError)): 2032 pickle.dumps(coro, proto) 2033 2034 aw = coro.__await__() 2035 try: 2036 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 2037 with self.assertRaises((TypeError, pickle.PicklingError)): 2038 pickle.dumps(aw, proto) 2039 finally: 2040 aw.close() 2041 2042 def test_fatal_coro_warning(self): 2043 # Issue 27811 2044 async def func(): pass 2045 with warnings.catch_warnings(), \ 2046 support.catch_unraisable_exception() as cm: 2047 warnings.filterwarnings("error") 2048 coro = func() 2049 # only store repr() to avoid keeping the coroutine alive 2050 coro_repr = repr(coro) 2051 coro = None 2052 support.gc_collect() 2053 2054 self.assertIn("was never awaited", str(cm.unraisable.exc_value)) 2055 self.assertEqual(repr(cm.unraisable.object), coro_repr) 2056 2057 def test_for_assign_raising_stop_async_iteration(self): 2058 class BadTarget: 2059 def __setitem__(self, key, value): 2060 raise StopAsyncIteration(42) 2061 tgt = BadTarget() 2062 async def source(): 2063 yield 10 2064 2065 async def run_for(): 2066 with self.assertRaises(StopAsyncIteration) as cm: 2067 async for tgt[0] in source(): 2068 pass 2069 self.assertEqual(cm.exception.args, (42,)) 2070 return 'end' 2071 self.assertEqual(run_async(run_for()), ([], 'end')) 2072 2073 async def run_list(): 2074 with self.assertRaises(StopAsyncIteration) as cm: 2075 return [0 async for tgt[0] in source()] 2076 self.assertEqual(cm.exception.args, (42,)) 2077 return 'end' 2078 self.assertEqual(run_async(run_list()), ([], 'end')) 2079 2080 async def run_gen(): 2081 gen = (0 async for tgt[0] in source()) 2082 a = gen.asend(None) 2083 with self.assertRaises(RuntimeError) as cm: 2084 await a 2085 self.assertIsInstance(cm.exception.__cause__, StopAsyncIteration) 2086 self.assertEqual(cm.exception.__cause__.args, (42,)) 2087 return 'end' 2088 self.assertEqual(run_async(run_gen()), ([], 'end')) 2089 2090 def test_for_assign_raising_stop_async_iteration_2(self): 2091 class BadIterable: 2092 def __iter__(self): 2093 raise StopAsyncIteration(42) 2094 async def badpairs(): 2095 yield BadIterable() 2096 2097 async def run_for(): 2098 with self.assertRaises(StopAsyncIteration) as cm: 2099 async for i, j in badpairs(): 2100 pass 2101 self.assertEqual(cm.exception.args, (42,)) 2102 return 'end' 2103 self.assertEqual(run_async(run_for()), ([], 'end')) 2104 2105 async def run_list(): 2106 with self.assertRaises(StopAsyncIteration) as cm: 2107 return [0 async for i, j in badpairs()] 2108 self.assertEqual(cm.exception.args, (42,)) 2109 return 'end' 2110 self.assertEqual(run_async(run_list()), ([], 'end')) 2111 2112 async def run_gen(): 2113 gen = (0 async for i, j in badpairs()) 2114 a = gen.asend(None) 2115 with self.assertRaises(RuntimeError) as cm: 2116 await a 2117 self.assertIsInstance(cm.exception.__cause__, StopAsyncIteration) 2118 self.assertEqual(cm.exception.__cause__.args, (42,)) 2119 return 'end' 2120 self.assertEqual(run_async(run_gen()), ([], 'end')) 2121 2122 2123class CoroAsyncIOCompatTest(unittest.TestCase): 2124 2125 def test_asyncio_1(self): 2126 # asyncio cannot be imported when Python is compiled without thread 2127 # support 2128 asyncio = import_helper.import_module('asyncio') 2129 2130 class MyException(Exception): 2131 pass 2132 2133 buffer = [] 2134 2135 class CM: 2136 async def __aenter__(self): 2137 buffer.append(1) 2138 await asyncio.sleep(0.01) 2139 buffer.append(2) 2140 return self 2141 2142 async def __aexit__(self, exc_type, exc_val, exc_tb): 2143 await asyncio.sleep(0.01) 2144 buffer.append(exc_type.__name__) 2145 2146 async def f(): 2147 async with CM() as c: 2148 await asyncio.sleep(0.01) 2149 raise MyException 2150 buffer.append('unreachable') 2151 2152 loop = asyncio.new_event_loop() 2153 asyncio.set_event_loop(loop) 2154 try: 2155 loop.run_until_complete(f()) 2156 except MyException: 2157 pass 2158 finally: 2159 loop.close() 2160 asyncio.set_event_loop_policy(None) 2161 2162 self.assertEqual(buffer, [1, 2, 'MyException']) 2163 2164 2165class OriginTrackingTest(unittest.TestCase): 2166 def here(self): 2167 info = inspect.getframeinfo(inspect.currentframe().f_back) 2168 return (info.filename, info.lineno) 2169 2170 def test_origin_tracking(self): 2171 orig_depth = sys.get_coroutine_origin_tracking_depth() 2172 try: 2173 async def corofn(): 2174 pass 2175 2176 sys.set_coroutine_origin_tracking_depth(0) 2177 self.assertEqual(sys.get_coroutine_origin_tracking_depth(), 0) 2178 2179 with contextlib.closing(corofn()) as coro: 2180 self.assertIsNone(coro.cr_origin) 2181 2182 sys.set_coroutine_origin_tracking_depth(1) 2183 self.assertEqual(sys.get_coroutine_origin_tracking_depth(), 1) 2184 2185 fname, lineno = self.here() 2186 with contextlib.closing(corofn()) as coro: 2187 self.assertEqual(coro.cr_origin, 2188 ((fname, lineno + 1, "test_origin_tracking"),)) 2189 2190 sys.set_coroutine_origin_tracking_depth(2) 2191 self.assertEqual(sys.get_coroutine_origin_tracking_depth(), 2) 2192 2193 def nested(): 2194 return (self.here(), corofn()) 2195 fname, lineno = self.here() 2196 ((nested_fname, nested_lineno), coro) = nested() 2197 with contextlib.closing(coro): 2198 self.assertEqual(coro.cr_origin, 2199 ((nested_fname, nested_lineno, "nested"), 2200 (fname, lineno + 1, "test_origin_tracking"))) 2201 2202 # Check we handle running out of frames correctly 2203 sys.set_coroutine_origin_tracking_depth(1000) 2204 with contextlib.closing(corofn()) as coro: 2205 self.assertTrue(2 < len(coro.cr_origin) < 1000) 2206 2207 # We can't set depth negative 2208 with self.assertRaises(ValueError): 2209 sys.set_coroutine_origin_tracking_depth(-1) 2210 # And trying leaves it unchanged 2211 self.assertEqual(sys.get_coroutine_origin_tracking_depth(), 1000) 2212 2213 finally: 2214 sys.set_coroutine_origin_tracking_depth(orig_depth) 2215 2216 def test_origin_tracking_warning(self): 2217 async def corofn(): 2218 pass 2219 2220 a1_filename, a1_lineno = self.here() 2221 def a1(): 2222 return corofn() # comment in a1 2223 a1_lineno += 2 2224 2225 a2_filename, a2_lineno = self.here() 2226 def a2(): 2227 return a1() # comment in a2 2228 a2_lineno += 2 2229 2230 def check(depth, msg): 2231 sys.set_coroutine_origin_tracking_depth(depth) 2232 with self.assertWarns(RuntimeWarning) as cm: 2233 a2() 2234 support.gc_collect() 2235 self.assertEqual(msg, str(cm.warning)) 2236 2237 orig_depth = sys.get_coroutine_origin_tracking_depth() 2238 try: 2239 msg = check(0, f"coroutine '{corofn.__qualname__}' was never awaited") 2240 check(1, "".join([ 2241 f"coroutine '{corofn.__qualname__}' was never awaited\n", 2242 "Coroutine created at (most recent call last)\n", 2243 f' File "{a1_filename}", line {a1_lineno}, in a1\n', 2244 f' return corofn() # comment in a1', 2245 ])) 2246 check(2, "".join([ 2247 f"coroutine '{corofn.__qualname__}' was never awaited\n", 2248 "Coroutine created at (most recent call last)\n", 2249 f' File "{a2_filename}", line {a2_lineno}, in a2\n', 2250 f' return a1() # comment in a2\n', 2251 f' File "{a1_filename}", line {a1_lineno}, in a1\n', 2252 f' return corofn() # comment in a1', 2253 ])) 2254 2255 finally: 2256 sys.set_coroutine_origin_tracking_depth(orig_depth) 2257 2258 def test_unawaited_warning_when_module_broken(self): 2259 # Make sure we don't blow up too bad if 2260 # warnings._warn_unawaited_coroutine is broken somehow (e.g. because 2261 # of shutdown problems) 2262 async def corofn(): 2263 pass 2264 2265 orig_wuc = warnings._warn_unawaited_coroutine 2266 try: 2267 warnings._warn_unawaited_coroutine = lambda coro: 1/0 2268 with support.catch_unraisable_exception() as cm, \ 2269 warnings_helper.check_warnings( 2270 (r'coroutine .* was never awaited', 2271 RuntimeWarning)): 2272 # only store repr() to avoid keeping the coroutine alive 2273 coro = corofn() 2274 coro_repr = repr(coro) 2275 2276 # clear reference to the coroutine without awaiting for it 2277 del coro 2278 support.gc_collect() 2279 2280 self.assertEqual(repr(cm.unraisable.object), coro_repr) 2281 self.assertEqual(cm.unraisable.exc_type, ZeroDivisionError) 2282 2283 del warnings._warn_unawaited_coroutine 2284 with warnings_helper.check_warnings( 2285 (r'coroutine .* was never awaited', RuntimeWarning)): 2286 corofn() 2287 support.gc_collect() 2288 2289 finally: 2290 warnings._warn_unawaited_coroutine = orig_wuc 2291 2292 2293class UnawaitedWarningDuringShutdownTest(unittest.TestCase): 2294 # https://bugs.python.org/issue32591#msg310726 2295 def test_unawaited_warning_during_shutdown(self): 2296 code = ("import asyncio\n" 2297 "async def f(): pass\n" 2298 "asyncio.gather(f())\n") 2299 assert_python_ok("-c", code) 2300 2301 code = ("import sys\n" 2302 "async def f(): pass\n" 2303 "sys.coro = f()\n") 2304 assert_python_ok("-c", code) 2305 2306 code = ("import sys\n" 2307 "async def f(): pass\n" 2308 "sys.corocycle = [f()]\n" 2309 "sys.corocycle.append(sys.corocycle)\n") 2310 assert_python_ok("-c", code) 2311 2312 2313@support.cpython_only 2314class CAPITest(unittest.TestCase): 2315 2316 def test_tp_await_1(self): 2317 from _testcapi import awaitType as at 2318 2319 async def foo(): 2320 future = at(iter([1])) 2321 return (await future) 2322 2323 self.assertEqual(foo().send(None), 1) 2324 2325 def test_tp_await_2(self): 2326 # Test tp_await to __await__ mapping 2327 from _testcapi import awaitType as at 2328 future = at(iter([1])) 2329 self.assertEqual(next(future.__await__()), 1) 2330 2331 def test_tp_await_3(self): 2332 from _testcapi import awaitType as at 2333 2334 async def foo(): 2335 future = at(1) 2336 return (await future) 2337 2338 with self.assertRaisesRegex( 2339 TypeError, "__await__.*returned non-iterator of type 'int'"): 2340 self.assertEqual(foo().send(None), 1) 2341 2342 2343if __name__=="__main__": 2344 unittest.main() 2345