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