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