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