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