blob: 23eb6a411cd19fc36adcfb605a6d5bea7a694165 [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
Yury Selivanoveb636452016-09-08 22:01:51 -0700136 sync_gen_result = sync_iterate(sync_gen)
137 async_gen_result = async_iterate(async_gen)
138 self.assertEqual(sync_gen_result, async_gen_result)
139 return async_gen_result
140
141 def test_async_gen_iteration_01(self):
142 async def gen():
143 await awaitable()
144 a = yield 123
145 self.assertIs(a, None)
146 await awaitable()
147 yield 456
148 await awaitable()
149 yield 789
150
151 self.assertEqual(to_list(gen()), [123, 456, 789])
152
153 def test_async_gen_iteration_02(self):
154 async def gen():
155 await awaitable()
156 yield 123
157 await awaitable()
158
159 g = gen()
160 ai = g.__aiter__()
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700161
162 an = ai.__anext__()
163 self.assertEqual(an.__next__(), ('result',))
Yury Selivanoveb636452016-09-08 22:01:51 -0700164
165 try:
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700166 an.__next__()
Yury Selivanoveb636452016-09-08 22:01:51 -0700167 except StopIteration as ex:
168 self.assertEqual(ex.args[0], 123)
169 else:
170 self.fail('StopIteration was not raised')
171
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700172 an = ai.__anext__()
173 self.assertEqual(an.__next__(), ('result',))
Yury Selivanoveb636452016-09-08 22:01:51 -0700174
175 try:
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700176 an.__next__()
Yury Selivanoveb636452016-09-08 22:01:51 -0700177 except StopAsyncIteration as ex:
178 self.assertFalse(ex.args)
179 else:
180 self.fail('StopAsyncIteration was not raised')
181
182 def test_async_gen_exception_03(self):
183 async def gen():
184 await awaitable()
185 yield 123
186 await awaitable(throw=True)
187 yield 456
188
189 with self.assertRaises(AwaitException):
190 to_list(gen())
191
192 def test_async_gen_exception_04(self):
193 async def gen():
194 await awaitable()
195 yield 123
196 1 / 0
197
198 g = gen()
199 ai = g.__aiter__()
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700200 an = ai.__anext__()
201 self.assertEqual(an.__next__(), ('result',))
Yury Selivanoveb636452016-09-08 22:01:51 -0700202
203 try:
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700204 an.__next__()
Yury Selivanoveb636452016-09-08 22:01:51 -0700205 except StopIteration as ex:
206 self.assertEqual(ex.args[0], 123)
207 else:
208 self.fail('StopIteration was not raised')
209
210 with self.assertRaises(ZeroDivisionError):
211 ai.__anext__().__next__()
212
213 def test_async_gen_exception_05(self):
214 async def gen():
215 yield 123
216 raise StopAsyncIteration
217
218 with self.assertRaisesRegex(RuntimeError,
219 'async generator.*StopAsyncIteration'):
220 to_list(gen())
221
222 def test_async_gen_exception_06(self):
223 async def gen():
224 yield 123
225 raise StopIteration
226
227 with self.assertRaisesRegex(RuntimeError,
228 'async generator.*StopIteration'):
229 to_list(gen())
230
231 def test_async_gen_exception_07(self):
232 def sync_gen():
233 try:
234 yield 1
235 1 / 0
236 finally:
237 yield 2
238 yield 3
239
240 yield 100
241
242 async def async_gen():
243 try:
244 yield 1
245 1 / 0
246 finally:
247 yield 2
248 yield 3
249
250 yield 100
251
252 self.compare_generators(sync_gen(), async_gen())
253
254 def test_async_gen_exception_08(self):
255 def sync_gen():
256 try:
257 yield 1
258 finally:
259 yield 2
260 1 / 0
261 yield 3
262
263 yield 100
264
265 async def async_gen():
266 try:
267 yield 1
268 await awaitable()
269 finally:
270 await awaitable()
271 yield 2
272 1 / 0
273 yield 3
274
275 yield 100
276
277 self.compare_generators(sync_gen(), async_gen())
278
279 def test_async_gen_exception_09(self):
280 def sync_gen():
281 try:
282 yield 1
283 1 / 0
284 finally:
285 yield 2
286 yield 3
287
288 yield 100
289
290 async def async_gen():
291 try:
292 await awaitable()
293 yield 1
294 1 / 0
295 finally:
296 yield 2
297 await awaitable()
298 yield 3
299
300 yield 100
301
302 self.compare_generators(sync_gen(), async_gen())
303
304 def test_async_gen_exception_10(self):
305 async def gen():
306 yield 123
307 with self.assertRaisesRegex(TypeError,
308 "non-None value .* async generator"):
309 gen().__anext__().send(100)
310
Yury Selivanov52698c72018-06-07 20:31:26 -0400311 def test_async_gen_exception_11(self):
312 def sync_gen():
313 yield 10
314 yield 20
315
316 def sync_gen_wrapper():
317 yield 1
318 sg = sync_gen()
319 sg.send(None)
320 try:
321 sg.throw(GeneratorExit())
322 except GeneratorExit:
323 yield 2
324 yield 3
325
326 async def async_gen():
327 yield 10
328 yield 20
329
330 async def async_gen_wrapper():
331 yield 1
332 asg = async_gen()
333 await asg.asend(None)
334 try:
335 await asg.athrow(GeneratorExit())
336 except GeneratorExit:
337 yield 2
338 yield 3
339
340 self.compare_generators(sync_gen_wrapper(), async_gen_wrapper())
341
Yury Selivanoveb636452016-09-08 22:01:51 -0700342 def test_async_gen_api_01(self):
343 async def gen():
344 yield 123
345
346 g = gen()
347
348 self.assertEqual(g.__name__, 'gen')
349 g.__name__ = '123'
350 self.assertEqual(g.__name__, '123')
351
352 self.assertIn('.gen', g.__qualname__)
353 g.__qualname__ = '123'
354 self.assertEqual(g.__qualname__, '123')
355
356 self.assertIsNone(g.ag_await)
357 self.assertIsInstance(g.ag_frame, types.FrameType)
358 self.assertFalse(g.ag_running)
359 self.assertIsInstance(g.ag_code, types.CodeType)
360
361 self.assertTrue(inspect.isawaitable(g.aclose()))
362
363
364class AsyncGenAsyncioTest(unittest.TestCase):
365
366 def setUp(self):
367 self.loop = asyncio.new_event_loop()
368 asyncio.set_event_loop(None)
369
370 def tearDown(self):
371 self.loop.close()
372 self.loop = None
Brett Cannon8425de42018-06-01 20:34:09 -0700373 asyncio.set_event_loop_policy(None)
Yury Selivanoveb636452016-09-08 22:01:51 -0700374
375 async def to_list(self, gen):
376 res = []
377 async for i in gen:
378 res.append(i)
379 return res
380
381 def test_async_gen_asyncio_01(self):
382 async def gen():
383 yield 1
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400384 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700385 yield 2
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400386 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700387 return
388 yield 3
389
390 res = self.loop.run_until_complete(self.to_list(gen()))
391 self.assertEqual(res, [1, 2])
392
393 def test_async_gen_asyncio_02(self):
394 async def gen():
395 yield 1
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400396 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700397 yield 2
398 1 / 0
399 yield 3
400
401 with self.assertRaises(ZeroDivisionError):
402 self.loop.run_until_complete(self.to_list(gen()))
403
404 def test_async_gen_asyncio_03(self):
405 loop = self.loop
406
407 class Gen:
408 async def __aiter__(self):
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
413 res = loop.run_until_complete(self.to_list(Gen()))
414 self.assertEqual(res, [1, 2])
415
416 def test_async_gen_asyncio_anext_04(self):
417 async def foo():
418 yield 1
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400419 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700420 try:
421 yield 2
422 yield 3
423 except ZeroDivisionError:
424 yield 1000
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400425 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700426 yield 4
427
428 async def run1():
429 it = foo().__aiter__()
430
431 self.assertEqual(await it.__anext__(), 1)
432 self.assertEqual(await it.__anext__(), 2)
433 self.assertEqual(await it.__anext__(), 3)
434 self.assertEqual(await it.__anext__(), 4)
435 with self.assertRaises(StopAsyncIteration):
436 await it.__anext__()
437 with self.assertRaises(StopAsyncIteration):
438 await it.__anext__()
439
440 async def run2():
441 it = foo().__aiter__()
442
443 self.assertEqual(await it.__anext__(), 1)
444 self.assertEqual(await it.__anext__(), 2)
445 try:
446 it.__anext__().throw(ZeroDivisionError)
447 except StopIteration as ex:
448 self.assertEqual(ex.args[0], 1000)
449 else:
450 self.fail('StopIteration was not raised')
451 self.assertEqual(await it.__anext__(), 4)
452 with self.assertRaises(StopAsyncIteration):
453 await it.__anext__()
454
455 self.loop.run_until_complete(run1())
456 self.loop.run_until_complete(run2())
457
458 def test_async_gen_asyncio_anext_05(self):
459 async def foo():
460 v = yield 1
461 v = yield v
462 yield v * 100
463
464 async def run():
465 it = foo().__aiter__()
466
467 try:
468 it.__anext__().send(None)
469 except StopIteration as ex:
470 self.assertEqual(ex.args[0], 1)
471 else:
472 self.fail('StopIteration was not raised')
473
474 try:
475 it.__anext__().send(10)
476 except StopIteration as ex:
477 self.assertEqual(ex.args[0], 10)
478 else:
479 self.fail('StopIteration was not raised')
480
481 try:
482 it.__anext__().send(12)
483 except StopIteration as ex:
484 self.assertEqual(ex.args[0], 1200)
485 else:
486 self.fail('StopIteration was not raised')
487
488 with self.assertRaises(StopAsyncIteration):
489 await it.__anext__()
490
491 self.loop.run_until_complete(run())
492
Yury Selivanov41782e42016-11-16 18:16:17 -0500493 def test_async_gen_asyncio_anext_06(self):
494 DONE = 0
495
496 # test synchronous generators
497 def foo():
498 try:
499 yield
500 except:
501 pass
502 g = foo()
503 g.send(None)
504 with self.assertRaises(StopIteration):
505 g.send(None)
506
507 # now with asynchronous generators
508
509 async def gen():
510 nonlocal DONE
511 try:
512 yield
513 except:
514 pass
515 DONE = 1
516
517 async def run():
518 nonlocal DONE
519 g = gen()
520 await g.asend(None)
521 with self.assertRaises(StopAsyncIteration):
522 await g.asend(None)
523 DONE += 10
524
525 self.loop.run_until_complete(run())
526 self.assertEqual(DONE, 11)
527
Serhiy Storchaka60e49aa2016-11-06 18:47:03 +0200528 def test_async_gen_asyncio_anext_tuple(self):
529 async def foo():
530 try:
531 yield (1,)
532 except ZeroDivisionError:
533 yield (2,)
534
535 async def run():
536 it = foo().__aiter__()
537
538 self.assertEqual(await it.__anext__(), (1,))
539 with self.assertRaises(StopIteration) as cm:
540 it.__anext__().throw(ZeroDivisionError)
541 self.assertEqual(cm.exception.args[0], (2,))
542 with self.assertRaises(StopAsyncIteration):
543 await it.__anext__()
544
545 self.loop.run_until_complete(run())
546
547 def test_async_gen_asyncio_anext_stopiteration(self):
548 async def foo():
549 try:
550 yield StopIteration(1)
551 except ZeroDivisionError:
552 yield StopIteration(3)
553
554 async def run():
555 it = foo().__aiter__()
556
557 v = await it.__anext__()
558 self.assertIsInstance(v, StopIteration)
559 self.assertEqual(v.value, 1)
560 with self.assertRaises(StopIteration) as cm:
561 it.__anext__().throw(ZeroDivisionError)
562 v = cm.exception.args[0]
563 self.assertIsInstance(v, StopIteration)
564 self.assertEqual(v.value, 3)
565 with self.assertRaises(StopAsyncIteration):
566 await it.__anext__()
567
568 self.loop.run_until_complete(run())
569
Yury Selivanoveb636452016-09-08 22:01:51 -0700570 def test_async_gen_asyncio_aclose_06(self):
571 async def foo():
572 try:
573 yield 1
574 1 / 0
575 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400576 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700577 yield 12
578
579 async def run():
580 gen = foo()
581 it = gen.__aiter__()
582 await it.__anext__()
583 await gen.aclose()
584
585 with self.assertRaisesRegex(
586 RuntimeError,
587 "async generator ignored GeneratorExit"):
588 self.loop.run_until_complete(run())
589
590 def test_async_gen_asyncio_aclose_07(self):
591 DONE = 0
592
593 async def foo():
594 nonlocal DONE
595 try:
596 yield 1
597 1 / 0
598 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400599 await asyncio.sleep(0.01)
600 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700601 DONE += 1
602 DONE += 1000
603
604 async def run():
605 gen = foo()
606 it = gen.__aiter__()
607 await it.__anext__()
608 await gen.aclose()
609
610 self.loop.run_until_complete(run())
611 self.assertEqual(DONE, 1)
612
613 def test_async_gen_asyncio_aclose_08(self):
614 DONE = 0
615
616 fut = asyncio.Future(loop=self.loop)
617
618 async def foo():
619 nonlocal DONE
620 try:
621 yield 1
622 await fut
623 DONE += 1000
624 yield 2
625 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400626 await asyncio.sleep(0.01)
627 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700628 DONE += 1
629 DONE += 1000
630
631 async def run():
632 gen = foo()
633 it = gen.__aiter__()
634 self.assertEqual(await it.__anext__(), 1)
Yury Selivanoveb636452016-09-08 22:01:51 -0700635 await gen.aclose()
Yury Selivanoveb636452016-09-08 22:01:51 -0700636
Yury Selivanovfc4a0442019-09-29 22:59:11 -0700637 self.loop.run_until_complete(run())
Yury Selivanoveb636452016-09-08 22:01:51 -0700638 self.assertEqual(DONE, 1)
639
640 # Silence ResourceWarnings
641 fut.cancel()
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400642 self.loop.run_until_complete(asyncio.sleep(0.01))
Yury Selivanoveb636452016-09-08 22:01:51 -0700643
644 def test_async_gen_asyncio_gc_aclose_09(self):
645 DONE = 0
646
647 async def gen():
648 nonlocal DONE
649 try:
650 while True:
651 yield 1
652 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400653 await asyncio.sleep(0.01)
654 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700655 DONE = 1
656
657 async def run():
658 g = gen()
659 await g.__anext__()
660 await g.__anext__()
661 del g
662
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400663 await asyncio.sleep(0.1)
Yury Selivanoveb636452016-09-08 22:01:51 -0700664
665 self.loop.run_until_complete(run())
666 self.assertEqual(DONE, 1)
667
Yury Selivanov41782e42016-11-16 18:16:17 -0500668 def test_async_gen_asyncio_aclose_10(self):
669 DONE = 0
670
671 # test synchronous generators
672 def foo():
673 try:
674 yield
675 except:
676 pass
677 g = foo()
678 g.send(None)
679 g.close()
680
681 # now with asynchronous generators
682
683 async def gen():
684 nonlocal DONE
685 try:
686 yield
687 except:
688 pass
689 DONE = 1
690
691 async def run():
692 nonlocal DONE
693 g = gen()
694 await g.asend(None)
695 await g.aclose()
696 DONE += 10
697
698 self.loop.run_until_complete(run())
699 self.assertEqual(DONE, 11)
700
701 def test_async_gen_asyncio_aclose_11(self):
702 DONE = 0
703
704 # test synchronous generators
705 def foo():
706 try:
707 yield
708 except:
709 pass
710 yield
711 g = foo()
712 g.send(None)
713 with self.assertRaisesRegex(RuntimeError, 'ignored GeneratorExit'):
714 g.close()
715
716 # now with asynchronous generators
717
718 async def gen():
719 nonlocal DONE
720 try:
721 yield
722 except:
723 pass
724 yield
725 DONE += 1
726
727 async def run():
728 nonlocal DONE
729 g = gen()
730 await g.asend(None)
731 with self.assertRaisesRegex(RuntimeError, 'ignored GeneratorExit'):
732 await g.aclose()
733 DONE += 10
734
735 self.loop.run_until_complete(run())
736 self.assertEqual(DONE, 10)
737
Yury Selivanoveb636452016-09-08 22:01:51 -0700738 def test_async_gen_asyncio_asend_01(self):
739 DONE = 0
740
741 # Sanity check:
742 def sgen():
743 v = yield 1
744 yield v * 2
745 sg = sgen()
746 v = sg.send(None)
747 self.assertEqual(v, 1)
748 v = sg.send(100)
749 self.assertEqual(v, 200)
750
751 async def gen():
752 nonlocal DONE
753 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400754 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700755 v = yield 1
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400756 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700757 yield v * 2
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400758 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700759 return
760 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400761 await asyncio.sleep(0.01)
762 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700763 DONE = 1
764
765 async def run():
766 g = gen()
767
768 v = await g.asend(None)
769 self.assertEqual(v, 1)
770
771 v = await g.asend(100)
772 self.assertEqual(v, 200)
773
774 with self.assertRaises(StopAsyncIteration):
775 await g.asend(None)
776
777 self.loop.run_until_complete(run())
778 self.assertEqual(DONE, 1)
779
780 def test_async_gen_asyncio_asend_02(self):
781 DONE = 0
782
783 async def sleep_n_crash(delay):
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400784 await asyncio.sleep(delay)
Yury Selivanoveb636452016-09-08 22:01:51 -0700785 1 / 0
786
787 async def gen():
788 nonlocal DONE
789 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400790 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700791 v = yield 1
792 await sleep_n_crash(0.01)
793 DONE += 1000
794 yield v * 2
795 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400796 await asyncio.sleep(0.01)
797 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700798 DONE = 1
799
800 async def run():
801 g = gen()
802
803 v = await g.asend(None)
804 self.assertEqual(v, 1)
805
806 await g.asend(100)
807
808 with self.assertRaises(ZeroDivisionError):
809 self.loop.run_until_complete(run())
810 self.assertEqual(DONE, 1)
811
812 def test_async_gen_asyncio_asend_03(self):
813 DONE = 0
814
815 async def sleep_n_crash(delay):
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400816 fut = asyncio.ensure_future(asyncio.sleep(delay),
Yury Selivanoveb636452016-09-08 22:01:51 -0700817 loop=self.loop)
818 self.loop.call_later(delay / 2, lambda: fut.cancel())
819 return await fut
820
821 async def gen():
822 nonlocal DONE
823 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400824 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700825 v = yield 1
826 await sleep_n_crash(0.01)
827 DONE += 1000
828 yield v * 2
829 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400830 await asyncio.sleep(0.01)
831 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700832 DONE = 1
833
834 async def run():
835 g = gen()
836
837 v = await g.asend(None)
838 self.assertEqual(v, 1)
839
840 await g.asend(100)
841
842 with self.assertRaises(asyncio.CancelledError):
843 self.loop.run_until_complete(run())
844 self.assertEqual(DONE, 1)
845
846 def test_async_gen_asyncio_athrow_01(self):
847 DONE = 0
848
849 class FooEr(Exception):
850 pass
851
852 # Sanity check:
853 def sgen():
854 try:
855 v = yield 1
856 except FooEr:
857 v = 1000
858 yield v * 2
859 sg = sgen()
860 v = sg.send(None)
861 self.assertEqual(v, 1)
862 v = sg.throw(FooEr)
863 self.assertEqual(v, 2000)
864 with self.assertRaises(StopIteration):
865 sg.send(None)
866
867 async def gen():
868 nonlocal DONE
869 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400870 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700871 try:
872 v = yield 1
873 except FooEr:
874 v = 1000
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400875 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700876 yield v * 2
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400877 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700878 # return
879 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400880 await asyncio.sleep(0.01)
881 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700882 DONE = 1
883
884 async def run():
885 g = gen()
886
887 v = await g.asend(None)
888 self.assertEqual(v, 1)
889
890 v = await g.athrow(FooEr)
891 self.assertEqual(v, 2000)
892
893 with self.assertRaises(StopAsyncIteration):
894 await g.asend(None)
895
896 self.loop.run_until_complete(run())
897 self.assertEqual(DONE, 1)
898
899 def test_async_gen_asyncio_athrow_02(self):
900 DONE = 0
901
902 class FooEr(Exception):
903 pass
904
905 async def sleep_n_crash(delay):
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400906 fut = asyncio.ensure_future(asyncio.sleep(delay),
Yury Selivanoveb636452016-09-08 22:01:51 -0700907 loop=self.loop)
908 self.loop.call_later(delay / 2, lambda: fut.cancel())
909 return await fut
910
911 async def gen():
912 nonlocal DONE
913 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400914 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700915 try:
916 v = yield 1
917 except FooEr:
918 await sleep_n_crash(0.01)
919 yield v * 2
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400920 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700921 # return
922 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -0400923 await asyncio.sleep(0.01)
924 await asyncio.sleep(0.01)
Yury Selivanoveb636452016-09-08 22:01:51 -0700925 DONE = 1
926
927 async def run():
928 g = gen()
929
930 v = await g.asend(None)
931 self.assertEqual(v, 1)
932
933 try:
934 await g.athrow(FooEr)
935 except asyncio.CancelledError:
936 self.assertEqual(DONE, 1)
937 raise
938 else:
939 self.fail('CancelledError was not raised')
940
941 with self.assertRaises(asyncio.CancelledError):
942 self.loop.run_until_complete(run())
943 self.assertEqual(DONE, 1)
944
Yury Selivanov41782e42016-11-16 18:16:17 -0500945 def test_async_gen_asyncio_athrow_03(self):
946 DONE = 0
947
948 # test synchronous generators
949 def foo():
950 try:
951 yield
952 except:
953 pass
954 g = foo()
955 g.send(None)
956 with self.assertRaises(StopIteration):
957 g.throw(ValueError)
958
959 # now with asynchronous generators
960
961 async def gen():
962 nonlocal DONE
963 try:
964 yield
965 except:
966 pass
967 DONE = 1
968
969 async def run():
970 nonlocal DONE
971 g = gen()
972 await g.asend(None)
973 with self.assertRaises(StopAsyncIteration):
974 await g.athrow(ValueError)
975 DONE += 10
976
977 self.loop.run_until_complete(run())
978 self.assertEqual(DONE, 11)
979
Serhiy Storchaka60e49aa2016-11-06 18:47:03 +0200980 def test_async_gen_asyncio_athrow_tuple(self):
981 async def gen():
982 try:
983 yield 1
984 except ZeroDivisionError:
985 yield (2,)
986
987 async def run():
988 g = gen()
989 v = await g.asend(None)
990 self.assertEqual(v, 1)
991 v = await g.athrow(ZeroDivisionError)
992 self.assertEqual(v, (2,))
993 with self.assertRaises(StopAsyncIteration):
994 await g.asend(None)
995
996 self.loop.run_until_complete(run())
997
998 def test_async_gen_asyncio_athrow_stopiteration(self):
999 async def gen():
1000 try:
1001 yield 1
1002 except ZeroDivisionError:
1003 yield StopIteration(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.assertIsInstance(v, StopIteration)
1011 self.assertEqual(v.value, 2)
1012 with self.assertRaises(StopAsyncIteration):
1013 await g.asend(None)
1014
1015 self.loop.run_until_complete(run())
1016
Yury Selivanoveb636452016-09-08 22:01:51 -07001017 def test_async_gen_asyncio_shutdown_01(self):
1018 finalized = 0
1019
1020 async def waiter(timeout):
1021 nonlocal finalized
1022 try:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001023 await asyncio.sleep(timeout)
Yury Selivanoveb636452016-09-08 22:01:51 -07001024 yield 1
1025 finally:
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001026 await asyncio.sleep(0)
Yury Selivanoveb636452016-09-08 22:01:51 -07001027 finalized += 1
1028
1029 async def wait():
1030 async for _ in waiter(1):
1031 pass
1032
1033 t1 = self.loop.create_task(wait())
1034 t2 = self.loop.create_task(wait())
1035
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001036 self.loop.run_until_complete(asyncio.sleep(0.1))
Yury Selivanoveb636452016-09-08 22:01:51 -07001037
Yury Selivanoveb636452016-09-08 22:01:51 -07001038 # Silence warnings
1039 t1.cancel()
1040 t2.cancel()
Yury Selivanoveb636452016-09-08 22:01:51 -07001041
Yury Selivanovfc4a0442019-09-29 22:59:11 -07001042 with self.assertRaises(asyncio.CancelledError):
1043 self.loop.run_until_complete(t1)
1044 with self.assertRaises(asyncio.CancelledError):
1045 self.loop.run_until_complete(t2)
Yury Selivanoveb636452016-09-08 22:01:51 -07001046
Yury Selivanoveb636452016-09-08 22:01:51 -07001047 self.loop.run_until_complete(self.loop.shutdown_asyncgens())
1048
Yury Selivanovfc4a0442019-09-29 22:59:11 -07001049 self.assertEqual(finalized, 2)
Yury Selivanoveb636452016-09-08 22:01:51 -07001050
Yury Selivanovb8ab9d32017-10-06 02:58:28 -04001051 def test_async_gen_expression_01(self):
1052 async def arange(n):
1053 for i in range(n):
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001054 await asyncio.sleep(0.01)
Yury Selivanovb8ab9d32017-10-06 02:58:28 -04001055 yield i
1056
1057 def make_arange(n):
1058 # This syntax is legal starting with Python 3.7
1059 return (i * 2 async for i in arange(n))
1060
1061 async def run():
1062 return [i async for i in make_arange(10)]
1063
1064 res = self.loop.run_until_complete(run())
1065 self.assertEqual(res, [i * 2 for i in range(10)])
1066
1067 def test_async_gen_expression_02(self):
1068 async def wrap(n):
Yury Selivanov9012a0f2018-10-02 13:53:06 -04001069 await asyncio.sleep(0.01)
Yury Selivanovb8ab9d32017-10-06 02:58:28 -04001070 return n
1071
1072 def make_arange(n):
1073 # This syntax is legal starting with Python 3.7
1074 return (i * 2 for i in range(n) if await wrap(i))
1075
1076 async def run():
1077 return [i async for i in make_arange(10)]
1078
1079 res = self.loop.run_until_complete(run())
1080 self.assertEqual(res, [i * 2 for i in range(1, 10)])
1081
Andrew Svetlovc2753122019-09-17 15:59:49 +03001082 def test_asyncgen_nonstarted_hooks_are_cancellable(self):
1083 # See https://bugs.python.org/issue38013
1084 messages = []
1085
1086 def exception_handler(loop, context):
1087 messages.append(context)
1088
1089 async def async_iterate():
1090 yield 1
1091 yield 2
1092
1093 async def main():
1094 loop = asyncio.get_running_loop()
1095 loop.set_exception_handler(exception_handler)
1096
1097 async for i in async_iterate():
1098 break
1099
1100 asyncio.run(main())
1101
1102 self.assertEqual([], messages)
1103
Yury Selivanovb8ab9d32017-10-06 02:58:28 -04001104
Yury Selivanoveb636452016-09-08 22:01:51 -07001105if __name__ == "__main__":
1106 unittest.main()