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