@@ -396,6 +396,75 @@ async def trio_task():
396396 assert fut .cancelled ()
397397
398398
399+ @pytest .mark .trio
400+ async def test_trio_as_fut_throws_after_cancelled ():
401+ """If a trio_as_future() future is cancelled, any exception
402+ thrown by the Trio task as it unwinds is ignored. (This is
403+ somewhat infelicitous, but the asyncio Future API doesn't allow
404+ a future to go from cancelled to some other outcome.)
405+ """
406+
407+ async def trio_task ():
408+ try :
409+ await trio .sleep_forever ()
410+ finally :
411+ raise ValueError ("hi" )
412+
413+ async with trio_asyncio .open_loop () as loop :
414+ fut = loop .trio_as_future (trio_task )
415+ await trio .testing .wait_all_tasks_blocked ()
416+ fut .cancel ()
417+ with pytest .raises (asyncio .CancelledError ):
418+ await fut
419+
420+
421+ @pytest .mark .trio
422+ async def test_run_trio_task_errors (monkeypatch ):
423+ async with trio_asyncio .open_loop () as loop :
424+ # Test never getting to start the task
425+ handle = loop .run_trio_task (trio .sleep_forever )
426+ handle .cancel ()
427+
428+ # Test cancelling the task
429+ handle = loop .run_trio_task (trio .sleep_forever )
430+ await trio .testing .wait_all_tasks_blocked ()
431+ handle .cancel ()
432+
433+ # Helper for the rest of this test, which covers cases where
434+ # the Trio task raises an exception
435+ async def raise_in_aio_loop (exc ):
436+ async def raise_it ():
437+ raise exc
438+
439+ async with trio_asyncio .open_loop () as loop :
440+ loop .run_trio_task (raise_it )
441+
442+ # We temporarily modify the default exception handler to collect
443+ # the exceptions instead of logging or raising them
444+
445+ exceptions = []
446+
447+ def collect_exceptions (loop , context ):
448+ if context .get ("exception" ):
449+ exceptions .append (context ["exception" ])
450+ else :
451+ exceptions .append (RuntimeError (context .get ("message" ) or "unknown" ))
452+
453+ monkeypatch .setattr (
454+ trio_asyncio .TrioEventLoop , "default_exception_handler" , collect_exceptions
455+ )
456+ expected = [
457+ ValueError ("hi" ), ValueError ("lo" ), KeyError (), IndexError ()
458+ ]
459+ await raise_in_aio_loop (expected [0 ])
460+ with pytest .raises (SystemExit ):
461+ await raise_in_aio_loop (SystemExit (0 ))
462+ with pytest .raises (SystemExit ):
463+ await raise_in_aio_loop (trio .MultiError ([expected [1 ], SystemExit ()]))
464+ await raise_in_aio_loop (trio .MultiError (expected [2 :]))
465+ assert exceptions == expected
466+
467+
399468@pytest .mark .trio
400469@pytest .mark .skipif (sys .version_info < (3 , 7 ), reason = "needs asyncio contextvars" )
401470async def test_contextvars ():
0 commit comments