forked from Rust-related/RustPython
Update to test_asyncgen from CPython 3.8
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user