Add an `asyncio`-internal cancel test

Verify that if the `asyncio` side task cancels (itself) that we raise
that `asyncio.CancelledError` on the `trio` side.  In the case where
`trio` initiated the cancel whether or not the `asyncio` side ended up
raising `CancelledError` doesn't really matter to us as long as the far
task did indeed terminate.
infect_asyncio
Tyler Goodlet 2021-11-17 13:32:42 -05:00
parent 1114b6980e
commit 04c0eda69d
1 changed files with 38 additions and 8 deletions

View File

@ -35,17 +35,20 @@ async def asyncio_actor(
if '.' in expect_err: if '.' in expect_err:
modpath, _, name = expect_err.rpartition('.') modpath, _, name = expect_err.rpartition('.')
mod = importlib.import_module(modpath) mod = importlib.import_module(modpath)
error = getattr(mod, name) error_type = getattr(mod, name)
error = builtins.__dict__.get(expect_err)
else: # toplevel builtin error type
error_type = builtins.__dict__.get(expect_err)
try: try:
# spawn an ``asyncio`` task to run a func and return result # spawn an ``asyncio`` task to run a func and return result
await tractor.to_asyncio.run_task(target) await tractor.to_asyncio.run_task(target)
except Exception as err:
if expect_err:
assert isinstance(err, error)
raise except BaseException as err:
if expect_err:
assert isinstance(err, error_type)
raise err
def test_aio_simple_error(arb_addr): def test_aio_simple_error(arb_addr):
@ -84,16 +87,43 @@ def test_tractor_cancels_aio(arb_addr):
portal = await n.run_in_actor( portal = await n.run_in_actor(
asyncio_actor, asyncio_actor,
target='sleep_forever', target='sleep_forever',
expect_err='asyncio.CancelledError', expect_err='trio.Cancelled',
infect_asyncio=True, infect_asyncio=True,
) )
# cancel the entire remote runtime
await portal.cancel_actor() await portal.cancel_actor()
trio.run(main) trio.run(main)
async def aio_cancel():
''''Cancel urself boi.
'''
await asyncio.sleep(0.5)
task = asyncio.current_task()
# cancel and enter sleep
task.cancel()
await sleep_forever()
def test_aio_cancelled_from_aio_causes_trio_cancelled(arb_addr): def test_aio_cancelled_from_aio_causes_trio_cancelled(arb_addr):
...
async def main():
async with tractor.open_nursery() as n:
portal = await n.run_in_actor(
asyncio_actor,
target='aio_cancel',
expect_err='asyncio.CancelledError',
infect_asyncio=True,
)
# with trio.CancelScope(shield=True):
await portal.result()
with pytest.raises(RemoteActorError) as excinfo:
trio.run(main)
def test_trio_cancels_aio(arb_addr): def test_trio_cancels_aio(arb_addr):