blob: f448f8d53b63227cbc1ea277ff552bdfd53e0d0a [file] [log] [blame]
Yury Selivanoveb636452016-09-08 22:01:51 -07001import inspect
Yury Selivanoveb636452016-09-08 22:01:51 -07002import types
3import unittest
Miss Islington (bot)adc80a52021-09-07 03:52:53 -07004import contextlib
Yury Selivanoveb636452016-09-08 22:01:51 -07005
Hai Shi46605972020-08-04 00:49:18 +08006from test.support.import_helper import import_module
Miss Islington (bot)2ad114d2021-09-04 13:37:56 -07007from test.support import gc_collect
Martin Panter94332cb2016-10-20 05:10:44 +00008asyncio = import_module("asyncio")
9
Yury Selivanoveb636452016-09-08 22:01:51 -070010
Miss Islington (bot)adc80a52021-09-07 03:52:53 -070011_no_default = object()
12
13
Yury Selivanoveb636452016-09-08 22:01:51 -070014class AwaitException(Exception):
15 pass
16
17
18@types.coroutine
19def awaitable(*, throw=False):
20 if throw:
21 yield ('throw',)
22 else:
23 yield ('result',)
24
25
26def run_until_complete(coro):
27 exc = False
28 while True:
29 try:
30 if exc:
31 exc = False
32 fut = coro.throw(AwaitException)
33 else:
34 fut = coro.send(None)
35 except StopIteration as ex:
36 return ex.args[0]
37
38 if fut == ('throw',):
39 exc = True
40
41
42def to_list(gen):
43 async def iterate():
44 res = []
45 async for i in gen:
46 res.append(i)
47 return res
48
49 return run_until_complete(iterate())
50
51
Miss Islington (bot)adc80a52021-09-07 03:52:53 -070052def py_anext(iterator, default=_no_default):
53 """Pure-Python implementation of anext() for testing purposes.
54
55 Closely matches the builtin anext() C implementation.
56 Can be used to compare the built-in implementation of the inner
57 coroutines machinery to C-implementation of __anext__() and send()
58 or throw() on the returned generator.
59 """
60
61 try:
62 __anext__ = type(iterator).__anext__
63 except AttributeError:
64 raise TypeError(f'{iterator!r} is not an async iterator')
65
66 if default is _no_default:
67 return __anext__(iterator)
68
69 async def anext_impl():
70 try:
71 # The C code is way more low-level than this, as it implements
72 # all methods of the iterator protocol. In this implementation
73 # we're relying on higher-level coroutine concepts, but that's
74 # exactly what we want -- crosstest pure-Python high-level
75 # implementation and low-level C anext() iterators.
76 return await __anext__(iterator)
77 except StopAsyncIteration:
78 return default
79
80 return anext_impl()
81
82
Yury Selivanoveb636452016-09-08 22:01:51 -070083class AsyncGenSyntaxTest(unittest.TestCase):
84
85 def test_async_gen_syntax_01(self):
86 code = '''async def foo():
87 await abc
88 yield from 123
89 '''
90
91 with self.assertRaisesRegex(SyntaxError, 'yield from.*inside async'):
92 exec(code, {}, {})
93
94 def test_async_gen_syntax_02(self):
95 code = '''async def foo():
96 yield from 123
97 '''
98
99 with self.assertRaisesRegex(SyntaxError, 'yield from.*inside async'):
100 exec(code, {}, {})
101
102 def test_async_gen_syntax_03(self):
103 code = '''async def foo():
104 await abc
105 yield
106 return 123
107 '''
108
109 with self.assertRaisesRegex(SyntaxError, 'return.*value.*async gen'):
110 exec(code, {}, {})
111
112 def test_async_gen_syntax_04(self):
113 code = '''async def foo():
114 yield
115 return 123
116 '''
117
118 with self.assertRaisesRegex(SyntaxError, 'return.*value.*async gen'):
119 exec(code, {}, {})
120
121 def test_async_gen_syntax_05(self):
122 code = '''async def foo():
123 if 0:
124 yield
125 return 12
126 '''
127
128 with self.assertRaisesRegex(SyntaxError, 'return.*value.*async gen'):
129 exec(code, {}, {})
130
131
132class AsyncGenTest(unittest.TestCase):
133
134 def compare_generators(self, sync_gen, async_gen):
135 def sync_iterate(g):
136 res = []
137 while True:
138 try:
139 res.append(g.__next__())
140 except StopIteration:
141 res.append('STOP')
142 break
143 except Exception as ex:
144 res.append(str(type(ex)))
145 return res
146
147 def async_iterate(g):
148 res = []
149 while True:
Yury Selivanov52698c72018-06-07 20:31:26 -0400150 an = g.__anext__()
151 try:
152 while True:
153 try:
154 an.__next__()
155 except StopIteration as ex:
156 if ex.args:
157 res.append(ex.args[0])
158 break
159 else:
160 res.append('EMPTY StopIteration')
161 break
162 except StopAsyncIteration:
163 raise
164 except Exception as ex:
165 res.append(str(type(ex)))
166 break
167 except StopAsyncIteration:
168 res.append('STOP')
169 break
170 return res
171
Yury Selivanoveb636452016-09-08 22:01:51 -0700172 sync_gen_result = sync_iterate(sync_gen)
173 async_gen_result = async_iterate(async_gen)
174 self.assertEqual(sync_gen_result, async_gen_result)
175 return async_gen_result
176
177 def test_async_gen_iteration_01(self):
178 async def gen():
179 await awaitable()
180 a = yield 123
181 self.assertIs(a, None)
182 await awaitable()
183 yield 456
184 await awaitable()
185 yield 789
186
187 self.assertEqual(to_list(gen()), [123, 456, 789])
188
189 def test_async_gen_iteration_02(self):
190 async def gen():
191 await awaitable()
192 yield 123
193 await awaitable()
194
195 g = gen()
196 ai = g.__aiter__()
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700197
198 an = ai.__anext__()
199 self.assertEqual(an.__next__(), ('result',))
Yury Selivanoveb636452016-09-08 22:01:51 -0700200
201 try:
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700202 an.__next__()
Yury Selivanoveb636452016-09-08 22:01:51 -0700203 except StopIteration as ex:
204 self.assertEqual(ex.args[0], 123)
205 else:
206 self.fail('StopIteration was not raised')
207
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700208 an = ai.__anext__()
209 self.assertEqual(an.__next__(), ('result',))
Yury Selivanoveb636452016-09-08 22:01:51 -0700210
211 try:
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700212 an.__next__()
Yury Selivanoveb636452016-09-08 22:01:51 -0700213 except StopAsyncIteration as ex:
214 self.assertFalse(ex.args)
215 else:
216 self.fail('StopAsyncIteration was not raised')
217
218 def test_async_gen_exception_03(self):
219 async def gen():
220 await awaitable()
221 yield 123
222 await awaitable(throw=True)
223 yield 456
224
225 with self.assertRaises(AwaitException):
226 to_list(gen())
227
228 def test_async_gen_exception_04(self):
229 async def gen():
230 await awaitable()
231 yield 123
232 1 / 0
233
234 g = gen()
235 ai = g.__aiter__()
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700236 an = ai.__anext__()
237 self.assertEqual(an.__next__(), ('result',))
Yury Selivanoveb636452016-09-08 22:01:51 -0700238
239 try:
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700240 an.__next__()
Yury Selivanoveb636452016-09-08 22:01:51 -0700241 except StopIteration as ex:
242 self.assertEqual(ex.args[0], 123)
243 else:
244 self.fail('StopIteration was not raised')
245
246 with self.assertRaises(ZeroDivisionError):
247 ai.__anext__().__next__()
248
249 def test_async_gen_exception_05(self):
250 async def gen():
251 yield 123
252 raise StopAsyncIteration
253
254 with self.assertRaisesRegex(RuntimeError,
255 'async generator.*StopAsyncIteration'):
256 to_list(gen())
257
258 def test_async_gen_exception_06(self):
259 async def gen():
260 yield 123
261 raise StopIteration
262
263 with self.assertRaisesRegex(RuntimeError,
264 'async generator.*StopIteration'):
265 to_list(gen())
266
267 def test_async_gen_exception_07(self):
268 def sync_gen():
269 try:
270 yield 1
271 1 / 0
272 finally:
273 yield 2
274 yield 3
275
276 yield 100
277
278 async def async_gen():
279 try:
280 yield 1
281 1 / 0
282 finally:
283 yield 2
284 yield 3
285
286 yield 100
287
288 self.compare_generators(sync_gen(), async_gen())
289
290 def test_async_gen_exception_08(self):
291 def sync_gen():
292 try:
293 yield 1
294 finally:
295 yield 2
296 1 / 0
297 yield 3
298
299 yield 100
300
301 async def async_gen():
302 try:
303 yield 1
304 await awaitable()
305 finally:
306 await awaitable()
307 yield 2
308 1 / 0
309 yield 3
310
311 yield 100
312
313 self.compare_generators(sync_gen(), async_gen())
314
315 def test_async_gen_exception_09(self):
316 def sync_gen():
317 try:
318 yield 1
319 1 / 0
320 finally:
321 yield 2
322 yield 3
323
324 yield 100
325
326 async def async_gen():
327 try:
328 await awaitable()
329 yield 1
330 1 / 0
331 finally:
332 yield 2
333 await awaitable()
334 yield 3
335
336 yield 100
337
338 self.compare_generators(sync_gen(), async_gen())
339
340 def test_async_gen_exception_10(self):
341 async def gen():
342 yield 123
343 with self.assertRaisesRegex(TypeError,
344 "non-None value .* async generator"):
345 gen().__anext__().send(100)
346
Yury Selivanov52698c72018-06-07 20:31:26 -0400347 def test_async_gen_exception_11(self):
348 def sync_gen():
349 yield 10
350 yield 20
351
352 def sync_gen_wrapper():
353 yield 1
354 sg = sync_gen()
355 sg.send(None)
356 try:
357 sg.throw(GeneratorExit())
358 except GeneratorExit:
359 yield 2
360 yield 3
361
362 async def async_gen():
363 yield 10
364 yield 20
365
366 async def async_gen_wrapper():
367 yield 1
368 asg = async_gen()
369 await asg.asend(None)
370 try:
371 await asg.athrow(GeneratorExit())
372 except GeneratorExit:
373 yield 2
374 yield 3
375
376 self.compare_generators(sync_gen_wrapper(), async_gen_wrapper())
377
Yury Selivanoveb636452016-09-08 22:01:51 -0700378 def test_async_gen_api_01(self):
379 async def gen():
380 yield 123
381
382 g = gen()
383
384 self.assertEqual(g.__name__, 'gen')
385 g.__name__ = '123'
386 self.assertEqual(g.__name__, '123')
387
388 self.assertIn('.gen', g.__qualname__)
389 g.__qualname__ = '123'
390 self.assertEqual(g.__qualname__, '123')
391
392 self.assertIsNone(g.ag_await)
393 self.assertIsInstance(g.ag_frame, types.FrameType)
394 self.assertFalse(g.ag_running)
395 self.assertIsInstance(g.ag_code, types.CodeType)
396
397 self.assertTrue(inspect.isawaitable(g.aclose()))
398
399
400class AsyncGenAsyncioTest(unittest.TestCase):
401
402 def setUp(self):
403 self.loop = asyncio.new_event_loop()
404 asyncio.set_event_loop(None)
405
406 def tearDown(self):
407 self.loop.close()
408 self.loop = None
Brett Cannon8425de42018-06-01 20:34:09 -0700409 asyncio.set_event_loop_policy(None)
Yury Selivanoveb636452016-09-08 22:01:51 -0700410
Dennis Sweeneydfb45322021-04-11 00:51:35 -0400411 def check_async_iterator_anext(self, ait_class):
Miss Islington (bot)adc80a52021-09-07 03:52:53 -0700412 with self.subTest(anext="pure-Python"):
413 self._check_async_iterator_anext(ait_class, py_anext)
414 with self.subTest(anext="builtin"):
415 self._check_async_iterator_anext(ait_class, anext)
416
417 def _check_async_iterator_anext(self, ait_class, anext):
Dennis Sweeneydfb45322021-04-11 00:51:35 -0400418 g = ait_class()
Joshua Bronsonf0a6fde2021-03-23 18:47:21 -0400419 async def consume():
420 results = []
421 results.append(await anext(g))
422 results.append(await anext(g))
423 results.append(await anext(g, 'buckle my shoe'))
424 return results
425 res = self.loop.run_until_complete(consume())
426 self.assertEqual(res, [1, 2, 'buckle my shoe'])
427 with self.assertRaises(StopAsyncIteration):
428 self.loop.run_until_complete(consume())
429
Dennis Sweeneydfb45322021-04-11 00:51:35 -0400430 async def test_2():
431 g1 = ait_class()
432 self.assertEqual(await anext(g1), 1)
433 self.assertEqual(await anext(g1), 2)
434 with self.assertRaises(StopAsyncIteration):
435 await anext(g1)
436 with self.assertRaises(StopAsyncIteration):
437 await anext(g1)
438
439 g2 = ait_class()
440 self.assertEqual(await anext(g2, "default"), 1)
441 self.assertEqual(await anext(g2, "default"), 2)
442 self.assertEqual(await anext(g2, "default"), "default")
443 self.assertEqual(await anext(g2, "default"), "default")
444
445 return "completed"
446
447 result = self.loop.run_until_complete(test_2())
448 self.assertEqual(result, "completed")
449
Miss Islington (bot)adc80a52021-09-07 03:52:53 -0700450 def test_send():
451 p = ait_class()
452 obj = anext(p, "completed")
453 with self.assertRaises(StopIteration):
454 with contextlib.closing(obj.__await__()) as g:
455 g.send(None)
456
457 test_send()
458
459 async def test_throw():
460 p = ait_class()
461 obj = anext(p, "completed")
462 self.assertRaises(SyntaxError, obj.throw, SyntaxError)
463 return "completed"
464
465 result = self.loop.run_until_complete(test_throw())
466 self.assertEqual(result, "completed")
467
Dennis Sweeneydfb45322021-04-11 00:51:35 -0400468 def test_async_generator_anext(self):
469 async def agen():
470 yield 1
471 yield 2
472 self.check_async_iterator_anext(agen)
473
474 def test_python_async_iterator_anext(self):
475 class MyAsyncIter:
476 """Asynchronously yield 1, then 2."""
477 def __init__(self):
478 self.yielded = 0
479 def __aiter__(self):
480 return self
481 async def __anext__(self):
482 if self.yielded >= 2:
483 raise StopAsyncIteration()
484 else:
485 self.yielded += 1
486 return self.yielded
487 self.check_async_iterator_anext(MyAsyncIter)
488
489 def test_python_async_iterator_types_coroutine_anext(self):
490 import types
491 class MyAsyncIterWithTypesCoro:
492 """Asynchronously yield 1, then 2."""
493 def __init__(self):
494 self.yielded = 0
495 def __aiter__(self):
496 return self
497 @types.coroutine
498 def __anext__(self):
499 if False:
500 yield "this is a generator-based coroutine"
501 if self.yielded >= 2:
502 raise StopAsyncIteration()
503 else:
504 self.yielded += 1
505 return self.yielded
506 self.check_async_iterator_anext(MyAsyncIterWithTypesCoro)
507
Joshua Bronsonf0a6fde2021-03-23 18:47:21 -0400508 def test_async_gen_aiter(self):
509 async def gen():
510 yield 1
511 yield 2
512 g = gen()
513 async def consume():
514 return [i async for i in aiter(g)]
515 res = self.loop.run_until_complete(consume())
516 self.assertEqual(res, [1, 2])
517
518 def test_async_gen_aiter_class(self):
519 results = []
520 class Gen:
521 async def __aiter__(self):
522 yield 1
523 yield 2
524 g = Gen()
525 async def consume():
526 ait = aiter(g)
527 while True:
528 try:
529 results.append(await anext(ait))
530 except StopAsyncIteration:
531 break
532 self.loop.run_until_complete(consume())
533 self.assertEqual(results, [1, 2])
534
535 def test_aiter_idempotent(self):
536 async def gen():
537 yield 1
538 applied_once = aiter(gen())
539 applied_twice = aiter(applied_once)
540 self.assertIs(applied_once, applied_twice)
541
542 def test_anext_bad_args(self):
543 async def gen():
544 yield 1
545 async def call_with_too_few_args():
546 await anext()
547 async def call_with_too_many_args():
548 await anext(gen(), 1, 3)
549 async def call_with_wrong_type_args():
550 await anext(1, gen())
Dennis Sweeneydfb45322021-04-11 00:51:35 -0400551 async def call_with_kwarg():
552 await anext(aiterator=gen())
Joshua Bronsonf0a6fde2021-03-23 18:47:21 -0400553 with self.assertRaises(TypeError):
554 self.loop.run_until_complete(call_with_too_few_args())
555 with self.assertRaises(TypeError):
556 self.loop.run_until_complete(call_with_too_many_args())
557 with self.assertRaises(TypeError):
558 self.loop.run_until_complete(call_with_wrong_type_args())
Dennis Sweeneydfb45322021-04-11 00:51:35 -0400559 with self.assertRaises(TypeError):
560 self.loop.run_until_complete(call_with_kwarg())
561
562 def test_anext_bad_await(self):
563 async def bad_awaitable():
564 class BadAwaitable:
565 def __await__(self):
566 return 42
567 class MyAsyncIter:
568 def __aiter__(self):
569 return self
570 def __anext__(self):
571 return BadAwaitable()
572 regex = r"__await__.*iterator"
573 awaitable = anext(MyAsyncIter(), "default")
574 with self.assertRaisesRegex(TypeError, regex):
575 await awaitable
576 awaitable = anext(MyAsyncIter())
577 with self.assertRaisesRegex(TypeError, regex):
578 await awaitable
579 return "completed"
580 result = self.loop.run_until_complete(bad_awaitable())
581 self.assertEqual(result, "completed")
582
583 async def check_anext_returning_iterator(self, aiter_class):
584 awaitable = anext(aiter_class(), "default")
585 with self.assertRaises(TypeError):
586 await awaitable
587 awaitable = anext(aiter_class())
588 with self.assertRaises(TypeError):
589 await awaitable
590 return "completed"
591
592 def test_anext_return_iterator(self):
593 class WithIterAnext:
594 def __aiter__(self):
595 return self
596 def __anext__(self):
597 return iter("abc")
598 result = self.loop.run_until_complete(self.check_anext_returning_iterator(WithIterAnext))
599 self.assertEqual(result, "completed")
600
601 def test_anext_return_generator(self):
602 class WithGenAnext:
603 def __aiter__(self):
604 return self
605 def __anext__(self):
606 yield
607 result = self.loop.run_until_complete(self.check_anext_returning_iterator(WithGenAnext))
608 self.assertEqual(result, "completed")
609
610 def test_anext_await_raises(self):
611 class RaisingAwaitable:
612 def __await__(self):
613 raise ZeroDivisionError()
614 yield
615 class WithRaisingAwaitableAnext:
616 def __aiter__(self):
617 return self
618 def __anext__(self):
619 return RaisingAwaitable()
620 async def do_test():
621 awaitable = anext(WithRaisingAwaitableAnext())
622 with self.assertRaises(ZeroDivisionError):
623 await awaitable
624 awaitable = anext(WithRaisingAwaitableAnext(), "default")
625 with self.assertRaises(ZeroDivisionError):
626 await awaitable
627 return "completed"
628 result = self.loop.run_until_complete(do_test())
629 self.assertEqual(result, "completed")
Joshua Bronsonf0a6fde2021-03-23 18:47:21 -0400630
Miss Islington (bot)adc80a52021-09-07 03:52:53 -0700631 def test_anext_iter(self):
632 @types.coroutine
633 def _async_yield(v):
634 return (yield v)
635
636 class MyError(Exception):
637 pass
638
639 async def agenfn():
640 try:
641 await _async_yield(1)
642 except MyError:
643 await _async_yield(2)
644 return
645 yield
646
647 def test1(anext):
648 agen = agenfn()
649 with contextlib.closing(anext(agen, "default").__await__()) as g:
650 self.assertEqual(g.send(None), 1)
651 self.assertEqual(g.throw(MyError, MyError(), None), 2)
652 try:
653 g.send(None)
654 except StopIteration as e:
655 err = e
656 else:
657 self.fail('StopIteration was not raised')
658 self.assertEqual(err.value, "default")
659
660 def test2(anext):
661 agen = agenfn()
662 with contextlib.closing(anext(agen, "default").__await__()) as g:
663 self.assertEqual(g.send(None), 1)
664 self.assertEqual(g.throw(MyError, MyError(), None), 2)
665 with self.assertRaises(MyError):
666 g.throw(MyError, MyError(), None)
667
668 def test3(anext):
669 agen = agenfn()
670 with contextlib.closing(anext(agen, "default").__await__()) as g:
671 self.assertEqual(g.send(None), 1)
672 g.close()
673 with self.assertRaisesRegex(RuntimeError, 'cannot reuse'):
674 self.assertEqual(g.send(None), 1)
675
676 def test4(anext):
677 @types.coroutine
678 def _async_yield(v):
679 yield v * 10
680 return (yield (v * 10 + 1))
681
682 async def agenfn():
683 try:
684 await _async_yield(1)
685 except MyError:
686 await _async_yield(2)
687 return
688 yield
689
690 agen = agenfn()
691 with contextlib.closing(anext(agen, "default").__await__()) as g:
692 self.assertEqual(g.send(None), 10)
693 self.assertEqual(g.throw(MyError, MyError(), None), 20)
694 with self.assertRaisesRegex(MyError, 'val'):
695 g.throw(MyError, MyError('val'), None)
696
697 def test5(anext):
698 @types.coroutine
699 def _async_yield(v):
700 yield v * 10
701 return (yield (v * 10 + 1))
702
703 async def agenfn():
704 try:
705 await _async_yield(1)
706 except MyError:
707 return
708 yield 'aaa'
709
710 agen = agenfn()
711 with contextlib.closing(anext(agen, "default").__await__()) as g:
712 self.assertEqual(g.send(None), 10)
713 with self.assertRaisesRegex(StopIteration, 'default'):
714 g.throw(MyError, MyError(), None)
715
716 def test6(anext):
717 @types.coroutine
718 def _async_yield(v):
719 yield v * 10
720 return (yield (v * 10 + 1))
721
722 async def agenfn():
723 await _async_yield(1)
724 yield 'aaa'
725
726 agen = agenfn()
727 with contextlib.closing(anext(agen, "default").__await__()) as g:
728 with self.assertRaises(MyError):
729 g.throw(MyError, MyError(), None)
730
731 def run_test(test):
732 with self.subTest('pure-Python anext()'):
733 test(py_anext)
734 with self.subTest('builtin anext()'):
735 test(anext)
736
737 run_test(test1)
738 run_test(test2)
739 run_test(test3)
740 run_test(test4)
741 run_test(test5)
742 run_test(test6)
743
Joshua Bronsonf0a6fde2021-03-23 18:47:21 -0400744 def test_aiter_bad_args(self):
745 async def gen():
746 yield 1
747 async def call_with_too_few_args():
748 await aiter()
749 async def call_with_too_many_args():
750 await aiter(gen(), 1)
751 async def call_with_wrong_type_arg():
752 await aiter(1)
753 with self.assertRaises(TypeError):
754 self.loop.run_until_complete(call_with_too_few_args())
755 with self.assertRaises(TypeError):
756 self.loop.run_until_complete(call_with_too_many_args())
757 with self.assertRaises(TypeError):
758 self.loop.run_until_complete(call_with_wrong_type_arg())
759
Yury Selivanoveb636452016-09-08 22:01:51 -0700760 async def to_list(self, gen):
761 res = []
762 async for i in gen:
763 res.append(i)
764 return res
765
766 def test_async_gen_asyncio_01(self):
767 async def gen():
768 yield 1
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400769 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700770 yield 2
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400771 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700772 return
773 yield 3
774
775 res = self.loop.run_until_complete(self.to_list(gen()))
776 self.assertEqual(res, [1, 2])
777
778 def test_async_gen_asyncio_02(self):
779 async def gen():
780 yield 1
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400781 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700782 yield 2
783 1 / 0
784 yield 3
785
786 with self.assertRaises(ZeroDivisionError):
787 self.loop.run_until_complete(self.to_list(gen()))
788
789 def test_async_gen_asyncio_03(self):
790 loop = self.loop
791
792 class Gen:
793 async def __aiter__(self):
794 yield 1
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400795 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700796 yield 2
797
798 res = loop.run_until_complete(self.to_list(Gen()))
799 self.assertEqual(res, [1, 2])
800
801 def test_async_gen_asyncio_anext_04(self):
802 async def foo():
803 yield 1
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400804 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700805 try:
806 yield 2
807 yield 3
808 except ZeroDivisionError:
809 yield 1000
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400810 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700811 yield 4
812
813 async def run1():
814 it = foo().__aiter__()
815
816 self.assertEqual(await it.__anext__(), 1)
817 self.assertEqual(await it.__anext__(), 2)
818 self.assertEqual(await it.__anext__(), 3)
819 self.assertEqual(await it.__anext__(), 4)
820 with self.assertRaises(StopAsyncIteration):
821 await it.__anext__()
822 with self.assertRaises(StopAsyncIteration):
823 await it.__anext__()
824
825 async def run2():
826 it = foo().__aiter__()
827
828 self.assertEqual(await it.__anext__(), 1)
829 self.assertEqual(await it.__anext__(), 2)
830 try:
831 it.__anext__().throw(ZeroDivisionError)
832 except StopIteration as ex:
833 self.assertEqual(ex.args[0], 1000)
834 else:
835 self.fail('StopIteration was not raised')
836 self.assertEqual(await it.__anext__(), 4)
837 with self.assertRaises(StopAsyncIteration):
838 await it.__anext__()
839
840 self.loop.run_until_complete(run1())
841 self.loop.run_until_complete(run2())
842
843 def test_async_gen_asyncio_anext_05(self):
844 async def foo():
845 v = yield 1
846 v = yield v
847 yield v * 100
848
849 async def run():
850 it = foo().__aiter__()
851
852 try:
853 it.__anext__().send(None)
854 except StopIteration as ex:
855 self.assertEqual(ex.args[0], 1)
856 else:
857 self.fail('StopIteration was not raised')
858
859 try:
860 it.__anext__().send(10)
861 except StopIteration as ex:
862 self.assertEqual(ex.args[0], 10)
863 else:
864 self.fail('StopIteration was not raised')
865
866 try:
867 it.__anext__().send(12)
868 except StopIteration as ex:
869 self.assertEqual(ex.args[0], 1200)
870 else:
871 self.fail('StopIteration was not raised')
872
873 with self.assertRaises(StopAsyncIteration):
874 await it.__anext__()
875
876 self.loop.run_until_complete(run())
877
Yury Selivanov41782e42016-11-16 18:16:17 -0500878 def test_async_gen_asyncio_anext_06(self):
879 DONE = 0
880
881 # test synchronous generators
882 def foo():
883 try:
884 yield
885 except:
886 pass
887 g = foo()
888 g.send(None)
889 with self.assertRaises(StopIteration):
890 g.send(None)
891
892 # now with asynchronous generators
893
894 async def gen():
895 nonlocal DONE
896 try:
897 yield
898 except:
899 pass
900 DONE = 1
901
902 async def run():
903 nonlocal DONE
904 g = gen()
905 await g.asend(None)
906 with self.assertRaises(StopAsyncIteration):
907 await g.asend(None)
908 DONE += 10
909
910 self.loop.run_until_complete(run())
911 self.assertEqual(DONE, 11)
912
Serhiy Storchaka60e49aa2016-11-06 18:47:03 +0200913 def test_async_gen_asyncio_anext_tuple(self):
914 async def foo():
915 try:
916 yield (1,)
917 except ZeroDivisionError:
918 yield (2,)
919
920 async def run():
921 it = foo().__aiter__()
922
923 self.assertEqual(await it.__anext__(), (1,))
924 with self.assertRaises(StopIteration) as cm:
925 it.__anext__().throw(ZeroDivisionError)
926 self.assertEqual(cm.exception.args[0], (2,))
927 with self.assertRaises(StopAsyncIteration):
928 await it.__anext__()
929
930 self.loop.run_until_complete(run())
931
932 def test_async_gen_asyncio_anext_stopiteration(self):
933 async def foo():
934 try:
935 yield StopIteration(1)
936 except ZeroDivisionError:
937 yield StopIteration(3)
938
939 async def run():
940 it = foo().__aiter__()
941
942 v = await it.__anext__()
943 self.assertIsInstance(v, StopIteration)
944 self.assertEqual(v.value, 1)
945 with self.assertRaises(StopIteration) as cm:
946 it.__anext__().throw(ZeroDivisionError)
947 v = cm.exception.args[0]
948 self.assertIsInstance(v, StopIteration)
949 self.assertEqual(v.value, 3)
950 with self.assertRaises(StopAsyncIteration):
951 await it.__anext__()
952
953 self.loop.run_until_complete(run())
954
Yury Selivanoveb636452016-09-08 22:01:51 -0700955 def test_async_gen_asyncio_aclose_06(self):
956 async def foo():
957 try:
958 yield 1
959 1 / 0
960 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400961 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700962 yield 12
963
964 async def run():
965 gen = foo()
966 it = gen.__aiter__()
967 await it.__anext__()
968 await gen.aclose()
969
970 with self.assertRaisesRegex(
971 RuntimeError,
972 "async generator ignored GeneratorExit"):
973 self.loop.run_until_complete(run())
974
975 def test_async_gen_asyncio_aclose_07(self):
976 DONE = 0
977
978 async def foo():
979 nonlocal DONE
980 try:
981 yield 1
982 1 / 0
983 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400984 await asyncio.sleep(0.01)
985 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700986 DONE += 1
987 DONE += 1000
988
989 async def run():
990 gen = foo()
991 it = gen.__aiter__()
992 await it.__anext__()
993 await gen.aclose()
994
995 self.loop.run_until_complete(run())
996 self.assertEqual(DONE, 1)
997
998 def test_async_gen_asyncio_aclose_08(self):
999 DONE = 0
1000
1001 fut = asyncio.Future(loop=self.loop)
1002
1003 async def foo():
1004 nonlocal DONE
1005 try:
1006 yield 1
1007 await fut
1008 DONE += 1000
1009 yield 2
1010 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001011 await asyncio.sleep(0.01)
1012 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001013 DONE += 1
1014 DONE += 1000
1015
1016 async def run():
1017 gen = foo()
1018 it = gen.__aiter__()
1019 self.assertEqual(await it.__anext__(), 1)
Yury Selivanoveb636452016-09-08 22:01:51 -07001020 await gen.aclose()
Yury Selivanoveb636452016-09-08 22:01:51 -07001021
Yury Selivanovfc4a0442019-09-29 22:59:11 -07001022 self.loop.run_until_complete(run())
Yury Selivanoveb636452016-09-08 22:01:51 -07001023 self.assertEqual(DONE, 1)
1024
1025 # Silence ResourceWarnings
1026 fut.cancel()
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001027 self.loop.run_until_complete(asyncio.sleep(0.01))
Yury Selivanoveb636452016-09-08 22:01:51 -07001028
1029 def test_async_gen_asyncio_gc_aclose_09(self):
1030 DONE = 0
1031
1032 async def gen():
1033 nonlocal DONE
1034 try:
1035 while True:
1036 yield 1
1037 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001038 await asyncio.sleep(0.01)
1039 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001040 DONE = 1
1041
1042 async def run():
1043 g = gen()
1044 await g.__anext__()
1045 await g.__anext__()
1046 del g
1047
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001048 await asyncio.sleep(0.1)
Yury Selivanoveb636452016-09-08 22:01:51 -07001049
1050 self.loop.run_until_complete(run())
1051 self.assertEqual(DONE, 1)
1052
Yury Selivanov41782e42016-11-16 18:16:17 -05001053 def test_async_gen_asyncio_aclose_10(self):
1054 DONE = 0
1055
1056 # test synchronous generators
1057 def foo():
1058 try:
1059 yield
1060 except:
1061 pass
1062 g = foo()
1063 g.send(None)
1064 g.close()
1065
1066 # now with asynchronous generators
1067
1068 async def gen():
1069 nonlocal DONE
1070 try:
1071 yield
1072 except:
1073 pass
1074 DONE = 1
1075
1076 async def run():
1077 nonlocal DONE
1078 g = gen()
1079 await g.asend(None)
1080 await g.aclose()
1081 DONE += 10
1082
1083 self.loop.run_until_complete(run())
1084 self.assertEqual(DONE, 11)
1085
1086 def test_async_gen_asyncio_aclose_11(self):
1087 DONE = 0
1088
1089 # test synchronous generators
1090 def foo():
1091 try:
1092 yield
1093 except:
1094 pass
1095 yield
1096 g = foo()
1097 g.send(None)
1098 with self.assertRaisesRegex(RuntimeError, 'ignored GeneratorExit'):
1099 g.close()
1100
1101 # now with asynchronous generators
1102
1103 async def gen():
1104 nonlocal DONE
1105 try:
1106 yield
1107 except:
1108 pass
1109 yield
1110 DONE += 1
1111
1112 async def run():
1113 nonlocal DONE
1114 g = gen()
1115 await g.asend(None)
1116 with self.assertRaisesRegex(RuntimeError, 'ignored GeneratorExit'):
1117 await g.aclose()
1118 DONE += 10
1119
1120 self.loop.run_until_complete(run())
1121 self.assertEqual(DONE, 10)
1122
Vincent Michel8e0de2a2019-11-19 05:53:52 -08001123 def test_async_gen_asyncio_aclose_12(self):
1124 DONE = 0
1125
1126 async def target():
1127 await asyncio.sleep(0.01)
1128 1 / 0
1129
1130 async def foo():
1131 nonlocal DONE
1132 task = asyncio.create_task(target())
1133 try:
1134 yield 1
1135 finally:
1136 try:
1137 await task
1138 except ZeroDivisionError:
1139 DONE = 1
1140
1141 async def run():
1142 gen = foo()
1143 it = gen.__aiter__()
1144 await it.__anext__()
1145 await gen.aclose()
1146
1147 self.loop.run_until_complete(run())
1148 self.assertEqual(DONE, 1)
1149
Yury Selivanoveb636452016-09-08 22:01:51 -07001150 def test_async_gen_asyncio_asend_01(self):
1151 DONE = 0
1152
1153 # Sanity check:
1154 def sgen():
1155 v = yield 1
1156 yield v * 2
1157 sg = sgen()
1158 v = sg.send(None)
1159 self.assertEqual(v, 1)
1160 v = sg.send(100)
1161 self.assertEqual(v, 200)
1162
1163 async def gen():
1164 nonlocal DONE
1165 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001166 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001167 v = yield 1
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001168 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001169 yield v * 2
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001170 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001171 return
1172 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001173 await asyncio.sleep(0.01)
1174 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001175 DONE = 1
1176
1177 async def run():
1178 g = gen()
1179
1180 v = await g.asend(None)
1181 self.assertEqual(v, 1)
1182
1183 v = await g.asend(100)
1184 self.assertEqual(v, 200)
1185
1186 with self.assertRaises(StopAsyncIteration):
1187 await g.asend(None)
1188
1189 self.loop.run_until_complete(run())
1190 self.assertEqual(DONE, 1)
1191
1192 def test_async_gen_asyncio_asend_02(self):
1193 DONE = 0
1194
1195 async def sleep_n_crash(delay):
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001196 await asyncio.sleep(delay)
Yury Selivanoveb636452016-09-08 22:01:51 -07001197 1 / 0
1198
1199 async def gen():
1200 nonlocal DONE
1201 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001202 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001203 v = yield 1
1204 await sleep_n_crash(0.01)
1205 DONE += 1000
1206 yield v * 2
1207 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001208 await asyncio.sleep(0.01)
1209 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001210 DONE = 1
1211
1212 async def run():
1213 g = gen()
1214
1215 v = await g.asend(None)
1216 self.assertEqual(v, 1)
1217
1218 await g.asend(100)
1219
1220 with self.assertRaises(ZeroDivisionError):
1221 self.loop.run_until_complete(run())
1222 self.assertEqual(DONE, 1)
1223
1224 def test_async_gen_asyncio_asend_03(self):
1225 DONE = 0
1226
1227 async def sleep_n_crash(delay):
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001228 fut = asyncio.ensure_future(asyncio.sleep(delay),
Yury Selivanoveb636452016-09-08 22:01:51 -07001229 loop=self.loop)
1230 self.loop.call_later(delay / 2, lambda: fut.cancel())
1231 return await fut
1232
1233 async def gen():
1234 nonlocal DONE
1235 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001236 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001237 v = yield 1
1238 await sleep_n_crash(0.01)
1239 DONE += 1000
1240 yield v * 2
1241 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001242 await asyncio.sleep(0.01)
1243 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001244 DONE = 1
1245
1246 async def run():
1247 g = gen()
1248
1249 v = await g.asend(None)
1250 self.assertEqual(v, 1)
1251
1252 await g.asend(100)
1253
1254 with self.assertRaises(asyncio.CancelledError):
1255 self.loop.run_until_complete(run())
1256 self.assertEqual(DONE, 1)
1257
1258 def test_async_gen_asyncio_athrow_01(self):
1259 DONE = 0
1260
1261 class FooEr(Exception):
1262 pass
1263
1264 # Sanity check:
1265 def sgen():
1266 try:
1267 v = yield 1
1268 except FooEr:
1269 v = 1000
1270 yield v * 2
1271 sg = sgen()
1272 v = sg.send(None)
1273 self.assertEqual(v, 1)
1274 v = sg.throw(FooEr)
1275 self.assertEqual(v, 2000)
1276 with self.assertRaises(StopIteration):
1277 sg.send(None)
1278
1279 async def gen():
1280 nonlocal DONE
1281 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001282 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001283 try:
1284 v = yield 1
1285 except FooEr:
1286 v = 1000
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001287 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001288 yield v * 2
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001289 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001290 # return
1291 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001292 await asyncio.sleep(0.01)
1293 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001294 DONE = 1
1295
1296 async def run():
1297 g = gen()
1298
1299 v = await g.asend(None)
1300 self.assertEqual(v, 1)
1301
1302 v = await g.athrow(FooEr)
1303 self.assertEqual(v, 2000)
1304
1305 with self.assertRaises(StopAsyncIteration):
1306 await g.asend(None)
1307
1308 self.loop.run_until_complete(run())
1309 self.assertEqual(DONE, 1)
1310
1311 def test_async_gen_asyncio_athrow_02(self):
1312 DONE = 0
1313
1314 class FooEr(Exception):
1315 pass
1316
1317 async def sleep_n_crash(delay):
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001318 fut = asyncio.ensure_future(asyncio.sleep(delay),
Yury Selivanoveb636452016-09-08 22:01:51 -07001319 loop=self.loop)
1320 self.loop.call_later(delay / 2, lambda: fut.cancel())
1321 return await fut
1322
1323 async def gen():
1324 nonlocal DONE
1325 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001326 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001327 try:
1328 v = yield 1
1329 except FooEr:
1330 await sleep_n_crash(0.01)
1331 yield v * 2
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001332 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001333 # return
1334 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001335 await asyncio.sleep(0.01)
1336 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -07001337 DONE = 1
1338
1339 async def run():
1340 g = gen()
1341
1342 v = await g.asend(None)
1343 self.assertEqual(v, 1)
1344
1345 try:
1346 await g.athrow(FooEr)
1347 except asyncio.CancelledError:
1348 self.assertEqual(DONE, 1)
1349 raise
1350 else:
1351 self.fail('CancelledError was not raised')
1352
1353 with self.assertRaises(asyncio.CancelledError):
1354 self.loop.run_until_complete(run())
1355 self.assertEqual(DONE, 1)
1356
Yury Selivanov41782e42016-11-16 18:16:17 -05001357 def test_async_gen_asyncio_athrow_03(self):
1358 DONE = 0
1359
1360 # test synchronous generators
1361 def foo():
1362 try:
1363 yield
1364 except:
1365 pass
1366 g = foo()
1367 g.send(None)
1368 with self.assertRaises(StopIteration):
1369 g.throw(ValueError)
1370
1371 # now with asynchronous generators
1372
1373 async def gen():
1374 nonlocal DONE
1375 try:
1376 yield
1377 except:
1378 pass
1379 DONE = 1
1380
1381 async def run():
1382 nonlocal DONE
1383 g = gen()
1384 await g.asend(None)
1385 with self.assertRaises(StopAsyncIteration):
1386 await g.athrow(ValueError)
1387 DONE += 10
1388
1389 self.loop.run_until_complete(run())
1390 self.assertEqual(DONE, 11)
1391
Serhiy Storchaka60e49aa2016-11-06 18:47:03 +02001392 def test_async_gen_asyncio_athrow_tuple(self):
1393 async def gen():
1394 try:
1395 yield 1
1396 except ZeroDivisionError:
1397 yield (2,)
1398
1399 async def run():
1400 g = gen()
1401 v = await g.asend(None)
1402 self.assertEqual(v, 1)
1403 v = await g.athrow(ZeroDivisionError)
1404 self.assertEqual(v, (2,))
1405 with self.assertRaises(StopAsyncIteration):
1406 await g.asend(None)
1407
1408 self.loop.run_until_complete(run())
1409
1410 def test_async_gen_asyncio_athrow_stopiteration(self):
1411 async def gen():
1412 try:
1413 yield 1
1414 except ZeroDivisionError:
1415 yield StopIteration(2)
1416
1417 async def run():
1418 g = gen()
1419 v = await g.asend(None)
1420 self.assertEqual(v, 1)
1421 v = await g.athrow(ZeroDivisionError)
1422 self.assertIsInstance(v, StopIteration)
1423 self.assertEqual(v.value, 2)
1424 with self.assertRaises(StopAsyncIteration):
1425 await g.asend(None)
1426
1427 self.loop.run_until_complete(run())
1428
Yury Selivanoveb636452016-09-08 22:01:51 -07001429 def test_async_gen_asyncio_shutdown_01(self):
1430 finalized = 0
1431
1432 async def waiter(timeout):
1433 nonlocal finalized
1434 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001435 await asyncio.sleep(timeout)
Yury Selivanoveb636452016-09-08 22:01:51 -07001436 yield 1
1437 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001438 await asyncio.sleep(0)
Yury Selivanoveb636452016-09-08 22:01:51 -07001439 finalized += 1
1440
1441 async def wait():
1442 async for _ in waiter(1):
1443 pass
1444
1445 t1 = self.loop.create_task(wait())
1446 t2 = self.loop.create_task(wait())
1447
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001448 self.loop.run_until_complete(asyncio.sleep(0.1))
Yury Selivanoveb636452016-09-08 22:01:51 -07001449
Yury Selivanoveb636452016-09-08 22:01:51 -07001450 # Silence warnings
1451 t1.cancel()
1452 t2.cancel()
Yury Selivanoveb636452016-09-08 22:01:51 -07001453
Yury Selivanovfc4a0442019-09-29 22:59:11 -07001454 with self.assertRaises(asyncio.CancelledError):
1455 self.loop.run_until_complete(t1)
1456 with self.assertRaises(asyncio.CancelledError):
1457 self.loop.run_until_complete(t2)
Yury Selivanoveb636452016-09-08 22:01:51 -07001458
Yury Selivanoveb636452016-09-08 22:01:51 -07001459 self.loop.run_until_complete(self.loop.shutdown_asyncgens())
1460
Yury Selivanovfc4a0442019-09-29 22:59:11 -07001461 self.assertEqual(finalized, 2)
Yury Selivanoveb636452016-09-08 22:01:51 -07001462
Miss Islington (bot)2ad114d2021-09-04 13:37:56 -07001463 def test_async_gen_asyncio_shutdown_02(self):
1464 messages = []
1465
1466 def exception_handler(loop, context):
1467 messages.append(context)
1468
1469 async def async_iterate():
1470 yield 1
1471 yield 2
1472
1473 it = async_iterate()
1474 async def main():
1475 loop = asyncio.get_running_loop()
1476 loop.set_exception_handler(exception_handler)
1477
1478 async for i in it:
1479 break
1480
1481 asyncio.run(main())
1482
1483 self.assertEqual(messages, [])
1484
1485 def test_async_gen_asyncio_shutdown_exception_01(self):
1486 messages = []
1487
1488 def exception_handler(loop, context):
1489 messages.append(context)
1490
1491 async def async_iterate():
1492 try:
1493 yield 1
1494 yield 2
1495 finally:
1496 1/0
1497
1498 it = async_iterate()
1499 async def main():
1500 loop = asyncio.get_running_loop()
1501 loop.set_exception_handler(exception_handler)
1502
1503 async for i in it:
1504 break
1505
1506 asyncio.run(main())
1507
1508 message, = messages
1509 self.assertEqual(message['asyncgen'], it)
1510 self.assertIsInstance(message['exception'], ZeroDivisionError)
1511 self.assertIn('an error occurred during closing of asynchronous generator',
1512 message['message'])
1513
1514 def test_async_gen_asyncio_shutdown_exception_02(self):
1515 messages = []
1516
1517 def exception_handler(loop, context):
1518 messages.append(context)
1519
1520 async def async_iterate():
1521 try:
1522 yield 1
1523 yield 2
1524 finally:
1525 1/0
1526
1527 async def main():
1528 loop = asyncio.get_running_loop()
1529 loop.set_exception_handler(exception_handler)
1530
1531 async for i in async_iterate():
1532 break
1533 gc_collect()
1534
1535 asyncio.run(main())
1536
1537 message, = messages
1538 self.assertIsInstance(message['exception'], ZeroDivisionError)
1539 self.assertIn('unhandled exception during asyncio.run() shutdown',
1540 message['message'])
1541
Yury Selivanovb8ab9d32017-10-06 02:58:28 -04001542 def test_async_gen_expression_01(self):
1543 async def arange(n):
1544 for i in range(n):
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001545 await asyncio.sleep(0.01)
Yury Selivanovb8ab9d32017-10-06 02:58:28 -04001546 yield i
1547
1548 def make_arange(n):
1549 # This syntax is legal starting with Python 3.7
1550 return (i * 2 async for i in arange(n))
1551
1552 async def run():
1553 return [i async for i in make_arange(10)]
1554
1555 res = self.loop.run_until_complete(run())
1556 self.assertEqual(res, [i * 2 for i in range(10)])
1557
1558 def test_async_gen_expression_02(self):
1559 async def wrap(n):
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001560 await asyncio.sleep(0.01)
Yury Selivanovb8ab9d32017-10-06 02:58:28 -04001561 return n
1562
1563 def make_arange(n):
1564 # This syntax is legal starting with Python 3.7
1565 return (i * 2 for i in range(n) if await wrap(i))
1566
1567 async def run():
1568 return [i async for i in make_arange(10)]
1569
1570 res = self.loop.run_until_complete(run())
1571 self.assertEqual(res, [i * 2 for i in range(1, 10)])
1572
Andrew Svetlovc2753122019-09-17 15:59:49 +03001573 def test_asyncgen_nonstarted_hooks_are_cancellable(self):
1574 # See https://bugs.python.org/issue38013
1575 messages = []
1576
1577 def exception_handler(loop, context):
1578 messages.append(context)
1579
1580 async def async_iterate():
1581 yield 1
1582 yield 2
1583
1584 async def main():
1585 loop = asyncio.get_running_loop()
1586 loop.set_exception_handler(exception_handler)
1587
1588 async for i in async_iterate():
1589 break
1590
1591 asyncio.run(main())
1592
1593 self.assertEqual([], messages)
1594
Nathaniel J. Smith925dc7f2020-02-13 00:15:38 -08001595 def test_async_gen_await_same_anext_coro_twice(self):
Andrew Svetlova96e06d2020-01-21 00:49:30 +02001596 async def async_iterate():
1597 yield 1
1598 yield 2
1599
1600 async def run():
1601 it = async_iterate()
1602 nxt = it.__anext__()
1603 await nxt
1604 with self.assertRaisesRegex(
1605 RuntimeError,
1606 r"cannot reuse already awaited __anext__\(\)/asend\(\)"
1607 ):
1608 await nxt
1609
1610 await it.aclose() # prevent unfinished iterator warning
1611
1612 self.loop.run_until_complete(run())
1613
Nathaniel J. Smith925dc7f2020-02-13 00:15:38 -08001614 def test_async_gen_await_same_aclose_coro_twice(self):
Andrew Svetlova96e06d2020-01-21 00:49:30 +02001615 async def async_iterate():
1616 yield 1
1617 yield 2
1618
1619 async def run():
1620 it = async_iterate()
1621 nxt = it.aclose()
1622 await nxt
1623 with self.assertRaisesRegex(
1624 RuntimeError,
1625 r"cannot reuse already awaited aclose\(\)/athrow\(\)"
1626 ):
1627 await nxt
1628
1629 self.loop.run_until_complete(run())
1630
Nathaniel J. Smith925dc7f2020-02-13 00:15:38 -08001631 def test_async_gen_aclose_twice_with_different_coros(self):
1632 # Regression test for https://bugs.python.org/issue39606
1633 async def async_iterate():
1634 yield 1
1635 yield 2
1636
1637 async def run():
1638 it = async_iterate()
1639 await it.aclose()
1640 await it.aclose()
1641
1642 self.loop.run_until_complete(run())
1643
1644 def test_async_gen_aclose_after_exhaustion(self):
1645 # Regression test for https://bugs.python.org/issue39606
1646 async def async_iterate():
1647 yield 1
1648 yield 2
1649
1650 async def run():
1651 it = async_iterate()
1652 async for _ in it:
1653 pass
1654 await it.aclose()
1655
1656 self.loop.run_until_complete(run())
Yury Selivanovb8ab9d32017-10-06 02:58:28 -04001657
Lidi Zheng44823372020-03-02 04:45:54 -08001658 def test_async_gen_aclose_compatible_with_get_stack(self):
1659 async def async_generator():
1660 yield object()
1661
1662 async def run():
1663 ag = async_generator()
1664 asyncio.create_task(ag.aclose())
1665 tasks = asyncio.all_tasks()
1666 for task in tasks:
1667 # No AttributeError raised
1668 task.get_stack()
1669
1670 self.loop.run_until_complete(run())
1671
1672
Yury Selivanoveb636452016-09-08 22:01:51 -07001673if __name__ == "__main__":
1674 unittest.main()