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