this repo has no description
1# Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com)
2# WARNING: This is a temporary copy of code from the cpython library to
3# facilitate bringup.
4#
5# flake8: noqa
6# fmt: off
7
8import inspect
9import sys
10import types
11import unittest
12from test.support import import_module
13
14from test_support import cpython_only, pyro_only
15
16asyncio = import_module("asyncio")
17
18
19class AwaitException(Exception):
20 pass
21
22
23@types.coroutine
24def awaitable(*, throw=False):
25 if throw:
26 yield ('throw',)
27 else:
28 yield ('result',)
29
30
31def run_until_complete(coro):
32 exc = False
33 while True:
34 try:
35 if exc:
36 exc = False
37 fut = coro.throw(AwaitException)
38 else:
39 fut = coro.send(None)
40 except StopIteration as ex:
41 return ex.args[0]
42
43 if fut == ('throw',):
44 exc = True
45
46
47def to_list(gen):
48 async def iterate():
49 res = []
50 async for i in gen:
51 res.append(i)
52 return res
53
54 return run_until_complete(iterate())
55
56
57# TODO(T71327927) - Make compile() work as well as it does when running full
58# scripts.
59@cpython_only
60class AsyncGenSyntaxTest(unittest.TestCase):
61
62 def test_async_gen_syntax_01(self):
63 code = '''async def foo():
64 await abc
65 yield from 123
66 '''
67
68 with self.assertRaisesRegex(SyntaxError, 'yield from.*inside async'):
69 exec(code, {}, {})
70
71 def test_async_gen_syntax_02(self):
72 code = '''async def foo():
73 yield from 123
74 '''
75
76 with self.assertRaisesRegex(SyntaxError, 'yield from.*inside async'):
77 exec(code, {}, {})
78
79 def test_async_gen_syntax_03(self):
80 code = '''async def foo():
81 await abc
82 yield
83 return 123
84 '''
85
86 with self.assertRaisesRegex(SyntaxError, 'return.*value.*async gen'):
87 exec(code, {}, {})
88
89 def test_async_gen_syntax_04(self):
90 code = '''async def foo():
91 yield
92 return 123
93 '''
94
95 with self.assertRaisesRegex(SyntaxError, 'return.*value.*async gen'):
96 exec(code, {}, {})
97
98 def test_async_gen_syntax_05(self):
99 code = '''async def foo():
100 if 0:
101 yield
102 return 12
103 '''
104
105 with self.assertRaisesRegex(SyntaxError, 'return.*value.*async gen'):
106 exec(code, {}, {})
107
108
109class AsyncGenTest(unittest.TestCase):
110
111 def compare_generators(self, sync_gen, async_gen):
112 def sync_iterate(g):
113 res = []
114 while True:
115 try:
116 res.append(g.__next__())
117 except StopIteration:
118 res.append('STOP')
119 break
120 except Exception as ex:
121 res.append(str(type(ex)))
122 return res
123
124 def async_iterate(g):
125 res = []
126 while True:
127 an = g.__anext__()
128 try:
129 while True:
130 try:
131 an.__next__()
132 except StopIteration as ex:
133 if ex.args:
134 res.append(ex.args[0])
135 break
136 else:
137 res.append('EMPTY StopIteration')
138 break
139 except StopAsyncIteration:
140 raise
141 except Exception as ex:
142 res.append(str(type(ex)))
143 break
144 except StopAsyncIteration:
145 res.append('STOP')
146 break
147 return res
148
149 sync_gen_result = sync_iterate(sync_gen)
150 async_gen_result = async_iterate(async_gen)
151 self.assertEqual(sync_gen_result, async_gen_result)
152 return async_gen_result
153
154 def test_async_gen_iteration_01(self):
155 async def gen():
156 await awaitable()
157 a = yield 123
158 self.assertIs(a, None)
159 await awaitable()
160 yield 456
161 await awaitable()
162 yield 789
163
164 self.assertEqual(to_list(gen()), [123, 456, 789])
165
166 def test_async_gen_iteration_02(self):
167 async def gen():
168 await awaitable()
169 yield 123
170 await awaitable()
171
172 g = gen()
173 ai = g.__aiter__()
174
175 an = ai.__anext__()
176 self.assertEqual(an.__next__(), ('result',))
177
178 try:
179 an.__next__()
180 except StopIteration as ex:
181 self.assertEqual(ex.args[0], 123)
182 else:
183 self.fail('StopIteration was not raised')
184
185 an = ai.__anext__()
186 self.assertEqual(an.__next__(), ('result',))
187
188 try:
189 an.__next__()
190 except StopAsyncIteration as ex:
191 self.assertFalse(ex.args)
192 else:
193 self.fail('StopAsyncIteration was not raised')
194
195 def test_async_gen_exception_03(self):
196 async def gen():
197 await awaitable()
198 yield 123
199 await awaitable(throw=True)
200 yield 456
201
202 with self.assertRaises(AwaitException):
203 to_list(gen())
204
205 def test_async_gen_exception_04(self):
206 async def gen():
207 await awaitable()
208 yield 123
209 1 / 0
210
211 g = gen()
212 ai = g.__aiter__()
213 an = ai.__anext__()
214 self.assertEqual(an.__next__(), ('result',))
215
216 try:
217 an.__next__()
218 except StopIteration as ex:
219 self.assertEqual(ex.args[0], 123)
220 else:
221 self.fail('StopIteration was not raised')
222
223 with self.assertRaises(ZeroDivisionError):
224 ai.__anext__().__next__()
225
226 def test_async_gen_exception_05(self):
227 async def gen():
228 yield 123
229 raise StopAsyncIteration
230
231 with self.assertRaisesRegex(RuntimeError,
232 'async generator.*StopAsyncIteration'):
233 to_list(gen())
234
235 def test_async_gen_exception_06(self):
236 async def gen():
237 yield 123
238 raise StopIteration
239
240 with self.assertRaisesRegex(RuntimeError,
241 'async generator.*StopIteration'):
242 to_list(gen())
243
244 def test_async_gen_exception_07(self):
245 def sync_gen():
246 try:
247 yield 1
248 1 / 0
249 finally:
250 yield 2
251 yield 3
252
253 yield 100
254
255 async def async_gen():
256 try:
257 yield 1
258 1 / 0
259 finally:
260 yield 2
261 yield 3
262
263 yield 100
264
265 self.compare_generators(sync_gen(), async_gen())
266
267 def test_async_gen_exception_08(self):
268 def sync_gen():
269 try:
270 yield 1
271 finally:
272 yield 2
273 1 / 0
274 yield 3
275
276 yield 100
277
278 async def async_gen():
279 try:
280 yield 1
281 await awaitable()
282 finally:
283 await awaitable()
284 yield 2
285 1 / 0
286 yield 3
287
288 yield 100
289
290 self.compare_generators(sync_gen(), async_gen())
291
292 def test_async_gen_exception_09(self):
293 def sync_gen():
294 try:
295 yield 1
296 1 / 0
297 finally:
298 yield 2
299 yield 3
300
301 yield 100
302
303 async def async_gen():
304 try:
305 await awaitable()
306 yield 1
307 1 / 0
308 finally:
309 yield 2
310 await awaitable()
311 yield 3
312
313 yield 100
314
315 self.compare_generators(sync_gen(), async_gen())
316
317 def test_async_gen_exception_10(self):
318 async def gen():
319 yield 123
320 # TODO(T71566677) - Restore regex match on exception text.
321 with self.assertRaises(TypeError):
322 gen().__anext__().send(100)
323
324 def test_async_gen_exception_11(self):
325 def sync_gen():
326 yield 10
327 yield 20
328
329 def sync_gen_wrapper():
330 yield 1
331 sg = sync_gen()
332 sg.send(None)
333 try:
334 sg.throw(GeneratorExit())
335 except GeneratorExit:
336 yield 2
337 yield 3
338
339 async def async_gen():
340 yield 10
341 yield 20
342
343 async def async_gen_wrapper():
344 yield 1
345 asg = async_gen()
346 await asg.asend(None)
347 try:
348 await asg.athrow(GeneratorExit())
349 except GeneratorExit:
350 yield 2
351 yield 3
352
353 self.compare_generators(sync_gen_wrapper(), async_gen_wrapper())
354
355 # TODO(T71329077) Make __name__ and __qualname__ read/write on generators
356 @cpython_only
357 def test_async_gen_api_01(self):
358 async def gen():
359 yield 123
360
361 g = gen()
362
363 self.assertEqual(g.__name__, 'gen')
364 g.__name__ = '123'
365 self.assertEqual(g.__name__, '123')
366
367 self.assertIn('.gen', g.__qualname__)
368 g.__qualname__ = '123'
369 self.assertEqual(g.__qualname__, '123')
370
371 self.assertIsNone(g.ag_await)
372 self.assertIsInstance(g.ag_frame, types.FrameType)
373 self.assertFalse(g.ag_running)
374 self.assertIsInstance(g.ag_code, types.CodeType)
375
376 self.assertTrue(inspect.isawaitable(g.aclose()))
377
378
379class AsyncGenAsyncioTest(unittest.TestCase):
380
381 def setUp(self):
382 self.loop = asyncio.new_event_loop()
383 asyncio.set_event_loop(None)
384
385 def tearDown(self):
386 self.loop.close()
387 self.loop = None
388 asyncio.set_event_loop_policy(None)
389
390 async def to_list(self, gen):
391 res = []
392 async for i in gen:
393 res.append(i)
394 return res
395
396 def test_async_gen_asyncio_01(self):
397 async def gen():
398 yield 1
399 await asyncio.sleep(0.01)
400 yield 2
401 await asyncio.sleep(0.01)
402 return
403 yield 3
404
405 res = self.loop.run_until_complete(self.to_list(gen()))
406 self.assertEqual(res, [1, 2])
407
408 def test_async_gen_asyncio_02(self):
409 async def gen():
410 yield 1
411 await asyncio.sleep(0.01)
412 yield 2
413 1 / 0
414 yield 3
415
416 with self.assertRaises(ZeroDivisionError):
417 self.loop.run_until_complete(self.to_list(gen()))
418
419 def test_async_gen_asyncio_03(self):
420 loop = self.loop
421
422 class Gen:
423 async def __aiter__(self):
424 yield 1
425 await asyncio.sleep(0.01)
426 yield 2
427
428 res = loop.run_until_complete(self.to_list(Gen()))
429 self.assertEqual(res, [1, 2])
430
431 def test_async_gen_asyncio_anext_04(self):
432 async def foo():
433 yield 1
434 await asyncio.sleep(0.01)
435 try:
436 yield 2
437 yield 3
438 except ZeroDivisionError:
439 yield 1000
440 await asyncio.sleep(0.01)
441 yield 4
442
443 async def run1():
444 it = foo().__aiter__()
445
446 self.assertEqual(await it.__anext__(), 1)
447 self.assertEqual(await it.__anext__(), 2)
448 self.assertEqual(await it.__anext__(), 3)
449 self.assertEqual(await it.__anext__(), 4)
450 with self.assertRaises(StopAsyncIteration):
451 await it.__anext__()
452 with self.assertRaises(StopAsyncIteration):
453 await it.__anext__()
454
455 async def run2():
456 it = foo().__aiter__()
457
458 self.assertEqual(await it.__anext__(), 1)
459 self.assertEqual(await it.__anext__(), 2)
460 try:
461 it.__anext__().throw(ZeroDivisionError)
462 except StopIteration as ex:
463 self.assertEqual(ex.args[0], 1000)
464 else:
465 self.fail('StopIteration was not raised')
466 self.assertEqual(await it.__anext__(), 4)
467 with self.assertRaises(StopAsyncIteration):
468 await it.__anext__()
469
470 self.loop.run_until_complete(run1())
471 self.loop.run_until_complete(run2())
472
473 def test_async_gen_asyncio_anext_05(self):
474 async def foo():
475 v = yield 1
476 v = yield v
477 yield v * 100
478
479 async def run():
480 it = foo().__aiter__()
481
482 try:
483 it.__anext__().send(None)
484 except StopIteration as ex:
485 self.assertEqual(ex.args[0], 1)
486 else:
487 self.fail('StopIteration was not raised')
488
489 try:
490 it.__anext__().send(10)
491 except StopIteration as ex:
492 self.assertEqual(ex.args[0], 10)
493 else:
494 self.fail('StopIteration was not raised')
495
496 try:
497 it.__anext__().send(12)
498 except StopIteration as ex:
499 self.assertEqual(ex.args[0], 1200)
500 else:
501 self.fail('StopIteration was not raised')
502
503 with self.assertRaises(StopAsyncIteration):
504 await it.__anext__()
505
506 self.loop.run_until_complete(run())
507
508 def test_async_gen_asyncio_anext_06(self):
509 DONE = 0
510
511 # test synchronous generators
512 def foo():
513 try:
514 yield
515 except:
516 pass
517 g = foo()
518 g.send(None)
519 with self.assertRaises(StopIteration):
520 g.send(None)
521
522 # now with asynchronous generators
523
524 async def gen():
525 nonlocal DONE
526 try:
527 yield
528 except:
529 pass
530 DONE = 1
531
532 async def run():
533 nonlocal DONE
534 g = gen()
535 await g.asend(None)
536 with self.assertRaises(StopAsyncIteration):
537 await g.asend(None)
538 DONE += 10
539
540 self.loop.run_until_complete(run())
541 self.assertEqual(DONE, 11)
542
543 def test_async_gen_asyncio_anext_tuple(self):
544 async def foo():
545 try:
546 yield (1,)
547 except ZeroDivisionError:
548 yield (2,)
549
550 async def run():
551 it = foo().__aiter__()
552
553 self.assertEqual(await it.__anext__(), (1,))
554 with self.assertRaises(StopIteration) as cm:
555 it.__anext__().throw(ZeroDivisionError)
556 self.assertEqual(cm.exception.args[0], (2,))
557 with self.assertRaises(StopAsyncIteration):
558 await it.__anext__()
559
560 self.loop.run_until_complete(run())
561
562 def test_async_gen_asyncio_anext_stopiteration(self):
563 async def foo():
564 try:
565 yield StopIteration(1)
566 except ZeroDivisionError:
567 yield StopIteration(3)
568
569 async def run():
570 it = foo().__aiter__()
571
572 v = await it.__anext__()
573 self.assertIsInstance(v, StopIteration)
574 self.assertEqual(v.value, 1)
575 with self.assertRaises(StopIteration) as cm:
576 it.__anext__().throw(ZeroDivisionError)
577 v = cm.exception.args[0]
578 self.assertIsInstance(v, StopIteration)
579 self.assertEqual(v.value, 3)
580 with self.assertRaises(StopAsyncIteration):
581 await it.__anext__()
582
583 self.loop.run_until_complete(run())
584
585 def test_async_gen_asyncio_aclose_06(self):
586 async def foo():
587 try:
588 yield 1
589 1 / 0
590 finally:
591 await asyncio.sleep(0.01)
592 yield 12
593
594 async def run():
595 gen = foo()
596 it = gen.__aiter__()
597 await it.__anext__()
598 await gen.aclose()
599
600 with self.assertRaisesRegex(
601 RuntimeError,
602 "async generator ignored GeneratorExit"):
603 self.loop.run_until_complete(run())
604
605 def test_async_gen_asyncio_aclose_07(self):
606 DONE = 0
607
608 async def foo():
609 nonlocal DONE
610 try:
611 yield 1
612 1 / 0
613 finally:
614 await asyncio.sleep(0.01)
615 await asyncio.sleep(0.01)
616 DONE += 1
617 DONE += 1000
618
619 async def run():
620 gen = foo()
621 it = gen.__aiter__()
622 await it.__anext__()
623 await gen.aclose()
624
625 self.loop.run_until_complete(run())
626 self.assertEqual(DONE, 1)
627
628 def test_async_gen_asyncio_aclose_08(self):
629 DONE = 0
630
631 fut = asyncio.Future(loop=self.loop)
632
633 async def foo():
634 nonlocal DONE
635 try:
636 yield 1
637 await fut
638 DONE += 1000
639 yield 2
640 finally:
641 await asyncio.sleep(0.01)
642 await asyncio.sleep(0.01)
643 DONE += 1
644 DONE += 1000
645
646 async def run():
647 gen = foo()
648 it = gen.__aiter__()
649 self.assertEqual(await it.__anext__(), 1)
650 await gen.aclose()
651
652 self.loop.run_until_complete(run())
653 self.assertEqual(DONE, 1)
654
655 # Silence ResourceWarnings
656 fut.cancel()
657 self.loop.run_until_complete(asyncio.sleep(0.01))
658
659 @cpython_only
660 def test_async_gen_asyncio_gc_aclose_09(self):
661 DONE = 0
662
663 async def gen():
664 nonlocal DONE
665 try:
666 while True:
667 yield 1
668 finally:
669 await asyncio.sleep(0.01)
670 await asyncio.sleep(0.01)
671 DONE = 1
672
673 async def run():
674 g = gen()
675 await g.__anext__()
676 await g.__anext__()
677 del g
678
679 await asyncio.sleep(0.1)
680
681 self.loop.run_until_complete(run())
682 self.assertEqual(DONE, 1)
683
684 def test_async_gen_asyncio_aclose_10(self):
685 DONE = 0
686
687 # test synchronous generators
688 def foo():
689 try:
690 yield
691 except:
692 pass
693 g = foo()
694 g.send(None)
695 g.close()
696
697 # now with asynchronous generators
698
699 async def gen():
700 nonlocal DONE
701 try:
702 yield
703 except:
704 pass
705 DONE = 1
706
707 async def run():
708 nonlocal DONE
709 g = gen()
710 await g.asend(None)
711 await g.aclose()
712 DONE += 10
713
714 self.loop.run_until_complete(run())
715 self.assertEqual(DONE, 11)
716
717 def test_async_gen_asyncio_aclose_11(self):
718 DONE = 0
719
720 # test synchronous generators
721 def foo():
722 try:
723 yield
724 except:
725 pass
726 yield
727 g = foo()
728 g.send(None)
729 with self.assertRaisesRegex(RuntimeError, 'ignored GeneratorExit'):
730 g.close()
731
732 # now with asynchronous generators
733
734 async def gen():
735 nonlocal DONE
736 try:
737 yield
738 except:
739 pass
740 yield
741 DONE += 1
742
743 async def run():
744 nonlocal DONE
745 g = gen()
746 await g.asend(None)
747 with self.assertRaisesRegex(RuntimeError, 'ignored GeneratorExit'):
748 await g.aclose()
749 DONE += 10
750
751 self.loop.run_until_complete(run())
752 self.assertEqual(DONE, 10)
753
754 def test_async_gen_asyncio_aclose_12(self):
755 DONE = 0
756
757 async def target():
758 await asyncio.sleep(0.01)
759 1 / 0
760
761 async def foo():
762 nonlocal DONE
763 task = asyncio.create_task(target())
764 try:
765 yield 1
766 finally:
767 try:
768 await task
769 except ZeroDivisionError:
770 DONE = 1
771
772 async def run():
773 gen = foo()
774 it = gen.__aiter__()
775 await it.__anext__()
776 await gen.aclose()
777
778 self.loop.run_until_complete(run())
779 self.assertEqual(DONE, 1)
780
781 def test_async_gen_asyncio_asend_01(self):
782 DONE = 0
783
784 # Sanity check:
785 def sgen():
786 v = yield 1
787 yield v * 2
788 sg = sgen()
789 v = sg.send(None)
790 self.assertEqual(v, 1)
791 v = sg.send(100)
792 self.assertEqual(v, 200)
793
794 async def gen():
795 nonlocal DONE
796 try:
797 await asyncio.sleep(0.01)
798 v = yield 1
799 await asyncio.sleep(0.01)
800 yield v * 2
801 await asyncio.sleep(0.01)
802 return
803 finally:
804 await asyncio.sleep(0.01)
805 await asyncio.sleep(0.01)
806 DONE = 1
807
808 async def run():
809 g = gen()
810
811 v = await g.asend(None)
812 self.assertEqual(v, 1)
813
814 v = await g.asend(100)
815 self.assertEqual(v, 200)
816
817 with self.assertRaises(StopAsyncIteration):
818 await g.asend(None)
819
820 self.loop.run_until_complete(run())
821 self.assertEqual(DONE, 1)
822
823 def test_async_gen_asyncio_asend_02(self):
824 DONE = 0
825
826 async def sleep_n_crash(delay):
827 await asyncio.sleep(delay)
828 1 / 0
829
830 async def gen():
831 nonlocal DONE
832 try:
833 await asyncio.sleep(0.01)
834 v = yield 1
835 await sleep_n_crash(0.01)
836 DONE += 1000
837 yield v * 2
838 finally:
839 await asyncio.sleep(0.01)
840 await asyncio.sleep(0.01)
841 DONE = 1
842
843 async def run():
844 g = gen()
845
846 v = await g.asend(None)
847 self.assertEqual(v, 1)
848
849 await g.asend(100)
850
851 with self.assertRaises(ZeroDivisionError):
852 self.loop.run_until_complete(run())
853 self.assertEqual(DONE, 1)
854
855 def test_async_gen_asyncio_asend_03(self):
856 DONE = 0
857
858 async def sleep_n_crash(delay):
859 fut = asyncio.ensure_future(asyncio.sleep(delay),
860 loop=self.loop)
861 self.loop.call_later(delay / 2, lambda: fut.cancel())
862 return await fut
863
864 async def gen():
865 nonlocal DONE
866 try:
867 await asyncio.sleep(0.01)
868 v = yield 1
869 await sleep_n_crash(0.01)
870 DONE += 1000
871 yield v * 2
872 finally:
873 await asyncio.sleep(0.01)
874 await asyncio.sleep(0.01)
875 DONE = 1
876
877 async def run():
878 g = gen()
879
880 v = await g.asend(None)
881 self.assertEqual(v, 1)
882
883 await g.asend(100)
884
885 with self.assertRaises(asyncio.CancelledError):
886 self.loop.run_until_complete(run())
887 self.assertEqual(DONE, 1)
888
889 def test_async_gen_asyncio_athrow_01(self):
890 DONE = 0
891
892 class FooEr(Exception):
893 pass
894
895 # Sanity check:
896 def sgen():
897 try:
898 v = yield 1
899 except FooEr:
900 v = 1000
901 yield v * 2
902 sg = sgen()
903 v = sg.send(None)
904 self.assertEqual(v, 1)
905 v = sg.throw(FooEr)
906 self.assertEqual(v, 2000)
907 with self.assertRaises(StopIteration):
908 sg.send(None)
909
910 async def gen():
911 nonlocal DONE
912 try:
913 await asyncio.sleep(0.01)
914 try:
915 v = yield 1
916 except FooEr:
917 v = 1000
918 await asyncio.sleep(0.01)
919 yield v * 2
920 await asyncio.sleep(0.01)
921 # return
922 finally:
923 await asyncio.sleep(0.01)
924 await asyncio.sleep(0.01)
925 DONE = 1
926
927 async def run():
928 g = gen()
929
930 v = await g.asend(None)
931 self.assertEqual(v, 1)
932
933 v = await g.athrow(FooEr)
934 self.assertEqual(v, 2000)
935
936 with self.assertRaises(StopAsyncIteration):
937 await g.asend(None)
938
939 self.loop.run_until_complete(run())
940 self.assertEqual(DONE, 1)
941
942 def test_async_gen_asyncio_athrow_02(self):
943 DONE = 0
944
945 class FooEr(Exception):
946 pass
947
948 async def sleep_n_crash(delay):
949 fut = asyncio.ensure_future(asyncio.sleep(delay),
950 loop=self.loop)
951 self.loop.call_later(delay / 2, lambda: fut.cancel())
952 return await fut
953
954 async def gen():
955 nonlocal DONE
956 try:
957 await asyncio.sleep(0.01)
958 try:
959 v = yield 1
960 except FooEr:
961 await sleep_n_crash(0.01)
962 yield v * 2
963 await asyncio.sleep(0.01)
964 # return
965 finally:
966 await asyncio.sleep(0.01)
967 await asyncio.sleep(0.01)
968 DONE = 1
969
970 async def run():
971 g = gen()
972
973 v = await g.asend(None)
974 self.assertEqual(v, 1)
975
976 try:
977 await g.athrow(FooEr)
978 except asyncio.CancelledError:
979 self.assertEqual(DONE, 1)
980 raise
981 else:
982 self.fail('CancelledError was not raised')
983
984 with self.assertRaises(asyncio.CancelledError):
985 self.loop.run_until_complete(run())
986 self.assertEqual(DONE, 1)
987
988 def test_async_gen_asyncio_athrow_03(self):
989 DONE = 0
990
991 # test synchronous generators
992 def foo():
993 try:
994 yield
995 except:
996 pass
997 g = foo()
998 g.send(None)
999 with self.assertRaises(StopIteration):
1000 g.throw(ValueError)
1001
1002 # now with asynchronous generators
1003
1004 async def gen():
1005 nonlocal DONE
1006 try:
1007 yield
1008 except:
1009 pass
1010 DONE = 1
1011
1012 async def run():
1013 nonlocal DONE
1014 g = gen()
1015 await g.asend(None)
1016 with self.assertRaises(StopAsyncIteration):
1017 await g.athrow(ValueError)
1018 DONE += 10
1019
1020 self.loop.run_until_complete(run())
1021 self.assertEqual(DONE, 11)
1022
1023 def test_async_gen_asyncio_athrow_tuple(self):
1024 async def gen():
1025 try:
1026 yield 1
1027 except ZeroDivisionError:
1028 yield (2,)
1029
1030 async def run():
1031 g = gen()
1032 v = await g.asend(None)
1033 self.assertEqual(v, 1)
1034 v = await g.athrow(ZeroDivisionError)
1035 self.assertEqual(v, (2,))
1036 with self.assertRaises(StopAsyncIteration):
1037 await g.asend(None)
1038
1039 self.loop.run_until_complete(run())
1040
1041 def test_async_gen_asyncio_athrow_stopiteration(self):
1042 async def gen():
1043 try:
1044 yield 1
1045 except ZeroDivisionError:
1046 yield StopIteration(2)
1047
1048 async def run():
1049 g = gen()
1050 v = await g.asend(None)
1051 self.assertEqual(v, 1)
1052 v = await g.athrow(ZeroDivisionError)
1053 self.assertIsInstance(v, StopIteration)
1054 self.assertEqual(v.value, 2)
1055 with self.assertRaises(StopAsyncIteration):
1056 await g.asend(None)
1057
1058 self.loop.run_until_complete(run())
1059
1060 def test_async_gen_asyncio_shutdown_01(self):
1061 finalized = 0
1062
1063 async def waiter(timeout):
1064 nonlocal finalized
1065 try:
1066 await asyncio.sleep(timeout)
1067 yield 1
1068 finally:
1069 await asyncio.sleep(0)
1070 finalized += 1
1071
1072 async def wait():
1073 async for _ in waiter(1):
1074 pass
1075
1076 t1 = self.loop.create_task(wait())
1077 t2 = self.loop.create_task(wait())
1078
1079 self.loop.run_until_complete(asyncio.sleep(0.1))
1080
1081 # Silence warnings
1082 t1.cancel()
1083 t2.cancel()
1084
1085 with self.assertRaises(asyncio.CancelledError):
1086 self.loop.run_until_complete(t1)
1087 with self.assertRaises(asyncio.CancelledError):
1088 self.loop.run_until_complete(t2)
1089
1090 self.loop.run_until_complete(self.loop.shutdown_asyncgens())
1091
1092 self.assertEqual(finalized, 2)
1093
1094 def test_async_gen_expression_01(self):
1095 async def arange(n):
1096 for i in range(n):
1097 await asyncio.sleep(0.01)
1098 yield i
1099
1100 def make_arange(n):
1101 # This syntax is legal starting with Python 3.7
1102 return (i * 2 async for i in arange(n))
1103
1104 async def run():
1105 return [i async for i in make_arange(10)]
1106
1107 res = self.loop.run_until_complete(run())
1108 self.assertEqual(res, [i * 2 for i in range(10)])
1109
1110 def test_async_gen_expression_02(self):
1111 async def wrap(n):
1112 await asyncio.sleep(0.01)
1113 return n
1114
1115 def make_arange(n):
1116 # This syntax is legal starting with Python 3.7
1117 return (i * 2 for i in range(n) if await wrap(i))
1118
1119 async def run():
1120 return [i async for i in make_arange(10)]
1121
1122 res = self.loop.run_until_complete(run())
1123 self.assertEqual(res, [i * 2 for i in range(1, 10)])
1124
1125 def test_asyncgen_nonstarted_hooks_are_cancellable(self):
1126 # See https://bugs.python.org/issue38013
1127 messages = []
1128
1129 def exception_handler(loop, context):
1130 messages.append(context)
1131
1132 async def async_iterate():
1133 yield 1
1134 yield 2
1135
1136 async def main():
1137 loop = asyncio.get_running_loop()
1138 loop.set_exception_handler(exception_handler)
1139
1140 async for i in async_iterate():
1141 break
1142
1143 asyncio.run(main())
1144
1145 self.assertEqual([], messages)
1146
1147 def test_async_gen_await_same_anext_coro_twice(self):
1148 async def async_iterate():
1149 yield 1
1150 yield 2
1151
1152 async def run():
1153 it = async_iterate()
1154 nxt = it.__anext__()
1155 await nxt
1156 with self.assertRaisesRegex(
1157 RuntimeError,
1158 r"cannot reuse already awaited __anext__\(\)/asend\(\)"
1159 ):
1160 await nxt
1161
1162 await it.aclose() # prevent unfinished iterator warning
1163
1164 self.loop.run_until_complete(run())
1165
1166 def test_async_gen_await_same_aclose_coro_twice(self):
1167 async def async_iterate():
1168 yield 1
1169 yield 2
1170
1171 async def run():
1172 it = async_iterate()
1173 nxt = it.aclose()
1174 await nxt
1175 with self.assertRaisesRegex(
1176 RuntimeError,
1177 r"cannot reuse already awaited aclose\(\)/athrow\(\)"
1178 ):
1179 await nxt
1180
1181 self.loop.run_until_complete(run())
1182
1183 def test_async_gen_aclose_twice_with_different_coros(self):
1184 # Regression test for https://bugs.python.org/issue39606
1185 async def async_iterate():
1186 yield 1
1187 yield 2
1188
1189 async def run():
1190 it = async_iterate()
1191 await it.aclose()
1192 await it.aclose()
1193
1194 self.loop.run_until_complete(run())
1195
1196 def test_async_gen_aclose_after_exhaustion(self):
1197 # Regression test for https://bugs.python.org/issue39606
1198 async def async_iterate():
1199 yield 1
1200 yield 2
1201
1202 async def run():
1203 it = async_iterate()
1204 async for _ in it:
1205 pass
1206 await it.aclose()
1207
1208 self.loop.run_until_complete(run())
1209
1210 def test_async_gen_aclose_compatible_with_get_stack(self):
1211 async def async_generator():
1212 yield object()
1213
1214 async def run():
1215 ag = async_generator()
1216 asyncio.create_task(ag.aclose())
1217 tasks = asyncio.all_tasks()
1218 for task in tasks:
1219 # No AttributeError raised
1220 task.get_stack()
1221
1222 self.loop.run_until_complete(run())
1223
1224
1225if __name__ == "__main__":
1226 unittest.main()