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