blob: f2839a719a3ab766faec01c17672ee0bf51f932f [file] [log] [blame]
Yury Selivanov75445082015-05-11 22:57:16 -04001import contextlib
Serhiy Storchaka609a2e12015-11-12 11:31:51 +02002import copy
Yury Selivanov8085b802015-05-18 12:50:52 -04003import inspect
Serhiy Storchaka609a2e12015-11-12 11:31:51 +02004import pickle
Yury Selivanov75445082015-05-11 22:57:16 -04005import sys
6import types
7import unittest
8import warnings
9from test import support
10
11
12class AsyncYieldFrom:
13 def __init__(self, obj):
14 self.obj = obj
15
16 def __await__(self):
17 yield from self.obj
18
19
20class AsyncYield:
21 def __init__(self, value):
22 self.value = value
23
24 def __await__(self):
25 yield self.value
26
27
28def run_async(coro):
Yury Selivanov5376ba92015-06-22 12:19:30 -040029 assert coro.__class__ in {types.GeneratorType, types.CoroutineType}
Yury Selivanov75445082015-05-11 22:57:16 -040030
31 buffer = []
32 result = None
33 while True:
34 try:
35 buffer.append(coro.send(None))
36 except StopIteration as ex:
37 result = ex.args[0] if ex.args else None
38 break
39 return buffer, result
40
41
Yury Selivanov5376ba92015-06-22 12:19:30 -040042def run_async__await__(coro):
43 assert coro.__class__ is types.CoroutineType
44 aw = coro.__await__()
45 buffer = []
46 result = None
47 i = 0
48 while True:
49 try:
50 if i % 2:
51 buffer.append(next(aw))
52 else:
53 buffer.append(aw.send(None))
54 i += 1
55 except StopIteration as ex:
56 result = ex.args[0] if ex.args else None
57 break
58 return buffer, result
59
60
Yury Selivanov75445082015-05-11 22:57:16 -040061@contextlib.contextmanager
62def silence_coro_gc():
63 with warnings.catch_warnings():
64 warnings.simplefilter("ignore")
65 yield
66 support.gc_collect()
67
68
69class AsyncBadSyntaxTest(unittest.TestCase):
70
71 def test_badsyntax_1(self):
Yury Selivanov8fb307c2015-07-22 13:33:45 +030072 samples = [
Yury Selivanov52c4e7c2016-09-09 10:36:01 -070073 """def foo():
74 await something()
75 """,
76
77 """await something()""",
78
79 """async def foo():
80 yield from []
81 """,
82
83 """async def foo():
84 await await fut
85 """,
86
87 """async def foo(a=await something()):
88 pass
89 """,
90
91 """async def foo(a:await something()):
92 pass
93 """,
94
95 """async def foo():
96 def bar():
97 [i async for i in els]
98 """,
99
100 """async def foo():
101 def bar():
102 [await i for i in els]
103 """,
104
105 """async def foo():
106 def bar():
107 [i for i in els
108 async for b in els]
109 """,
110
111 """async def foo():
112 def bar():
113 [i for i in els
114 for c in b
115 async for b in els]
116 """,
117
118 """async def foo():
119 def bar():
120 [i for i in els
121 async for b in els
122 for c in b]
123 """,
124
125 """async def foo():
126 def bar():
127 [i for i in els
128 for b in await els]
129 """,
130
131 """async def foo():
132 def bar():
133 [i for i in els
134 for b in els
135 if await b]
136 """,
137
138 """async def foo():
139 def bar():
140 [i for i in await els]
141 """,
142
143 """async def foo():
144 def bar():
145 [i for i in els if await i]
146 """,
147
148 """def bar():
149 [i async for i in els]
150 """,
151
152 """def bar():
153 [await i for i in els]
154 """,
155
156 """def bar():
157 [i for i in els
158 async for b in els]
159 """,
160
161 """def bar():
162 [i for i in els
163 for c in b
164 async for b in els]
165 """,
166
167 """def bar():
168 [i for i in els
169 async for b in els
170 for c in b]
171 """,
172
173 """def bar():
174 [i for i in els
175 for b in await els]
176 """,
177
178 """def bar():
179 [i for i in els
180 for b in els
181 if await b]
182 """,
183
184 """def bar():
185 [i for i in await els]
186 """,
187
188 """def bar():
189 [i for i in els if await i]
190 """,
191
192 """async def foo():
193 await
194 """,
195
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300196 """async def foo():
197 def bar(): pass
198 await = 1
199 """,
200
201 """async def foo():
202
203 def bar(): pass
204 await = 1
205 """,
206
207 """async def foo():
208 def bar(): pass
209 if 1:
210 await = 1
211 """,
212
213 """def foo():
214 async def bar(): pass
215 if 1:
216 await a
217 """,
218
219 """def foo():
220 async def bar(): pass
221 await a
222 """,
223
224 """def foo():
225 def baz(): pass
226 async def bar(): pass
227 await a
228 """,
229
230 """def foo():
231 def baz(): pass
232 # 456
233 async def bar(): pass
234 # 123
235 await a
236 """,
237
238 """async def foo():
239 def baz(): pass
240 # 456
241 async def bar(): pass
242 # 123
243 await = 2
244 """,
245
246 """def foo():
247
248 def baz(): pass
249
250 async def bar(): pass
251
252 await a
253 """,
254
255 """async def foo():
256
257 def baz(): pass
258
259 async def bar(): pass
260
261 await = 2
262 """,
263
264 """async def foo():
265 def async(): pass
266 """,
267
268 """async def foo():
269 def await(): pass
270 """,
271
272 """async def foo():
273 def bar():
274 await
275 """,
276
277 """async def foo():
278 return lambda async: await
279 """,
280
281 """async def foo():
282 return lambda a: await
283 """,
284
Yury Selivanovb7666a32015-07-22 14:48:57 +0300285 """await a()""",
286
287 """async def foo(a=await b):
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300288 pass
289 """,
290
Yury Selivanovf315c1c2015-07-23 09:10:44 +0300291 """async def foo(a:await b):
292 pass
293 """,
294
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300295 """def baz():
Yury Selivanovb7666a32015-07-22 14:48:57 +0300296 async def foo(a=await b):
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300297 pass
298 """,
299
300 """async def foo(async):
301 pass
302 """,
303
304 """async def foo():
305 def bar():
306 def baz():
307 async = 1
308 """,
309
310 """async def foo():
311 def bar():
312 def baz():
313 pass
314 async = 1
315 """,
316
317 """def foo():
318 async def bar():
319
320 async def baz():
321 pass
322
323 def baz():
324 42
325
326 async = 1
327 """,
328
329 """async def foo():
330 def bar():
331 def baz():
332 pass\nawait foo()
333 """,
334
335 """def foo():
336 def bar():
337 async def baz():
338 pass\nawait foo()
339 """,
340
341 """async def foo(await):
342 pass
343 """,
344
345 """def foo():
346
347 async def bar(): pass
348
349 await a
350 """,
351
352 """def foo():
353 async def bar():
354 pass\nawait a
355 """]
356
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300357 for code in samples:
358 with self.subTest(code=code), self.assertRaises(SyntaxError):
Yury Selivanovb7666a32015-07-22 14:48:57 +0300359 compile(code, "<test>", "exec")
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300360
Yury Selivanov8987c9d2016-09-15 12:50:23 -0400361 def test_badsyntax_2(self):
362 samples = [
363 """def foo():
364 await = 1
365 """,
366
367 """class Bar:
368 def async(): pass
369 """,
370
371 """class Bar:
372 async = 1
373 """,
374
375 """class async:
376 pass
377 """,
378
379 """class await:
380 pass
381 """,
382
383 """import math as await""",
384
385 """def async():
386 pass""",
387
388 """def foo(*, await=1):
389 pass"""
390
391 """async = 1""",
392
393 """print(await=1)"""
394 ]
395
396 for code in samples:
397 with self.subTest(code=code), self.assertWarnsRegex(
398 DeprecationWarning,
399 "'await' will become reserved keywords"):
400 compile(code, "<test>", "exec")
401
402 def test_badsyntax_3(self):
403 with self.assertRaises(DeprecationWarning):
404 with warnings.catch_warnings():
405 warnings.simplefilter("error")
406 compile("async = 1", "<test>", "exec")
407
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300408 def test_goodsyntax_1(self):
409 # Tests for issue 24619
410
Yury Selivanov8987c9d2016-09-15 12:50:23 -0400411 samples = [
412 '''def foo(await):
413 async def foo(): pass
414 async def foo():
415 pass
416 return await + 1
417 ''',
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300418
Yury Selivanov8987c9d2016-09-15 12:50:23 -0400419 '''def foo(await):
420 async def foo(): pass
421 async def foo(): pass
422 return await + 1
423 ''',
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300424
Yury Selivanov8987c9d2016-09-15 12:50:23 -0400425 '''def foo(await):
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300426
Yury Selivanov8987c9d2016-09-15 12:50:23 -0400427 async def foo(): pass
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300428
Yury Selivanov8987c9d2016-09-15 12:50:23 -0400429 async def foo(): pass
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300430
Yury Selivanov8987c9d2016-09-15 12:50:23 -0400431 return await + 1
432 ''',
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300433
Yury Selivanov8987c9d2016-09-15 12:50:23 -0400434 '''def foo(await):
435 """spam"""
436 async def foo(): \
437 pass
438 # 123
439 async def foo(): pass
440 # 456
441 return await + 1
442 ''',
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300443
Yury Selivanov8987c9d2016-09-15 12:50:23 -0400444 '''def foo(await):
445 def foo(): pass
446 def foo(): pass
447 async def bar(): return await_
448 await_ = await
449 try:
450 bar().send(None)
451 except StopIteration as ex:
452 return ex.args[0] + 1
453 '''
454 ]
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300455
Yury Selivanov8987c9d2016-09-15 12:50:23 -0400456 for code in samples:
457 with self.subTest(code=code):
458 loc = {}
459
460 with warnings.catch_warnings():
461 warnings.simplefilter("ignore")
462 exec(code, loc, loc)
463
464 self.assertEqual(loc['foo'](10), 11)
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300465
Yury Selivanov75445082015-05-11 22:57:16 -0400466
Yury Selivanov8085b802015-05-18 12:50:52 -0400467class TokenizerRegrTest(unittest.TestCase):
468
469 def test_oneline_defs(self):
470 buf = []
471 for i in range(500):
472 buf.append('def i{i}(): return {i}'.format(i=i))
473 buf = '\n'.join(buf)
474
475 # Test that 500 consequent, one-line defs is OK
476 ns = {}
477 exec(buf, ns, ns)
478 self.assertEqual(ns['i499'](), 499)
479
480 # Test that 500 consequent, one-line defs *and*
481 # one 'async def' following them is OK
482 buf += '\nasync def foo():\n return'
483 ns = {}
484 exec(buf, ns, ns)
485 self.assertEqual(ns['i499'](), 499)
486 self.assertTrue(inspect.iscoroutinefunction(ns['foo']))
487
488
Yury Selivanov75445082015-05-11 22:57:16 -0400489class CoroutineTest(unittest.TestCase):
490
491 def test_gen_1(self):
492 def gen(): yield
493 self.assertFalse(hasattr(gen, '__await__'))
494
495 def test_func_1(self):
496 async def foo():
497 return 10
498
499 f = foo()
Yury Selivanov5376ba92015-06-22 12:19:30 -0400500 self.assertIsInstance(f, types.CoroutineType)
501 self.assertTrue(bool(foo.__code__.co_flags & inspect.CO_COROUTINE))
502 self.assertFalse(bool(foo.__code__.co_flags & inspect.CO_GENERATOR))
503 self.assertTrue(bool(f.cr_code.co_flags & inspect.CO_COROUTINE))
504 self.assertFalse(bool(f.cr_code.co_flags & inspect.CO_GENERATOR))
Yury Selivanov75445082015-05-11 22:57:16 -0400505 self.assertEqual(run_async(f), ([], 10))
506
Yury Selivanov5376ba92015-06-22 12:19:30 -0400507 self.assertEqual(run_async__await__(foo()), ([], 10))
508
Yury Selivanov75445082015-05-11 22:57:16 -0400509 def bar(): pass
Yury Selivanov5376ba92015-06-22 12:19:30 -0400510 self.assertFalse(bool(bar.__code__.co_flags & inspect.CO_COROUTINE))
Yury Selivanov75445082015-05-11 22:57:16 -0400511
512 def test_func_2(self):
513 async def foo():
514 raise StopIteration
515
516 with self.assertRaisesRegex(
Yury Selivanov5376ba92015-06-22 12:19:30 -0400517 RuntimeError, "coroutine raised StopIteration"):
Yury Selivanov75445082015-05-11 22:57:16 -0400518
519 run_async(foo())
520
521 def test_func_3(self):
522 async def foo():
523 raise StopIteration
524
525 with silence_coro_gc():
526 self.assertRegex(repr(foo()), '^<coroutine object.* at 0x.*>$')
527
528 def test_func_4(self):
529 async def foo():
530 raise StopIteration
531
532 check = lambda: self.assertRaisesRegex(
Yury Selivanov5376ba92015-06-22 12:19:30 -0400533 TypeError, "'coroutine' object is not iterable")
Yury Selivanov75445082015-05-11 22:57:16 -0400534
535 with check():
536 list(foo())
537
538 with check():
539 tuple(foo())
540
541 with check():
542 sum(foo())
543
544 with check():
545 iter(foo())
546
Yury Selivanov75445082015-05-11 22:57:16 -0400547 with silence_coro_gc(), check():
548 for i in foo():
549 pass
550
551 with silence_coro_gc(), check():
552 [i for i in foo()]
553
554 def test_func_5(self):
555 @types.coroutine
556 def bar():
557 yield 1
558
559 async def foo():
560 await bar()
561
562 check = lambda: self.assertRaisesRegex(
Yury Selivanov5376ba92015-06-22 12:19:30 -0400563 TypeError, "'coroutine' object is not iterable")
Yury Selivanov75445082015-05-11 22:57:16 -0400564
565 with check():
566 for el in foo(): pass
567
568 # the following should pass without an error
569 for el in bar():
570 self.assertEqual(el, 1)
571 self.assertEqual([el for el in bar()], [1])
572 self.assertEqual(tuple(bar()), (1,))
573 self.assertEqual(next(iter(bar())), 1)
574
575 def test_func_6(self):
576 @types.coroutine
577 def bar():
578 yield 1
579 yield 2
580
581 async def foo():
582 await bar()
583
584 f = foo()
Zachary Ware37ac5902015-05-13 01:03:06 -0500585 self.assertEqual(f.send(None), 1)
586 self.assertEqual(f.send(None), 2)
Yury Selivanov75445082015-05-11 22:57:16 -0400587 with self.assertRaises(StopIteration):
588 f.send(None)
589
590 def test_func_7(self):
591 async def bar():
592 return 10
593
594 def foo():
595 yield from bar()
596
597 with silence_coro_gc(), self.assertRaisesRegex(
598 TypeError,
Yury Selivanov5376ba92015-06-22 12:19:30 -0400599 "cannot 'yield from' a coroutine object in a non-coroutine generator"):
Yury Selivanov75445082015-05-11 22:57:16 -0400600
601 list(foo())
602
603 def test_func_8(self):
604 @types.coroutine
605 def bar():
606 return (yield from foo())
607
608 async def foo():
609 return 'spam'
610
611 self.assertEqual(run_async(bar()), ([], 'spam') )
612
613 def test_func_9(self):
614 async def foo(): pass
615
616 with self.assertWarnsRegex(
617 RuntimeWarning, "coroutine '.*test_func_9.*foo' was never awaited"):
618
619 foo()
620 support.gc_collect()
621
Yury Selivanov5376ba92015-06-22 12:19:30 -0400622 def test_func_10(self):
623 N = 0
624
625 @types.coroutine
626 def gen():
627 nonlocal N
628 try:
629 a = yield
630 yield (a ** 2)
631 except ZeroDivisionError:
632 N += 100
633 raise
634 finally:
635 N += 1
636
637 async def foo():
638 await gen()
639
640 coro = foo()
641 aw = coro.__await__()
642 self.assertIs(aw, iter(aw))
643 next(aw)
644 self.assertEqual(aw.send(10), 100)
645
646 self.assertEqual(N, 0)
647 aw.close()
648 self.assertEqual(N, 1)
649
650 coro = foo()
651 aw = coro.__await__()
652 next(aw)
653 with self.assertRaises(ZeroDivisionError):
654 aw.throw(ZeroDivisionError, None, None)
655 self.assertEqual(N, 102)
656
657 def test_func_11(self):
658 async def func(): pass
659 coro = func()
660 # Test that PyCoro_Type and _PyCoroWrapper_Type types were properly
661 # initialized
662 self.assertIn('__await__', dir(coro))
663 self.assertIn('__iter__', dir(coro.__await__()))
664 self.assertIn('coroutine_wrapper', repr(coro.__await__()))
665 coro.close() # avoid RuntimeWarning
666
667 def test_func_12(self):
668 async def g():
669 i = me.send(None)
670 await foo
671 me = g()
672 with self.assertRaisesRegex(ValueError,
673 "coroutine already executing"):
674 me.send(None)
675
676 def test_func_13(self):
677 async def g():
678 pass
679 with self.assertRaisesRegex(
680 TypeError,
681 "can't send non-None value to a just-started coroutine"):
682
683 g().send('spam')
684
685 def test_func_14(self):
686 @types.coroutine
687 def gen():
688 yield
689 async def coro():
690 try:
691 await gen()
692 except GeneratorExit:
693 await gen()
694 c = coro()
695 c.send(None)
696 with self.assertRaisesRegex(RuntimeError,
697 "coroutine ignored GeneratorExit"):
698 c.close()
699
Yury Selivanov77c96812016-02-13 17:59:05 -0500700 def test_func_15(self):
701 # See http://bugs.python.org/issue25887 for details
702
703 async def spammer():
704 return 'spam'
705 async def reader(coro):
706 return await coro
707
708 spammer_coro = spammer()
709
710 with self.assertRaisesRegex(StopIteration, 'spam'):
711 reader(spammer_coro).send(None)
712
713 with self.assertRaisesRegex(RuntimeError,
714 'cannot reuse already awaited coroutine'):
715 reader(spammer_coro).send(None)
716
717 def test_func_16(self):
718 # See http://bugs.python.org/issue25887 for details
719
720 @types.coroutine
721 def nop():
722 yield
723 async def send():
724 await nop()
725 return 'spam'
726 async def read(coro):
727 await nop()
728 return await coro
729
730 spammer = send()
731
732 reader = read(spammer)
733 reader.send(None)
734 reader.send(None)
735 with self.assertRaisesRegex(Exception, 'ham'):
736 reader.throw(Exception('ham'))
737
738 reader = read(spammer)
739 reader.send(None)
740 with self.assertRaisesRegex(RuntimeError,
741 'cannot reuse already awaited coroutine'):
742 reader.send(None)
743
744 with self.assertRaisesRegex(RuntimeError,
745 'cannot reuse already awaited coroutine'):
746 reader.throw(Exception('wat'))
747
748 def test_func_17(self):
749 # See http://bugs.python.org/issue25887 for details
750
751 async def coroutine():
752 return 'spam'
753
754 coro = coroutine()
755 with self.assertRaisesRegex(StopIteration, 'spam'):
756 coro.send(None)
757
758 with self.assertRaisesRegex(RuntimeError,
759 'cannot reuse already awaited coroutine'):
760 coro.send(None)
761
762 with self.assertRaisesRegex(RuntimeError,
763 'cannot reuse already awaited coroutine'):
764 coro.throw(Exception('wat'))
765
766 # Closing a coroutine shouldn't raise any exception even if it's
767 # already closed/exhausted (similar to generators)
768 coro.close()
769 coro.close()
770
771 def test_func_18(self):
772 # See http://bugs.python.org/issue25887 for details
773
774 async def coroutine():
775 return 'spam'
776
777 coro = coroutine()
778 await_iter = coro.__await__()
779 it = iter(await_iter)
780
781 with self.assertRaisesRegex(StopIteration, 'spam'):
782 it.send(None)
783
784 with self.assertRaisesRegex(RuntimeError,
785 'cannot reuse already awaited coroutine'):
786 it.send(None)
787
788 with self.assertRaisesRegex(RuntimeError,
789 'cannot reuse already awaited coroutine'):
790 # Although the iterator protocol requires iterators to
791 # raise another StopIteration here, we don't want to do
792 # that. In this particular case, the iterator will raise
793 # a RuntimeError, so that 'yield from' and 'await'
794 # expressions will trigger the error, instead of silently
795 # ignoring the call.
796 next(it)
797
798 with self.assertRaisesRegex(RuntimeError,
799 'cannot reuse already awaited coroutine'):
800 it.throw(Exception('wat'))
801
802 with self.assertRaisesRegex(RuntimeError,
803 'cannot reuse already awaited coroutine'):
804 it.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 it.close()
809 it.close()
810
811 def test_func_19(self):
812 CHK = 0
813
814 @types.coroutine
815 def foo():
816 nonlocal CHK
817 yield
818 try:
819 yield
820 except GeneratorExit:
821 CHK += 1
822
823 async def coroutine():
824 await foo()
825
826 coro = coroutine()
827
828 coro.send(None)
829 coro.send(None)
830
831 self.assertEqual(CHK, 0)
832 coro.close()
833 self.assertEqual(CHK, 1)
834
835 for _ in range(3):
836 # Closing a coroutine shouldn't raise any exception even if it's
837 # already closed/exhausted (similar to generators)
838 coro.close()
839 self.assertEqual(CHK, 1)
840
Yury Selivanove13f8f32015-07-03 00:23:30 -0400841 def test_cr_await(self):
842 @types.coroutine
843 def a():
844 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_RUNNING)
845 self.assertIsNone(coro_b.cr_await)
846 yield
847 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_RUNNING)
848 self.assertIsNone(coro_b.cr_await)
849
850 async def c():
851 await a()
852
853 async def b():
854 self.assertIsNone(coro_b.cr_await)
855 await c()
856 self.assertIsNone(coro_b.cr_await)
857
858 coro_b = b()
859 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_CREATED)
860 self.assertIsNone(coro_b.cr_await)
861
862 coro_b.send(None)
863 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_SUSPENDED)
864 self.assertEqual(coro_b.cr_await.cr_await.gi_code.co_name, 'a')
865
866 with self.assertRaises(StopIteration):
867 coro_b.send(None) # complete coroutine
868 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_CLOSED)
869 self.assertIsNone(coro_b.cr_await)
870
Yury Selivanov5376ba92015-06-22 12:19:30 -0400871 def test_corotype_1(self):
872 ct = types.CoroutineType
873 self.assertIn('into coroutine', ct.send.__doc__)
874 self.assertIn('inside coroutine', ct.close.__doc__)
875 self.assertIn('in coroutine', ct.throw.__doc__)
876 self.assertIn('of the coroutine', ct.__dict__['__name__'].__doc__)
877 self.assertIn('of the coroutine', ct.__dict__['__qualname__'].__doc__)
878 self.assertEqual(ct.__name__, 'coroutine')
879
880 async def f(): pass
881 c = f()
882 self.assertIn('coroutine object', repr(c))
883 c.close()
884
Yury Selivanov75445082015-05-11 22:57:16 -0400885 def test_await_1(self):
886
887 async def foo():
888 await 1
889 with self.assertRaisesRegex(TypeError, "object int can.t.*await"):
890 run_async(foo())
891
892 def test_await_2(self):
893 async def foo():
894 await []
895 with self.assertRaisesRegex(TypeError, "object list can.t.*await"):
896 run_async(foo())
897
898 def test_await_3(self):
899 async def foo():
900 await AsyncYieldFrom([1, 2, 3])
901
902 self.assertEqual(run_async(foo()), ([1, 2, 3], None))
Yury Selivanov5376ba92015-06-22 12:19:30 -0400903 self.assertEqual(run_async__await__(foo()), ([1, 2, 3], None))
Yury Selivanov75445082015-05-11 22:57:16 -0400904
905 def test_await_4(self):
906 async def bar():
907 return 42
908
909 async def foo():
910 return await bar()
911
912 self.assertEqual(run_async(foo()), ([], 42))
913
914 def test_await_5(self):
915 class Awaitable:
916 def __await__(self):
917 return
918
919 async def foo():
920 return (await Awaitable())
921
922 with self.assertRaisesRegex(
923 TypeError, "__await__.*returned non-iterator of type"):
924
925 run_async(foo())
926
927 def test_await_6(self):
928 class Awaitable:
929 def __await__(self):
930 return iter([52])
931
932 async def foo():
933 return (await Awaitable())
934
935 self.assertEqual(run_async(foo()), ([52], None))
936
937 def test_await_7(self):
938 class Awaitable:
939 def __await__(self):
940 yield 42
941 return 100
942
943 async def foo():
944 return (await Awaitable())
945
946 self.assertEqual(run_async(foo()), ([42], 100))
947
948 def test_await_8(self):
949 class Awaitable:
950 pass
951
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300952 async def foo(): return await Awaitable()
Yury Selivanov75445082015-05-11 22:57:16 -0400953
954 with self.assertRaisesRegex(
955 TypeError, "object Awaitable can't be used in 'await' expression"):
956
957 run_async(foo())
958
959 def test_await_9(self):
960 def wrap():
961 return bar
962
963 async def bar():
964 return 42
965
966 async def foo():
967 b = bar()
968
969 db = {'b': lambda: wrap}
970
971 class DB:
972 b = wrap
973
974 return (await bar() + await wrap()() + await db['b']()()() +
975 await bar() * 1000 + await DB.b()())
976
977 async def foo2():
978 return -await bar()
979
980 self.assertEqual(run_async(foo()), ([], 42168))
981 self.assertEqual(run_async(foo2()), ([], -42))
982
983 def test_await_10(self):
984 async def baz():
985 return 42
986
987 async def bar():
988 return baz()
989
990 async def foo():
991 return await (await bar())
992
993 self.assertEqual(run_async(foo()), ([], 42))
994
995 def test_await_11(self):
996 def ident(val):
997 return val
998
999 async def bar():
1000 return 'spam'
1001
1002 async def foo():
1003 return ident(val=await bar())
1004
1005 async def foo2():
1006 return await bar(), 'ham'
1007
1008 self.assertEqual(run_async(foo2()), ([], ('spam', 'ham')))
1009
1010 def test_await_12(self):
1011 async def coro():
1012 return 'spam'
1013
1014 class Awaitable:
1015 def __await__(self):
1016 return coro()
1017
1018 async def foo():
1019 return await Awaitable()
1020
1021 with self.assertRaisesRegex(
R David Murray44b548d2016-09-08 13:59:53 -04001022 TypeError, r"__await__\(\) returned a coroutine"):
Yury Selivanov75445082015-05-11 22:57:16 -04001023
1024 run_async(foo())
1025
1026 def test_await_13(self):
1027 class Awaitable:
1028 def __await__(self):
1029 return self
1030
1031 async def foo():
1032 return await Awaitable()
1033
1034 with self.assertRaisesRegex(
1035 TypeError, "__await__.*returned non-iterator of type"):
1036
1037 run_async(foo())
1038
Yury Selivanovf2701522015-07-01 12:29:55 -04001039 def test_await_14(self):
1040 class Wrapper:
1041 # Forces the interpreter to use CoroutineType.__await__
1042 def __init__(self, coro):
1043 assert coro.__class__ is types.CoroutineType
1044 self.coro = coro
1045 def __await__(self):
1046 return self.coro.__await__()
1047
1048 class FutureLike:
1049 def __await__(self):
1050 return (yield)
1051
1052 class Marker(Exception):
1053 pass
1054
1055 async def coro1():
1056 try:
1057 return await FutureLike()
1058 except ZeroDivisionError:
1059 raise Marker
1060 async def coro2():
1061 return await Wrapper(coro1())
1062
1063 c = coro2()
1064 c.send(None)
1065 with self.assertRaisesRegex(StopIteration, 'spam'):
1066 c.send('spam')
1067
1068 c = coro2()
1069 c.send(None)
1070 with self.assertRaises(Marker):
1071 c.throw(ZeroDivisionError)
1072
Yury Selivanovc724bae2016-03-02 11:30:46 -05001073 def test_await_15(self):
1074 @types.coroutine
1075 def nop():
1076 yield
1077
1078 async def coroutine():
1079 await nop()
1080
1081 async def waiter(coro):
1082 await coro
1083
1084 coro = coroutine()
1085 coro.send(None)
1086
1087 with self.assertRaisesRegex(RuntimeError,
1088 "coroutine is being awaited already"):
1089 waiter(coro).send(None)
1090
Yury Selivanov75445082015-05-11 22:57:16 -04001091 def test_with_1(self):
1092 class Manager:
1093 def __init__(self, name):
1094 self.name = name
1095
1096 async def __aenter__(self):
1097 await AsyncYieldFrom(['enter-1-' + self.name,
1098 'enter-2-' + self.name])
1099 return self
1100
1101 async def __aexit__(self, *args):
1102 await AsyncYieldFrom(['exit-1-' + self.name,
1103 'exit-2-' + self.name])
1104
1105 if self.name == 'B':
1106 return True
1107
1108
1109 async def foo():
1110 async with Manager("A") as a, Manager("B") as b:
1111 await AsyncYieldFrom([('managers', a.name, b.name)])
1112 1/0
1113
1114 f = foo()
1115 result, _ = run_async(f)
1116
1117 self.assertEqual(
1118 result, ['enter-1-A', 'enter-2-A', 'enter-1-B', 'enter-2-B',
1119 ('managers', 'A', 'B'),
1120 'exit-1-B', 'exit-2-B', 'exit-1-A', 'exit-2-A']
1121 )
1122
1123 async def foo():
1124 async with Manager("A") as a, Manager("C") as c:
1125 await AsyncYieldFrom([('managers', a.name, c.name)])
1126 1/0
1127
1128 with self.assertRaises(ZeroDivisionError):
1129 run_async(foo())
1130
1131 def test_with_2(self):
1132 class CM:
1133 def __aenter__(self):
1134 pass
1135
1136 async def foo():
1137 async with CM():
1138 pass
1139
1140 with self.assertRaisesRegex(AttributeError, '__aexit__'):
1141 run_async(foo())
1142
1143 def test_with_3(self):
1144 class CM:
1145 def __aexit__(self):
1146 pass
1147
1148 async def foo():
1149 async with CM():
1150 pass
1151
1152 with self.assertRaisesRegex(AttributeError, '__aenter__'):
1153 run_async(foo())
1154
1155 def test_with_4(self):
1156 class CM:
1157 def __enter__(self):
1158 pass
1159
1160 def __exit__(self):
1161 pass
1162
1163 async def foo():
1164 async with CM():
1165 pass
1166
1167 with self.assertRaisesRegex(AttributeError, '__aexit__'):
1168 run_async(foo())
1169
1170 def test_with_5(self):
1171 # While this test doesn't make a lot of sense,
1172 # it's a regression test for an early bug with opcodes
1173 # generation
1174
1175 class CM:
1176 async def __aenter__(self):
1177 return self
1178
1179 async def __aexit__(self, *exc):
1180 pass
1181
1182 async def func():
1183 async with CM():
1184 assert (1, ) == 1
1185
1186 with self.assertRaises(AssertionError):
1187 run_async(func())
1188
1189 def test_with_6(self):
1190 class CM:
1191 def __aenter__(self):
1192 return 123
1193
1194 def __aexit__(self, *e):
1195 return 456
1196
1197 async def foo():
1198 async with CM():
1199 pass
1200
1201 with self.assertRaisesRegex(
1202 TypeError, "object int can't be used in 'await' expression"):
1203 # it's important that __aexit__ wasn't called
1204 run_async(foo())
1205
1206 def test_with_7(self):
1207 class CM:
1208 async def __aenter__(self):
1209 return self
1210
1211 def __aexit__(self, *e):
Nick Coghlanbaaadbf2015-05-13 15:54:02 +10001212 return 444
Yury Selivanov75445082015-05-11 22:57:16 -04001213
1214 async def foo():
1215 async with CM():
Nick Coghlanbaaadbf2015-05-13 15:54:02 +10001216 1/0
1217
1218 try:
1219 run_async(foo())
1220 except TypeError as exc:
1221 self.assertRegex(
1222 exc.args[0], "object int can't be used in 'await' expression")
1223 self.assertTrue(exc.__context__ is not None)
1224 self.assertTrue(isinstance(exc.__context__, ZeroDivisionError))
1225 else:
1226 self.fail('invalid asynchronous context manager did not fail')
1227
1228
1229 def test_with_8(self):
1230 CNT = 0
1231
1232 class CM:
1233 async def __aenter__(self):
1234 return self
1235
1236 def __aexit__(self, *e):
1237 return 456
1238
1239 async def foo():
1240 nonlocal CNT
1241 async with CM():
1242 CNT += 1
1243
Yury Selivanov75445082015-05-11 22:57:16 -04001244
1245 with self.assertRaisesRegex(
1246 TypeError, "object int can't be used in 'await' expression"):
1247
1248 run_async(foo())
1249
Nick Coghlanbaaadbf2015-05-13 15:54:02 +10001250 self.assertEqual(CNT, 1)
1251
1252
1253 def test_with_9(self):
1254 CNT = 0
1255
1256 class CM:
1257 async def __aenter__(self):
1258 return self
1259
1260 async def __aexit__(self, *e):
1261 1/0
1262
1263 async def foo():
1264 nonlocal CNT
1265 async with CM():
1266 CNT += 1
1267
1268 with self.assertRaises(ZeroDivisionError):
1269 run_async(foo())
1270
1271 self.assertEqual(CNT, 1)
1272
1273 def test_with_10(self):
1274 CNT = 0
1275
1276 class CM:
1277 async def __aenter__(self):
1278 return self
1279
1280 async def __aexit__(self, *e):
1281 1/0
1282
1283 async def foo():
1284 nonlocal CNT
1285 async with CM():
1286 async with CM():
1287 raise RuntimeError
1288
1289 try:
1290 run_async(foo())
1291 except ZeroDivisionError as exc:
1292 self.assertTrue(exc.__context__ is not None)
1293 self.assertTrue(isinstance(exc.__context__, ZeroDivisionError))
1294 self.assertTrue(isinstance(exc.__context__.__context__,
1295 RuntimeError))
1296 else:
1297 self.fail('exception from __aexit__ did not propagate')
1298
1299 def test_with_11(self):
1300 CNT = 0
1301
1302 class CM:
1303 async def __aenter__(self):
1304 raise NotImplementedError
1305
1306 async def __aexit__(self, *e):
1307 1/0
1308
1309 async def foo():
1310 nonlocal CNT
1311 async with CM():
1312 raise RuntimeError
1313
1314 try:
1315 run_async(foo())
1316 except NotImplementedError as exc:
1317 self.assertTrue(exc.__context__ is None)
1318 else:
1319 self.fail('exception from __aenter__ did not propagate')
1320
1321 def test_with_12(self):
1322 CNT = 0
1323
1324 class CM:
1325 async def __aenter__(self):
1326 return self
1327
1328 async def __aexit__(self, *e):
1329 return True
1330
1331 async def foo():
1332 nonlocal CNT
1333 async with CM() as cm:
1334 self.assertIs(cm.__class__, CM)
1335 raise RuntimeError
1336
1337 run_async(foo())
1338
Yury Selivanov9113dc72015-05-13 16:49:35 -04001339 def test_with_13(self):
1340 CNT = 0
1341
1342 class CM:
1343 async def __aenter__(self):
1344 1/0
1345
1346 async def __aexit__(self, *e):
1347 return True
1348
1349 async def foo():
1350 nonlocal CNT
1351 CNT += 1
1352 async with CM():
1353 CNT += 1000
1354 CNT += 10000
1355
1356 with self.assertRaises(ZeroDivisionError):
1357 run_async(foo())
1358 self.assertEqual(CNT, 1)
1359
Yury Selivanov75445082015-05-11 22:57:16 -04001360 def test_for_1(self):
1361 aiter_calls = 0
1362
1363 class AsyncIter:
1364 def __init__(self):
1365 self.i = 0
1366
1367 async def __aiter__(self):
1368 nonlocal aiter_calls
1369 aiter_calls += 1
1370 return self
1371
1372 async def __anext__(self):
1373 self.i += 1
1374
1375 if not (self.i % 10):
1376 await AsyncYield(self.i * 10)
1377
1378 if self.i > 100:
1379 raise StopAsyncIteration
1380
1381 return self.i, self.i
1382
1383
1384 buffer = []
1385 async def test1():
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001386 with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
1387 async for i1, i2 in AsyncIter():
1388 buffer.append(i1 + i2)
Yury Selivanov75445082015-05-11 22:57:16 -04001389
1390 yielded, _ = run_async(test1())
1391 # Make sure that __aiter__ was called only once
1392 self.assertEqual(aiter_calls, 1)
1393 self.assertEqual(yielded, [i * 100 for i in range(1, 11)])
1394 self.assertEqual(buffer, [i*2 for i in range(1, 101)])
1395
1396
1397 buffer = []
1398 async def test2():
1399 nonlocal buffer
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001400 with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
1401 async for i in AsyncIter():
1402 buffer.append(i[0])
1403 if i[0] == 20:
1404 break
1405 else:
1406 buffer.append('what?')
Yury Selivanov75445082015-05-11 22:57:16 -04001407 buffer.append('end')
1408
1409 yielded, _ = run_async(test2())
1410 # Make sure that __aiter__ was called only once
1411 self.assertEqual(aiter_calls, 2)
1412 self.assertEqual(yielded, [100, 200])
1413 self.assertEqual(buffer, [i for i in range(1, 21)] + ['end'])
1414
1415
1416 buffer = []
1417 async def test3():
1418 nonlocal buffer
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001419 with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
1420 async for i in AsyncIter():
1421 if i[0] > 20:
1422 continue
1423 buffer.append(i[0])
1424 else:
1425 buffer.append('what?')
Yury Selivanov75445082015-05-11 22:57:16 -04001426 buffer.append('end')
1427
1428 yielded, _ = run_async(test3())
1429 # Make sure that __aiter__ was called only once
1430 self.assertEqual(aiter_calls, 3)
1431 self.assertEqual(yielded, [i * 100 for i in range(1, 11)])
1432 self.assertEqual(buffer, [i for i in range(1, 21)] +
1433 ['what?', 'end'])
1434
1435 def test_for_2(self):
1436 tup = (1, 2, 3)
1437 refs_before = sys.getrefcount(tup)
1438
1439 async def foo():
1440 async for i in tup:
1441 print('never going to happen')
1442
1443 with self.assertRaisesRegex(
1444 TypeError, "async for' requires an object.*__aiter__.*tuple"):
1445
1446 run_async(foo())
1447
1448 self.assertEqual(sys.getrefcount(tup), refs_before)
1449
1450 def test_for_3(self):
1451 class I:
1452 def __aiter__(self):
1453 return self
1454
1455 aiter = I()
1456 refs_before = sys.getrefcount(aiter)
1457
1458 async def foo():
1459 async for i in aiter:
1460 print('never going to happen')
1461
1462 with self.assertRaisesRegex(
1463 TypeError,
R David Murray44b548d2016-09-08 13:59:53 -04001464 r"async for' received an invalid object.*__aiter.*\: I"):
Yury Selivanov75445082015-05-11 22:57:16 -04001465
1466 run_async(foo())
1467
1468 self.assertEqual(sys.getrefcount(aiter), refs_before)
1469
1470 def test_for_4(self):
1471 class I:
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001472 def __aiter__(self):
Yury Selivanov75445082015-05-11 22:57:16 -04001473 return self
1474
1475 def __anext__(self):
1476 return ()
1477
1478 aiter = I()
1479 refs_before = sys.getrefcount(aiter)
1480
1481 async def foo():
1482 async for i in aiter:
1483 print('never going to happen')
1484
1485 with self.assertRaisesRegex(
1486 TypeError,
1487 "async for' received an invalid object.*__anext__.*tuple"):
1488
1489 run_async(foo())
1490
1491 self.assertEqual(sys.getrefcount(aiter), refs_before)
1492
1493 def test_for_5(self):
1494 class I:
1495 async def __aiter__(self):
1496 return self
1497
1498 def __anext__(self):
1499 return 123
1500
1501 async def foo():
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001502 with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
1503 async for i in I():
1504 print('never going to happen')
Yury Selivanov75445082015-05-11 22:57:16 -04001505
1506 with self.assertRaisesRegex(
1507 TypeError,
1508 "async for' received an invalid object.*__anext.*int"):
1509
1510 run_async(foo())
1511
1512 def test_for_6(self):
1513 I = 0
1514
1515 class Manager:
1516 async def __aenter__(self):
1517 nonlocal I
1518 I += 10000
1519
1520 async def __aexit__(self, *args):
1521 nonlocal I
1522 I += 100000
1523
1524 class Iterable:
1525 def __init__(self):
1526 self.i = 0
1527
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001528 def __aiter__(self):
Yury Selivanov75445082015-05-11 22:57:16 -04001529 return self
1530
1531 async def __anext__(self):
1532 if self.i > 10:
1533 raise StopAsyncIteration
1534 self.i += 1
1535 return self.i
1536
1537 ##############
1538
1539 manager = Manager()
1540 iterable = Iterable()
1541 mrefs_before = sys.getrefcount(manager)
1542 irefs_before = sys.getrefcount(iterable)
1543
1544 async def main():
1545 nonlocal I
1546
1547 async with manager:
1548 async for i in iterable:
1549 I += 1
1550 I += 1000
1551
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001552 with warnings.catch_warnings():
1553 warnings.simplefilter("error")
Martin Panter70c502a2016-06-12 06:14:03 +00001554 # Test that __aiter__ that returns an asynchronous iterator
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001555 # directly does not throw any warnings.
1556 run_async(main())
Yury Selivanov75445082015-05-11 22:57:16 -04001557 self.assertEqual(I, 111011)
1558
1559 self.assertEqual(sys.getrefcount(manager), mrefs_before)
1560 self.assertEqual(sys.getrefcount(iterable), irefs_before)
1561
1562 ##############
1563
1564 async def main():
1565 nonlocal I
1566
1567 async with Manager():
1568 async for i in Iterable():
1569 I += 1
1570 I += 1000
1571
1572 async with Manager():
1573 async for i in Iterable():
1574 I += 1
1575 I += 1000
1576
1577 run_async(main())
1578 self.assertEqual(I, 333033)
1579
1580 ##############
1581
1582 async def main():
1583 nonlocal I
1584
1585 async with Manager():
1586 I += 100
1587 async for i in Iterable():
1588 I += 1
1589 else:
1590 I += 10000000
1591 I += 1000
1592
1593 async with Manager():
1594 I += 100
1595 async for i in Iterable():
1596 I += 1
1597 else:
1598 I += 10000000
1599 I += 1000
1600
1601 run_async(main())
1602 self.assertEqual(I, 20555255)
1603
Yury Selivanov9113dc72015-05-13 16:49:35 -04001604 def test_for_7(self):
1605 CNT = 0
1606 class AI:
1607 async def __aiter__(self):
1608 1/0
1609 async def foo():
1610 nonlocal CNT
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001611 with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
1612 async for i in AI():
1613 CNT += 1
Yury Selivanov9113dc72015-05-13 16:49:35 -04001614 CNT += 10
1615 with self.assertRaises(ZeroDivisionError):
1616 run_async(foo())
1617 self.assertEqual(CNT, 0)
1618
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001619 def test_for_8(self):
1620 CNT = 0
1621 class AI:
1622 def __aiter__(self):
1623 1/0
1624 async def foo():
1625 nonlocal CNT
1626 async for i in AI():
1627 CNT += 1
1628 CNT += 10
1629 with self.assertRaises(ZeroDivisionError):
1630 with warnings.catch_warnings():
1631 warnings.simplefilter("error")
1632 # Test that if __aiter__ raises an exception it propagates
1633 # without any kind of warning.
1634 run_async(foo())
1635 self.assertEqual(CNT, 0)
1636
1637 def test_for_9(self):
1638 # Test that PendingDeprecationWarning can safely be converted into
1639 # an exception (__aiter__ should not have a chance to raise
1640 # a ZeroDivisionError.)
1641 class AI:
1642 async def __aiter__(self):
1643 1/0
1644 async def foo():
1645 async for i in AI():
1646 pass
1647
1648 with self.assertRaises(PendingDeprecationWarning):
1649 with warnings.catch_warnings():
1650 warnings.simplefilter("error")
1651 run_async(foo())
1652
1653 def test_for_10(self):
1654 # Test that PendingDeprecationWarning can safely be converted into
1655 # an exception.
1656 class AI:
1657 async def __aiter__(self):
1658 pass
1659 async def foo():
1660 async for i in AI():
1661 pass
1662
1663 with self.assertRaises(PendingDeprecationWarning):
1664 with warnings.catch_warnings():
1665 warnings.simplefilter("error")
1666 run_async(foo())
1667
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001668 def test_comp_1(self):
1669 async def f(i):
1670 return i
1671
1672 async def run_list():
1673 return [await c for c in [f(1), f(41)]]
1674
1675 async def run_set():
1676 return {await c for c in [f(1), f(41)]}
1677
1678 async def run_dict1():
1679 return {await c: 'a' for c in [f(1), f(41)]}
1680
1681 async def run_dict2():
1682 return {i: await c for i, c in enumerate([f(1), f(41)])}
1683
1684 self.assertEqual(run_async(run_list()), ([], [1, 41]))
1685 self.assertEqual(run_async(run_set()), ([], {1, 41}))
1686 self.assertEqual(run_async(run_dict1()), ([], {1: 'a', 41: 'a'}))
1687 self.assertEqual(run_async(run_dict2()), ([], {0: 1, 1: 41}))
1688
1689 def test_comp_2(self):
1690 async def f(i):
1691 return i
1692
1693 async def run_list():
1694 return [s for c in [f(''), f('abc'), f(''), f(['de', 'fg'])]
1695 for s in await c]
1696
1697 self.assertEqual(
1698 run_async(run_list()),
1699 ([], ['a', 'b', 'c', 'de', 'fg']))
1700
1701 async def run_set():
1702 return {d
1703 for c in [f([f([10, 30]),
1704 f([20])])]
1705 for s in await c
1706 for d in await s}
1707
1708 self.assertEqual(
1709 run_async(run_set()),
1710 ([], {10, 20, 30}))
1711
1712 async def run_set2():
1713 return {await s
1714 for c in [f([f(10), f(20)])]
1715 for s in await c}
1716
1717 self.assertEqual(
1718 run_async(run_set2()),
1719 ([], {10, 20}))
1720
1721 def test_comp_3(self):
1722 async def f(it):
1723 for i in it:
1724 yield i
1725
1726 async def run_list():
1727 return [i + 1 async for i in f([10, 20])]
1728 self.assertEqual(
1729 run_async(run_list()),
1730 ([], [11, 21]))
1731
1732 async def run_set():
1733 return {i + 1 async for i in f([10, 20])}
1734 self.assertEqual(
1735 run_async(run_set()),
1736 ([], {11, 21}))
1737
1738 async def run_dict():
1739 return {i + 1: i + 2 async for i in f([10, 20])}
1740 self.assertEqual(
1741 run_async(run_dict()),
1742 ([], {11: 12, 21: 22}))
1743
1744 async def run_gen():
1745 gen = (i + 1 async for i in f([10, 20]))
1746 return [g + 100 async for g in gen]
1747 self.assertEqual(
1748 run_async(run_gen()),
1749 ([], [111, 121]))
1750
1751 def test_comp_4(self):
1752 async def f(it):
1753 for i in it:
1754 yield i
1755
1756 async def run_list():
1757 return [i + 1 async for i in f([10, 20]) if i > 10]
1758 self.assertEqual(
1759 run_async(run_list()),
1760 ([], [21]))
1761
1762 async def run_set():
1763 return {i + 1 async for i in f([10, 20]) if i > 10}
1764 self.assertEqual(
1765 run_async(run_set()),
1766 ([], {21}))
1767
1768 async def run_dict():
1769 return {i + 1: i + 2 async for i in f([10, 20]) if i > 10}
1770 self.assertEqual(
1771 run_async(run_dict()),
1772 ([], {21: 22}))
1773
1774 async def run_gen():
1775 gen = (i + 1 async for i in f([10, 20]) if i > 10)
1776 return [g + 100 async for g in gen]
1777 self.assertEqual(
1778 run_async(run_gen()),
1779 ([], [121]))
1780
1781 def test_comp_5(self):
1782 async def f(it):
1783 for i in it:
1784 yield i
1785
1786 async def run_list():
1787 return [i + 1 for pair in ([10, 20], [30, 40]) if pair[0] > 10
1788 async for i in f(pair) if i > 30]
1789 self.assertEqual(
1790 run_async(run_list()),
1791 ([], [41]))
1792
1793 def test_comp_6(self):
1794 async def f(it):
1795 for i in it:
1796 yield i
1797
1798 async def run_list():
1799 return [i + 1 async for seq in f([(10, 20), (30,)])
1800 for i in seq]
1801
1802 self.assertEqual(
1803 run_async(run_list()),
1804 ([], [11, 21, 31]))
1805
1806 def test_comp_7(self):
1807 async def f():
1808 yield 1
1809 yield 2
1810 raise Exception('aaa')
1811
1812 async def run_list():
1813 return [i async for i in f()]
1814
1815 with self.assertRaisesRegex(Exception, 'aaa'):
1816 run_async(run_list())
1817
1818 def test_comp_8(self):
1819 async def f():
1820 return [i for i in [1, 2, 3]]
1821
1822 self.assertEqual(
1823 run_async(f()),
1824 ([], [1, 2, 3]))
1825
1826 def test_comp_9(self):
1827 async def gen():
1828 yield 1
1829 yield 2
1830 async def f():
1831 l = [i async for i in gen()]
1832 return [i for i in l]
1833
1834 self.assertEqual(
1835 run_async(f()),
1836 ([], [1, 2]))
1837
1838 def test_comp_10(self):
1839 async def f():
1840 xx = {i for i in [1, 2, 3]}
1841 return {x: x for x in xx}
1842
1843 self.assertEqual(
1844 run_async(f()),
1845 ([], {1: 1, 2: 2, 3: 3}))
1846
Serhiy Storchaka609a2e12015-11-12 11:31:51 +02001847 def test_copy(self):
1848 async def func(): pass
1849 coro = func()
1850 with self.assertRaises(TypeError):
1851 copy.copy(coro)
1852
1853 aw = coro.__await__()
1854 try:
1855 with self.assertRaises(TypeError):
1856 copy.copy(aw)
1857 finally:
1858 aw.close()
1859
1860 def test_pickle(self):
1861 async def func(): pass
1862 coro = func()
1863 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1864 with self.assertRaises((TypeError, pickle.PicklingError)):
1865 pickle.dumps(coro, proto)
1866
1867 aw = coro.__await__()
1868 try:
1869 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1870 with self.assertRaises((TypeError, pickle.PicklingError)):
1871 pickle.dumps(aw, proto)
1872 finally:
1873 aw.close()
1874
Benjamin Peterson2f40ed42016-09-05 10:14:54 -07001875 def test_fatal_coro_warning(self):
1876 # Issue 27811
1877 async def func(): pass
Benjamin Peterson48c88302016-09-07 09:00:48 -07001878 with warnings.catch_warnings(), support.captured_stderr() as stderr:
Benjamin Peterson2f40ed42016-09-05 10:14:54 -07001879 warnings.filterwarnings("error")
1880 func()
1881 support.gc_collect()
Benjamin Peterson48c88302016-09-07 09:00:48 -07001882 self.assertIn("was never awaited", stderr.getvalue())
Benjamin Peterson2f40ed42016-09-05 10:14:54 -07001883
Yury Selivanov75445082015-05-11 22:57:16 -04001884
1885class CoroAsyncIOCompatTest(unittest.TestCase):
1886
1887 def test_asyncio_1(self):
Victor Stinnerb45c0f72015-10-11 10:10:31 +02001888 # asyncio cannot be imported when Python is compiled without thread
1889 # support
Victor Stinner718c9842015-10-11 10:53:15 +02001890 asyncio = support.import_module('asyncio')
Yury Selivanov75445082015-05-11 22:57:16 -04001891
1892 class MyException(Exception):
1893 pass
1894
1895 buffer = []
1896
1897 class CM:
1898 async def __aenter__(self):
1899 buffer.append(1)
1900 await asyncio.sleep(0.01)
1901 buffer.append(2)
1902 return self
1903
1904 async def __aexit__(self, exc_type, exc_val, exc_tb):
1905 await asyncio.sleep(0.01)
1906 buffer.append(exc_type.__name__)
1907
1908 async def f():
1909 async with CM() as c:
1910 await asyncio.sleep(0.01)
1911 raise MyException
1912 buffer.append('unreachable')
1913
Yury Selivanovfdba8382015-05-12 14:28:08 -04001914 loop = asyncio.new_event_loop()
1915 asyncio.set_event_loop(loop)
Yury Selivanov75445082015-05-11 22:57:16 -04001916 try:
1917 loop.run_until_complete(f())
1918 except MyException:
1919 pass
1920 finally:
1921 loop.close()
Yury Selivanovfdba8382015-05-12 14:28:08 -04001922 asyncio.set_event_loop(None)
Yury Selivanov75445082015-05-11 22:57:16 -04001923
1924 self.assertEqual(buffer, [1, 2, 'MyException'])
1925
1926
1927class SysSetCoroWrapperTest(unittest.TestCase):
1928
1929 def test_set_wrapper_1(self):
1930 async def foo():
1931 return 'spam'
1932
1933 wrapped = None
1934 def wrap(gen):
1935 nonlocal wrapped
1936 wrapped = gen
1937 return gen
1938
1939 self.assertIsNone(sys.get_coroutine_wrapper())
1940
1941 sys.set_coroutine_wrapper(wrap)
1942 self.assertIs(sys.get_coroutine_wrapper(), wrap)
1943 try:
1944 f = foo()
1945 self.assertTrue(wrapped)
1946
1947 self.assertEqual(run_async(f), ([], 'spam'))
1948 finally:
1949 sys.set_coroutine_wrapper(None)
1950
1951 self.assertIsNone(sys.get_coroutine_wrapper())
1952
1953 wrapped = None
1954 with silence_coro_gc():
1955 foo()
1956 self.assertFalse(wrapped)
1957
1958 def test_set_wrapper_2(self):
1959 self.assertIsNone(sys.get_coroutine_wrapper())
1960 with self.assertRaisesRegex(TypeError, "callable expected, got int"):
1961 sys.set_coroutine_wrapper(1)
1962 self.assertIsNone(sys.get_coroutine_wrapper())
1963
Yury Selivanovaab3c4a2015-06-02 18:43:51 -04001964 def test_set_wrapper_3(self):
1965 async def foo():
1966 return 'spam'
1967
1968 def wrapper(coro):
1969 async def wrap(coro):
1970 return await coro
1971 return wrap(coro)
1972
1973 sys.set_coroutine_wrapper(wrapper)
1974 try:
Yury Selivanov94c22632015-06-04 10:16:51 -04001975 with silence_coro_gc(), self.assertRaisesRegex(
Yury Selivanovaab3c4a2015-06-02 18:43:51 -04001976 RuntimeError,
R David Murray44b548d2016-09-08 13:59:53 -04001977 r"coroutine wrapper.*\.wrapper at 0x.*attempted to "
1978 r"recursively wrap .* wrap .*"):
Yury Selivanovaab3c4a2015-06-02 18:43:51 -04001979
1980 foo()
1981 finally:
1982 sys.set_coroutine_wrapper(None)
1983
Yury Selivanov5376ba92015-06-22 12:19:30 -04001984 def test_set_wrapper_4(self):
1985 @types.coroutine
1986 def foo():
1987 return 'spam'
1988
1989 wrapped = None
1990 def wrap(gen):
1991 nonlocal wrapped
1992 wrapped = gen
1993 return gen
1994
1995 sys.set_coroutine_wrapper(wrap)
1996 try:
1997 foo()
1998 self.assertIs(
1999 wrapped, None,
2000 "generator-based coroutine was wrapped via "
2001 "sys.set_coroutine_wrapper")
2002 finally:
2003 sys.set_coroutine_wrapper(None)
2004
Yury Selivanov75445082015-05-11 22:57:16 -04002005
2006class CAPITest(unittest.TestCase):
2007
2008 def test_tp_await_1(self):
2009 from _testcapi import awaitType as at
2010
2011 async def foo():
2012 future = at(iter([1]))
2013 return (await future)
2014
2015 self.assertEqual(foo().send(None), 1)
2016
2017 def test_tp_await_2(self):
2018 # Test tp_await to __await__ mapping
2019 from _testcapi import awaitType as at
2020 future = at(iter([1]))
2021 self.assertEqual(next(future.__await__()), 1)
2022
2023 def test_tp_await_3(self):
2024 from _testcapi import awaitType as at
2025
2026 async def foo():
2027 future = at(1)
2028 return (await future)
2029
2030 with self.assertRaisesRegex(
2031 TypeError, "__await__.*returned non-iterator of type 'int'"):
2032 self.assertEqual(foo().send(None), 1)
2033
2034
Yury Selivanov75445082015-05-11 22:57:16 -04002035if __name__=="__main__":
Zachary Ware37ac5902015-05-13 01:03:06 -05002036 unittest.main()