blob: 79cbec9899b0855ce3eda82f21d4ec14a1eaf479 [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 with self.assertRaisesRegex(SyntaxError, "'await' outside"):
Yury Selivanov75445082015-05-11 22:57:16 -040073 import test.badsyntax_async1
74
75 def test_badsyntax_2(self):
Yury Selivanov8fb307c2015-07-22 13:33:45 +030076 with self.assertRaisesRegex(SyntaxError, "'await' outside"):
Yury Selivanov75445082015-05-11 22:57:16 -040077 import test.badsyntax_async2
78
79 def test_badsyntax_3(self):
80 with self.assertRaisesRegex(SyntaxError, 'invalid syntax'):
81 import test.badsyntax_async3
82
83 def test_badsyntax_4(self):
84 with self.assertRaisesRegex(SyntaxError, 'invalid syntax'):
85 import test.badsyntax_async4
86
87 def test_badsyntax_5(self):
88 with self.assertRaisesRegex(SyntaxError, 'invalid syntax'):
89 import test.badsyntax_async5
90
91 def test_badsyntax_6(self):
92 with self.assertRaisesRegex(
93 SyntaxError, "'yield' inside async function"):
94
95 import test.badsyntax_async6
96
97 def test_badsyntax_7(self):
98 with self.assertRaisesRegex(
99 SyntaxError, "'yield from' inside async function"):
100
101 import test.badsyntax_async7
102
103 def test_badsyntax_8(self):
104 with self.assertRaisesRegex(SyntaxError, 'invalid syntax'):
105 import test.badsyntax_async8
106
107 def test_badsyntax_9(self):
Yury Selivanov9dec0352015-06-30 12:49:04 -0400108 ns = {}
109 for comp in {'(await a for a in b)',
110 '[await a for a in b]',
111 '{await a for a in b}',
112 '{await a: c for a in b}'}:
113
Yury Selivanov86cd7d62015-06-30 12:51:12 -0400114 with self.assertRaisesRegex(SyntaxError, 'await.*in comprehen'):
Yury Selivanov9dec0352015-06-30 12:49:04 -0400115 exec('async def f():\n\t{}'.format(comp), ns, ns)
116
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300117 def test_badsyntax_10(self):
118 # Tests for issue 24619
119
120 samples = [
121 """async def foo():
122 def bar(): pass
123 await = 1
124 """,
125
126 """async def foo():
127
128 def bar(): pass
129 await = 1
130 """,
131
132 """async def foo():
133 def bar(): pass
134 if 1:
135 await = 1
136 """,
137
138 """def foo():
139 async def bar(): pass
140 if 1:
141 await a
142 """,
143
144 """def foo():
145 async def bar(): pass
146 await a
147 """,
148
149 """def foo():
150 def baz(): pass
151 async def bar(): pass
152 await a
153 """,
154
155 """def foo():
156 def baz(): pass
157 # 456
158 async def bar(): pass
159 # 123
160 await a
161 """,
162
163 """async def foo():
164 def baz(): pass
165 # 456
166 async def bar(): pass
167 # 123
168 await = 2
169 """,
170
171 """def foo():
172
173 def baz(): pass
174
175 async def bar(): pass
176
177 await a
178 """,
179
180 """async def foo():
181
182 def baz(): pass
183
184 async def bar(): pass
185
186 await = 2
187 """,
188
189 """async def foo():
190 def async(): pass
191 """,
192
193 """async def foo():
194 def await(): pass
195 """,
196
197 """async def foo():
198 def bar():
199 await
200 """,
201
202 """async def foo():
203 return lambda async: await
204 """,
205
206 """async def foo():
207 return lambda a: await
208 """,
209
Yury Selivanovb7666a32015-07-22 14:48:57 +0300210 """await a()""",
211
212 """async def foo(a=await b):
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300213 pass
214 """,
215
Yury Selivanovf315c1c2015-07-23 09:10:44 +0300216 """async def foo(a:await b):
217 pass
218 """,
219
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300220 """def baz():
Yury Selivanovb7666a32015-07-22 14:48:57 +0300221 async def foo(a=await b):
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300222 pass
223 """,
224
225 """async def foo(async):
226 pass
227 """,
228
229 """async def foo():
230 def bar():
231 def baz():
232 async = 1
233 """,
234
235 """async def foo():
236 def bar():
237 def baz():
238 pass
239 async = 1
240 """,
241
242 """def foo():
243 async def bar():
244
245 async def baz():
246 pass
247
248 def baz():
249 42
250
251 async = 1
252 """,
253
254 """async def foo():
255 def bar():
256 def baz():
257 pass\nawait foo()
258 """,
259
260 """def foo():
261 def bar():
262 async def baz():
263 pass\nawait foo()
264 """,
265
266 """async def foo(await):
267 pass
268 """,
269
270 """def foo():
271
272 async def bar(): pass
273
274 await a
275 """,
276
277 """def foo():
278 async def bar():
279 pass\nawait a
280 """]
281
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300282 for code in samples:
283 with self.subTest(code=code), self.assertRaises(SyntaxError):
Yury Selivanovb7666a32015-07-22 14:48:57 +0300284 compile(code, "<test>", "exec")
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300285
286 def test_goodsyntax_1(self):
287 # Tests for issue 24619
288
289 def foo(await):
290 async def foo(): pass
291 async def foo():
292 pass
293 return await + 1
294 self.assertEqual(foo(10), 11)
295
296 def foo(await):
297 async def foo(): pass
298 async def foo(): pass
299 return await + 2
300 self.assertEqual(foo(20), 22)
301
302 def foo(await):
303
304 async def foo(): pass
305
306 async def foo(): pass
307
308 return await + 2
309 self.assertEqual(foo(20), 22)
310
311 def foo(await):
312 """spam"""
313 async def foo(): \
314 pass
315 # 123
316 async def foo(): pass
317 # 456
318 return await + 2
319 self.assertEqual(foo(20), 22)
320
321 def foo(await):
322 def foo(): pass
323 def foo(): pass
324 async def bar(): return await_
325 await_ = await
326 try:
327 bar().send(None)
328 except StopIteration as ex:
329 return ex.args[0]
330 self.assertEqual(foo(42), 42)
331
332 async def f():
333 async def g(): pass
334 await z
Yury Selivanov96ec9342015-07-23 15:01:58 +0300335 await = 1
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300336 self.assertTrue(inspect.iscoroutinefunction(f))
337
Yury Selivanov75445082015-05-11 22:57:16 -0400338
Yury Selivanov8085b802015-05-18 12:50:52 -0400339class TokenizerRegrTest(unittest.TestCase):
340
341 def test_oneline_defs(self):
342 buf = []
343 for i in range(500):
344 buf.append('def i{i}(): return {i}'.format(i=i))
345 buf = '\n'.join(buf)
346
347 # Test that 500 consequent, one-line defs is OK
348 ns = {}
349 exec(buf, ns, ns)
350 self.assertEqual(ns['i499'](), 499)
351
352 # Test that 500 consequent, one-line defs *and*
353 # one 'async def' following them is OK
354 buf += '\nasync def foo():\n return'
355 ns = {}
356 exec(buf, ns, ns)
357 self.assertEqual(ns['i499'](), 499)
358 self.assertTrue(inspect.iscoroutinefunction(ns['foo']))
359
360
Yury Selivanov75445082015-05-11 22:57:16 -0400361class CoroutineTest(unittest.TestCase):
362
363 def test_gen_1(self):
364 def gen(): yield
365 self.assertFalse(hasattr(gen, '__await__'))
366
367 def test_func_1(self):
368 async def foo():
369 return 10
370
371 f = foo()
Yury Selivanov5376ba92015-06-22 12:19:30 -0400372 self.assertIsInstance(f, types.CoroutineType)
373 self.assertTrue(bool(foo.__code__.co_flags & inspect.CO_COROUTINE))
374 self.assertFalse(bool(foo.__code__.co_flags & inspect.CO_GENERATOR))
375 self.assertTrue(bool(f.cr_code.co_flags & inspect.CO_COROUTINE))
376 self.assertFalse(bool(f.cr_code.co_flags & inspect.CO_GENERATOR))
Yury Selivanov75445082015-05-11 22:57:16 -0400377 self.assertEqual(run_async(f), ([], 10))
378
Yury Selivanov5376ba92015-06-22 12:19:30 -0400379 self.assertEqual(run_async__await__(foo()), ([], 10))
380
Yury Selivanov75445082015-05-11 22:57:16 -0400381 def bar(): pass
Yury Selivanov5376ba92015-06-22 12:19:30 -0400382 self.assertFalse(bool(bar.__code__.co_flags & inspect.CO_COROUTINE))
Yury Selivanov75445082015-05-11 22:57:16 -0400383
384 def test_func_2(self):
385 async def foo():
386 raise StopIteration
387
388 with self.assertRaisesRegex(
Yury Selivanov5376ba92015-06-22 12:19:30 -0400389 RuntimeError, "coroutine raised StopIteration"):
Yury Selivanov75445082015-05-11 22:57:16 -0400390
391 run_async(foo())
392
393 def test_func_3(self):
394 async def foo():
395 raise StopIteration
396
397 with silence_coro_gc():
398 self.assertRegex(repr(foo()), '^<coroutine object.* at 0x.*>$')
399
400 def test_func_4(self):
401 async def foo():
402 raise StopIteration
403
404 check = lambda: self.assertRaisesRegex(
Yury Selivanov5376ba92015-06-22 12:19:30 -0400405 TypeError, "'coroutine' object is not iterable")
Yury Selivanov75445082015-05-11 22:57:16 -0400406
407 with check():
408 list(foo())
409
410 with check():
411 tuple(foo())
412
413 with check():
414 sum(foo())
415
416 with check():
417 iter(foo())
418
Yury Selivanov75445082015-05-11 22:57:16 -0400419 with silence_coro_gc(), check():
420 for i in foo():
421 pass
422
423 with silence_coro_gc(), check():
424 [i for i in foo()]
425
426 def test_func_5(self):
427 @types.coroutine
428 def bar():
429 yield 1
430
431 async def foo():
432 await bar()
433
434 check = lambda: self.assertRaisesRegex(
Yury Selivanov5376ba92015-06-22 12:19:30 -0400435 TypeError, "'coroutine' object is not iterable")
Yury Selivanov75445082015-05-11 22:57:16 -0400436
437 with check():
438 for el in foo(): pass
439
440 # the following should pass without an error
441 for el in bar():
442 self.assertEqual(el, 1)
443 self.assertEqual([el for el in bar()], [1])
444 self.assertEqual(tuple(bar()), (1,))
445 self.assertEqual(next(iter(bar())), 1)
446
447 def test_func_6(self):
448 @types.coroutine
449 def bar():
450 yield 1
451 yield 2
452
453 async def foo():
454 await bar()
455
456 f = foo()
Zachary Ware37ac5902015-05-13 01:03:06 -0500457 self.assertEqual(f.send(None), 1)
458 self.assertEqual(f.send(None), 2)
Yury Selivanov75445082015-05-11 22:57:16 -0400459 with self.assertRaises(StopIteration):
460 f.send(None)
461
462 def test_func_7(self):
463 async def bar():
464 return 10
465
466 def foo():
467 yield from bar()
468
469 with silence_coro_gc(), self.assertRaisesRegex(
470 TypeError,
Yury Selivanov5376ba92015-06-22 12:19:30 -0400471 "cannot 'yield from' a coroutine object in a non-coroutine generator"):
Yury Selivanov75445082015-05-11 22:57:16 -0400472
473 list(foo())
474
475 def test_func_8(self):
476 @types.coroutine
477 def bar():
478 return (yield from foo())
479
480 async def foo():
481 return 'spam'
482
483 self.assertEqual(run_async(bar()), ([], 'spam') )
484
485 def test_func_9(self):
486 async def foo(): pass
487
488 with self.assertWarnsRegex(
489 RuntimeWarning, "coroutine '.*test_func_9.*foo' was never awaited"):
490
491 foo()
492 support.gc_collect()
493
Yury Selivanov5376ba92015-06-22 12:19:30 -0400494 def test_func_10(self):
495 N = 0
496
497 @types.coroutine
498 def gen():
499 nonlocal N
500 try:
501 a = yield
502 yield (a ** 2)
503 except ZeroDivisionError:
504 N += 100
505 raise
506 finally:
507 N += 1
508
509 async def foo():
510 await gen()
511
512 coro = foo()
513 aw = coro.__await__()
514 self.assertIs(aw, iter(aw))
515 next(aw)
516 self.assertEqual(aw.send(10), 100)
517
518 self.assertEqual(N, 0)
519 aw.close()
520 self.assertEqual(N, 1)
521
522 coro = foo()
523 aw = coro.__await__()
524 next(aw)
525 with self.assertRaises(ZeroDivisionError):
526 aw.throw(ZeroDivisionError, None, None)
527 self.assertEqual(N, 102)
528
529 def test_func_11(self):
530 async def func(): pass
531 coro = func()
532 # Test that PyCoro_Type and _PyCoroWrapper_Type types were properly
533 # initialized
534 self.assertIn('__await__', dir(coro))
535 self.assertIn('__iter__', dir(coro.__await__()))
536 self.assertIn('coroutine_wrapper', repr(coro.__await__()))
537 coro.close() # avoid RuntimeWarning
538
539 def test_func_12(self):
540 async def g():
541 i = me.send(None)
542 await foo
543 me = g()
544 with self.assertRaisesRegex(ValueError,
545 "coroutine already executing"):
546 me.send(None)
547
548 def test_func_13(self):
549 async def g():
550 pass
551 with self.assertRaisesRegex(
552 TypeError,
553 "can't send non-None value to a just-started coroutine"):
554
555 g().send('spam')
556
557 def test_func_14(self):
558 @types.coroutine
559 def gen():
560 yield
561 async def coro():
562 try:
563 await gen()
564 except GeneratorExit:
565 await gen()
566 c = coro()
567 c.send(None)
568 with self.assertRaisesRegex(RuntimeError,
569 "coroutine ignored GeneratorExit"):
570 c.close()
571
Yury Selivanov77c96812016-02-13 17:59:05 -0500572 def test_func_15(self):
573 # See http://bugs.python.org/issue25887 for details
574
575 async def spammer():
576 return 'spam'
577 async def reader(coro):
578 return await coro
579
580 spammer_coro = spammer()
581
582 with self.assertRaisesRegex(StopIteration, 'spam'):
583 reader(spammer_coro).send(None)
584
585 with self.assertRaisesRegex(RuntimeError,
586 'cannot reuse already awaited coroutine'):
587 reader(spammer_coro).send(None)
588
589 def test_func_16(self):
590 # See http://bugs.python.org/issue25887 for details
591
592 @types.coroutine
593 def nop():
594 yield
595 async def send():
596 await nop()
597 return 'spam'
598 async def read(coro):
599 await nop()
600 return await coro
601
602 spammer = send()
603
604 reader = read(spammer)
605 reader.send(None)
606 reader.send(None)
607 with self.assertRaisesRegex(Exception, 'ham'):
608 reader.throw(Exception('ham'))
609
610 reader = read(spammer)
611 reader.send(None)
612 with self.assertRaisesRegex(RuntimeError,
613 'cannot reuse already awaited coroutine'):
614 reader.send(None)
615
616 with self.assertRaisesRegex(RuntimeError,
617 'cannot reuse already awaited coroutine'):
618 reader.throw(Exception('wat'))
619
620 def test_func_17(self):
621 # See http://bugs.python.org/issue25887 for details
622
623 async def coroutine():
624 return 'spam'
625
626 coro = coroutine()
627 with self.assertRaisesRegex(StopIteration, 'spam'):
628 coro.send(None)
629
630 with self.assertRaisesRegex(RuntimeError,
631 'cannot reuse already awaited coroutine'):
632 coro.send(None)
633
634 with self.assertRaisesRegex(RuntimeError,
635 'cannot reuse already awaited coroutine'):
636 coro.throw(Exception('wat'))
637
638 # Closing a coroutine shouldn't raise any exception even if it's
639 # already closed/exhausted (similar to generators)
640 coro.close()
641 coro.close()
642
643 def test_func_18(self):
644 # See http://bugs.python.org/issue25887 for details
645
646 async def coroutine():
647 return 'spam'
648
649 coro = coroutine()
650 await_iter = coro.__await__()
651 it = iter(await_iter)
652
653 with self.assertRaisesRegex(StopIteration, 'spam'):
654 it.send(None)
655
656 with self.assertRaisesRegex(RuntimeError,
657 'cannot reuse already awaited coroutine'):
658 it.send(None)
659
660 with self.assertRaisesRegex(RuntimeError,
661 'cannot reuse already awaited coroutine'):
662 # Although the iterator protocol requires iterators to
663 # raise another StopIteration here, we don't want to do
664 # that. In this particular case, the iterator will raise
665 # a RuntimeError, so that 'yield from' and 'await'
666 # expressions will trigger the error, instead of silently
667 # ignoring the call.
668 next(it)
669
670 with self.assertRaisesRegex(RuntimeError,
671 'cannot reuse already awaited coroutine'):
672 it.throw(Exception('wat'))
673
674 with self.assertRaisesRegex(RuntimeError,
675 'cannot reuse already awaited coroutine'):
676 it.throw(Exception('wat'))
677
678 # Closing a coroutine shouldn't raise any exception even if it's
679 # already closed/exhausted (similar to generators)
680 it.close()
681 it.close()
682
683 def test_func_19(self):
684 CHK = 0
685
686 @types.coroutine
687 def foo():
688 nonlocal CHK
689 yield
690 try:
691 yield
692 except GeneratorExit:
693 CHK += 1
694
695 async def coroutine():
696 await foo()
697
698 coro = coroutine()
699
700 coro.send(None)
701 coro.send(None)
702
703 self.assertEqual(CHK, 0)
704 coro.close()
705 self.assertEqual(CHK, 1)
706
707 for _ in range(3):
708 # Closing a coroutine shouldn't raise any exception even if it's
709 # already closed/exhausted (similar to generators)
710 coro.close()
711 self.assertEqual(CHK, 1)
712
Yury Selivanove13f8f32015-07-03 00:23:30 -0400713 def test_cr_await(self):
714 @types.coroutine
715 def a():
716 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_RUNNING)
717 self.assertIsNone(coro_b.cr_await)
718 yield
719 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_RUNNING)
720 self.assertIsNone(coro_b.cr_await)
721
722 async def c():
723 await a()
724
725 async def b():
726 self.assertIsNone(coro_b.cr_await)
727 await c()
728 self.assertIsNone(coro_b.cr_await)
729
730 coro_b = b()
731 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_CREATED)
732 self.assertIsNone(coro_b.cr_await)
733
734 coro_b.send(None)
735 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_SUSPENDED)
736 self.assertEqual(coro_b.cr_await.cr_await.gi_code.co_name, 'a')
737
738 with self.assertRaises(StopIteration):
739 coro_b.send(None) # complete coroutine
740 self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_CLOSED)
741 self.assertIsNone(coro_b.cr_await)
742
Yury Selivanov5376ba92015-06-22 12:19:30 -0400743 def test_corotype_1(self):
744 ct = types.CoroutineType
745 self.assertIn('into coroutine', ct.send.__doc__)
746 self.assertIn('inside coroutine', ct.close.__doc__)
747 self.assertIn('in coroutine', ct.throw.__doc__)
748 self.assertIn('of the coroutine', ct.__dict__['__name__'].__doc__)
749 self.assertIn('of the coroutine', ct.__dict__['__qualname__'].__doc__)
750 self.assertEqual(ct.__name__, 'coroutine')
751
752 async def f(): pass
753 c = f()
754 self.assertIn('coroutine object', repr(c))
755 c.close()
756
Yury Selivanov75445082015-05-11 22:57:16 -0400757 def test_await_1(self):
758
759 async def foo():
760 await 1
761 with self.assertRaisesRegex(TypeError, "object int can.t.*await"):
762 run_async(foo())
763
764 def test_await_2(self):
765 async def foo():
766 await []
767 with self.assertRaisesRegex(TypeError, "object list can.t.*await"):
768 run_async(foo())
769
770 def test_await_3(self):
771 async def foo():
772 await AsyncYieldFrom([1, 2, 3])
773
774 self.assertEqual(run_async(foo()), ([1, 2, 3], None))
Yury Selivanov5376ba92015-06-22 12:19:30 -0400775 self.assertEqual(run_async__await__(foo()), ([1, 2, 3], None))
Yury Selivanov75445082015-05-11 22:57:16 -0400776
777 def test_await_4(self):
778 async def bar():
779 return 42
780
781 async def foo():
782 return await bar()
783
784 self.assertEqual(run_async(foo()), ([], 42))
785
786 def test_await_5(self):
787 class Awaitable:
788 def __await__(self):
789 return
790
791 async def foo():
792 return (await Awaitable())
793
794 with self.assertRaisesRegex(
795 TypeError, "__await__.*returned non-iterator of type"):
796
797 run_async(foo())
798
799 def test_await_6(self):
800 class Awaitable:
801 def __await__(self):
802 return iter([52])
803
804 async def foo():
805 return (await Awaitable())
806
807 self.assertEqual(run_async(foo()), ([52], None))
808
809 def test_await_7(self):
810 class Awaitable:
811 def __await__(self):
812 yield 42
813 return 100
814
815 async def foo():
816 return (await Awaitable())
817
818 self.assertEqual(run_async(foo()), ([42], 100))
819
820 def test_await_8(self):
821 class Awaitable:
822 pass
823
Yury Selivanov8fb307c2015-07-22 13:33:45 +0300824 async def foo(): return await Awaitable()
Yury Selivanov75445082015-05-11 22:57:16 -0400825
826 with self.assertRaisesRegex(
827 TypeError, "object Awaitable can't be used in 'await' expression"):
828
829 run_async(foo())
830
831 def test_await_9(self):
832 def wrap():
833 return bar
834
835 async def bar():
836 return 42
837
838 async def foo():
839 b = bar()
840
841 db = {'b': lambda: wrap}
842
843 class DB:
844 b = wrap
845
846 return (await bar() + await wrap()() + await db['b']()()() +
847 await bar() * 1000 + await DB.b()())
848
849 async def foo2():
850 return -await bar()
851
852 self.assertEqual(run_async(foo()), ([], 42168))
853 self.assertEqual(run_async(foo2()), ([], -42))
854
855 def test_await_10(self):
856 async def baz():
857 return 42
858
859 async def bar():
860 return baz()
861
862 async def foo():
863 return await (await bar())
864
865 self.assertEqual(run_async(foo()), ([], 42))
866
867 def test_await_11(self):
868 def ident(val):
869 return val
870
871 async def bar():
872 return 'spam'
873
874 async def foo():
875 return ident(val=await bar())
876
877 async def foo2():
878 return await bar(), 'ham'
879
880 self.assertEqual(run_async(foo2()), ([], ('spam', 'ham')))
881
882 def test_await_12(self):
883 async def coro():
884 return 'spam'
885
886 class Awaitable:
887 def __await__(self):
888 return coro()
889
890 async def foo():
891 return await Awaitable()
892
893 with self.assertRaisesRegex(
894 TypeError, "__await__\(\) returned a coroutine"):
895
896 run_async(foo())
897
898 def test_await_13(self):
899 class Awaitable:
900 def __await__(self):
901 return self
902
903 async def foo():
904 return await Awaitable()
905
906 with self.assertRaisesRegex(
907 TypeError, "__await__.*returned non-iterator of type"):
908
909 run_async(foo())
910
Yury Selivanovf2701522015-07-01 12:29:55 -0400911 def test_await_14(self):
912 class Wrapper:
913 # Forces the interpreter to use CoroutineType.__await__
914 def __init__(self, coro):
915 assert coro.__class__ is types.CoroutineType
916 self.coro = coro
917 def __await__(self):
918 return self.coro.__await__()
919
920 class FutureLike:
921 def __await__(self):
922 return (yield)
923
924 class Marker(Exception):
925 pass
926
927 async def coro1():
928 try:
929 return await FutureLike()
930 except ZeroDivisionError:
931 raise Marker
932 async def coro2():
933 return await Wrapper(coro1())
934
935 c = coro2()
936 c.send(None)
937 with self.assertRaisesRegex(StopIteration, 'spam'):
938 c.send('spam')
939
940 c = coro2()
941 c.send(None)
942 with self.assertRaises(Marker):
943 c.throw(ZeroDivisionError)
944
Yury Selivanovc724bae2016-03-02 11:30:46 -0500945 def test_await_15(self):
946 @types.coroutine
947 def nop():
948 yield
949
950 async def coroutine():
951 await nop()
952
953 async def waiter(coro):
954 await coro
955
956 coro = coroutine()
957 coro.send(None)
958
959 with self.assertRaisesRegex(RuntimeError,
960 "coroutine is being awaited already"):
961 waiter(coro).send(None)
962
Yury Selivanov75445082015-05-11 22:57:16 -0400963 def test_with_1(self):
964 class Manager:
965 def __init__(self, name):
966 self.name = name
967
968 async def __aenter__(self):
969 await AsyncYieldFrom(['enter-1-' + self.name,
970 'enter-2-' + self.name])
971 return self
972
973 async def __aexit__(self, *args):
974 await AsyncYieldFrom(['exit-1-' + self.name,
975 'exit-2-' + self.name])
976
977 if self.name == 'B':
978 return True
979
980
981 async def foo():
982 async with Manager("A") as a, Manager("B") as b:
983 await AsyncYieldFrom([('managers', a.name, b.name)])
984 1/0
985
986 f = foo()
987 result, _ = run_async(f)
988
989 self.assertEqual(
990 result, ['enter-1-A', 'enter-2-A', 'enter-1-B', 'enter-2-B',
991 ('managers', 'A', 'B'),
992 'exit-1-B', 'exit-2-B', 'exit-1-A', 'exit-2-A']
993 )
994
995 async def foo():
996 async with Manager("A") as a, Manager("C") as c:
997 await AsyncYieldFrom([('managers', a.name, c.name)])
998 1/0
999
1000 with self.assertRaises(ZeroDivisionError):
1001 run_async(foo())
1002
1003 def test_with_2(self):
1004 class CM:
1005 def __aenter__(self):
1006 pass
1007
1008 async def foo():
1009 async with CM():
1010 pass
1011
1012 with self.assertRaisesRegex(AttributeError, '__aexit__'):
1013 run_async(foo())
1014
1015 def test_with_3(self):
1016 class CM:
1017 def __aexit__(self):
1018 pass
1019
1020 async def foo():
1021 async with CM():
1022 pass
1023
1024 with self.assertRaisesRegex(AttributeError, '__aenter__'):
1025 run_async(foo())
1026
1027 def test_with_4(self):
1028 class CM:
1029 def __enter__(self):
1030 pass
1031
1032 def __exit__(self):
1033 pass
1034
1035 async def foo():
1036 async with CM():
1037 pass
1038
1039 with self.assertRaisesRegex(AttributeError, '__aexit__'):
1040 run_async(foo())
1041
1042 def test_with_5(self):
1043 # While this test doesn't make a lot of sense,
1044 # it's a regression test for an early bug with opcodes
1045 # generation
1046
1047 class CM:
1048 async def __aenter__(self):
1049 return self
1050
1051 async def __aexit__(self, *exc):
1052 pass
1053
1054 async def func():
1055 async with CM():
1056 assert (1, ) == 1
1057
1058 with self.assertRaises(AssertionError):
1059 run_async(func())
1060
1061 def test_with_6(self):
1062 class CM:
1063 def __aenter__(self):
1064 return 123
1065
1066 def __aexit__(self, *e):
1067 return 456
1068
1069 async def foo():
1070 async with CM():
1071 pass
1072
1073 with self.assertRaisesRegex(
1074 TypeError, "object int can't be used in 'await' expression"):
1075 # it's important that __aexit__ wasn't called
1076 run_async(foo())
1077
1078 def test_with_7(self):
1079 class CM:
1080 async def __aenter__(self):
1081 return self
1082
1083 def __aexit__(self, *e):
Nick Coghlanbaaadbf2015-05-13 15:54:02 +10001084 return 444
Yury Selivanov75445082015-05-11 22:57:16 -04001085
1086 async def foo():
1087 async with CM():
Nick Coghlanbaaadbf2015-05-13 15:54:02 +10001088 1/0
1089
1090 try:
1091 run_async(foo())
1092 except TypeError as exc:
1093 self.assertRegex(
1094 exc.args[0], "object int can't be used in 'await' expression")
1095 self.assertTrue(exc.__context__ is not None)
1096 self.assertTrue(isinstance(exc.__context__, ZeroDivisionError))
1097 else:
1098 self.fail('invalid asynchronous context manager did not fail')
1099
1100
1101 def test_with_8(self):
1102 CNT = 0
1103
1104 class CM:
1105 async def __aenter__(self):
1106 return self
1107
1108 def __aexit__(self, *e):
1109 return 456
1110
1111 async def foo():
1112 nonlocal CNT
1113 async with CM():
1114 CNT += 1
1115
Yury Selivanov75445082015-05-11 22:57:16 -04001116
1117 with self.assertRaisesRegex(
1118 TypeError, "object int can't be used in 'await' expression"):
1119
1120 run_async(foo())
1121
Nick Coghlanbaaadbf2015-05-13 15:54:02 +10001122 self.assertEqual(CNT, 1)
1123
1124
1125 def test_with_9(self):
1126 CNT = 0
1127
1128 class CM:
1129 async def __aenter__(self):
1130 return self
1131
1132 async def __aexit__(self, *e):
1133 1/0
1134
1135 async def foo():
1136 nonlocal CNT
1137 async with CM():
1138 CNT += 1
1139
1140 with self.assertRaises(ZeroDivisionError):
1141 run_async(foo())
1142
1143 self.assertEqual(CNT, 1)
1144
1145 def test_with_10(self):
1146 CNT = 0
1147
1148 class CM:
1149 async def __aenter__(self):
1150 return self
1151
1152 async def __aexit__(self, *e):
1153 1/0
1154
1155 async def foo():
1156 nonlocal CNT
1157 async with CM():
1158 async with CM():
1159 raise RuntimeError
1160
1161 try:
1162 run_async(foo())
1163 except ZeroDivisionError as exc:
1164 self.assertTrue(exc.__context__ is not None)
1165 self.assertTrue(isinstance(exc.__context__, ZeroDivisionError))
1166 self.assertTrue(isinstance(exc.__context__.__context__,
1167 RuntimeError))
1168 else:
1169 self.fail('exception from __aexit__ did not propagate')
1170
1171 def test_with_11(self):
1172 CNT = 0
1173
1174 class CM:
1175 async def __aenter__(self):
1176 raise NotImplementedError
1177
1178 async def __aexit__(self, *e):
1179 1/0
1180
1181 async def foo():
1182 nonlocal CNT
1183 async with CM():
1184 raise RuntimeError
1185
1186 try:
1187 run_async(foo())
1188 except NotImplementedError as exc:
1189 self.assertTrue(exc.__context__ is None)
1190 else:
1191 self.fail('exception from __aenter__ did not propagate')
1192
1193 def test_with_12(self):
1194 CNT = 0
1195
1196 class CM:
1197 async def __aenter__(self):
1198 return self
1199
1200 async def __aexit__(self, *e):
1201 return True
1202
1203 async def foo():
1204 nonlocal CNT
1205 async with CM() as cm:
1206 self.assertIs(cm.__class__, CM)
1207 raise RuntimeError
1208
1209 run_async(foo())
1210
Yury Selivanov9113dc72015-05-13 16:49:35 -04001211 def test_with_13(self):
1212 CNT = 0
1213
1214 class CM:
1215 async def __aenter__(self):
1216 1/0
1217
1218 async def __aexit__(self, *e):
1219 return True
1220
1221 async def foo():
1222 nonlocal CNT
1223 CNT += 1
1224 async with CM():
1225 CNT += 1000
1226 CNT += 10000
1227
1228 with self.assertRaises(ZeroDivisionError):
1229 run_async(foo())
1230 self.assertEqual(CNT, 1)
1231
Yury Selivanov75445082015-05-11 22:57:16 -04001232 def test_for_1(self):
1233 aiter_calls = 0
1234
1235 class AsyncIter:
1236 def __init__(self):
1237 self.i = 0
1238
1239 async def __aiter__(self):
1240 nonlocal aiter_calls
1241 aiter_calls += 1
1242 return self
1243
1244 async def __anext__(self):
1245 self.i += 1
1246
1247 if not (self.i % 10):
1248 await AsyncYield(self.i * 10)
1249
1250 if self.i > 100:
1251 raise StopAsyncIteration
1252
1253 return self.i, self.i
1254
1255
1256 buffer = []
1257 async def test1():
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001258 with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
1259 async for i1, i2 in AsyncIter():
1260 buffer.append(i1 + i2)
Yury Selivanov75445082015-05-11 22:57:16 -04001261
1262 yielded, _ = run_async(test1())
1263 # Make sure that __aiter__ was called only once
1264 self.assertEqual(aiter_calls, 1)
1265 self.assertEqual(yielded, [i * 100 for i in range(1, 11)])
1266 self.assertEqual(buffer, [i*2 for i in range(1, 101)])
1267
1268
1269 buffer = []
1270 async def test2():
1271 nonlocal buffer
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001272 with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
1273 async for i in AsyncIter():
1274 buffer.append(i[0])
1275 if i[0] == 20:
1276 break
1277 else:
1278 buffer.append('what?')
Yury Selivanov75445082015-05-11 22:57:16 -04001279 buffer.append('end')
1280
1281 yielded, _ = run_async(test2())
1282 # Make sure that __aiter__ was called only once
1283 self.assertEqual(aiter_calls, 2)
1284 self.assertEqual(yielded, [100, 200])
1285 self.assertEqual(buffer, [i for i in range(1, 21)] + ['end'])
1286
1287
1288 buffer = []
1289 async def test3():
1290 nonlocal buffer
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001291 with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
1292 async for i in AsyncIter():
1293 if i[0] > 20:
1294 continue
1295 buffer.append(i[0])
1296 else:
1297 buffer.append('what?')
Yury Selivanov75445082015-05-11 22:57:16 -04001298 buffer.append('end')
1299
1300 yielded, _ = run_async(test3())
1301 # Make sure that __aiter__ was called only once
1302 self.assertEqual(aiter_calls, 3)
1303 self.assertEqual(yielded, [i * 100 for i in range(1, 11)])
1304 self.assertEqual(buffer, [i for i in range(1, 21)] +
1305 ['what?', 'end'])
1306
1307 def test_for_2(self):
1308 tup = (1, 2, 3)
1309 refs_before = sys.getrefcount(tup)
1310
1311 async def foo():
1312 async for i in tup:
1313 print('never going to happen')
1314
1315 with self.assertRaisesRegex(
1316 TypeError, "async for' requires an object.*__aiter__.*tuple"):
1317
1318 run_async(foo())
1319
1320 self.assertEqual(sys.getrefcount(tup), refs_before)
1321
1322 def test_for_3(self):
1323 class I:
1324 def __aiter__(self):
1325 return self
1326
1327 aiter = I()
1328 refs_before = sys.getrefcount(aiter)
1329
1330 async def foo():
1331 async for i in aiter:
1332 print('never going to happen')
1333
1334 with self.assertRaisesRegex(
1335 TypeError,
1336 "async for' received an invalid object.*__aiter.*\: I"):
1337
1338 run_async(foo())
1339
1340 self.assertEqual(sys.getrefcount(aiter), refs_before)
1341
1342 def test_for_4(self):
1343 class I:
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001344 def __aiter__(self):
Yury Selivanov75445082015-05-11 22:57:16 -04001345 return self
1346
1347 def __anext__(self):
1348 return ()
1349
1350 aiter = I()
1351 refs_before = sys.getrefcount(aiter)
1352
1353 async def foo():
1354 async for i in aiter:
1355 print('never going to happen')
1356
1357 with self.assertRaisesRegex(
1358 TypeError,
1359 "async for' received an invalid object.*__anext__.*tuple"):
1360
1361 run_async(foo())
1362
1363 self.assertEqual(sys.getrefcount(aiter), refs_before)
1364
1365 def test_for_5(self):
1366 class I:
1367 async def __aiter__(self):
1368 return self
1369
1370 def __anext__(self):
1371 return 123
1372
1373 async def foo():
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001374 with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
1375 async for i in I():
1376 print('never going to happen')
Yury Selivanov75445082015-05-11 22:57:16 -04001377
1378 with self.assertRaisesRegex(
1379 TypeError,
1380 "async for' received an invalid object.*__anext.*int"):
1381
1382 run_async(foo())
1383
1384 def test_for_6(self):
1385 I = 0
1386
1387 class Manager:
1388 async def __aenter__(self):
1389 nonlocal I
1390 I += 10000
1391
1392 async def __aexit__(self, *args):
1393 nonlocal I
1394 I += 100000
1395
1396 class Iterable:
1397 def __init__(self):
1398 self.i = 0
1399
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001400 def __aiter__(self):
Yury Selivanov75445082015-05-11 22:57:16 -04001401 return self
1402
1403 async def __anext__(self):
1404 if self.i > 10:
1405 raise StopAsyncIteration
1406 self.i += 1
1407 return self.i
1408
1409 ##############
1410
1411 manager = Manager()
1412 iterable = Iterable()
1413 mrefs_before = sys.getrefcount(manager)
1414 irefs_before = sys.getrefcount(iterable)
1415
1416 async def main():
1417 nonlocal I
1418
1419 async with manager:
1420 async for i in iterable:
1421 I += 1
1422 I += 1000
1423
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001424 with warnings.catch_warnings():
1425 warnings.simplefilter("error")
Martin Panter70c502a2016-06-12 06:14:03 +00001426 # Test that __aiter__ that returns an asynchronous iterator
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001427 # directly does not throw any warnings.
1428 run_async(main())
Yury Selivanov75445082015-05-11 22:57:16 -04001429 self.assertEqual(I, 111011)
1430
1431 self.assertEqual(sys.getrefcount(manager), mrefs_before)
1432 self.assertEqual(sys.getrefcount(iterable), irefs_before)
1433
1434 ##############
1435
1436 async def main():
1437 nonlocal I
1438
1439 async with Manager():
1440 async for i in Iterable():
1441 I += 1
1442 I += 1000
1443
1444 async with Manager():
1445 async for i in Iterable():
1446 I += 1
1447 I += 1000
1448
1449 run_async(main())
1450 self.assertEqual(I, 333033)
1451
1452 ##############
1453
1454 async def main():
1455 nonlocal I
1456
1457 async with Manager():
1458 I += 100
1459 async for i in Iterable():
1460 I += 1
1461 else:
1462 I += 10000000
1463 I += 1000
1464
1465 async with Manager():
1466 I += 100
1467 async for i in Iterable():
1468 I += 1
1469 else:
1470 I += 10000000
1471 I += 1000
1472
1473 run_async(main())
1474 self.assertEqual(I, 20555255)
1475
Yury Selivanov9113dc72015-05-13 16:49:35 -04001476 def test_for_7(self):
1477 CNT = 0
1478 class AI:
1479 async def __aiter__(self):
1480 1/0
1481 async def foo():
1482 nonlocal CNT
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001483 with self.assertWarnsRegex(PendingDeprecationWarning, "legacy"):
1484 async for i in AI():
1485 CNT += 1
Yury Selivanov9113dc72015-05-13 16:49:35 -04001486 CNT += 10
1487 with self.assertRaises(ZeroDivisionError):
1488 run_async(foo())
1489 self.assertEqual(CNT, 0)
1490
Yury Selivanova6f6edb2016-06-09 15:08:31 -04001491 def test_for_8(self):
1492 CNT = 0
1493 class AI:
1494 def __aiter__(self):
1495 1/0
1496 async def foo():
1497 nonlocal CNT
1498 async for i in AI():
1499 CNT += 1
1500 CNT += 10
1501 with self.assertRaises(ZeroDivisionError):
1502 with warnings.catch_warnings():
1503 warnings.simplefilter("error")
1504 # Test that if __aiter__ raises an exception it propagates
1505 # without any kind of warning.
1506 run_async(foo())
1507 self.assertEqual(CNT, 0)
1508
1509 def test_for_9(self):
1510 # Test that PendingDeprecationWarning can safely be converted into
1511 # an exception (__aiter__ should not have a chance to raise
1512 # a ZeroDivisionError.)
1513 class AI:
1514 async def __aiter__(self):
1515 1/0
1516 async def foo():
1517 async for i in AI():
1518 pass
1519
1520 with self.assertRaises(PendingDeprecationWarning):
1521 with warnings.catch_warnings():
1522 warnings.simplefilter("error")
1523 run_async(foo())
1524
1525 def test_for_10(self):
1526 # Test that PendingDeprecationWarning can safely be converted into
1527 # an exception.
1528 class AI:
1529 async def __aiter__(self):
1530 pass
1531 async def foo():
1532 async for i in AI():
1533 pass
1534
1535 with self.assertRaises(PendingDeprecationWarning):
1536 with warnings.catch_warnings():
1537 warnings.simplefilter("error")
1538 run_async(foo())
1539
Serhiy Storchaka609a2e12015-11-12 11:31:51 +02001540 def test_copy(self):
1541 async def func(): pass
1542 coro = func()
1543 with self.assertRaises(TypeError):
1544 copy.copy(coro)
1545
1546 aw = coro.__await__()
1547 try:
1548 with self.assertRaises(TypeError):
1549 copy.copy(aw)
1550 finally:
1551 aw.close()
1552
1553 def test_pickle(self):
1554 async def func(): pass
1555 coro = func()
1556 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1557 with self.assertRaises((TypeError, pickle.PicklingError)):
1558 pickle.dumps(coro, proto)
1559
1560 aw = coro.__await__()
1561 try:
1562 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1563 with self.assertRaises((TypeError, pickle.PicklingError)):
1564 pickle.dumps(aw, proto)
1565 finally:
1566 aw.close()
1567
Benjamin Peterson2f40ed42016-09-05 10:14:54 -07001568 def test_fatal_coro_warning(self):
1569 # Issue 27811
1570 async def func(): pass
1571 with warnings.catch_warnings():
1572 warnings.filterwarnings("error")
1573 func()
1574 support.gc_collect()
1575
Yury Selivanov75445082015-05-11 22:57:16 -04001576
1577class CoroAsyncIOCompatTest(unittest.TestCase):
1578
1579 def test_asyncio_1(self):
Victor Stinnerb45c0f72015-10-11 10:10:31 +02001580 # asyncio cannot be imported when Python is compiled without thread
1581 # support
Victor Stinner718c9842015-10-11 10:53:15 +02001582 asyncio = support.import_module('asyncio')
Yury Selivanov75445082015-05-11 22:57:16 -04001583
1584 class MyException(Exception):
1585 pass
1586
1587 buffer = []
1588
1589 class CM:
1590 async def __aenter__(self):
1591 buffer.append(1)
1592 await asyncio.sleep(0.01)
1593 buffer.append(2)
1594 return self
1595
1596 async def __aexit__(self, exc_type, exc_val, exc_tb):
1597 await asyncio.sleep(0.01)
1598 buffer.append(exc_type.__name__)
1599
1600 async def f():
1601 async with CM() as c:
1602 await asyncio.sleep(0.01)
1603 raise MyException
1604 buffer.append('unreachable')
1605
Yury Selivanovfdba8382015-05-12 14:28:08 -04001606 loop = asyncio.new_event_loop()
1607 asyncio.set_event_loop(loop)
Yury Selivanov75445082015-05-11 22:57:16 -04001608 try:
1609 loop.run_until_complete(f())
1610 except MyException:
1611 pass
1612 finally:
1613 loop.close()
Yury Selivanovfdba8382015-05-12 14:28:08 -04001614 asyncio.set_event_loop(None)
Yury Selivanov75445082015-05-11 22:57:16 -04001615
1616 self.assertEqual(buffer, [1, 2, 'MyException'])
1617
1618
1619class SysSetCoroWrapperTest(unittest.TestCase):
1620
1621 def test_set_wrapper_1(self):
1622 async def foo():
1623 return 'spam'
1624
1625 wrapped = None
1626 def wrap(gen):
1627 nonlocal wrapped
1628 wrapped = gen
1629 return gen
1630
1631 self.assertIsNone(sys.get_coroutine_wrapper())
1632
1633 sys.set_coroutine_wrapper(wrap)
1634 self.assertIs(sys.get_coroutine_wrapper(), wrap)
1635 try:
1636 f = foo()
1637 self.assertTrue(wrapped)
1638
1639 self.assertEqual(run_async(f), ([], 'spam'))
1640 finally:
1641 sys.set_coroutine_wrapper(None)
1642
1643 self.assertIsNone(sys.get_coroutine_wrapper())
1644
1645 wrapped = None
1646 with silence_coro_gc():
1647 foo()
1648 self.assertFalse(wrapped)
1649
1650 def test_set_wrapper_2(self):
1651 self.assertIsNone(sys.get_coroutine_wrapper())
1652 with self.assertRaisesRegex(TypeError, "callable expected, got int"):
1653 sys.set_coroutine_wrapper(1)
1654 self.assertIsNone(sys.get_coroutine_wrapper())
1655
Yury Selivanovaab3c4a2015-06-02 18:43:51 -04001656 def test_set_wrapper_3(self):
1657 async def foo():
1658 return 'spam'
1659
1660 def wrapper(coro):
1661 async def wrap(coro):
1662 return await coro
1663 return wrap(coro)
1664
1665 sys.set_coroutine_wrapper(wrapper)
1666 try:
Yury Selivanov94c22632015-06-04 10:16:51 -04001667 with silence_coro_gc(), self.assertRaisesRegex(
Yury Selivanovaab3c4a2015-06-02 18:43:51 -04001668 RuntimeError,
1669 "coroutine wrapper.*\.wrapper at 0x.*attempted to "
Yury Selivanov94c22632015-06-04 10:16:51 -04001670 "recursively wrap .* wrap .*"):
Yury Selivanovaab3c4a2015-06-02 18:43:51 -04001671
1672 foo()
1673 finally:
1674 sys.set_coroutine_wrapper(None)
1675
Yury Selivanov5376ba92015-06-22 12:19:30 -04001676 def test_set_wrapper_4(self):
1677 @types.coroutine
1678 def foo():
1679 return 'spam'
1680
1681 wrapped = None
1682 def wrap(gen):
1683 nonlocal wrapped
1684 wrapped = gen
1685 return gen
1686
1687 sys.set_coroutine_wrapper(wrap)
1688 try:
1689 foo()
1690 self.assertIs(
1691 wrapped, None,
1692 "generator-based coroutine was wrapped via "
1693 "sys.set_coroutine_wrapper")
1694 finally:
1695 sys.set_coroutine_wrapper(None)
1696
Yury Selivanov75445082015-05-11 22:57:16 -04001697
1698class CAPITest(unittest.TestCase):
1699
1700 def test_tp_await_1(self):
1701 from _testcapi import awaitType as at
1702
1703 async def foo():
1704 future = at(iter([1]))
1705 return (await future)
1706
1707 self.assertEqual(foo().send(None), 1)
1708
1709 def test_tp_await_2(self):
1710 # Test tp_await to __await__ mapping
1711 from _testcapi import awaitType as at
1712 future = at(iter([1]))
1713 self.assertEqual(next(future.__await__()), 1)
1714
1715 def test_tp_await_3(self):
1716 from _testcapi import awaitType as at
1717
1718 async def foo():
1719 future = at(1)
1720 return (await future)
1721
1722 with self.assertRaisesRegex(
1723 TypeError, "__await__.*returned non-iterator of type 'int'"):
1724 self.assertEqual(foo().send(None), 1)
1725
1726
Yury Selivanov75445082015-05-11 22:57:16 -04001727if __name__=="__main__":
Zachary Ware37ac5902015-05-13 01:03:06 -05001728 unittest.main()