blob: 34ab8a04eee2dc34d03ca0298ffc2d5a51008b51 [file] [log] [blame]
Yury Selivanoveb636452016-09-08 22:01:51 -07001import inspect
2import sys
3import types
4import unittest
5
6from unittest import mock
7
Martin Panter94332cb2016-10-20 05:10:44 +00008from test.support import import_module
9asyncio = import_module("asyncio")
10
Yury Selivanoveb636452016-09-08 22:01:51 -070011
12class AwaitException(Exception):
13 pass
14
15
16@types.coroutine
17def awaitable(*, throw=False):
18 if throw:
19 yield ('throw',)
20 else:
21 yield ('result',)
22
23
24def run_until_complete(coro):
25 exc = False
26 while True:
27 try:
28 if exc:
29 exc = False
30 fut = coro.throw(AwaitException)
31 else:
32 fut = coro.send(None)
33 except StopIteration as ex:
34 return ex.args[0]
35
36 if fut == ('throw',):
37 exc = True
38
39
40def to_list(gen):
41 async def iterate():
42 res = []
43 async for i in gen:
44 res.append(i)
45 return res
46
47 return run_until_complete(iterate())
48
49
50class AsyncGenSyntaxTest(unittest.TestCase):
51
52 def test_async_gen_syntax_01(self):
53 code = '''async def foo():
54 await abc
55 yield from 123
56 '''
57
58 with self.assertRaisesRegex(SyntaxError, 'yield from.*inside async'):
59 exec(code, {}, {})
60
61 def test_async_gen_syntax_02(self):
62 code = '''async def foo():
63 yield from 123
64 '''
65
66 with self.assertRaisesRegex(SyntaxError, 'yield from.*inside async'):
67 exec(code, {}, {})
68
69 def test_async_gen_syntax_03(self):
70 code = '''async def foo():
71 await abc
72 yield
73 return 123
74 '''
75
76 with self.assertRaisesRegex(SyntaxError, 'return.*value.*async gen'):
77 exec(code, {}, {})
78
79 def test_async_gen_syntax_04(self):
80 code = '''async def foo():
81 yield
82 return 123
83 '''
84
85 with self.assertRaisesRegex(SyntaxError, 'return.*value.*async gen'):
86 exec(code, {}, {})
87
88 def test_async_gen_syntax_05(self):
89 code = '''async def foo():
90 if 0:
91 yield
92 return 12
93 '''
94
95 with self.assertRaisesRegex(SyntaxError, 'return.*value.*async gen'):
96 exec(code, {}, {})
97
98
99class AsyncGenTest(unittest.TestCase):
100
101 def compare_generators(self, sync_gen, async_gen):
102 def sync_iterate(g):
103 res = []
104 while True:
105 try:
106 res.append(g.__next__())
107 except StopIteration:
108 res.append('STOP')
109 break
110 except Exception as ex:
111 res.append(str(type(ex)))
112 return res
113
114 def async_iterate(g):
115 res = []
116 while True:
117 try:
118 g.__anext__().__next__()
119 except StopAsyncIteration:
120 res.append('STOP')
121 break
122 except StopIteration as ex:
123 if ex.args:
124 res.append(ex.args[0])
125 else:
126 res.append('EMPTY StopIteration')
127 break
128 except Exception as ex:
129 res.append(str(type(ex)))
130 return res
131
132 sync_gen_result = sync_iterate(sync_gen)
133 async_gen_result = async_iterate(async_gen)
134 self.assertEqual(sync_gen_result, async_gen_result)
135 return async_gen_result
136
137 def test_async_gen_iteration_01(self):
138 async def gen():
139 await awaitable()
140 a = yield 123
141 self.assertIs(a, None)
142 await awaitable()
143 yield 456
144 await awaitable()
145 yield 789
146
147 self.assertEqual(to_list(gen()), [123, 456, 789])
148
149 def test_async_gen_iteration_02(self):
150 async def gen():
151 await awaitable()
152 yield 123
153 await awaitable()
154
155 g = gen()
156 ai = g.__aiter__()
157 self.assertEqual(ai.__anext__().__next__(), ('result',))
158
159 try:
160 ai.__anext__().__next__()
161 except StopIteration as ex:
162 self.assertEqual(ex.args[0], 123)
163 else:
164 self.fail('StopIteration was not raised')
165
166 self.assertEqual(ai.__anext__().__next__(), ('result',))
167
168 try:
169 ai.__anext__().__next__()
170 except StopAsyncIteration as ex:
171 self.assertFalse(ex.args)
172 else:
173 self.fail('StopAsyncIteration was not raised')
174
175 def test_async_gen_exception_03(self):
176 async def gen():
177 await awaitable()
178 yield 123
179 await awaitable(throw=True)
180 yield 456
181
182 with self.assertRaises(AwaitException):
183 to_list(gen())
184
185 def test_async_gen_exception_04(self):
186 async def gen():
187 await awaitable()
188 yield 123
189 1 / 0
190
191 g = gen()
192 ai = g.__aiter__()
193 self.assertEqual(ai.__anext__().__next__(), ('result',))
194
195 try:
196 ai.__anext__().__next__()
197 except StopIteration as ex:
198 self.assertEqual(ex.args[0], 123)
199 else:
200 self.fail('StopIteration was not raised')
201
202 with self.assertRaises(ZeroDivisionError):
203 ai.__anext__().__next__()
204
205 def test_async_gen_exception_05(self):
206 async def gen():
207 yield 123
208 raise StopAsyncIteration
209
210 with self.assertRaisesRegex(RuntimeError,
211 'async generator.*StopAsyncIteration'):
212 to_list(gen())
213
214 def test_async_gen_exception_06(self):
215 async def gen():
216 yield 123
217 raise StopIteration
218
219 with self.assertRaisesRegex(RuntimeError,
220 'async generator.*StopIteration'):
221 to_list(gen())
222
223 def test_async_gen_exception_07(self):
224 def sync_gen():
225 try:
226 yield 1
227 1 / 0
228 finally:
229 yield 2
230 yield 3
231
232 yield 100
233
234 async def async_gen():
235 try:
236 yield 1
237 1 / 0
238 finally:
239 yield 2
240 yield 3
241
242 yield 100
243
244 self.compare_generators(sync_gen(), async_gen())
245
246 def test_async_gen_exception_08(self):
247 def sync_gen():
248 try:
249 yield 1
250 finally:
251 yield 2
252 1 / 0
253 yield 3
254
255 yield 100
256
257 async def async_gen():
258 try:
259 yield 1
260 await awaitable()
261 finally:
262 await awaitable()
263 yield 2
264 1 / 0
265 yield 3
266
267 yield 100
268
269 self.compare_generators(sync_gen(), async_gen())
270
271 def test_async_gen_exception_09(self):
272 def sync_gen():
273 try:
274 yield 1
275 1 / 0
276 finally:
277 yield 2
278 yield 3
279
280 yield 100
281
282 async def async_gen():
283 try:
284 await awaitable()
285 yield 1
286 1 / 0
287 finally:
288 yield 2
289 await awaitable()
290 yield 3
291
292 yield 100
293
294 self.compare_generators(sync_gen(), async_gen())
295
296 def test_async_gen_exception_10(self):
297 async def gen():
298 yield 123
299 with self.assertRaisesRegex(TypeError,
300 "non-None value .* async generator"):
301 gen().__anext__().send(100)
302
303 def test_async_gen_api_01(self):
304 async def gen():
305 yield 123
306
307 g = gen()
308
309 self.assertEqual(g.__name__, 'gen')
310 g.__name__ = '123'
311 self.assertEqual(g.__name__, '123')
312
313 self.assertIn('.gen', g.__qualname__)
314 g.__qualname__ = '123'
315 self.assertEqual(g.__qualname__, '123')
316
317 self.assertIsNone(g.ag_await)
318 self.assertIsInstance(g.ag_frame, types.FrameType)
319 self.assertFalse(g.ag_running)
320 self.assertIsInstance(g.ag_code, types.CodeType)
321
322 self.assertTrue(inspect.isawaitable(g.aclose()))
323
324
325class AsyncGenAsyncioTest(unittest.TestCase):
326
327 def setUp(self):
328 self.loop = asyncio.new_event_loop()
329 asyncio.set_event_loop(None)
330
331 def tearDown(self):
332 self.loop.close()
333 self.loop = None
334
335 async def to_list(self, gen):
336 res = []
337 async for i in gen:
338 res.append(i)
339 return res
340
341 def test_async_gen_asyncio_01(self):
342 async def gen():
343 yield 1
344 await asyncio.sleep(0.01, loop=self.loop)
345 yield 2
346 await asyncio.sleep(0.01, loop=self.loop)
347 return
348 yield 3
349
350 res = self.loop.run_until_complete(self.to_list(gen()))
351 self.assertEqual(res, [1, 2])
352
353 def test_async_gen_asyncio_02(self):
354 async def gen():
355 yield 1
356 await asyncio.sleep(0.01, loop=self.loop)
357 yield 2
358 1 / 0
359 yield 3
360
361 with self.assertRaises(ZeroDivisionError):
362 self.loop.run_until_complete(self.to_list(gen()))
363
364 def test_async_gen_asyncio_03(self):
365 loop = self.loop
366
367 class Gen:
368 async def __aiter__(self):
369 yield 1
370 await asyncio.sleep(0.01, loop=loop)
371 yield 2
372
373 res = loop.run_until_complete(self.to_list(Gen()))
374 self.assertEqual(res, [1, 2])
375
376 def test_async_gen_asyncio_anext_04(self):
377 async def foo():
378 yield 1
379 await asyncio.sleep(0.01, loop=self.loop)
380 try:
381 yield 2
382 yield 3
383 except ZeroDivisionError:
384 yield 1000
385 await asyncio.sleep(0.01, loop=self.loop)
386 yield 4
387
388 async def run1():
389 it = foo().__aiter__()
390
391 self.assertEqual(await it.__anext__(), 1)
392 self.assertEqual(await it.__anext__(), 2)
393 self.assertEqual(await it.__anext__(), 3)
394 self.assertEqual(await it.__anext__(), 4)
395 with self.assertRaises(StopAsyncIteration):
396 await it.__anext__()
397 with self.assertRaises(StopAsyncIteration):
398 await it.__anext__()
399
400 async def run2():
401 it = foo().__aiter__()
402
403 self.assertEqual(await it.__anext__(), 1)
404 self.assertEqual(await it.__anext__(), 2)
405 try:
406 it.__anext__().throw(ZeroDivisionError)
407 except StopIteration as ex:
408 self.assertEqual(ex.args[0], 1000)
409 else:
410 self.fail('StopIteration was not raised')
411 self.assertEqual(await it.__anext__(), 4)
412 with self.assertRaises(StopAsyncIteration):
413 await it.__anext__()
414
415 self.loop.run_until_complete(run1())
416 self.loop.run_until_complete(run2())
417
418 def test_async_gen_asyncio_anext_05(self):
419 async def foo():
420 v = yield 1
421 v = yield v
422 yield v * 100
423
424 async def run():
425 it = foo().__aiter__()
426
427 try:
428 it.__anext__().send(None)
429 except StopIteration as ex:
430 self.assertEqual(ex.args[0], 1)
431 else:
432 self.fail('StopIteration was not raised')
433
434 try:
435 it.__anext__().send(10)
436 except StopIteration as ex:
437 self.assertEqual(ex.args[0], 10)
438 else:
439 self.fail('StopIteration was not raised')
440
441 try:
442 it.__anext__().send(12)
443 except StopIteration as ex:
444 self.assertEqual(ex.args[0], 1200)
445 else:
446 self.fail('StopIteration was not raised')
447
448 with self.assertRaises(StopAsyncIteration):
449 await it.__anext__()
450
451 self.loop.run_until_complete(run())
452
Yury Selivanov41782e42016-11-16 18:16:17 -0500453 def test_async_gen_asyncio_anext_06(self):
454 DONE = 0
455
456 # test synchronous generators
457 def foo():
458 try:
459 yield
460 except:
461 pass
462 g = foo()
463 g.send(None)
464 with self.assertRaises(StopIteration):
465 g.send(None)
466
467 # now with asynchronous generators
468
469 async def gen():
470 nonlocal DONE
471 try:
472 yield
473 except:
474 pass
475 DONE = 1
476
477 async def run():
478 nonlocal DONE
479 g = gen()
480 await g.asend(None)
481 with self.assertRaises(StopAsyncIteration):
482 await g.asend(None)
483 DONE += 10
484
485 self.loop.run_until_complete(run())
486 self.assertEqual(DONE, 11)
487
Serhiy Storchaka60e49aa2016-11-06 18:47:03 +0200488 def test_async_gen_asyncio_anext_tuple(self):
489 async def foo():
490 try:
491 yield (1,)
492 except ZeroDivisionError:
493 yield (2,)
494
495 async def run():
496 it = foo().__aiter__()
497
498 self.assertEqual(await it.__anext__(), (1,))
499 with self.assertRaises(StopIteration) as cm:
500 it.__anext__().throw(ZeroDivisionError)
501 self.assertEqual(cm.exception.args[0], (2,))
502 with self.assertRaises(StopAsyncIteration):
503 await it.__anext__()
504
505 self.loop.run_until_complete(run())
506
507 def test_async_gen_asyncio_anext_stopiteration(self):
508 async def foo():
509 try:
510 yield StopIteration(1)
511 except ZeroDivisionError:
512 yield StopIteration(3)
513
514 async def run():
515 it = foo().__aiter__()
516
517 v = await it.__anext__()
518 self.assertIsInstance(v, StopIteration)
519 self.assertEqual(v.value, 1)
520 with self.assertRaises(StopIteration) as cm:
521 it.__anext__().throw(ZeroDivisionError)
522 v = cm.exception.args[0]
523 self.assertIsInstance(v, StopIteration)
524 self.assertEqual(v.value, 3)
525 with self.assertRaises(StopAsyncIteration):
526 await it.__anext__()
527
528 self.loop.run_until_complete(run())
529
Yury Selivanoveb636452016-09-08 22:01:51 -0700530 def test_async_gen_asyncio_aclose_06(self):
531 async def foo():
532 try:
533 yield 1
534 1 / 0
535 finally:
536 await asyncio.sleep(0.01, loop=self.loop)
537 yield 12
538
539 async def run():
540 gen = foo()
541 it = gen.__aiter__()
542 await it.__anext__()
543 await gen.aclose()
544
545 with self.assertRaisesRegex(
546 RuntimeError,
547 "async generator ignored GeneratorExit"):
548 self.loop.run_until_complete(run())
549
550 def test_async_gen_asyncio_aclose_07(self):
551 DONE = 0
552
553 async def foo():
554 nonlocal DONE
555 try:
556 yield 1
557 1 / 0
558 finally:
559 await asyncio.sleep(0.01, loop=self.loop)
560 await asyncio.sleep(0.01, loop=self.loop)
561 DONE += 1
562 DONE += 1000
563
564 async def run():
565 gen = foo()
566 it = gen.__aiter__()
567 await it.__anext__()
568 await gen.aclose()
569
570 self.loop.run_until_complete(run())
571 self.assertEqual(DONE, 1)
572
573 def test_async_gen_asyncio_aclose_08(self):
574 DONE = 0
575
576 fut = asyncio.Future(loop=self.loop)
577
578 async def foo():
579 nonlocal DONE
580 try:
581 yield 1
582 await fut
583 DONE += 1000
584 yield 2
585 finally:
586 await asyncio.sleep(0.01, loop=self.loop)
587 await asyncio.sleep(0.01, loop=self.loop)
588 DONE += 1
589 DONE += 1000
590
591 async def run():
592 gen = foo()
593 it = gen.__aiter__()
594 self.assertEqual(await it.__anext__(), 1)
595 t = self.loop.create_task(it.__anext__())
596 await asyncio.sleep(0.01, loop=self.loop)
597 await gen.aclose()
598 return t
599
600 t = self.loop.run_until_complete(run())
601 self.assertEqual(DONE, 1)
602
603 # Silence ResourceWarnings
604 fut.cancel()
605 t.cancel()
606 self.loop.run_until_complete(asyncio.sleep(0.01, loop=self.loop))
607
608 def test_async_gen_asyncio_gc_aclose_09(self):
609 DONE = 0
610
611 async def gen():
612 nonlocal DONE
613 try:
614 while True:
615 yield 1
616 finally:
617 await asyncio.sleep(0.01, loop=self.loop)
618 await asyncio.sleep(0.01, loop=self.loop)
619 DONE = 1
620
621 async def run():
622 g = gen()
623 await g.__anext__()
624 await g.__anext__()
625 del g
626
627 await asyncio.sleep(0.1, loop=self.loop)
628
629 self.loop.run_until_complete(run())
630 self.assertEqual(DONE, 1)
631
Yury Selivanov41782e42016-11-16 18:16:17 -0500632 def test_async_gen_asyncio_aclose_10(self):
633 DONE = 0
634
635 # test synchronous generators
636 def foo():
637 try:
638 yield
639 except:
640 pass
641 g = foo()
642 g.send(None)
643 g.close()
644
645 # now with asynchronous generators
646
647 async def gen():
648 nonlocal DONE
649 try:
650 yield
651 except:
652 pass
653 DONE = 1
654
655 async def run():
656 nonlocal DONE
657 g = gen()
658 await g.asend(None)
659 await g.aclose()
660 DONE += 10
661
662 self.loop.run_until_complete(run())
663 self.assertEqual(DONE, 11)
664
665 def test_async_gen_asyncio_aclose_11(self):
666 DONE = 0
667
668 # test synchronous generators
669 def foo():
670 try:
671 yield
672 except:
673 pass
674 yield
675 g = foo()
676 g.send(None)
677 with self.assertRaisesRegex(RuntimeError, 'ignored GeneratorExit'):
678 g.close()
679
680 # now with asynchronous generators
681
682 async def gen():
683 nonlocal DONE
684 try:
685 yield
686 except:
687 pass
688 yield
689 DONE += 1
690
691 async def run():
692 nonlocal DONE
693 g = gen()
694 await g.asend(None)
695 with self.assertRaisesRegex(RuntimeError, 'ignored GeneratorExit'):
696 await g.aclose()
697 DONE += 10
698
699 self.loop.run_until_complete(run())
700 self.assertEqual(DONE, 10)
701
Yury Selivanoveb636452016-09-08 22:01:51 -0700702 def test_async_gen_asyncio_asend_01(self):
703 DONE = 0
704
705 # Sanity check:
706 def sgen():
707 v = yield 1
708 yield v * 2
709 sg = sgen()
710 v = sg.send(None)
711 self.assertEqual(v, 1)
712 v = sg.send(100)
713 self.assertEqual(v, 200)
714
715 async def gen():
716 nonlocal DONE
717 try:
718 await asyncio.sleep(0.01, loop=self.loop)
719 v = yield 1
720 await asyncio.sleep(0.01, loop=self.loop)
721 yield v * 2
722 await asyncio.sleep(0.01, loop=self.loop)
723 return
724 finally:
725 await asyncio.sleep(0.01, loop=self.loop)
726 await asyncio.sleep(0.01, loop=self.loop)
727 DONE = 1
728
729 async def run():
730 g = gen()
731
732 v = await g.asend(None)
733 self.assertEqual(v, 1)
734
735 v = await g.asend(100)
736 self.assertEqual(v, 200)
737
738 with self.assertRaises(StopAsyncIteration):
739 await g.asend(None)
740
741 self.loop.run_until_complete(run())
742 self.assertEqual(DONE, 1)
743
744 def test_async_gen_asyncio_asend_02(self):
745 DONE = 0
746
747 async def sleep_n_crash(delay):
748 await asyncio.sleep(delay, loop=self.loop)
749 1 / 0
750
751 async def gen():
752 nonlocal DONE
753 try:
754 await asyncio.sleep(0.01, loop=self.loop)
755 v = yield 1
756 await sleep_n_crash(0.01)
757 DONE += 1000
758 yield v * 2
759 finally:
760 await asyncio.sleep(0.01, loop=self.loop)
761 await asyncio.sleep(0.01, loop=self.loop)
762 DONE = 1
763
764 async def run():
765 g = gen()
766
767 v = await g.asend(None)
768 self.assertEqual(v, 1)
769
770 await g.asend(100)
771
772 with self.assertRaises(ZeroDivisionError):
773 self.loop.run_until_complete(run())
774 self.assertEqual(DONE, 1)
775
776 def test_async_gen_asyncio_asend_03(self):
777 DONE = 0
778
779 async def sleep_n_crash(delay):
780 fut = asyncio.ensure_future(asyncio.sleep(delay, loop=self.loop),
781 loop=self.loop)
782 self.loop.call_later(delay / 2, lambda: fut.cancel())
783 return await fut
784
785 async def gen():
786 nonlocal DONE
787 try:
788 await asyncio.sleep(0.01, loop=self.loop)
789 v = yield 1
790 await sleep_n_crash(0.01)
791 DONE += 1000
792 yield v * 2
793 finally:
794 await asyncio.sleep(0.01, loop=self.loop)
795 await asyncio.sleep(0.01, loop=self.loop)
796 DONE = 1
797
798 async def run():
799 g = gen()
800
801 v = await g.asend(None)
802 self.assertEqual(v, 1)
803
804 await g.asend(100)
805
806 with self.assertRaises(asyncio.CancelledError):
807 self.loop.run_until_complete(run())
808 self.assertEqual(DONE, 1)
809
810 def test_async_gen_asyncio_athrow_01(self):
811 DONE = 0
812
813 class FooEr(Exception):
814 pass
815
816 # Sanity check:
817 def sgen():
818 try:
819 v = yield 1
820 except FooEr:
821 v = 1000
822 yield v * 2
823 sg = sgen()
824 v = sg.send(None)
825 self.assertEqual(v, 1)
826 v = sg.throw(FooEr)
827 self.assertEqual(v, 2000)
828 with self.assertRaises(StopIteration):
829 sg.send(None)
830
831 async def gen():
832 nonlocal DONE
833 try:
834 await asyncio.sleep(0.01, loop=self.loop)
835 try:
836 v = yield 1
837 except FooEr:
838 v = 1000
839 await asyncio.sleep(0.01, loop=self.loop)
840 yield v * 2
841 await asyncio.sleep(0.01, loop=self.loop)
842 # return
843 finally:
844 await asyncio.sleep(0.01, loop=self.loop)
845 await asyncio.sleep(0.01, loop=self.loop)
846 DONE = 1
847
848 async def run():
849 g = gen()
850
851 v = await g.asend(None)
852 self.assertEqual(v, 1)
853
854 v = await g.athrow(FooEr)
855 self.assertEqual(v, 2000)
856
857 with self.assertRaises(StopAsyncIteration):
858 await g.asend(None)
859
860 self.loop.run_until_complete(run())
861 self.assertEqual(DONE, 1)
862
863 def test_async_gen_asyncio_athrow_02(self):
864 DONE = 0
865
866 class FooEr(Exception):
867 pass
868
869 async def sleep_n_crash(delay):
870 fut = asyncio.ensure_future(asyncio.sleep(delay, loop=self.loop),
871 loop=self.loop)
872 self.loop.call_later(delay / 2, lambda: fut.cancel())
873 return await fut
874
875 async def gen():
876 nonlocal DONE
877 try:
878 await asyncio.sleep(0.01, loop=self.loop)
879 try:
880 v = yield 1
881 except FooEr:
882 await sleep_n_crash(0.01)
883 yield v * 2
884 await asyncio.sleep(0.01, loop=self.loop)
885 # return
886 finally:
887 await asyncio.sleep(0.01, loop=self.loop)
888 await asyncio.sleep(0.01, loop=self.loop)
889 DONE = 1
890
891 async def run():
892 g = gen()
893
894 v = await g.asend(None)
895 self.assertEqual(v, 1)
896
897 try:
898 await g.athrow(FooEr)
899 except asyncio.CancelledError:
900 self.assertEqual(DONE, 1)
901 raise
902 else:
903 self.fail('CancelledError was not raised')
904
905 with self.assertRaises(asyncio.CancelledError):
906 self.loop.run_until_complete(run())
907 self.assertEqual(DONE, 1)
908
Yury Selivanov41782e42016-11-16 18:16:17 -0500909 def test_async_gen_asyncio_athrow_03(self):
910 DONE = 0
911
912 # test synchronous generators
913 def foo():
914 try:
915 yield
916 except:
917 pass
918 g = foo()
919 g.send(None)
920 with self.assertRaises(StopIteration):
921 g.throw(ValueError)
922
923 # now with asynchronous generators
924
925 async def gen():
926 nonlocal DONE
927 try:
928 yield
929 except:
930 pass
931 DONE = 1
932
933 async def run():
934 nonlocal DONE
935 g = gen()
936 await g.asend(None)
937 with self.assertRaises(StopAsyncIteration):
938 await g.athrow(ValueError)
939 DONE += 10
940
941 self.loop.run_until_complete(run())
942 self.assertEqual(DONE, 11)
943
Serhiy Storchaka60e49aa2016-11-06 18:47:03 +0200944 def test_async_gen_asyncio_athrow_tuple(self):
945 async def gen():
946 try:
947 yield 1
948 except ZeroDivisionError:
949 yield (2,)
950
951 async def run():
952 g = gen()
953 v = await g.asend(None)
954 self.assertEqual(v, 1)
955 v = await g.athrow(ZeroDivisionError)
956 self.assertEqual(v, (2,))
957 with self.assertRaises(StopAsyncIteration):
958 await g.asend(None)
959
960 self.loop.run_until_complete(run())
961
962 def test_async_gen_asyncio_athrow_stopiteration(self):
963 async def gen():
964 try:
965 yield 1
966 except ZeroDivisionError:
967 yield StopIteration(2)
968
969 async def run():
970 g = gen()
971 v = await g.asend(None)
972 self.assertEqual(v, 1)
973 v = await g.athrow(ZeroDivisionError)
974 self.assertIsInstance(v, StopIteration)
975 self.assertEqual(v.value, 2)
976 with self.assertRaises(StopAsyncIteration):
977 await g.asend(None)
978
979 self.loop.run_until_complete(run())
980
Yury Selivanoveb636452016-09-08 22:01:51 -0700981 def test_async_gen_asyncio_shutdown_01(self):
982 finalized = 0
983
984 async def waiter(timeout):
985 nonlocal finalized
986 try:
987 await asyncio.sleep(timeout, loop=self.loop)
988 yield 1
989 finally:
990 await asyncio.sleep(0, loop=self.loop)
991 finalized += 1
992
993 async def wait():
994 async for _ in waiter(1):
995 pass
996
997 t1 = self.loop.create_task(wait())
998 t2 = self.loop.create_task(wait())
999
1000 self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop))
1001
1002 self.loop.run_until_complete(self.loop.shutdown_asyncgens())
1003 self.assertEqual(finalized, 2)
1004
1005 # Silence warnings
1006 t1.cancel()
1007 t2.cancel()
1008 self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop))
1009
1010 def test_async_gen_asyncio_shutdown_02(self):
1011 logged = 0
1012
1013 def logger(loop, context):
1014 nonlocal logged
1015 self.assertIn('asyncgen', context)
1016 expected = 'an error occurred during closing of asynchronous'
1017 if expected in context['message']:
1018 logged += 1
1019
1020 async def waiter(timeout):
1021 try:
1022 await asyncio.sleep(timeout, loop=self.loop)
1023 yield 1
1024 finally:
1025 1 / 0
1026
1027 async def wait():
1028 async for _ in waiter(1):
1029 pass
1030
1031 t = self.loop.create_task(wait())
1032 self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop))
1033
1034 self.loop.set_exception_handler(logger)
1035 self.loop.run_until_complete(self.loop.shutdown_asyncgens())
1036
1037 self.assertEqual(logged, 1)
1038
1039 # Silence warnings
1040 t.cancel()
1041 self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop))
1042
1043if __name__ == "__main__":
1044 unittest.main()