blob: 77c15c02bc8914fb36ea9c7a622990c4b5938155 [file] [log] [blame]
Yury Selivanoveb636452016-09-08 22:01:51 -07001import inspect
Yury Selivanoveb636452016-09-08 22:01:51 -07002import types
3import unittest
4
Hai Shi46605972020-08-04 00:49:18 +08005from test.support.import_helper import import_module
Martin Panter94332cb2016-10-20 05:10:44 +00006asyncio = import_module("asyncio")
7
Yury Selivanoveb636452016-09-08 22:01:51 -07008
9class AwaitException(Exception):
10 pass
11
12
13@types.coroutine
14def awaitable(*, throw=False):
15 if throw:
16 yield ('throw',)
17 else:
18 yield ('result',)
19
20
21def run_until_complete(coro):
22 exc = False
23 while True:
24 try:
25 if exc:
26 exc = False
27 fut = coro.throw(AwaitException)
28 else:
29 fut = coro.send(None)
30 except StopIteration as ex:
31 return ex.args[0]
32
33 if fut == ('throw',):
34 exc = True
35
36
37def to_list(gen):
38 async def iterate():
39 res = []
40 async for i in gen:
41 res.append(i)
42 return res
43
44 return run_until_complete(iterate())
45
46
47class AsyncGenSyntaxTest(unittest.TestCase):
48
49 def test_async_gen_syntax_01(self):
50 code = '''async def foo():
51 await abc
52 yield from 123
53 '''
54
55 with self.assertRaisesRegex(SyntaxError, 'yield from.*inside async'):
56 exec(code, {}, {})
57
58 def test_async_gen_syntax_02(self):
59 code = '''async def foo():
60 yield from 123
61 '''
62
63 with self.assertRaisesRegex(SyntaxError, 'yield from.*inside async'):
64 exec(code, {}, {})
65
66 def test_async_gen_syntax_03(self):
67 code = '''async def foo():
68 await abc
69 yield
70 return 123
71 '''
72
73 with self.assertRaisesRegex(SyntaxError, 'return.*value.*async gen'):
74 exec(code, {}, {})
75
76 def test_async_gen_syntax_04(self):
77 code = '''async def foo():
78 yield
79 return 123
80 '''
81
82 with self.assertRaisesRegex(SyntaxError, 'return.*value.*async gen'):
83 exec(code, {}, {})
84
85 def test_async_gen_syntax_05(self):
86 code = '''async def foo():
87 if 0:
88 yield
89 return 12
90 '''
91
92 with self.assertRaisesRegex(SyntaxError, 'return.*value.*async gen'):
93 exec(code, {}, {})
94
95
96class AsyncGenTest(unittest.TestCase):
97
98 def compare_generators(self, sync_gen, async_gen):
99 def sync_iterate(g):
100 res = []
101 while True:
102 try:
103 res.append(g.__next__())
104 except StopIteration:
105 res.append('STOP')
106 break
107 except Exception as ex:
108 res.append(str(type(ex)))
109 return res
110
111 def async_iterate(g):
112 res = []
113 while True:
Yury Selivanov52698c72018-06-07 20:31:26 -0400114 an = g.__anext__()
115 try:
116 while True:
117 try:
118 an.__next__()
119 except StopIteration as ex:
120 if ex.args:
121 res.append(ex.args[0])
122 break
123 else:
124 res.append('EMPTY StopIteration')
125 break
126 except StopAsyncIteration:
127 raise
128 except Exception as ex:
129 res.append(str(type(ex)))
130 break
131 except StopAsyncIteration:
132 res.append('STOP')
133 break
134 return res
135
Yury Selivanoveb636452016-09-08 22:01:51 -0700136 sync_gen_result = sync_iterate(sync_gen)
137 async_gen_result = async_iterate(async_gen)
138 self.assertEqual(sync_gen_result, async_gen_result)
139 return async_gen_result
140
141 def test_async_gen_iteration_01(self):
142 async def gen():
143 await awaitable()
144 a = yield 123
145 self.assertIs(a, None)
146 await awaitable()
147 yield 456
148 await awaitable()
149 yield 789
150
151 self.assertEqual(to_list(gen()), [123, 456, 789])
152
153 def test_async_gen_iteration_02(self):
154 async def gen():
155 await awaitable()
156 yield 123
157 await awaitable()
158
159 g = gen()
160 ai = g.__aiter__()
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700161
162 an = ai.__anext__()
163 self.assertEqual(an.__next__(), ('result',))
Yury Selivanoveb636452016-09-08 22:01:51 -0700164
165 try:
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700166 an.__next__()
Yury Selivanoveb636452016-09-08 22:01:51 -0700167 except StopIteration as ex:
168 self.assertEqual(ex.args[0], 123)
169 else:
170 self.fail('StopIteration was not raised')
171
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700172 an = ai.__anext__()
173 self.assertEqual(an.__next__(), ('result',))
Yury Selivanoveb636452016-09-08 22:01:51 -0700174
175 try:
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700176 an.__next__()
Yury Selivanoveb636452016-09-08 22:01:51 -0700177 except StopAsyncIteration as ex:
178 self.assertFalse(ex.args)
179 else:
180 self.fail('StopAsyncIteration was not raised')
181
182 def test_async_gen_exception_03(self):
183 async def gen():
184 await awaitable()
185 yield 123
186 await awaitable(throw=True)
187 yield 456
188
189 with self.assertRaises(AwaitException):
190 to_list(gen())
191
192 def test_async_gen_exception_04(self):
193 async def gen():
194 await awaitable()
195 yield 123
196 1 / 0
197
198 g = gen()
199 ai = g.__aiter__()
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700200 an = ai.__anext__()
201 self.assertEqual(an.__next__(), ('result',))
Yury Selivanoveb636452016-09-08 22:01:51 -0700202
203 try:
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700204 an.__next__()
Yury Selivanoveb636452016-09-08 22:01:51 -0700205 except StopIteration as ex:
206 self.assertEqual(ex.args[0], 123)
207 else:
208 self.fail('StopIteration was not raised')
209
210 with self.assertRaises(ZeroDivisionError):
211 ai.__anext__().__next__()
212
213 def test_async_gen_exception_05(self):
214 async def gen():
215 yield 123
216 raise StopAsyncIteration
217
218 with self.assertRaisesRegex(RuntimeError,
219 'async generator.*StopAsyncIteration'):
220 to_list(gen())
221
222 def test_async_gen_exception_06(self):
223 async def gen():
224 yield 123
225 raise StopIteration
226
227 with self.assertRaisesRegex(RuntimeError,
228 'async generator.*StopIteration'):
229 to_list(gen())
230
231 def test_async_gen_exception_07(self):
232 def sync_gen():
233 try:
234 yield 1
235 1 / 0
236 finally:
237 yield 2
238 yield 3
239
240 yield 100
241
242 async def async_gen():
243 try:
244 yield 1
245 1 / 0
246 finally:
247 yield 2
248 yield 3
249
250 yield 100
251
252 self.compare_generators(sync_gen(), async_gen())
253
254 def test_async_gen_exception_08(self):
255 def sync_gen():
256 try:
257 yield 1
258 finally:
259 yield 2
260 1 / 0
261 yield 3
262
263 yield 100
264
265 async def async_gen():
266 try:
267 yield 1
268 await awaitable()
269 finally:
270 await awaitable()
271 yield 2
272 1 / 0
273 yield 3
274
275 yield 100
276
277 self.compare_generators(sync_gen(), async_gen())
278
279 def test_async_gen_exception_09(self):
280 def sync_gen():
281 try:
282 yield 1
283 1 / 0
284 finally:
285 yield 2
286 yield 3
287
288 yield 100
289
290 async def async_gen():
291 try:
292 await awaitable()
293 yield 1
294 1 / 0
295 finally:
296 yield 2
297 await awaitable()
298 yield 3
299
300 yield 100
301
302 self.compare_generators(sync_gen(), async_gen())
303
304 def test_async_gen_exception_10(self):
305 async def gen():
306 yield 123
307 with self.assertRaisesRegex(TypeError,
308 "non-None value .* async generator"):
309 gen().__anext__().send(100)
310
Yury Selivanov52698c72018-06-07 20:31:26 -0400311 def test_async_gen_exception_11(self):
312 def sync_gen():
313 yield 10
314 yield 20
315
316 def sync_gen_wrapper():
317 yield 1
318 sg = sync_gen()
319 sg.send(None)
320 try:
321 sg.throw(GeneratorExit())
322 except GeneratorExit:
323 yield 2
324 yield 3
325
326 async def async_gen():
327 yield 10
328 yield 20
329
330 async def async_gen_wrapper():
331 yield 1
332 asg = async_gen()
333 await asg.asend(None)
334 try:
335 await asg.athrow(GeneratorExit())
336 except GeneratorExit:
337 yield 2
338 yield 3
339
340 self.compare_generators(sync_gen_wrapper(), async_gen_wrapper())
341
Yury Selivanoveb636452016-09-08 22:01:51 -0700342 def test_async_gen_api_01(self):
343 async def gen():
344 yield 123
345
346 g = gen()
347
348 self.assertEqual(g.__name__, 'gen')
349 g.__name__ = '123'
350 self.assertEqual(g.__name__, '123')
351
352 self.assertIn('.gen', g.__qualname__)
353 g.__qualname__ = '123'
354 self.assertEqual(g.__qualname__, '123')
355
356 self.assertIsNone(g.ag_await)
357 self.assertIsInstance(g.ag_frame, types.FrameType)
358 self.assertFalse(g.ag_running)
359 self.assertIsInstance(g.ag_code, types.CodeType)
360
361 self.assertTrue(inspect.isawaitable(g.aclose()))
362
363
364class AsyncGenAsyncioTest(unittest.TestCase):
365
366 def setUp(self):
367 self.loop = asyncio.new_event_loop()
368 asyncio.set_event_loop(None)
369
370 def tearDown(self):
371 self.loop.close()
372 self.loop = None
Brett Cannon8425de42018-06-01 20:34:09 -0700373 asyncio.set_event_loop_policy(None)
Yury Selivanoveb636452016-09-08 22:01:51 -0700374
Dennis Sweeneydfb45322021-04-11 00:51:35 -0400375 def check_async_iterator_anext(self, ait_class):
376 g = ait_class()
Joshua Bronsonf0a6fde2021-03-23 18:47:21 -0400377 async def consume():
378 results = []
379 results.append(await anext(g))
380 results.append(await anext(g))
381 results.append(await anext(g, 'buckle my shoe'))
382 return results
383 res = self.loop.run_until_complete(consume())
384 self.assertEqual(res, [1, 2, 'buckle my shoe'])
385 with self.assertRaises(StopAsyncIteration):
386 self.loop.run_until_complete(consume())
387
Dennis Sweeneydfb45322021-04-11 00:51:35 -0400388 async def test_2():
389 g1 = ait_class()
390 self.assertEqual(await anext(g1), 1)
391 self.assertEqual(await anext(g1), 2)
392 with self.assertRaises(StopAsyncIteration):
393 await anext(g1)
394 with self.assertRaises(StopAsyncIteration):
395 await anext(g1)
396
397 g2 = ait_class()
398 self.assertEqual(await anext(g2, "default"), 1)
399 self.assertEqual(await anext(g2, "default"), 2)
400 self.assertEqual(await anext(g2, "default"), "default")
401 self.assertEqual(await anext(g2, "default"), "default")
402
403 return "completed"
404
405 result = self.loop.run_until_complete(test_2())
406 self.assertEqual(result, "completed")
407
408 def test_async_generator_anext(self):
409 async def agen():
410 yield 1
411 yield 2
412 self.check_async_iterator_anext(agen)
413
414 def test_python_async_iterator_anext(self):
415 class MyAsyncIter:
416 """Asynchronously yield 1, then 2."""
417 def __init__(self):
418 self.yielded = 0
419 def __aiter__(self):
420 return self
421 async def __anext__(self):
422 if self.yielded >= 2:
423 raise StopAsyncIteration()
424 else:
425 self.yielded += 1
426 return self.yielded
427 self.check_async_iterator_anext(MyAsyncIter)
428
429 def test_python_async_iterator_types_coroutine_anext(self):
430 import types
431 class MyAsyncIterWithTypesCoro:
432 """Asynchronously yield 1, then 2."""
433 def __init__(self):
434 self.yielded = 0
435 def __aiter__(self):
436 return self
437 @types.coroutine
438 def __anext__(self):
439 if False:
440 yield "this is a generator-based coroutine"
441 if self.yielded >= 2:
442 raise StopAsyncIteration()
443 else:
444 self.yielded += 1
445 return self.yielded
446 self.check_async_iterator_anext(MyAsyncIterWithTypesCoro)
447
Joshua Bronsonf0a6fde2021-03-23 18:47:21 -0400448 def test_async_gen_aiter(self):
449 async def gen():
450 yield 1
451 yield 2
452 g = gen()
453 async def consume():
454 return [i async for i in aiter(g)]
455 res = self.loop.run_until_complete(consume())
456 self.assertEqual(res, [1, 2])
457
458 def test_async_gen_aiter_class(self):
459 results = []
460 class Gen:
461 async def __aiter__(self):
462 yield 1
463 yield 2
464 g = Gen()
465 async def consume():
466 ait = aiter(g)
467 while True:
468 try:
469 results.append(await anext(ait))
470 except StopAsyncIteration:
471 break
472 self.loop.run_until_complete(consume())
473 self.assertEqual(results, [1, 2])
474
475 def test_aiter_idempotent(self):
476 async def gen():
477 yield 1
478 applied_once = aiter(gen())
479 applied_twice = aiter(applied_once)
480 self.assertIs(applied_once, applied_twice)
481
482 def test_anext_bad_args(self):
483 async def gen():
484 yield 1
485 async def call_with_too_few_args():
486 await anext()
487 async def call_with_too_many_args():
488 await anext(gen(), 1, 3)
489 async def call_with_wrong_type_args():
490 await anext(1, gen())
Dennis Sweeneydfb45322021-04-11 00:51:35 -0400491 async def call_with_kwarg():
492 await anext(aiterator=gen())
Joshua Bronsonf0a6fde2021-03-23 18:47:21 -0400493 with self.assertRaises(TypeError):
494 self.loop.run_until_complete(call_with_too_few_args())
495 with self.assertRaises(TypeError):
496 self.loop.run_until_complete(call_with_too_many_args())
497 with self.assertRaises(TypeError):
498 self.loop.run_until_complete(call_with_wrong_type_args())
Dennis Sweeneydfb45322021-04-11 00:51:35 -0400499 with self.assertRaises(TypeError):
500 self.loop.run_until_complete(call_with_kwarg())
501
502 def test_anext_bad_await(self):
503 async def bad_awaitable():
504 class BadAwaitable:
505 def __await__(self):
506 return 42
507 class MyAsyncIter:
508 def __aiter__(self):
509 return self
510 def __anext__(self):
511 return BadAwaitable()
512 regex = r"__await__.*iterator"
513 awaitable = anext(MyAsyncIter(), "default")
514 with self.assertRaisesRegex(TypeError, regex):
515 await awaitable
516 awaitable = anext(MyAsyncIter())
517 with self.assertRaisesRegex(TypeError, regex):
518 await awaitable
519 return "completed"
520 result = self.loop.run_until_complete(bad_awaitable())
521 self.assertEqual(result, "completed")
522
523 async def check_anext_returning_iterator(self, aiter_class):
524 awaitable = anext(aiter_class(), "default")
525 with self.assertRaises(TypeError):
526 await awaitable
527 awaitable = anext(aiter_class())
528 with self.assertRaises(TypeError):
529 await awaitable
530 return "completed"
531
532 def test_anext_return_iterator(self):
533 class WithIterAnext:
534 def __aiter__(self):
535 return self
536 def __anext__(self):
537 return iter("abc")
538 result = self.loop.run_until_complete(self.check_anext_returning_iterator(WithIterAnext))
539 self.assertEqual(result, "completed")
540
541 def test_anext_return_generator(self):
542 class WithGenAnext:
543 def __aiter__(self):
544 return self
545 def __anext__(self):
546 yield
547 result = self.loop.run_until_complete(self.check_anext_returning_iterator(WithGenAnext))
548 self.assertEqual(result, "completed")
549
550 def test_anext_await_raises(self):
551 class RaisingAwaitable:
552 def __await__(self):
553 raise ZeroDivisionError()
554 yield
555 class WithRaisingAwaitableAnext:
556 def __aiter__(self):
557 return self
558 def __anext__(self):
559 return RaisingAwaitable()
560 async def do_test():
561 awaitable = anext(WithRaisingAwaitableAnext())
562 with self.assertRaises(ZeroDivisionError):
563 await awaitable
564 awaitable = anext(WithRaisingAwaitableAnext(), "default")
565 with self.assertRaises(ZeroDivisionError):
566 await awaitable
567 return "completed"
568 result = self.loop.run_until_complete(do_test())
569 self.assertEqual(result, "completed")
Joshua Bronsonf0a6fde2021-03-23 18:47:21 -0400570
571 def test_aiter_bad_args(self):
572 async def gen():
573 yield 1
574 async def call_with_too_few_args():
575 await aiter()
576 async def call_with_too_many_args():
577 await aiter(gen(), 1)
578 async def call_with_wrong_type_arg():
579 await aiter(1)
580 with self.assertRaises(TypeError):
581 self.loop.run_until_complete(call_with_too_few_args())
582 with self.assertRaises(TypeError):
583 self.loop.run_until_complete(call_with_too_many_args())
584 with self.assertRaises(TypeError):
585 self.loop.run_until_complete(call_with_wrong_type_arg())
586
Yury Selivanoveb636452016-09-08 22:01:51 -0700587 async def to_list(self, gen):
588 res = []
589 async for i in gen:
590 res.append(i)
591 return res
592
593 def test_async_gen_asyncio_01(self):
594 async def gen():
595 yield 1
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400596 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700597 yield 2
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400598 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700599 return
600 yield 3
601
602 res = self.loop.run_until_complete(self.to_list(gen()))
603 self.assertEqual(res, [1, 2])
604
605 def test_async_gen_asyncio_02(self):
606 async def gen():
607 yield 1
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400608 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700609 yield 2
610 1 / 0
611 yield 3
612
613 with self.assertRaises(ZeroDivisionError):
614 self.loop.run_until_complete(self.to_list(gen()))
615
616 def test_async_gen_asyncio_03(self):
617 loop = self.loop
618
619 class Gen:
620 async def __aiter__(self):
621 yield 1
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400622 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700623 yield 2
624
625 res = loop.run_until_complete(self.to_list(Gen()))
626 self.assertEqual(res, [1, 2])
627
628 def test_async_gen_asyncio_anext_04(self):
629 async def foo():
630 yield 1
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400631 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700632 try:
633 yield 2
634 yield 3
635 except ZeroDivisionError:
636 yield 1000
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400637 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700638 yield 4
639
640 async def run1():
641 it = foo().__aiter__()
642
643 self.assertEqual(await it.__anext__(), 1)
644 self.assertEqual(await it.__anext__(), 2)
645 self.assertEqual(await it.__anext__(), 3)
646 self.assertEqual(await it.__anext__(), 4)
647 with self.assertRaises(StopAsyncIteration):
648 await it.__anext__()
649 with self.assertRaises(StopAsyncIteration):
650 await it.__anext__()
651
652 async def run2():
653 it = foo().__aiter__()
654
655 self.assertEqual(await it.__anext__(), 1)
656 self.assertEqual(await it.__anext__(), 2)
657 try:
658 it.__anext__().throw(ZeroDivisionError)
659 except StopIteration as ex:
660 self.assertEqual(ex.args[0], 1000)
661 else:
662 self.fail('StopIteration was not raised')
663 self.assertEqual(await it.__anext__(), 4)
664 with self.assertRaises(StopAsyncIteration):
665 await it.__anext__()
666
667 self.loop.run_until_complete(run1())
668 self.loop.run_until_complete(run2())
669
670 def test_async_gen_asyncio_anext_05(self):
671 async def foo():
672 v = yield 1
673 v = yield v
674 yield v * 100
675
676 async def run():
677 it = foo().__aiter__()
678
679 try:
680 it.__anext__().send(None)
681 except StopIteration as ex:
682 self.assertEqual(ex.args[0], 1)
683 else:
684 self.fail('StopIteration was not raised')
685
686 try:
687 it.__anext__().send(10)
688 except StopIteration as ex:
689 self.assertEqual(ex.args[0], 10)
690 else:
691 self.fail('StopIteration was not raised')
692
693 try:
694 it.__anext__().send(12)
695 except StopIteration as ex:
696 self.assertEqual(ex.args[0], 1200)
697 else:
698 self.fail('StopIteration was not raised')
699
700 with self.assertRaises(StopAsyncIteration):
701 await it.__anext__()
702
703 self.loop.run_until_complete(run())
704
Yury Selivanov41782e42016-11-16 18:16:17 -0500705 def test_async_gen_asyncio_anext_06(self):
706 DONE = 0
707
708 # test synchronous generators
709 def foo():
710 try:
711 yield
712 except:
713 pass
714 g = foo()
715 g.send(None)
716 with self.assertRaises(StopIteration):
717 g.send(None)
718
719 # now with asynchronous generators
720
721 async def gen():
722 nonlocal DONE
723 try:
724 yield
725 except:
726 pass
727 DONE = 1
728
729 async def run():
730 nonlocal DONE
731 g = gen()
732 await g.asend(None)
733 with self.assertRaises(StopAsyncIteration):
734 await g.asend(None)
735 DONE += 10
736
737 self.loop.run_until_complete(run())
738 self.assertEqual(DONE, 11)
739
Serhiy Storchaka60e49aa2016-11-06 18:47:03 +0200740 def test_async_gen_asyncio_anext_tuple(self):
741 async def foo():
742 try:
743 yield (1,)
744 except ZeroDivisionError:
745 yield (2,)
746
747 async def run():
748 it = foo().__aiter__()
749
750 self.assertEqual(await it.__anext__(), (1,))
751 with self.assertRaises(StopIteration) as cm:
752 it.__anext__().throw(ZeroDivisionError)
753 self.assertEqual(cm.exception.args[0], (2,))
754 with self.assertRaises(StopAsyncIteration):
755 await it.__anext__()
756
757 self.loop.run_until_complete(run())
758
759 def test_async_gen_asyncio_anext_stopiteration(self):
760 async def foo():
761 try:
762 yield StopIteration(1)
763 except ZeroDivisionError:
764 yield StopIteration(3)
765
766 async def run():
767 it = foo().__aiter__()
768
769 v = await it.__anext__()
770 self.assertIsInstance(v, StopIteration)
771 self.assertEqual(v.value, 1)
772 with self.assertRaises(StopIteration) as cm:
773 it.__anext__().throw(ZeroDivisionError)
774 v = cm.exception.args[0]
775 self.assertIsInstance(v, StopIteration)
776 self.assertEqual(v.value, 3)
777 with self.assertRaises(StopAsyncIteration):
778 await it.__anext__()
779
780 self.loop.run_until_complete(run())
781
Yury Selivanoveb636452016-09-08 22:01:51 -0700782 def test_async_gen_asyncio_aclose_06(self):
783 async def foo():
784 try:
785 yield 1
786 1 / 0
787 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400788 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700789 yield 12
790
791 async def run():
792 gen = foo()
793 it = gen.__aiter__()
794 await it.__anext__()
795 await gen.aclose()
796
797 with self.assertRaisesRegex(
798 RuntimeError,
799 "async generator ignored GeneratorExit"):
800 self.loop.run_until_complete(run())
801
802 def test_async_gen_asyncio_aclose_07(self):
803 DONE = 0
804
805 async def foo():
806 nonlocal DONE
807 try:
808 yield 1
809 1 / 0
810 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400811 await asyncio.sleep(0.01)
812 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700813 DONE += 1
814 DONE += 1000
815
816 async def run():
817 gen = foo()
818 it = gen.__aiter__()
819 await it.__anext__()
820 await gen.aclose()
821
822 self.loop.run_until_complete(run())
823 self.assertEqual(DONE, 1)
824
825 def test_async_gen_asyncio_aclose_08(self):
826 DONE = 0
827
828 fut = asyncio.Future(loop=self.loop)
829
830 async def foo():
831 nonlocal DONE
832 try:
833 yield 1
834 await fut
835 DONE += 1000
836 yield 2
837 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400838 await asyncio.sleep(0.01)
839 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700840 DONE += 1
841 DONE += 1000
842
843 async def run():
844 gen = foo()
845 it = gen.__aiter__()
846 self.assertEqual(await it.__anext__(), 1)
Yury Selivanoveb636452016-09-08 22:01:51 -0700847 await gen.aclose()
Yury Selivanoveb636452016-09-08 22:01:51 -0700848
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700849 self.loop.run_until_complete(run())
Yury Selivanoveb636452016-09-08 22:01:51 -0700850 self.assertEqual(DONE, 1)
851
852 # Silence ResourceWarnings
853 fut.cancel()
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400854 self.loop.run_until_complete(asyncio.sleep(0.01))
Yury Selivanoveb636452016-09-08 22:01:51 -0700855
856 def test_async_gen_asyncio_gc_aclose_09(self):
857 DONE = 0
858
859 async def gen():
860 nonlocal DONE
861 try:
862 while True:
863 yield 1
864 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400865 await asyncio.sleep(0.01)
866 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700867 DONE = 1
868
869 async def run():
870 g = gen()
871 await g.__anext__()
872 await g.__anext__()
873 del g
874
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400875 await asyncio.sleep(0.1)
Yury Selivanoveb636452016-09-08 22:01:51 -0700876
877 self.loop.run_until_complete(run())
878 self.assertEqual(DONE, 1)
879
Yury Selivanov41782e42016-11-16 18:16:17 -0500880 def test_async_gen_asyncio_aclose_10(self):
881 DONE = 0
882
883 # test synchronous generators
884 def foo():
885 try:
886 yield
887 except:
888 pass
889 g = foo()
890 g.send(None)
891 g.close()
892
893 # now with asynchronous generators
894
895 async def gen():
896 nonlocal DONE
897 try:
898 yield
899 except:
900 pass
901 DONE = 1
902
903 async def run():
904 nonlocal DONE
905 g = gen()
906 await g.asend(None)
907 await g.aclose()
908 DONE += 10
909
910 self.loop.run_until_complete(run())
911 self.assertEqual(DONE, 11)
912
913 def test_async_gen_asyncio_aclose_11(self):
914 DONE = 0
915
916 # test synchronous generators
917 def foo():
918 try:
919 yield
920 except:
921 pass
922 yield
923 g = foo()
924 g.send(None)
925 with self.assertRaisesRegex(RuntimeError, 'ignored GeneratorExit'):
926 g.close()
927
928 # now with asynchronous generators
929
930 async def gen():
931 nonlocal DONE
932 try:
933 yield
934 except:
935 pass
936 yield
937 DONE += 1
938
939 async def run():
940 nonlocal DONE
941 g = gen()
942 await g.asend(None)
943 with self.assertRaisesRegex(RuntimeError, 'ignored GeneratorExit'):
944 await g.aclose()
945 DONE += 10
946
947 self.loop.run_until_complete(run())
948 self.assertEqual(DONE, 10)
949
Vincent Michel8e0de2a2019-11-19 05:53:52 -0800950 def test_async_gen_asyncio_aclose_12(self):
951 DONE = 0
952
953 async def target():
954 await asyncio.sleep(0.01)
955 1 / 0
956
957 async def foo():
958 nonlocal DONE
959 task = asyncio.create_task(target())
960 try:
961 yield 1
962 finally:
963 try:
964 await task
965 except ZeroDivisionError:
966 DONE = 1
967
968 async def run():
969 gen = foo()
970 it = gen.__aiter__()
971 await it.__anext__()
972 await gen.aclose()
973
974 self.loop.run_until_complete(run())
975 self.assertEqual(DONE, 1)
976
Yury Selivanoveb636452016-09-08 22:01:51 -0700977 def test_async_gen_asyncio_asend_01(self):
978 DONE = 0
979
980 # Sanity check:
981 def sgen():
982 v = yield 1
983 yield v * 2
984 sg = sgen()
985 v = sg.send(None)
986 self.assertEqual(v, 1)
987 v = sg.send(100)
988 self.assertEqual(v, 200)
989
990 async def gen():
991 nonlocal DONE
992 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400993 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700994 v = yield 1
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400995 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700996 yield v * 2
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400997 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700998 return
999 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001000 await asyncio.sleep(0.01)
1001 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001002 DONE = 1
1003
1004 async def run():
1005 g = gen()
1006
1007 v = await g.asend(None)
1008 self.assertEqual(v, 1)
1009
1010 v = await g.asend(100)
1011 self.assertEqual(v, 200)
1012
1013 with self.assertRaises(StopAsyncIteration):
1014 await g.asend(None)
1015
1016 self.loop.run_until_complete(run())
1017 self.assertEqual(DONE, 1)
1018
1019 def test_async_gen_asyncio_asend_02(self):
1020 DONE = 0
1021
1022 async def sleep_n_crash(delay):
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001023 await asyncio.sleep(delay)
Yury Selivanoveb636452016-09-08 22:01:51 -07001024 1 / 0
1025
1026 async def gen():
1027 nonlocal DONE
1028 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001029 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001030 v = yield 1
1031 await sleep_n_crash(0.01)
1032 DONE += 1000
1033 yield v * 2
1034 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001035 await asyncio.sleep(0.01)
1036 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001037 DONE = 1
1038
1039 async def run():
1040 g = gen()
1041
1042 v = await g.asend(None)
1043 self.assertEqual(v, 1)
1044
1045 await g.asend(100)
1046
1047 with self.assertRaises(ZeroDivisionError):
1048 self.loop.run_until_complete(run())
1049 self.assertEqual(DONE, 1)
1050
1051 def test_async_gen_asyncio_asend_03(self):
1052 DONE = 0
1053
1054 async def sleep_n_crash(delay):
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001055 fut = asyncio.ensure_future(asyncio.sleep(delay),
Yury Selivanoveb636452016-09-08 22:01:51 -07001056 loop=self.loop)
1057 self.loop.call_later(delay / 2, lambda: fut.cancel())
1058 return await fut
1059
1060 async def gen():
1061 nonlocal DONE
1062 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001063 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001064 v = yield 1
1065 await sleep_n_crash(0.01)
1066 DONE += 1000
1067 yield v * 2
1068 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001069 await asyncio.sleep(0.01)
1070 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001071 DONE = 1
1072
1073 async def run():
1074 g = gen()
1075
1076 v = await g.asend(None)
1077 self.assertEqual(v, 1)
1078
1079 await g.asend(100)
1080
1081 with self.assertRaises(asyncio.CancelledError):
1082 self.loop.run_until_complete(run())
1083 self.assertEqual(DONE, 1)
1084
1085 def test_async_gen_asyncio_athrow_01(self):
1086 DONE = 0
1087
1088 class FooEr(Exception):
1089 pass
1090
1091 # Sanity check:
1092 def sgen():
1093 try:
1094 v = yield 1
1095 except FooEr:
1096 v = 1000
1097 yield v * 2
1098 sg = sgen()
1099 v = sg.send(None)
1100 self.assertEqual(v, 1)
1101 v = sg.throw(FooEr)
1102 self.assertEqual(v, 2000)
1103 with self.assertRaises(StopIteration):
1104 sg.send(None)
1105
1106 async def gen():
1107 nonlocal DONE
1108 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001109 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001110 try:
1111 v = yield 1
1112 except FooEr:
1113 v = 1000
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001114 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001115 yield v * 2
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001116 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001117 # return
1118 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001119 await asyncio.sleep(0.01)
1120 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001121 DONE = 1
1122
1123 async def run():
1124 g = gen()
1125
1126 v = await g.asend(None)
1127 self.assertEqual(v, 1)
1128
1129 v = await g.athrow(FooEr)
1130 self.assertEqual(v, 2000)
1131
1132 with self.assertRaises(StopAsyncIteration):
1133 await g.asend(None)
1134
1135 self.loop.run_until_complete(run())
1136 self.assertEqual(DONE, 1)
1137
1138 def test_async_gen_asyncio_athrow_02(self):
1139 DONE = 0
1140
1141 class FooEr(Exception):
1142 pass
1143
1144 async def sleep_n_crash(delay):
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001145 fut = asyncio.ensure_future(asyncio.sleep(delay),
Yury Selivanoveb636452016-09-08 22:01:51 -07001146 loop=self.loop)
1147 self.loop.call_later(delay / 2, lambda: fut.cancel())
1148 return await fut
1149
1150 async def gen():
1151 nonlocal DONE
1152 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001153 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001154 try:
1155 v = yield 1
1156 except FooEr:
1157 await sleep_n_crash(0.01)
1158 yield v * 2
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001159 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001160 # return
1161 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001162 await asyncio.sleep(0.01)
1163 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001164 DONE = 1
1165
1166 async def run():
1167 g = gen()
1168
1169 v = await g.asend(None)
1170 self.assertEqual(v, 1)
1171
1172 try:
1173 await g.athrow(FooEr)
1174 except asyncio.CancelledError:
1175 self.assertEqual(DONE, 1)
1176 raise
1177 else:
1178 self.fail('CancelledError was not raised')
1179
1180 with self.assertRaises(asyncio.CancelledError):
1181 self.loop.run_until_complete(run())
1182 self.assertEqual(DONE, 1)
1183
Yury Selivanov41782e42016-11-16 18:16:17 -05001184 def test_async_gen_asyncio_athrow_03(self):
1185 DONE = 0
1186
1187 # test synchronous generators
1188 def foo():
1189 try:
1190 yield
1191 except:
1192 pass
1193 g = foo()
1194 g.send(None)
1195 with self.assertRaises(StopIteration):
1196 g.throw(ValueError)
1197
1198 # now with asynchronous generators
1199
1200 async def gen():
1201 nonlocal DONE
1202 try:
1203 yield
1204 except:
1205 pass
1206 DONE = 1
1207
1208 async def run():
1209 nonlocal DONE
1210 g = gen()
1211 await g.asend(None)
1212 with self.assertRaises(StopAsyncIteration):
1213 await g.athrow(ValueError)
1214 DONE += 10
1215
1216 self.loop.run_until_complete(run())
1217 self.assertEqual(DONE, 11)
1218
Serhiy Storchaka60e49aa2016-11-06 18:47:03 +02001219 def test_async_gen_asyncio_athrow_tuple(self):
1220 async def gen():
1221 try:
1222 yield 1
1223 except ZeroDivisionError:
1224 yield (2,)
1225
1226 async def run():
1227 g = gen()
1228 v = await g.asend(None)
1229 self.assertEqual(v, 1)
1230 v = await g.athrow(ZeroDivisionError)
1231 self.assertEqual(v, (2,))
1232 with self.assertRaises(StopAsyncIteration):
1233 await g.asend(None)
1234
1235 self.loop.run_until_complete(run())
1236
1237 def test_async_gen_asyncio_athrow_stopiteration(self):
1238 async def gen():
1239 try:
1240 yield 1
1241 except ZeroDivisionError:
1242 yield StopIteration(2)
1243
1244 async def run():
1245 g = gen()
1246 v = await g.asend(None)
1247 self.assertEqual(v, 1)
1248 v = await g.athrow(ZeroDivisionError)
1249 self.assertIsInstance(v, StopIteration)
1250 self.assertEqual(v.value, 2)
1251 with self.assertRaises(StopAsyncIteration):
1252 await g.asend(None)
1253
1254 self.loop.run_until_complete(run())
1255
Yury Selivanoveb636452016-09-08 22:01:51 -07001256 def test_async_gen_asyncio_shutdown_01(self):
1257 finalized = 0
1258
1259 async def waiter(timeout):
1260 nonlocal finalized
1261 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001262 await asyncio.sleep(timeout)
Yury Selivanoveb636452016-09-08 22:01:51 -07001263 yield 1
1264 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001265 await asyncio.sleep(0)
Yury Selivanoveb636452016-09-08 22:01:51 -07001266 finalized += 1
1267
1268 async def wait():
1269 async for _ in waiter(1):
1270 pass
1271
1272 t1 = self.loop.create_task(wait())
1273 t2 = self.loop.create_task(wait())
1274
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001275 self.loop.run_until_complete(asyncio.sleep(0.1))
Yury Selivanoveb636452016-09-08 22:01:51 -07001276
Yury Selivanoveb636452016-09-08 22:01:51 -07001277 # Silence warnings
1278 t1.cancel()
1279 t2.cancel()
Yury Selivanoveb636452016-09-08 22:01:51 -07001280
Yury Selivanovfc4a0442019-09-29 22:59:11 -07001281 with self.assertRaises(asyncio.CancelledError):
1282 self.loop.run_until_complete(t1)
1283 with self.assertRaises(asyncio.CancelledError):
1284 self.loop.run_until_complete(t2)
Yury Selivanoveb636452016-09-08 22:01:51 -07001285
Yury Selivanoveb636452016-09-08 22:01:51 -07001286 self.loop.run_until_complete(self.loop.shutdown_asyncgens())
1287
Yury Selivanovfc4a0442019-09-29 22:59:11 -07001288 self.assertEqual(finalized, 2)
Yury Selivanoveb636452016-09-08 22:01:51 -07001289
Yury Selivanovb8ab9d32017-10-06 02:58:28 -04001290 def test_async_gen_expression_01(self):
1291 async def arange(n):
1292 for i in range(n):
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001293 await asyncio.sleep(0.01)
Yury Selivanovb8ab9d32017-10-06 02:58:28 -04001294 yield i
1295
1296 def make_arange(n):
1297 # This syntax is legal starting with Python 3.7
1298 return (i * 2 async for i in arange(n))
1299
1300 async def run():
1301 return [i async for i in make_arange(10)]
1302
1303 res = self.loop.run_until_complete(run())
1304 self.assertEqual(res, [i * 2 for i in range(10)])
1305
1306 def test_async_gen_expression_02(self):
1307 async def wrap(n):
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001308 await asyncio.sleep(0.01)
Yury Selivanovb8ab9d32017-10-06 02:58:28 -04001309 return n
1310
1311 def make_arange(n):
1312 # This syntax is legal starting with Python 3.7
1313 return (i * 2 for i in range(n) if await wrap(i))
1314
1315 async def run():
1316 return [i async for i in make_arange(10)]
1317
1318 res = self.loop.run_until_complete(run())
1319 self.assertEqual(res, [i * 2 for i in range(1, 10)])
1320
Andrew Svetlovc2753122019-09-17 15:59:49 +03001321 def test_asyncgen_nonstarted_hooks_are_cancellable(self):
1322 # See https://bugs.python.org/issue38013
1323 messages = []
1324
1325 def exception_handler(loop, context):
1326 messages.append(context)
1327
1328 async def async_iterate():
1329 yield 1
1330 yield 2
1331
1332 async def main():
1333 loop = asyncio.get_running_loop()
1334 loop.set_exception_handler(exception_handler)
1335
1336 async for i in async_iterate():
1337 break
1338
1339 asyncio.run(main())
1340
1341 self.assertEqual([], messages)
1342
Nathaniel J. Smith925dc7f2020-02-13 00:15:38 -08001343 def test_async_gen_await_same_anext_coro_twice(self):
Andrew Svetlova96e06d2020-01-21 00:49:30 +02001344 async def async_iterate():
1345 yield 1
1346 yield 2
1347
1348 async def run():
1349 it = async_iterate()
1350 nxt = it.__anext__()
1351 await nxt
1352 with self.assertRaisesRegex(
1353 RuntimeError,
1354 r"cannot reuse already awaited __anext__\(\)/asend\(\)"
1355 ):
1356 await nxt
1357
1358 await it.aclose() # prevent unfinished iterator warning
1359
1360 self.loop.run_until_complete(run())
1361
Nathaniel J. Smith925dc7f2020-02-13 00:15:38 -08001362 def test_async_gen_await_same_aclose_coro_twice(self):
Andrew Svetlova96e06d2020-01-21 00:49:30 +02001363 async def async_iterate():
1364 yield 1
1365 yield 2
1366
1367 async def run():
1368 it = async_iterate()
1369 nxt = it.aclose()
1370 await nxt
1371 with self.assertRaisesRegex(
1372 RuntimeError,
1373 r"cannot reuse already awaited aclose\(\)/athrow\(\)"
1374 ):
1375 await nxt
1376
1377 self.loop.run_until_complete(run())
1378
Nathaniel J. Smith925dc7f2020-02-13 00:15:38 -08001379 def test_async_gen_aclose_twice_with_different_coros(self):
1380 # Regression test for https://bugs.python.org/issue39606
1381 async def async_iterate():
1382 yield 1
1383 yield 2
1384
1385 async def run():
1386 it = async_iterate()
1387 await it.aclose()
1388 await it.aclose()
1389
1390 self.loop.run_until_complete(run())
1391
1392 def test_async_gen_aclose_after_exhaustion(self):
1393 # Regression test for https://bugs.python.org/issue39606
1394 async def async_iterate():
1395 yield 1
1396 yield 2
1397
1398 async def run():
1399 it = async_iterate()
1400 async for _ in it:
1401 pass
1402 await it.aclose()
1403
1404 self.loop.run_until_complete(run())
Yury Selivanovb8ab9d32017-10-06 02:58:28 -04001405
Lidi Zheng44823372020-03-02 04:45:54 -08001406 def test_async_gen_aclose_compatible_with_get_stack(self):
1407 async def async_generator():
1408 yield object()
1409
1410 async def run():
1411 ag = async_generator()
1412 asyncio.create_task(ag.aclose())
1413 tasks = asyncio.all_tasks()
1414 for task in tasks:
1415 # No AttributeError raised
1416 task.get_stack()
1417
1418 self.loop.run_until_complete(run())
1419
1420
Yury Selivanoveb636452016-09-08 22:01:51 -07001421if __name__ == "__main__":
1422 unittest.main()