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