blob: b4c7b5be6e208c79d040f3a5034d217cd2edf1ae [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
Serhiy Storchaka24411f82016-11-06 18:44:42 +0200841 def test_coro_wrapper_send_tuple(self):
842 async def foo():
843 return (10,)
844
845 result = run_async__await__(foo())
846 self.assertEqual(result, ([], (10,)))
847
848 def test_coro_wrapper_send_stop_iterator(self):
849 async def foo():
850 return StopIteration(10)
851
852 result = run_async__await__(foo())
853 self.assertIsInstance(result[1], StopIteration)
854 self.assertEqual(result[1].value, 10)
855
Yury Selivanove13f8f32015-07-03 00:23:30 -0400856 def test_cr_await(self):
857 @types.coroutine
858 def a():
859 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_RUNNING)
860 self.assertIsNone(coro_b.cr_await)
861 yield
862 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_RUNNING)
863 self.assertIsNone(coro_b.cr_await)
864
865 async def c():
866 await a()
867
868 async def b():
869 self.assertIsNone(coro_b.cr_await)
870 await c()
871 self.assertIsNone(coro_b.cr_await)
872
873 coro_b = b()
874 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_CREATED)
875 self.assertIsNone(coro_b.cr_await)
876
877 coro_b.send(None)
878 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_SUSPENDED)
879 self.assertEqual(coro_b.cr_await.cr_await.gi_code.co_name, 'a')
880
881 with self.assertRaises(StopIteration):
882 coro_b.send(None) # complete coroutine
883 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_CLOSED)
884 self.assertIsNone(coro_b.cr_await)
885
Yury Selivanov5376ba92015-06-22 12:19:30 -0400886 def test_corotype_1(self):
887 ct = types.CoroutineType
888 self.assertIn('into coroutine', ct.send.__doc__)
889 self.assertIn('inside coroutine', ct.close.__doc__)
890 self.assertIn('in coroutine', ct.throw.__doc__)
891 self.assertIn('of the coroutine', ct.__dict__['__name__'].__doc__)
892 self.assertIn('of the coroutine', ct.__dict__['__qualname__'].__doc__)
893 self.assertEqual(ct.__name__, 'coroutine')
894
895 async def f(): pass
896 c = f()
897 self.assertIn('coroutine object', repr(c))
898 c.close()
899
Yury Selivanov75445082015-05-11 22:57:16 -0400900 def test_await_1(self):
901
902 async def foo():
903 await 1
904 with self.assertRaisesRegex(TypeError, "object int can.t.*await"):
905 run_async(foo())
906
907 def test_await_2(self):
908 async def foo():
909 await []
910 with self.assertRaisesRegex(TypeError, "object list can.t.*await"):
911 run_async(foo())
912
913 def test_await_3(self):
914 async def foo():
915 await AsyncYieldFrom([1, 2, 3])
916
917 self.assertEqual(run_async(foo()), ([1, 2, 3], None))
Yury Selivanov5376ba92015-06-22 12:19:30 -0400918 self.assertEqual(run_async__await__(foo()), ([1, 2, 3], None))
Yury Selivanov75445082015-05-11 22:57:16 -0400919
920 def test_await_4(self):
921 async def bar():
922 return 42
923
924 async def foo():
925 return await bar()
926
927 self.assertEqual(run_async(foo()), ([], 42))
928
929 def test_await_5(self):
930 class Awaitable:
931 def __await__(self):
932 return
933
934 async def foo():
935 return (await Awaitable())
936
937 with self.assertRaisesRegex(
938 TypeError, "__await__.*returned non-iterator of type"):
939
940 run_async(foo())
941
942 def test_await_6(self):
943 class Awaitable:
944 def __await__(self):
945 return iter([52])
946
947 async def foo():
948 return (await Awaitable())
949
950 self.assertEqual(run_async(foo()), ([52], None))
951
952 def test_await_7(self):
953 class Awaitable:
954 def __await__(self):
955 yield 42
956 return 100
957
958 async def foo():
959 return (await Awaitable())
960
961 self.assertEqual(run_async(foo()), ([42], 100))
962
963 def test_await_8(self):
964 class Awaitable:
965 pass
966
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300967 async def foo(): return await Awaitable()
Yury Selivanov75445082015-05-11 22:57:16 -0400968
969 with self.assertRaisesRegex(
970 TypeError, "object Awaitable can't be used in 'await' expression"):
971
972 run_async(foo())
973
974 def test_await_9(self):
975 def wrap():
976 return bar
977
978 async def bar():
979 return 42
980
981 async def foo():
982 b = bar()
983
984 db = {'b': lambda: wrap}
985
986 class DB:
987 b = wrap
988
989 return (await bar() + await wrap()() + await db['b']()()() +
990 await bar() * 1000 + await DB.b()())
991
992 async def foo2():
993 return -await bar()
994
995 self.assertEqual(run_async(foo()), ([], 42168))
996 self.assertEqual(run_async(foo2()), ([], -42))
997
998 def test_await_10(self):
999 async def baz():
1000 return 42
1001
1002 async def bar():
1003 return baz()
1004
1005 async def foo():
1006 return await (await bar())
1007
1008 self.assertEqual(run_async(foo()), ([], 42))
1009
1010 def test_await_11(self):
1011 def ident(val):
1012 return val
1013
1014 async def bar():
1015 return 'spam'
1016
1017 async def foo():
1018 return ident(val=await bar())
1019
1020 async def foo2():
1021 return await bar(), 'ham'
1022
1023 self.assertEqual(run_async(foo2()), ([], ('spam', 'ham')))
1024
1025 def test_await_12(self):
1026 async def coro():
1027 return 'spam'
1028
1029 class Awaitable:
1030 def __await__(self):
1031 return coro()
1032
1033 async def foo():
1034 return await Awaitable()
1035
1036 with self.assertRaisesRegex(
R David Murray44b548d2016-09-08 13:59:53 -04001037 TypeError, r"__await__\(\) returned a coroutine"):
Yury Selivanov75445082015-05-11 22:57:16 -04001038
1039 run_async(foo())
1040
1041 def test_await_13(self):
1042 class Awaitable:
1043 def __await__(self):
1044 return self
1045
1046 async def foo():
1047 return await Awaitable()
1048
1049 with self.assertRaisesRegex(
1050 TypeError, "__await__.*returned non-iterator of type"):
1051
1052 run_async(foo())
1053
Yury Selivanovf2701522015-07-01 12:29:55 -04001054 def test_await_14(self):
1055 class Wrapper:
1056 # Forces the interpreter to use CoroutineType.__await__
1057 def __init__(self, coro):
1058 assert coro.__class__ is types.CoroutineType
1059 self.coro = coro
1060 def __await__(self):
1061 return self.coro.__await__()
1062
1063 class FutureLike:
1064 def __await__(self):
1065 return (yield)
1066
1067 class Marker(Exception):
1068 pass
1069
1070 async def coro1():
1071 try:
1072 return await FutureLike()
1073 except ZeroDivisionError:
1074 raise Marker
1075 async def coro2():
1076 return await Wrapper(coro1())
1077
1078 c = coro2()
1079 c.send(None)
1080 with self.assertRaisesRegex(StopIteration, 'spam'):
1081 c.send('spam')
1082
1083 c = coro2()
1084 c.send(None)
1085 with self.assertRaises(Marker):
1086 c.throw(ZeroDivisionError)
1087
Yury Selivanovc724bae2016-03-02 11:30:46 -05001088 def test_await_15(self):
1089 @types.coroutine
1090 def nop():
1091 yield
1092
1093 async def coroutine():
1094 await nop()
1095
1096 async def waiter(coro):
1097 await coro
1098
1099 coro = coroutine()
1100 coro.send(None)
1101
1102 with self.assertRaisesRegex(RuntimeError,
1103 "coroutine is being awaited already"):
1104 waiter(coro).send(None)
1105
Yury Selivanov75445082015-05-11 22:57:16 -04001106 def test_with_1(self):
1107 class Manager:
1108 def __init__(self, name):
1109 self.name = name
1110
1111 async def __aenter__(self):
1112 await AsyncYieldFrom(['enter-1-' + self.name,
1113 'enter-2-' + self.name])
1114 return self
1115
1116 async def __aexit__(self, *args):
1117 await AsyncYieldFrom(['exit-1-' + self.name,
1118 'exit-2-' + self.name])
1119
1120 if self.name == 'B':
1121 return True
1122
1123
1124 async def foo():
1125 async with Manager("A") as a, Manager("B") as b:
1126 await AsyncYieldFrom([('managers', a.name, b.name)])
1127 1/0
1128
1129 f = foo()
1130 result, _ = run_async(f)
1131
1132 self.assertEqual(
1133 result, ['enter-1-A', 'enter-2-A', 'enter-1-B', 'enter-2-B',
1134 ('managers', 'A', 'B'),
1135 'exit-1-B', 'exit-2-B', 'exit-1-A', 'exit-2-A']
1136 )
1137
1138 async def foo():
1139 async with Manager("A") as a, Manager("C") as c:
1140 await AsyncYieldFrom([('managers', a.name, c.name)])
1141 1/0
1142
1143 with self.assertRaises(ZeroDivisionError):
1144 run_async(foo())
1145
1146 def test_with_2(self):
1147 class CM:
1148 def __aenter__(self):
1149 pass
1150
1151 async def foo():
1152 async with CM():
1153 pass
1154
1155 with self.assertRaisesRegex(AttributeError, '__aexit__'):
1156 run_async(foo())
1157
1158 def test_with_3(self):
1159 class CM:
1160 def __aexit__(self):
1161 pass
1162
1163 async def foo():
1164 async with CM():
1165 pass
1166
1167 with self.assertRaisesRegex(AttributeError, '__aenter__'):
1168 run_async(foo())
1169
1170 def test_with_4(self):
1171 class CM:
1172 def __enter__(self):
1173 pass
1174
1175 def __exit__(self):
1176 pass
1177
1178 async def foo():
1179 async with CM():
1180 pass
1181
1182 with self.assertRaisesRegex(AttributeError, '__aexit__'):
1183 run_async(foo())
1184
1185 def test_with_5(self):
1186 # While this test doesn't make a lot of sense,
1187 # it's a regression test for an early bug with opcodes
1188 # generation
1189
1190 class CM:
1191 async def __aenter__(self):
1192 return self
1193
1194 async def __aexit__(self, *exc):
1195 pass
1196
1197 async def func():
1198 async with CM():
1199 assert (1, ) == 1
1200
1201 with self.assertRaises(AssertionError):
1202 run_async(func())
1203
1204 def test_with_6(self):
1205 class CM:
1206 def __aenter__(self):
1207 return 123
1208
1209 def __aexit__(self, *e):
1210 return 456
1211
1212 async def foo():
1213 async with CM():
1214 pass
1215
1216 with self.assertRaisesRegex(
1217 TypeError, "object int can't be used in 'await' expression"):
1218 # it's important that __aexit__ wasn't called
1219 run_async(foo())
1220
1221 def test_with_7(self):
1222 class CM:
1223 async def __aenter__(self):
1224 return self
1225
1226 def __aexit__(self, *e):
Nick Coghlanbaaadbf2015-05-13 15:54:02 +10001227 return 444
Yury Selivanov75445082015-05-11 22:57:16 -04001228
1229 async def foo():
1230 async with CM():
Nick Coghlanbaaadbf2015-05-13 15:54:02 +10001231 1/0
1232
1233 try:
1234 run_async(foo())
1235 except TypeError as exc:
1236 self.assertRegex(
1237 exc.args[0], "object int can't be used in 'await' expression")
1238 self.assertTrue(exc.__context__ is not None)
1239 self.assertTrue(isinstance(exc.__context__, ZeroDivisionError))
1240 else:
1241 self.fail('invalid asynchronous context manager did not fail')
1242
1243
1244 def test_with_8(self):
1245 CNT = 0
1246
1247 class CM:
1248 async def __aenter__(self):
1249 return self
1250
1251 def __aexit__(self, *e):
1252 return 456
1253
1254 async def foo():
1255 nonlocal CNT
1256 async with CM():
1257 CNT += 1
1258
Yury Selivanov75445082015-05-11 22:57:16 -04001259
1260 with self.assertRaisesRegex(
1261 TypeError, "object int can't be used in 'await' expression"):
1262
1263 run_async(foo())
1264
Nick Coghlanbaaadbf2015-05-13 15:54:02 +10001265 self.assertEqual(CNT, 1)
1266
1267
1268 def test_with_9(self):
1269 CNT = 0
1270
1271 class CM:
1272 async def __aenter__(self):
1273 return self
1274
1275 async def __aexit__(self, *e):
1276 1/0
1277
1278 async def foo():
1279 nonlocal CNT
1280 async with CM():
1281 CNT += 1
1282
1283 with self.assertRaises(ZeroDivisionError):
1284 run_async(foo())
1285
1286 self.assertEqual(CNT, 1)
1287
1288 def test_with_10(self):
1289 CNT = 0
1290
1291 class CM:
1292 async def __aenter__(self):
1293 return self
1294
1295 async def __aexit__(self, *e):
1296 1/0
1297
1298 async def foo():
1299 nonlocal CNT
1300 async with CM():
1301 async with CM():
1302 raise RuntimeError
1303
1304 try:
1305 run_async(foo())
1306 except ZeroDivisionError as exc:
1307 self.assertTrue(exc.__context__ is not None)
1308 self.assertTrue(isinstance(exc.__context__, ZeroDivisionError))
1309 self.assertTrue(isinstance(exc.__context__.__context__,
1310 RuntimeError))
1311 else:
1312 self.fail('exception from __aexit__ did not propagate')
1313
1314 def test_with_11(self):
1315 CNT = 0
1316
1317 class CM:
1318 async def __aenter__(self):
1319 raise NotImplementedError
1320
1321 async def __aexit__(self, *e):
1322 1/0
1323
1324 async def foo():
1325 nonlocal CNT
1326 async with CM():
1327 raise RuntimeError
1328
1329 try:
1330 run_async(foo())
1331 except NotImplementedError as exc:
1332 self.assertTrue(exc.__context__ is None)
1333 else:
1334 self.fail('exception from __aenter__ did not propagate')
1335
1336 def test_with_12(self):
1337 CNT = 0
1338
1339 class CM:
1340 async def __aenter__(self):
1341 return self
1342
1343 async def __aexit__(self, *e):
1344 return True
1345
1346 async def foo():
1347 nonlocal CNT
1348 async with CM() as cm:
1349 self.assertIs(cm.__class__, CM)
1350 raise RuntimeError
1351
1352 run_async(foo())
1353
Yury Selivanov9113dc72015-05-13 16:49:35 -04001354 def test_with_13(self):
1355 CNT = 0
1356
1357 class CM:
1358 async def __aenter__(self):
1359 1/0
1360
1361 async def __aexit__(self, *e):
1362 return True
1363
1364 async def foo():
1365 nonlocal CNT
1366 CNT += 1
1367 async with CM():
1368 CNT += 1000
1369 CNT += 10000
1370
1371 with self.assertRaises(ZeroDivisionError):
1372 run_async(foo())
1373 self.assertEqual(CNT, 1)
1374
Yury Selivanov75445082015-05-11 22:57:16 -04001375 def test_for_1(self):
1376 aiter_calls = 0
1377
1378 class AsyncIter:
1379 def __init__(self):
1380 self.i = 0
1381
1382 async def __aiter__(self):
1383 nonlocal aiter_calls
1384 aiter_calls += 1
1385 return self
1386
1387 async def __anext__(self):
1388 self.i += 1
1389
1390 if not (self.i % 10):
1391 await AsyncYield(self.i * 10)
1392
1393 if self.i > 100:
1394 raise StopAsyncIteration
1395
1396 return self.i, self.i
1397
1398
1399 buffer = []
1400 async def test1():
Yury Selivanov2edd8a12016-11-08 15:13:07 -05001401 with self.assertWarnsRegex(DeprecationWarning, "legacy"):
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001402 async for i1, i2 in AsyncIter():
1403 buffer.append(i1 + i2)
Yury Selivanov75445082015-05-11 22:57:16 -04001404
1405 yielded, _ = run_async(test1())
1406 # Make sure that __aiter__ was called only once
1407 self.assertEqual(aiter_calls, 1)
1408 self.assertEqual(yielded, [i * 100 for i in range(1, 11)])
1409 self.assertEqual(buffer, [i*2 for i in range(1, 101)])
1410
1411
1412 buffer = []
1413 async def test2():
1414 nonlocal buffer
Yury Selivanov2edd8a12016-11-08 15:13:07 -05001415 with self.assertWarnsRegex(DeprecationWarning, "legacy"):
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001416 async for i in AsyncIter():
1417 buffer.append(i[0])
1418 if i[0] == 20:
1419 break
1420 else:
1421 buffer.append('what?')
Yury Selivanov75445082015-05-11 22:57:16 -04001422 buffer.append('end')
1423
1424 yielded, _ = run_async(test2())
1425 # Make sure that __aiter__ was called only once
1426 self.assertEqual(aiter_calls, 2)
1427 self.assertEqual(yielded, [100, 200])
1428 self.assertEqual(buffer, [i for i in range(1, 21)] + ['end'])
1429
1430
1431 buffer = []
1432 async def test3():
1433 nonlocal buffer
Yury Selivanov2edd8a12016-11-08 15:13:07 -05001434 with self.assertWarnsRegex(DeprecationWarning, "legacy"):
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001435 async for i in AsyncIter():
1436 if i[0] > 20:
1437 continue
1438 buffer.append(i[0])
1439 else:
1440 buffer.append('what?')
Yury Selivanov75445082015-05-11 22:57:16 -04001441 buffer.append('end')
1442
1443 yielded, _ = run_async(test3())
1444 # Make sure that __aiter__ was called only once
1445 self.assertEqual(aiter_calls, 3)
1446 self.assertEqual(yielded, [i * 100 for i in range(1, 11)])
1447 self.assertEqual(buffer, [i for i in range(1, 21)] +
1448 ['what?', 'end'])
1449
1450 def test_for_2(self):
1451 tup = (1, 2, 3)
1452 refs_before = sys.getrefcount(tup)
1453
1454 async def foo():
1455 async for i in tup:
1456 print('never going to happen')
1457
1458 with self.assertRaisesRegex(
1459 TypeError, "async for' requires an object.*__aiter__.*tuple"):
1460
1461 run_async(foo())
1462
1463 self.assertEqual(sys.getrefcount(tup), refs_before)
1464
1465 def test_for_3(self):
1466 class I:
1467 def __aiter__(self):
1468 return self
1469
1470 aiter = I()
1471 refs_before = sys.getrefcount(aiter)
1472
1473 async def foo():
1474 async for i in aiter:
1475 print('never going to happen')
1476
1477 with self.assertRaisesRegex(
1478 TypeError,
R David Murray44b548d2016-09-08 13:59:53 -04001479 r"async for' received an invalid object.*__aiter.*\: I"):
Yury Selivanov75445082015-05-11 22:57:16 -04001480
1481 run_async(foo())
1482
1483 self.assertEqual(sys.getrefcount(aiter), refs_before)
1484
1485 def test_for_4(self):
1486 class I:
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001487 def __aiter__(self):
Yury Selivanov75445082015-05-11 22:57:16 -04001488 return self
1489
1490 def __anext__(self):
1491 return ()
1492
1493 aiter = I()
1494 refs_before = sys.getrefcount(aiter)
1495
1496 async def foo():
1497 async for i in aiter:
1498 print('never going to happen')
1499
1500 with self.assertRaisesRegex(
1501 TypeError,
1502 "async for' received an invalid object.*__anext__.*tuple"):
1503
1504 run_async(foo())
1505
1506 self.assertEqual(sys.getrefcount(aiter), refs_before)
1507
1508 def test_for_5(self):
1509 class I:
1510 async def __aiter__(self):
1511 return self
1512
1513 def __anext__(self):
1514 return 123
1515
1516 async def foo():
Yury Selivanov2edd8a12016-11-08 15:13:07 -05001517 with self.assertWarnsRegex(DeprecationWarning, "legacy"):
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001518 async for i in I():
1519 print('never going to happen')
Yury Selivanov75445082015-05-11 22:57:16 -04001520
1521 with self.assertRaisesRegex(
1522 TypeError,
1523 "async for' received an invalid object.*__anext.*int"):
1524
1525 run_async(foo())
1526
1527 def test_for_6(self):
1528 I = 0
1529
1530 class Manager:
1531 async def __aenter__(self):
1532 nonlocal I
1533 I += 10000
1534
1535 async def __aexit__(self, *args):
1536 nonlocal I
1537 I += 100000
1538
1539 class Iterable:
1540 def __init__(self):
1541 self.i = 0
1542
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001543 def __aiter__(self):
Yury Selivanov75445082015-05-11 22:57:16 -04001544 return self
1545
1546 async def __anext__(self):
1547 if self.i > 10:
1548 raise StopAsyncIteration
1549 self.i += 1
1550 return self.i
1551
1552 ##############
1553
1554 manager = Manager()
1555 iterable = Iterable()
1556 mrefs_before = sys.getrefcount(manager)
1557 irefs_before = sys.getrefcount(iterable)
1558
1559 async def main():
1560 nonlocal I
1561
1562 async with manager:
1563 async for i in iterable:
1564 I += 1
1565 I += 1000
1566
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001567 with warnings.catch_warnings():
1568 warnings.simplefilter("error")
Martin Panter70c502a2016-06-12 06:14:03 +00001569 # Test that __aiter__ that returns an asynchronous iterator
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001570 # directly does not throw any warnings.
1571 run_async(main())
Yury Selivanov75445082015-05-11 22:57:16 -04001572 self.assertEqual(I, 111011)
1573
1574 self.assertEqual(sys.getrefcount(manager), mrefs_before)
1575 self.assertEqual(sys.getrefcount(iterable), irefs_before)
1576
1577 ##############
1578
1579 async def main():
1580 nonlocal I
1581
1582 async with Manager():
1583 async for i in Iterable():
1584 I += 1
1585 I += 1000
1586
1587 async with Manager():
1588 async for i in Iterable():
1589 I += 1
1590 I += 1000
1591
1592 run_async(main())
1593 self.assertEqual(I, 333033)
1594
1595 ##############
1596
1597 async def main():
1598 nonlocal I
1599
1600 async with Manager():
1601 I += 100
1602 async for i in Iterable():
1603 I += 1
1604 else:
1605 I += 10000000
1606 I += 1000
1607
1608 async with Manager():
1609 I += 100
1610 async for i in Iterable():
1611 I += 1
1612 else:
1613 I += 10000000
1614 I += 1000
1615
1616 run_async(main())
1617 self.assertEqual(I, 20555255)
1618
Yury Selivanov9113dc72015-05-13 16:49:35 -04001619 def test_for_7(self):
1620 CNT = 0
1621 class AI:
1622 async def __aiter__(self):
1623 1/0
1624 async def foo():
1625 nonlocal CNT
Yury Selivanov2edd8a12016-11-08 15:13:07 -05001626 with self.assertWarnsRegex(DeprecationWarning, "legacy"):
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001627 async for i in AI():
1628 CNT += 1
Yury Selivanov9113dc72015-05-13 16:49:35 -04001629 CNT += 10
1630 with self.assertRaises(ZeroDivisionError):
1631 run_async(foo())
1632 self.assertEqual(CNT, 0)
1633
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001634 def test_for_8(self):
1635 CNT = 0
1636 class AI:
1637 def __aiter__(self):
1638 1/0
1639 async def foo():
1640 nonlocal CNT
1641 async for i in AI():
1642 CNT += 1
1643 CNT += 10
1644 with self.assertRaises(ZeroDivisionError):
1645 with warnings.catch_warnings():
1646 warnings.simplefilter("error")
1647 # Test that if __aiter__ raises an exception it propagates
1648 # without any kind of warning.
1649 run_async(foo())
1650 self.assertEqual(CNT, 0)
1651
1652 def test_for_9(self):
Yury Selivanov2edd8a12016-11-08 15:13:07 -05001653 # Test that DeprecationWarning can safely be converted into
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001654 # an exception (__aiter__ should not have a chance to raise
1655 # a ZeroDivisionError.)
1656 class AI:
1657 async def __aiter__(self):
1658 1/0
1659 async def foo():
1660 async for i in AI():
1661 pass
1662
Yury Selivanov2edd8a12016-11-08 15:13:07 -05001663 with self.assertRaises(DeprecationWarning):
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001664 with warnings.catch_warnings():
1665 warnings.simplefilter("error")
1666 run_async(foo())
1667
1668 def test_for_10(self):
Yury Selivanov2edd8a12016-11-08 15:13:07 -05001669 # Test that DeprecationWarning can safely be converted into
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001670 # an exception.
1671 class AI:
1672 async def __aiter__(self):
1673 pass
1674 async def foo():
1675 async for i in AI():
1676 pass
1677
Yury Selivanov2edd8a12016-11-08 15:13:07 -05001678 with self.assertRaises(DeprecationWarning):
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001679 with warnings.catch_warnings():
1680 warnings.simplefilter("error")
1681 run_async(foo())
1682
Yury Selivanov398ff912017-03-02 22:20:00 -05001683 def test_for_11(self):
1684 class F:
1685 def __aiter__(self):
1686 return self
1687 def __anext__(self):
1688 return self
1689 def __await__(self):
1690 1 / 0
1691
1692 async def main():
1693 async for _ in F():
1694 pass
1695
1696 with self.assertRaisesRegex(TypeError,
1697 'an invalid object from __anext__') as c:
1698 main().send(None)
1699
1700 err = c.exception
1701 self.assertIsInstance(err.__cause__, ZeroDivisionError)
1702
1703 def test_for_12(self):
1704 class F:
1705 def __aiter__(self):
1706 return self
1707 def __await__(self):
1708 1 / 0
1709
1710 async def main():
1711 async for _ in F():
1712 pass
1713
1714 with self.assertRaisesRegex(TypeError,
1715 'an invalid object from __aiter__') as c:
1716 main().send(None)
1717
1718 err = c.exception
1719 self.assertIsInstance(err.__cause__, ZeroDivisionError)
1720
Serhiy Storchaka24411f82016-11-06 18:44:42 +02001721 def test_for_tuple(self):
1722 class Done(Exception): pass
1723
1724 class AIter(tuple):
1725 i = 0
1726 def __aiter__(self):
1727 return self
1728 async def __anext__(self):
1729 if self.i >= len(self):
1730 raise StopAsyncIteration
1731 self.i += 1
1732 return self[self.i - 1]
1733
1734 result = []
1735 async def foo():
1736 async for i in AIter([42]):
1737 result.append(i)
1738 raise Done
1739
1740 with self.assertRaises(Done):
1741 foo().send(None)
1742 self.assertEqual(result, [42])
1743
1744 def test_for_stop_iteration(self):
1745 class Done(Exception): pass
1746
1747 class AIter(StopIteration):
1748 i = 0
1749 def __aiter__(self):
1750 return self
1751 async def __anext__(self):
1752 if self.i:
1753 raise StopAsyncIteration
1754 self.i += 1
1755 return self.value
1756
1757 result = []
1758 async def foo():
1759 async for i in AIter(42):
1760 result.append(i)
1761 raise Done
1762
1763 with self.assertRaises(Done):
1764 foo().send(None)
1765 self.assertEqual(result, [42])
1766
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001767 def test_comp_1(self):
1768 async def f(i):
1769 return i
1770
1771 async def run_list():
1772 return [await c for c in [f(1), f(41)]]
1773
1774 async def run_set():
1775 return {await c for c in [f(1), f(41)]}
1776
1777 async def run_dict1():
1778 return {await c: 'a' for c in [f(1), f(41)]}
1779
1780 async def run_dict2():
1781 return {i: await c for i, c in enumerate([f(1), f(41)])}
1782
1783 self.assertEqual(run_async(run_list()), ([], [1, 41]))
1784 self.assertEqual(run_async(run_set()), ([], {1, 41}))
1785 self.assertEqual(run_async(run_dict1()), ([], {1: 'a', 41: 'a'}))
1786 self.assertEqual(run_async(run_dict2()), ([], {0: 1, 1: 41}))
1787
1788 def test_comp_2(self):
1789 async def f(i):
1790 return i
1791
1792 async def run_list():
1793 return [s for c in [f(''), f('abc'), f(''), f(['de', 'fg'])]
1794 for s in await c]
1795
1796 self.assertEqual(
1797 run_async(run_list()),
1798 ([], ['a', 'b', 'c', 'de', 'fg']))
1799
1800 async def run_set():
1801 return {d
1802 for c in [f([f([10, 30]),
1803 f([20])])]
1804 for s in await c
1805 for d in await s}
1806
1807 self.assertEqual(
1808 run_async(run_set()),
1809 ([], {10, 20, 30}))
1810
1811 async def run_set2():
1812 return {await s
1813 for c in [f([f(10), f(20)])]
1814 for s in await c}
1815
1816 self.assertEqual(
1817 run_async(run_set2()),
1818 ([], {10, 20}))
1819
1820 def test_comp_3(self):
1821 async def f(it):
1822 for i in it:
1823 yield i
1824
1825 async def run_list():
1826 return [i + 1 async for i in f([10, 20])]
1827 self.assertEqual(
1828 run_async(run_list()),
1829 ([], [11, 21]))
1830
1831 async def run_set():
1832 return {i + 1 async for i in f([10, 20])}
1833 self.assertEqual(
1834 run_async(run_set()),
1835 ([], {11, 21}))
1836
1837 async def run_dict():
1838 return {i + 1: i + 2 async for i in f([10, 20])}
1839 self.assertEqual(
1840 run_async(run_dict()),
1841 ([], {11: 12, 21: 22}))
1842
1843 async def run_gen():
1844 gen = (i + 1 async for i in f([10, 20]))
1845 return [g + 100 async for g in gen]
1846 self.assertEqual(
1847 run_async(run_gen()),
1848 ([], [111, 121]))
1849
1850 def test_comp_4(self):
1851 async def f(it):
1852 for i in it:
1853 yield i
1854
1855 async def run_list():
1856 return [i + 1 async for i in f([10, 20]) if i > 10]
1857 self.assertEqual(
1858 run_async(run_list()),
1859 ([], [21]))
1860
1861 async def run_set():
1862 return {i + 1 async for i in f([10, 20]) if i > 10}
1863 self.assertEqual(
1864 run_async(run_set()),
1865 ([], {21}))
1866
1867 async def run_dict():
1868 return {i + 1: i + 2 async for i in f([10, 20]) if i > 10}
1869 self.assertEqual(
1870 run_async(run_dict()),
1871 ([], {21: 22}))
1872
1873 async def run_gen():
1874 gen = (i + 1 async for i in f([10, 20]) if i > 10)
1875 return [g + 100 async for g in gen]
1876 self.assertEqual(
1877 run_async(run_gen()),
1878 ([], [121]))
1879
1880 def test_comp_5(self):
1881 async def f(it):
1882 for i in it:
1883 yield i
1884
1885 async def run_list():
1886 return [i + 1 for pair in ([10, 20], [30, 40]) if pair[0] > 10
1887 async for i in f(pair) if i > 30]
1888 self.assertEqual(
1889 run_async(run_list()),
1890 ([], [41]))
1891
1892 def test_comp_6(self):
1893 async def f(it):
1894 for i in it:
1895 yield i
1896
1897 async def run_list():
1898 return [i + 1 async for seq in f([(10, 20), (30,)])
1899 for i in seq]
1900
1901 self.assertEqual(
1902 run_async(run_list()),
1903 ([], [11, 21, 31]))
1904
1905 def test_comp_7(self):
1906 async def f():
1907 yield 1
1908 yield 2
1909 raise Exception('aaa')
1910
1911 async def run_list():
1912 return [i async for i in f()]
1913
1914 with self.assertRaisesRegex(Exception, 'aaa'):
1915 run_async(run_list())
1916
1917 def test_comp_8(self):
1918 async def f():
1919 return [i for i in [1, 2, 3]]
1920
1921 self.assertEqual(
1922 run_async(f()),
1923 ([], [1, 2, 3]))
1924
1925 def test_comp_9(self):
1926 async def gen():
1927 yield 1
1928 yield 2
1929 async def f():
1930 l = [i async for i in gen()]
1931 return [i for i in l]
1932
1933 self.assertEqual(
1934 run_async(f()),
1935 ([], [1, 2]))
1936
1937 def test_comp_10(self):
1938 async def f():
1939 xx = {i for i in [1, 2, 3]}
1940 return {x: x for x in xx}
1941
1942 self.assertEqual(
1943 run_async(f()),
1944 ([], {1: 1, 2: 2, 3: 3}))
1945
Serhiy Storchaka609a2e12015-11-12 11:31:51 +02001946 def test_copy(self):
1947 async def func(): pass
1948 coro = func()
1949 with self.assertRaises(TypeError):
1950 copy.copy(coro)
1951
1952 aw = coro.__await__()
1953 try:
1954 with self.assertRaises(TypeError):
1955 copy.copy(aw)
1956 finally:
1957 aw.close()
1958
1959 def test_pickle(self):
1960 async def func(): pass
1961 coro = func()
1962 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1963 with self.assertRaises((TypeError, pickle.PicklingError)):
1964 pickle.dumps(coro, proto)
1965
1966 aw = coro.__await__()
1967 try:
1968 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1969 with self.assertRaises((TypeError, pickle.PicklingError)):
1970 pickle.dumps(aw, proto)
1971 finally:
1972 aw.close()
1973
Benjamin Peterson2f40ed42016-09-05 10:14:54 -07001974 def test_fatal_coro_warning(self):
1975 # Issue 27811
1976 async def func(): pass
Benjamin Peterson48c88302016-09-07 09:00:48 -07001977 with warnings.catch_warnings(), support.captured_stderr() as stderr:
Benjamin Peterson2f40ed42016-09-05 10:14:54 -07001978 warnings.filterwarnings("error")
1979 func()
1980 support.gc_collect()
Benjamin Peterson48c88302016-09-07 09:00:48 -07001981 self.assertIn("was never awaited", stderr.getvalue())
Benjamin Peterson2f40ed42016-09-05 10:14:54 -07001982
Yury Selivanov75445082015-05-11 22:57:16 -04001983
1984class CoroAsyncIOCompatTest(unittest.TestCase):
1985
1986 def test_asyncio_1(self):
Victor Stinnerb45c0f72015-10-11 10:10:31 +02001987 # asyncio cannot be imported when Python is compiled without thread
1988 # support
Victor Stinner718c9842015-10-11 10:53:15 +02001989 asyncio = support.import_module('asyncio')
Yury Selivanov75445082015-05-11 22:57:16 -04001990
1991 class MyException(Exception):
1992 pass
1993
1994 buffer = []
1995
1996 class CM:
1997 async def __aenter__(self):
1998 buffer.append(1)
1999 await asyncio.sleep(0.01)
2000 buffer.append(2)
2001 return self
2002
2003 async def __aexit__(self, exc_type, exc_val, exc_tb):
2004 await asyncio.sleep(0.01)
2005 buffer.append(exc_type.__name__)
2006
2007 async def f():
2008 async with CM() as c:
2009 await asyncio.sleep(0.01)
2010 raise MyException
2011 buffer.append('unreachable')
2012
Yury Selivanovfdba8382015-05-12 14:28:08 -04002013 loop = asyncio.new_event_loop()
2014 asyncio.set_event_loop(loop)
Yury Selivanov75445082015-05-11 22:57:16 -04002015 try:
2016 loop.run_until_complete(f())
2017 except MyException:
2018 pass
2019 finally:
2020 loop.close()
Yury Selivanovfdba8382015-05-12 14:28:08 -04002021 asyncio.set_event_loop(None)
Yury Selivanov75445082015-05-11 22:57:16 -04002022
2023 self.assertEqual(buffer, [1, 2, 'MyException'])
2024
2025
2026class SysSetCoroWrapperTest(unittest.TestCase):
2027
2028 def test_set_wrapper_1(self):
2029 async def foo():
2030 return 'spam'
2031
2032 wrapped = None
2033 def wrap(gen):
2034 nonlocal wrapped
2035 wrapped = gen
2036 return gen
2037
2038 self.assertIsNone(sys.get_coroutine_wrapper())
2039
2040 sys.set_coroutine_wrapper(wrap)
2041 self.assertIs(sys.get_coroutine_wrapper(), wrap)
2042 try:
2043 f = foo()
2044 self.assertTrue(wrapped)
2045
2046 self.assertEqual(run_async(f), ([], 'spam'))
2047 finally:
2048 sys.set_coroutine_wrapper(None)
2049
2050 self.assertIsNone(sys.get_coroutine_wrapper())
2051
2052 wrapped = None
2053 with silence_coro_gc():
2054 foo()
2055 self.assertFalse(wrapped)
2056
2057 def test_set_wrapper_2(self):
2058 self.assertIsNone(sys.get_coroutine_wrapper())
2059 with self.assertRaisesRegex(TypeError, "callable expected, got int"):
2060 sys.set_coroutine_wrapper(1)
2061 self.assertIsNone(sys.get_coroutine_wrapper())
2062
Yury Selivanovaab3c4a2015-06-02 18:43:51 -04002063 def test_set_wrapper_3(self):
2064 async def foo():
2065 return 'spam'
2066
2067 def wrapper(coro):
2068 async def wrap(coro):
2069 return await coro
2070 return wrap(coro)
2071
2072 sys.set_coroutine_wrapper(wrapper)
2073 try:
Yury Selivanov94c22632015-06-04 10:16:51 -04002074 with silence_coro_gc(), self.assertRaisesRegex(
Yury Selivanovaab3c4a2015-06-02 18:43:51 -04002075 RuntimeError,
R David Murray44b548d2016-09-08 13:59:53 -04002076 r"coroutine wrapper.*\.wrapper at 0x.*attempted to "
2077 r"recursively wrap .* wrap .*"):
Yury Selivanovaab3c4a2015-06-02 18:43:51 -04002078
2079 foo()
2080 finally:
2081 sys.set_coroutine_wrapper(None)
2082
Yury Selivanov5376ba92015-06-22 12:19:30 -04002083 def test_set_wrapper_4(self):
2084 @types.coroutine
2085 def foo():
2086 return 'spam'
2087
2088 wrapped = None
2089 def wrap(gen):
2090 nonlocal wrapped
2091 wrapped = gen
2092 return gen
2093
2094 sys.set_coroutine_wrapper(wrap)
2095 try:
2096 foo()
2097 self.assertIs(
2098 wrapped, None,
2099 "generator-based coroutine was wrapped via "
2100 "sys.set_coroutine_wrapper")
2101 finally:
2102 sys.set_coroutine_wrapper(None)
2103
Yury Selivanov75445082015-05-11 22:57:16 -04002104
2105class CAPITest(unittest.TestCase):
2106
2107 def test_tp_await_1(self):
2108 from _testcapi import awaitType as at
2109
2110 async def foo():
2111 future = at(iter([1]))
2112 return (await future)
2113
2114 self.assertEqual(foo().send(None), 1)
2115
2116 def test_tp_await_2(self):
2117 # Test tp_await to __await__ mapping
2118 from _testcapi import awaitType as at
2119 future = at(iter([1]))
2120 self.assertEqual(next(future.__await__()), 1)
2121
2122 def test_tp_await_3(self):
2123 from _testcapi import awaitType as at
2124
2125 async def foo():
2126 future = at(1)
2127 return (await future)
2128
2129 with self.assertRaisesRegex(
2130 TypeError, "__await__.*returned non-iterator of type 'int'"):
2131 self.assertEqual(foo().send(None), 1)
2132
2133
Yury Selivanov75445082015-05-11 22:57:16 -04002134if __name__=="__main__":
Zachary Ware37ac5902015-05-13 01:03:06 -05002135 unittest.main()