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