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