blob: 71b0968c7944d6cabe0de937911281caec0fd1c2 [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:
Yury Selivanov52698c72018-06-07 20:31:26 -0400114 an = g.__anext__()
115 try:
116 while True:
117 try:
118 an.__next__()
119 except StopIteration as ex:
120 if ex.args:
121 res.append(ex.args[0])
122 break
123 else:
124 res.append('EMPTY StopIteration')
125 break
126 except StopAsyncIteration:
127 raise
128 except Exception as ex:
129 res.append(str(type(ex)))
130 break
131 except StopAsyncIteration:
132 res.append('STOP')
133 break
134 return res
135
136 def async_iterate(g):
137 res = []
138 while True:
Yury Selivanoveb636452016-09-08 22:01:51 -0700139 try:
140 g.__anext__().__next__()
141 except StopAsyncIteration:
142 res.append('STOP')
143 break
144 except StopIteration as ex:
145 if ex.args:
146 res.append(ex.args[0])
147 else:
148 res.append('EMPTY StopIteration')
149 break
150 except Exception as ex:
151 res.append(str(type(ex)))
152 return res
153
154 sync_gen_result = sync_iterate(sync_gen)
155 async_gen_result = async_iterate(async_gen)
156 self.assertEqual(sync_gen_result, async_gen_result)
157 return async_gen_result
158
159 def test_async_gen_iteration_01(self):
160 async def gen():
161 await awaitable()
162 a = yield 123
163 self.assertIs(a, None)
164 await awaitable()
165 yield 456
166 await awaitable()
167 yield 789
168
169 self.assertEqual(to_list(gen()), [123, 456, 789])
170
171 def test_async_gen_iteration_02(self):
172 async def gen():
173 await awaitable()
174 yield 123
175 await awaitable()
176
177 g = gen()
178 ai = g.__aiter__()
179 self.assertEqual(ai.__anext__().__next__(), ('result',))
180
181 try:
182 ai.__anext__().__next__()
183 except StopIteration as ex:
184 self.assertEqual(ex.args[0], 123)
185 else:
186 self.fail('StopIteration was not raised')
187
188 self.assertEqual(ai.__anext__().__next__(), ('result',))
189
190 try:
191 ai.__anext__().__next__()
192 except StopAsyncIteration as ex:
193 self.assertFalse(ex.args)
194 else:
195 self.fail('StopAsyncIteration was not raised')
196
197 def test_async_gen_exception_03(self):
198 async def gen():
199 await awaitable()
200 yield 123
201 await awaitable(throw=True)
202 yield 456
203
204 with self.assertRaises(AwaitException):
205 to_list(gen())
206
207 def test_async_gen_exception_04(self):
208 async def gen():
209 await awaitable()
210 yield 123
211 1 / 0
212
213 g = gen()
214 ai = g.__aiter__()
215 self.assertEqual(ai.__anext__().__next__(), ('result',))
216
217 try:
218 ai.__anext__().__next__()
219 except StopIteration as ex:
220 self.assertEqual(ex.args[0], 123)
221 else:
222 self.fail('StopIteration was not raised')
223
224 with self.assertRaises(ZeroDivisionError):
225 ai.__anext__().__next__()
226
227 def test_async_gen_exception_05(self):
228 async def gen():
229 yield 123
230 raise StopAsyncIteration
231
232 with self.assertRaisesRegex(RuntimeError,
233 'async generator.*StopAsyncIteration'):
234 to_list(gen())
235
236 def test_async_gen_exception_06(self):
237 async def gen():
238 yield 123
239 raise StopIteration
240
241 with self.assertRaisesRegex(RuntimeError,
242 'async generator.*StopIteration'):
243 to_list(gen())
244
245 def test_async_gen_exception_07(self):
246 def sync_gen():
247 try:
248 yield 1
249 1 / 0
250 finally:
251 yield 2
252 yield 3
253
254 yield 100
255
256 async def async_gen():
257 try:
258 yield 1
259 1 / 0
260 finally:
261 yield 2
262 yield 3
263
264 yield 100
265
266 self.compare_generators(sync_gen(), async_gen())
267
268 def test_async_gen_exception_08(self):
269 def sync_gen():
270 try:
271 yield 1
272 finally:
273 yield 2
274 1 / 0
275 yield 3
276
277 yield 100
278
279 async def async_gen():
280 try:
281 yield 1
282 await awaitable()
283 finally:
284 await awaitable()
285 yield 2
286 1 / 0
287 yield 3
288
289 yield 100
290
291 self.compare_generators(sync_gen(), async_gen())
292
293 def test_async_gen_exception_09(self):
294 def sync_gen():
295 try:
296 yield 1
297 1 / 0
298 finally:
299 yield 2
300 yield 3
301
302 yield 100
303
304 async def async_gen():
305 try:
306 await awaitable()
307 yield 1
308 1 / 0
309 finally:
310 yield 2
311 await awaitable()
312 yield 3
313
314 yield 100
315
316 self.compare_generators(sync_gen(), async_gen())
317
318 def test_async_gen_exception_10(self):
319 async def gen():
320 yield 123
321 with self.assertRaisesRegex(TypeError,
322 "non-None value .* async generator"):
323 gen().__anext__().send(100)
324
Yury Selivanov52698c72018-06-07 20:31:26 -0400325 def test_async_gen_exception_11(self):
326 def sync_gen():
327 yield 10
328 yield 20
329
330 def sync_gen_wrapper():
331 yield 1
332 sg = sync_gen()
333 sg.send(None)
334 try:
335 sg.throw(GeneratorExit())
336 except GeneratorExit:
337 yield 2
338 yield 3
339
340 async def async_gen():
341 yield 10
342 yield 20
343
344 async def async_gen_wrapper():
345 yield 1
346 asg = async_gen()
347 await asg.asend(None)
348 try:
349 await asg.athrow(GeneratorExit())
350 except GeneratorExit:
351 yield 2
352 yield 3
353
354 self.compare_generators(sync_gen_wrapper(), async_gen_wrapper())
355
Yury Selivanoveb636452016-09-08 22:01:51 -0700356 def test_async_gen_api_01(self):
357 async def gen():
358 yield 123
359
360 g = gen()
361
362 self.assertEqual(g.__name__, 'gen')
363 g.__name__ = '123'
364 self.assertEqual(g.__name__, '123')
365
366 self.assertIn('.gen', g.__qualname__)
367 g.__qualname__ = '123'
368 self.assertEqual(g.__qualname__, '123')
369
370 self.assertIsNone(g.ag_await)
371 self.assertIsInstance(g.ag_frame, types.FrameType)
372 self.assertFalse(g.ag_running)
373 self.assertIsInstance(g.ag_code, types.CodeType)
374
375 self.assertTrue(inspect.isawaitable(g.aclose()))
376
377
378class AsyncGenAsyncioTest(unittest.TestCase):
379
380 def setUp(self):
381 self.loop = asyncio.new_event_loop()
382 asyncio.set_event_loop(None)
383
384 def tearDown(self):
385 self.loop.close()
386 self.loop = None
Brett Cannon8425de42018-06-01 20:34:09 -0700387 asyncio.set_event_loop_policy(None)
Yury Selivanoveb636452016-09-08 22:01:51 -0700388
389 async def to_list(self, gen):
390 res = []
391 async for i in gen:
392 res.append(i)
393 return res
394
395 def test_async_gen_asyncio_01(self):
396 async def gen():
397 yield 1
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400398 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700399 yield 2
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400400 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700401 return
402 yield 3
403
404 res = self.loop.run_until_complete(self.to_list(gen()))
405 self.assertEqual(res, [1, 2])
406
407 def test_async_gen_asyncio_02(self):
408 async def gen():
409 yield 1
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400410 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700411 yield 2
412 1 / 0
413 yield 3
414
415 with self.assertRaises(ZeroDivisionError):
416 self.loop.run_until_complete(self.to_list(gen()))
417
418 def test_async_gen_asyncio_03(self):
419 loop = self.loop
420
421 class Gen:
422 async def __aiter__(self):
423 yield 1
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400424 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700425 yield 2
426
427 res = loop.run_until_complete(self.to_list(Gen()))
428 self.assertEqual(res, [1, 2])
429
430 def test_async_gen_asyncio_anext_04(self):
431 async def foo():
432 yield 1
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400433 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700434 try:
435 yield 2
436 yield 3
437 except ZeroDivisionError:
438 yield 1000
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400439 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700440 yield 4
441
442 async def run1():
443 it = foo().__aiter__()
444
445 self.assertEqual(await it.__anext__(), 1)
446 self.assertEqual(await it.__anext__(), 2)
447 self.assertEqual(await it.__anext__(), 3)
448 self.assertEqual(await it.__anext__(), 4)
449 with self.assertRaises(StopAsyncIteration):
450 await it.__anext__()
451 with self.assertRaises(StopAsyncIteration):
452 await it.__anext__()
453
454 async def run2():
455 it = foo().__aiter__()
456
457 self.assertEqual(await it.__anext__(), 1)
458 self.assertEqual(await it.__anext__(), 2)
459 try:
460 it.__anext__().throw(ZeroDivisionError)
461 except StopIteration as ex:
462 self.assertEqual(ex.args[0], 1000)
463 else:
464 self.fail('StopIteration was not raised')
465 self.assertEqual(await it.__anext__(), 4)
466 with self.assertRaises(StopAsyncIteration):
467 await it.__anext__()
468
469 self.loop.run_until_complete(run1())
470 self.loop.run_until_complete(run2())
471
472 def test_async_gen_asyncio_anext_05(self):
473 async def foo():
474 v = yield 1
475 v = yield v
476 yield v * 100
477
478 async def run():
479 it = foo().__aiter__()
480
481 try:
482 it.__anext__().send(None)
483 except StopIteration as ex:
484 self.assertEqual(ex.args[0], 1)
485 else:
486 self.fail('StopIteration was not raised')
487
488 try:
489 it.__anext__().send(10)
490 except StopIteration as ex:
491 self.assertEqual(ex.args[0], 10)
492 else:
493 self.fail('StopIteration was not raised')
494
495 try:
496 it.__anext__().send(12)
497 except StopIteration as ex:
498 self.assertEqual(ex.args[0], 1200)
499 else:
500 self.fail('StopIteration was not raised')
501
502 with self.assertRaises(StopAsyncIteration):
503 await it.__anext__()
504
505 self.loop.run_until_complete(run())
506
Yury Selivanov41782e42016-11-16 18:16:17 -0500507 def test_async_gen_asyncio_anext_06(self):
508 DONE = 0
509
510 # test synchronous generators
511 def foo():
512 try:
513 yield
514 except:
515 pass
516 g = foo()
517 g.send(None)
518 with self.assertRaises(StopIteration):
519 g.send(None)
520
521 # now with asynchronous generators
522
523 async def gen():
524 nonlocal DONE
525 try:
526 yield
527 except:
528 pass
529 DONE = 1
530
531 async def run():
532 nonlocal DONE
533 g = gen()
534 await g.asend(None)
535 with self.assertRaises(StopAsyncIteration):
536 await g.asend(None)
537 DONE += 10
538
539 self.loop.run_until_complete(run())
540 self.assertEqual(DONE, 11)
541
Serhiy Storchaka60e49aa2016-11-06 18:47:03 +0200542 def test_async_gen_asyncio_anext_tuple(self):
543 async def foo():
544 try:
545 yield (1,)
546 except ZeroDivisionError:
547 yield (2,)
548
549 async def run():
550 it = foo().__aiter__()
551
552 self.assertEqual(await it.__anext__(), (1,))
553 with self.assertRaises(StopIteration) as cm:
554 it.__anext__().throw(ZeroDivisionError)
555 self.assertEqual(cm.exception.args[0], (2,))
556 with self.assertRaises(StopAsyncIteration):
557 await it.__anext__()
558
559 self.loop.run_until_complete(run())
560
561 def test_async_gen_asyncio_anext_stopiteration(self):
562 async def foo():
563 try:
564 yield StopIteration(1)
565 except ZeroDivisionError:
566 yield StopIteration(3)
567
568 async def run():
569 it = foo().__aiter__()
570
571 v = await it.__anext__()
572 self.assertIsInstance(v, StopIteration)
573 self.assertEqual(v.value, 1)
574 with self.assertRaises(StopIteration) as cm:
575 it.__anext__().throw(ZeroDivisionError)
576 v = cm.exception.args[0]
577 self.assertIsInstance(v, StopIteration)
578 self.assertEqual(v.value, 3)
579 with self.assertRaises(StopAsyncIteration):
580 await it.__anext__()
581
582 self.loop.run_until_complete(run())
583
Yury Selivanoveb636452016-09-08 22:01:51 -0700584 def test_async_gen_asyncio_aclose_06(self):
585 async def foo():
586 try:
587 yield 1
588 1 / 0
589 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400590 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700591 yield 12
592
593 async def run():
594 gen = foo()
595 it = gen.__aiter__()
596 await it.__anext__()
597 await gen.aclose()
598
599 with self.assertRaisesRegex(
600 RuntimeError,
601 "async generator ignored GeneratorExit"):
602 self.loop.run_until_complete(run())
603
604 def test_async_gen_asyncio_aclose_07(self):
605 DONE = 0
606
607 async def foo():
608 nonlocal DONE
609 try:
610 yield 1
611 1 / 0
612 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400613 await asyncio.sleep(0.01)
614 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700615 DONE += 1
616 DONE += 1000
617
618 async def run():
619 gen = foo()
620 it = gen.__aiter__()
621 await it.__anext__()
622 await gen.aclose()
623
624 self.loop.run_until_complete(run())
625 self.assertEqual(DONE, 1)
626
627 def test_async_gen_asyncio_aclose_08(self):
628 DONE = 0
629
630 fut = asyncio.Future(loop=self.loop)
631
632 async def foo():
633 nonlocal DONE
634 try:
635 yield 1
636 await fut
637 DONE += 1000
638 yield 2
639 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400640 await asyncio.sleep(0.01)
641 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700642 DONE += 1
643 DONE += 1000
644
645 async def run():
646 gen = foo()
647 it = gen.__aiter__()
648 self.assertEqual(await it.__anext__(), 1)
649 t = self.loop.create_task(it.__anext__())
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400650 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700651 await gen.aclose()
652 return t
653
654 t = self.loop.run_until_complete(run())
655 self.assertEqual(DONE, 1)
656
657 # Silence ResourceWarnings
658 fut.cancel()
659 t.cancel()
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400660 self.loop.run_until_complete(asyncio.sleep(0.01))
Yury Selivanoveb636452016-09-08 22:01:51 -0700661
662 def test_async_gen_asyncio_gc_aclose_09(self):
663 DONE = 0
664
665 async def gen():
666 nonlocal DONE
667 try:
668 while True:
669 yield 1
670 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400671 await asyncio.sleep(0.01)
672 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700673 DONE = 1
674
675 async def run():
676 g = gen()
677 await g.__anext__()
678 await g.__anext__()
679 del g
680
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400681 await asyncio.sleep(0.1)
Yury Selivanoveb636452016-09-08 22:01:51 -0700682
683 self.loop.run_until_complete(run())
684 self.assertEqual(DONE, 1)
685
Yury Selivanov41782e42016-11-16 18:16:17 -0500686 def test_async_gen_asyncio_aclose_10(self):
687 DONE = 0
688
689 # test synchronous generators
690 def foo():
691 try:
692 yield
693 except:
694 pass
695 g = foo()
696 g.send(None)
697 g.close()
698
699 # now with asynchronous generators
700
701 async def gen():
702 nonlocal DONE
703 try:
704 yield
705 except:
706 pass
707 DONE = 1
708
709 async def run():
710 nonlocal DONE
711 g = gen()
712 await g.asend(None)
713 await g.aclose()
714 DONE += 10
715
716 self.loop.run_until_complete(run())
717 self.assertEqual(DONE, 11)
718
719 def test_async_gen_asyncio_aclose_11(self):
720 DONE = 0
721
722 # test synchronous generators
723 def foo():
724 try:
725 yield
726 except:
727 pass
728 yield
729 g = foo()
730 g.send(None)
731 with self.assertRaisesRegex(RuntimeError, 'ignored GeneratorExit'):
732 g.close()
733
734 # now with asynchronous generators
735
736 async def gen():
737 nonlocal DONE
738 try:
739 yield
740 except:
741 pass
742 yield
743 DONE += 1
744
745 async def run():
746 nonlocal DONE
747 g = gen()
748 await g.asend(None)
749 with self.assertRaisesRegex(RuntimeError, 'ignored GeneratorExit'):
750 await g.aclose()
751 DONE += 10
752
753 self.loop.run_until_complete(run())
754 self.assertEqual(DONE, 10)
755
Yury Selivanoveb636452016-09-08 22:01:51 -0700756 def test_async_gen_asyncio_asend_01(self):
757 DONE = 0
758
759 # Sanity check:
760 def sgen():
761 v = yield 1
762 yield v * 2
763 sg = sgen()
764 v = sg.send(None)
765 self.assertEqual(v, 1)
766 v = sg.send(100)
767 self.assertEqual(v, 200)
768
769 async def gen():
770 nonlocal DONE
771 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400772 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700773 v = yield 1
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400774 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700775 yield v * 2
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400776 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700777 return
778 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400779 await asyncio.sleep(0.01)
780 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700781 DONE = 1
782
783 async def run():
784 g = gen()
785
786 v = await g.asend(None)
787 self.assertEqual(v, 1)
788
789 v = await g.asend(100)
790 self.assertEqual(v, 200)
791
792 with self.assertRaises(StopAsyncIteration):
793 await g.asend(None)
794
795 self.loop.run_until_complete(run())
796 self.assertEqual(DONE, 1)
797
798 def test_async_gen_asyncio_asend_02(self):
799 DONE = 0
800
801 async def sleep_n_crash(delay):
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400802 await asyncio.sleep(delay)
Yury Selivanoveb636452016-09-08 22:01:51 -0700803 1 / 0
804
805 async def gen():
806 nonlocal DONE
807 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400808 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700809 v = yield 1
810 await sleep_n_crash(0.01)
811 DONE += 1000
812 yield v * 2
813 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400814 await asyncio.sleep(0.01)
815 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700816 DONE = 1
817
818 async def run():
819 g = gen()
820
821 v = await g.asend(None)
822 self.assertEqual(v, 1)
823
824 await g.asend(100)
825
826 with self.assertRaises(ZeroDivisionError):
827 self.loop.run_until_complete(run())
828 self.assertEqual(DONE, 1)
829
830 def test_async_gen_asyncio_asend_03(self):
831 DONE = 0
832
833 async def sleep_n_crash(delay):
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400834 fut = asyncio.ensure_future(asyncio.sleep(delay),
Yury Selivanoveb636452016-09-08 22:01:51 -0700835 loop=self.loop)
836 self.loop.call_later(delay / 2, lambda: fut.cancel())
837 return await fut
838
839 async def gen():
840 nonlocal DONE
841 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400842 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700843 v = yield 1
844 await sleep_n_crash(0.01)
845 DONE += 1000
846 yield v * 2
847 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400848 await asyncio.sleep(0.01)
849 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700850 DONE = 1
851
852 async def run():
853 g = gen()
854
855 v = await g.asend(None)
856 self.assertEqual(v, 1)
857
858 await g.asend(100)
859
860 with self.assertRaises(asyncio.CancelledError):
861 self.loop.run_until_complete(run())
862 self.assertEqual(DONE, 1)
863
864 def test_async_gen_asyncio_athrow_01(self):
865 DONE = 0
866
867 class FooEr(Exception):
868 pass
869
870 # Sanity check:
871 def sgen():
872 try:
873 v = yield 1
874 except FooEr:
875 v = 1000
876 yield v * 2
877 sg = sgen()
878 v = sg.send(None)
879 self.assertEqual(v, 1)
880 v = sg.throw(FooEr)
881 self.assertEqual(v, 2000)
882 with self.assertRaises(StopIteration):
883 sg.send(None)
884
885 async def gen():
886 nonlocal DONE
887 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400888 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700889 try:
890 v = yield 1
891 except FooEr:
892 v = 1000
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400893 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700894 yield v * 2
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400895 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700896 # return
897 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400898 await asyncio.sleep(0.01)
899 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700900 DONE = 1
901
902 async def run():
903 g = gen()
904
905 v = await g.asend(None)
906 self.assertEqual(v, 1)
907
908 v = await g.athrow(FooEr)
909 self.assertEqual(v, 2000)
910
911 with self.assertRaises(StopAsyncIteration):
912 await g.asend(None)
913
914 self.loop.run_until_complete(run())
915 self.assertEqual(DONE, 1)
916
917 def test_async_gen_asyncio_athrow_02(self):
918 DONE = 0
919
920 class FooEr(Exception):
921 pass
922
923 async def sleep_n_crash(delay):
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400924 fut = asyncio.ensure_future(asyncio.sleep(delay),
Yury Selivanoveb636452016-09-08 22:01:51 -0700925 loop=self.loop)
926 self.loop.call_later(delay / 2, lambda: fut.cancel())
927 return await fut
928
929 async def gen():
930 nonlocal DONE
931 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400932 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700933 try:
934 v = yield 1
935 except FooEr:
936 await sleep_n_crash(0.01)
937 yield v * 2
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400938 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700939 # return
940 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400941 await asyncio.sleep(0.01)
942 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700943 DONE = 1
944
945 async def run():
946 g = gen()
947
948 v = await g.asend(None)
949 self.assertEqual(v, 1)
950
951 try:
952 await g.athrow(FooEr)
953 except asyncio.CancelledError:
954 self.assertEqual(DONE, 1)
955 raise
956 else:
957 self.fail('CancelledError was not raised')
958
959 with self.assertRaises(asyncio.CancelledError):
960 self.loop.run_until_complete(run())
961 self.assertEqual(DONE, 1)
962
Yury Selivanov41782e42016-11-16 18:16:17 -0500963 def test_async_gen_asyncio_athrow_03(self):
964 DONE = 0
965
966 # test synchronous generators
967 def foo():
968 try:
969 yield
970 except:
971 pass
972 g = foo()
973 g.send(None)
974 with self.assertRaises(StopIteration):
975 g.throw(ValueError)
976
977 # now with asynchronous generators
978
979 async def gen():
980 nonlocal DONE
981 try:
982 yield
983 except:
984 pass
985 DONE = 1
986
987 async def run():
988 nonlocal DONE
989 g = gen()
990 await g.asend(None)
991 with self.assertRaises(StopAsyncIteration):
992 await g.athrow(ValueError)
993 DONE += 10
994
995 self.loop.run_until_complete(run())
996 self.assertEqual(DONE, 11)
997
Serhiy Storchaka60e49aa2016-11-06 18:47:03 +0200998 def test_async_gen_asyncio_athrow_tuple(self):
999 async def gen():
1000 try:
1001 yield 1
1002 except ZeroDivisionError:
1003 yield (2,)
1004
1005 async def run():
1006 g = gen()
1007 v = await g.asend(None)
1008 self.assertEqual(v, 1)
1009 v = await g.athrow(ZeroDivisionError)
1010 self.assertEqual(v, (2,))
1011 with self.assertRaises(StopAsyncIteration):
1012 await g.asend(None)
1013
1014 self.loop.run_until_complete(run())
1015
1016 def test_async_gen_asyncio_athrow_stopiteration(self):
1017 async def gen():
1018 try:
1019 yield 1
1020 except ZeroDivisionError:
1021 yield StopIteration(2)
1022
1023 async def run():
1024 g = gen()
1025 v = await g.asend(None)
1026 self.assertEqual(v, 1)
1027 v = await g.athrow(ZeroDivisionError)
1028 self.assertIsInstance(v, StopIteration)
1029 self.assertEqual(v.value, 2)
1030 with self.assertRaises(StopAsyncIteration):
1031 await g.asend(None)
1032
1033 self.loop.run_until_complete(run())
1034
Yury Selivanoveb636452016-09-08 22:01:51 -07001035 def test_async_gen_asyncio_shutdown_01(self):
1036 finalized = 0
1037
1038 async def waiter(timeout):
1039 nonlocal finalized
1040 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001041 await asyncio.sleep(timeout)
Yury Selivanoveb636452016-09-08 22:01:51 -07001042 yield 1
1043 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001044 await asyncio.sleep(0)
Yury Selivanoveb636452016-09-08 22:01:51 -07001045 finalized += 1
1046
1047 async def wait():
1048 async for _ in waiter(1):
1049 pass
1050
1051 t1 = self.loop.create_task(wait())
1052 t2 = self.loop.create_task(wait())
1053
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001054 self.loop.run_until_complete(asyncio.sleep(0.1))
Yury Selivanoveb636452016-09-08 22:01:51 -07001055
1056 self.loop.run_until_complete(self.loop.shutdown_asyncgens())
1057 self.assertEqual(finalized, 2)
1058
1059 # Silence warnings
1060 t1.cancel()
1061 t2.cancel()
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001062 self.loop.run_until_complete(asyncio.sleep(0.1))
Yury Selivanoveb636452016-09-08 22:01:51 -07001063
1064 def test_async_gen_asyncio_shutdown_02(self):
1065 logged = 0
1066
1067 def logger(loop, context):
1068 nonlocal logged
1069 self.assertIn('asyncgen', context)
1070 expected = 'an error occurred during closing of asynchronous'
1071 if expected in context['message']:
1072 logged += 1
1073
1074 async def waiter(timeout):
1075 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001076 await asyncio.sleep(timeout)
Yury Selivanoveb636452016-09-08 22:01:51 -07001077 yield 1
1078 finally:
1079 1 / 0
1080
1081 async def wait():
1082 async for _ in waiter(1):
1083 pass
1084
1085 t = self.loop.create_task(wait())
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001086 self.loop.run_until_complete(asyncio.sleep(0.1))
Yury Selivanoveb636452016-09-08 22:01:51 -07001087
1088 self.loop.set_exception_handler(logger)
1089 self.loop.run_until_complete(self.loop.shutdown_asyncgens())
1090
1091 self.assertEqual(logged, 1)
1092
1093 # Silence warnings
1094 t.cancel()
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001095 self.loop.run_until_complete(asyncio.sleep(0.1))
Yury Selivanoveb636452016-09-08 22:01:51 -07001096
Yury Selivanovb8ab9d32017-10-06 02:58:28 -04001097 def test_async_gen_expression_01(self):
1098 async def arange(n):
1099 for i in range(n):
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001100 await asyncio.sleep(0.01)
Yury Selivanovb8ab9d32017-10-06 02:58:28 -04001101 yield i
1102
1103 def make_arange(n):
1104 # This syntax is legal starting with Python 3.7
1105 return (i * 2 async for i in arange(n))
1106
1107 async def run():
1108 return [i async for i in make_arange(10)]
1109
1110 res = self.loop.run_until_complete(run())
1111 self.assertEqual(res, [i * 2 for i in range(10)])
1112
1113 def test_async_gen_expression_02(self):
1114 async def wrap(n):
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001115 await asyncio.sleep(0.01)
Yury Selivanovb8ab9d32017-10-06 02:58:28 -04001116 return n
1117
1118 def make_arange(n):
1119 # This syntax is legal starting with Python 3.7
1120 return (i * 2 for i in range(n) if await wrap(i))
1121
1122 async def run():
1123 return [i async for i in make_arange(10)]
1124
1125 res = self.loop.run_until_complete(run())
1126 self.assertEqual(res, [i * 2 for i in range(1, 10)])
1127
1128
Yury Selivanoveb636452016-09-08 22:01:51 -07001129if __name__ == "__main__":
1130 unittest.main()