Update to test_asyncgen from CPython 3.8

This commit is contained in:
Noah
2020-03-07 08:29:06 -06:00
parent af25fbed39
commit 8f2c03c307

View File

@@ -1,10 +1,7 @@
import inspect
import sys
import types
import unittest
from unittest import mock
from test.support import import_module
asyncio = import_module("asyncio")
@@ -136,24 +133,6 @@ class AsyncGenTest(unittest.TestCase):
break
return res
def async_iterate(g):
res = []
while True:
try:
g.__anext__().__next__()
except StopAsyncIteration:
res.append('STOP')
break
except StopIteration as ex:
if ex.args:
res.append(ex.args[0])
else:
res.append('EMPTY StopIteration')
break
except Exception as ex:
res.append(str(type(ex)))
return res
sync_gen_result = sync_iterate(sync_gen)
async_gen_result = async_iterate(async_gen)
self.assertEqual(sync_gen_result, async_gen_result)
@@ -179,19 +158,22 @@ class AsyncGenTest(unittest.TestCase):
g = gen()
ai = g.__aiter__()
self.assertEqual(ai.__anext__().__next__(), ('result',))
an = ai.__anext__()
self.assertEqual(an.__next__(), ('result',))
try:
ai.__anext__().__next__()
an.__next__()
except StopIteration as ex:
self.assertEqual(ex.args[0], 123)
else:
self.fail('StopIteration was not raised')
self.assertEqual(ai.__anext__().__next__(), ('result',))
an = ai.__anext__()
self.assertEqual(an.__next__(), ('result',))
try:
ai.__anext__().__next__()
an.__next__()
except StopAsyncIteration as ex:
self.assertFalse(ex.args)
else:
@@ -215,10 +197,11 @@ class AsyncGenTest(unittest.TestCase):
g = gen()
ai = g.__aiter__()
self.assertEqual(ai.__anext__().__next__(), ('result',))
an = ai.__anext__()
self.assertEqual(an.__next__(), ('result',))
try:
ai.__anext__().__next__()
an.__next__()
except StopIteration as ex:
self.assertEqual(ex.args[0], 123)
else:
@@ -246,6 +229,7 @@ class AsyncGenTest(unittest.TestCase):
'async generator.*StopIteration'):
to_list(gen())
@unittest.skip("TODO: RUSTPYTHON")
def test_async_gen_exception_07(self):
def sync_gen():
try:
@@ -390,6 +374,7 @@ class AsyncGenAsyncioTest(unittest.TestCase):
def tearDown(self):
self.loop.close()
self.loop = None
asyncio.set_event_loop_policy(None)
async def to_list(self, gen):
res = []
@@ -400,9 +385,9 @@ class AsyncGenAsyncioTest(unittest.TestCase):
def test_async_gen_asyncio_01(self):
async def gen():
yield 1
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
yield 2
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
return
yield 3
@@ -412,7 +397,7 @@ class AsyncGenAsyncioTest(unittest.TestCase):
def test_async_gen_asyncio_02(self):
async def gen():
yield 1
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
yield 2
1 / 0
yield 3
@@ -426,7 +411,7 @@ class AsyncGenAsyncioTest(unittest.TestCase):
class Gen:
async def __aiter__(self):
yield 1
await asyncio.sleep(0.01, loop=loop)
await asyncio.sleep(0.01)
yield 2
res = loop.run_until_complete(self.to_list(Gen()))
@@ -435,13 +420,13 @@ class AsyncGenAsyncioTest(unittest.TestCase):
def test_async_gen_asyncio_anext_04(self):
async def foo():
yield 1
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
try:
yield 2
yield 3
except ZeroDivisionError:
yield 1000
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
yield 4
async def run1():
@@ -592,7 +577,7 @@ class AsyncGenAsyncioTest(unittest.TestCase):
yield 1
1 / 0
finally:
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
yield 12
async def run():
@@ -615,8 +600,8 @@ class AsyncGenAsyncioTest(unittest.TestCase):
yield 1
1 / 0
finally:
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
await asyncio.sleep(0.01)
DONE += 1
DONE += 1000
@@ -642,8 +627,8 @@ class AsyncGenAsyncioTest(unittest.TestCase):
DONE += 1000
yield 2
finally:
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
await asyncio.sleep(0.01)
DONE += 1
DONE += 1000
@@ -651,18 +636,14 @@ class AsyncGenAsyncioTest(unittest.TestCase):
gen = foo()
it = gen.__aiter__()
self.assertEqual(await it.__anext__(), 1)
t = self.loop.create_task(it.__anext__())
await asyncio.sleep(0.01, loop=self.loop)
await gen.aclose()
return t
t = self.loop.run_until_complete(run())
self.loop.run_until_complete(run())
self.assertEqual(DONE, 1)
# Silence ResourceWarnings
fut.cancel()
t.cancel()
self.loop.run_until_complete(asyncio.sleep(0.01, loop=self.loop))
self.loop.run_until_complete(asyncio.sleep(0.01))
def test_async_gen_asyncio_gc_aclose_09(self):
DONE = 0
@@ -673,8 +654,8 @@ class AsyncGenAsyncioTest(unittest.TestCase):
while True:
yield 1
finally:
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
await asyncio.sleep(0.01)
DONE = 1
async def run():
@@ -683,7 +664,7 @@ class AsyncGenAsyncioTest(unittest.TestCase):
await g.__anext__()
del g
await asyncio.sleep(0.1, loop=self.loop)
await asyncio.sleep(0.1)
self.loop.run_until_complete(run())
self.assertEqual(DONE, 1)
@@ -758,6 +739,33 @@ class AsyncGenAsyncioTest(unittest.TestCase):
self.loop.run_until_complete(run())
self.assertEqual(DONE, 10)
def test_async_gen_asyncio_aclose_12(self):
DONE = 0
async def target():
await asyncio.sleep(0.01)
1 / 0
async def foo():
nonlocal DONE
task = asyncio.create_task(target())
try:
yield 1
finally:
try:
await task
except ZeroDivisionError:
DONE = 1
async def run():
gen = foo()
it = gen.__aiter__()
await it.__anext__()
await gen.aclose()
self.loop.run_until_complete(run())
self.assertEqual(DONE, 1)
def test_async_gen_asyncio_asend_01(self):
DONE = 0
@@ -774,15 +782,15 @@ class AsyncGenAsyncioTest(unittest.TestCase):
async def gen():
nonlocal DONE
try:
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
v = yield 1
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
yield v * 2
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
return
finally:
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
await asyncio.sleep(0.01)
DONE = 1
async def run():
@@ -804,20 +812,20 @@ class AsyncGenAsyncioTest(unittest.TestCase):
DONE = 0
async def sleep_n_crash(delay):
await asyncio.sleep(delay, loop=self.loop)
await asyncio.sleep(delay)
1 / 0
async def gen():
nonlocal DONE
try:
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
v = yield 1
await sleep_n_crash(0.01)
DONE += 1000
yield v * 2
finally:
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
await asyncio.sleep(0.01)
DONE = 1
async def run():
@@ -836,7 +844,7 @@ class AsyncGenAsyncioTest(unittest.TestCase):
DONE = 0
async def sleep_n_crash(delay):
fut = asyncio.ensure_future(asyncio.sleep(delay, loop=self.loop),
fut = asyncio.ensure_future(asyncio.sleep(delay),
loop=self.loop)
self.loop.call_later(delay / 2, lambda: fut.cancel())
return await fut
@@ -844,14 +852,14 @@ class AsyncGenAsyncioTest(unittest.TestCase):
async def gen():
nonlocal DONE
try:
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
v = yield 1
await sleep_n_crash(0.01)
DONE += 1000
yield v * 2
finally:
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
await asyncio.sleep(0.01)
DONE = 1
async def run():
@@ -890,18 +898,18 @@ class AsyncGenAsyncioTest(unittest.TestCase):
async def gen():
nonlocal DONE
try:
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
try:
v = yield 1
except FooEr:
v = 1000
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
yield v * 2
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
# return
finally:
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
await asyncio.sleep(0.01)
DONE = 1
async def run():
@@ -926,7 +934,7 @@ class AsyncGenAsyncioTest(unittest.TestCase):
pass
async def sleep_n_crash(delay):
fut = asyncio.ensure_future(asyncio.sleep(delay, loop=self.loop),
fut = asyncio.ensure_future(asyncio.sleep(delay),
loop=self.loop)
self.loop.call_later(delay / 2, lambda: fut.cancel())
return await fut
@@ -934,17 +942,17 @@ class AsyncGenAsyncioTest(unittest.TestCase):
async def gen():
nonlocal DONE
try:
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
try:
v = yield 1
except FooEr:
await sleep_n_crash(0.01)
yield v * 2
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
# return
finally:
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01, loop=self.loop)
await asyncio.sleep(0.01)
await asyncio.sleep(0.01)
DONE = 1
async def run():
@@ -1043,10 +1051,10 @@ class AsyncGenAsyncioTest(unittest.TestCase):
async def waiter(timeout):
nonlocal finalized
try:
await asyncio.sleep(timeout, loop=self.loop)
await asyncio.sleep(timeout)
yield 1
finally:
await asyncio.sleep(0, loop=self.loop)
await asyncio.sleep(0)
finalized += 1
async def wait():
@@ -1056,48 +1064,152 @@ class AsyncGenAsyncioTest(unittest.TestCase):
t1 = self.loop.create_task(wait())
t2 = self.loop.create_task(wait())
self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop))
self.loop.run_until_complete(self.loop.shutdown_asyncgens())
self.assertEqual(finalized, 2)
self.loop.run_until_complete(asyncio.sleep(0.1))
# Silence warnings
t1.cancel()
t2.cancel()
self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop))
def test_async_gen_asyncio_shutdown_02(self):
logged = 0
with self.assertRaises(asyncio.CancelledError):
self.loop.run_until_complete(t1)
with self.assertRaises(asyncio.CancelledError):
self.loop.run_until_complete(t2)
def logger(loop, context):
nonlocal logged
self.assertIn('asyncgen', context)
expected = 'an error occurred during closing of asynchronous'
if expected in context['message']:
logged += 1
async def waiter(timeout):
try:
await asyncio.sleep(timeout, loop=self.loop)
yield 1
finally:
1 / 0
async def wait():
async for _ in waiter(1):
pass
t = self.loop.create_task(wait())
self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop))
self.loop.set_exception_handler(logger)
self.loop.run_until_complete(self.loop.shutdown_asyncgens())
self.assertEqual(logged, 1)
self.assertEqual(finalized, 2)
# TODO: RUSTPYTHON: async for gen expression compilation
# def test_async_gen_expression_01(self):
# async def arange(n):
# for i in range(n):
# await asyncio.sleep(0.01)
# yield i
# def make_arange(n):
# # This syntax is legal starting with Python 3.7
# return (i * 2 async for i in arange(n))
# async def run():
# return [i async for i in make_arange(10)]
# res = self.loop.run_until_complete(run())
# self.assertEqual(res, [i * 2 for i in range(10)])
# def test_async_gen_expression_02(self):
# async def wrap(n):
# await asyncio.sleep(0.01)
# return n
# def make_arange(n):
# # This syntax is legal starting with Python 3.7
# return (i * 2 for i in range(n) if await wrap(i))
# async def run():
# return [i async for i in make_arange(10)]
# res = self.loop.run_until_complete(run())
# self.assertEqual(res, [i * 2 for i in range(1, 10)])
def test_asyncgen_nonstarted_hooks_are_cancellable(self):
# See https://bugs.python.org/issue38013
messages = []
def exception_handler(loop, context):
messages.append(context)
async def async_iterate():
yield 1
yield 2
async def main():
loop = asyncio.get_running_loop()
loop.set_exception_handler(exception_handler)
async for i in async_iterate():
break
asyncio.run(main())
self.assertEqual([], messages)
def test_async_gen_await_same_anext_coro_twice(self):
async def async_iterate():
yield 1
yield 2
async def run():
it = async_iterate()
nxt = it.__anext__()
await nxt
with self.assertRaisesRegex(
RuntimeError,
r"cannot reuse already awaited __anext__\(\)/asend\(\)"
):
await nxt
await it.aclose() # prevent unfinished iterator warning
self.loop.run_until_complete(run())
def test_async_gen_await_same_aclose_coro_twice(self):
async def async_iterate():
yield 1
yield 2
async def run():
it = async_iterate()
nxt = it.aclose()
await nxt
with self.assertRaisesRegex(
RuntimeError,
r"cannot reuse already awaited aclose\(\)/athrow\(\)"
):
await nxt
self.loop.run_until_complete(run())
def test_async_gen_aclose_twice_with_different_coros(self):
# Regression test for https://bugs.python.org/issue39606
async def async_iterate():
yield 1
yield 2
async def run():
it = async_iterate()
await it.aclose()
await it.aclose()
self.loop.run_until_complete(run())
def test_async_gen_aclose_after_exhaustion(self):
# Regression test for https://bugs.python.org/issue39606
async def async_iterate():
yield 1
yield 2
async def run():
it = async_iterate()
async for _ in it:
pass
await it.aclose()
self.loop.run_until_complete(run())
def test_async_gen_aclose_compatible_with_get_stack(self):
async def async_generator():
yield object()
async def run():
ag = async_generator()
asyncio.create_task(ag.aclose())
tasks = asyncio.all_tasks()
for task in tasks:
# No AttributeError raised
task.get_stack()
self.loop.run_until_complete(run())
# Silence warnings
t.cancel()
self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop))
if __name__ == "__main__":
unittest.main()