@@ -278,3 +278,60 @@ async def cancel_sleep():
278278 with test_utils .deprecate (self ):
279279 await loop .run_asyncio (cancel_sleep )
280280 assert owch == 0
281+
282+
283+ @pytest .mark .trio
284+ async def test_wrong_context_manager_order ():
285+ async def work_in_asyncio ():
286+ await asyncio .sleep (0 )
287+
288+ async def runner (* , task_status = trio .TASK_STATUS_IGNORED ):
289+ await trio_asyncio .run_asyncio (work_in_asyncio )
290+ try :
291+ task_status .started ()
292+ await trio .sleep_forever ()
293+ finally :
294+ await trio_asyncio .run_asyncio (work_in_asyncio )
295+
296+ async with trio .open_nursery () as nursery :
297+ async with trio_asyncio .open_loop ():
298+ await nursery .start (runner )
299+
300+
301+ @pytest .mark .trio
302+ async def test_keyboard_interrupt_teardown ():
303+ asyncio_loop_closed = trio .Event ()
304+
305+ async def work_in_trio_no_matter_what (* , task_status = trio .TASK_STATUS_IGNORED ):
306+ await trio_asyncio .run_asyncio (work_in_asyncio )
307+ try :
308+ # KeyboardInterrupt won't cancel this coroutine thanks to the shield
309+ with trio .open_cancel_scope (shield = True ):
310+ task_status .started ()
311+ await asyncio_loop_closed .wait ()
312+ finally :
313+ # Hence this call will be exceuted after run_asyncio_loop is cancelled
314+ await trio_asyncio .run_asyncio (work_in_asyncio )
315+
316+ async def work_in_asyncio ():
317+ await asyncio .sleep (0 )
318+
319+ async def run_asyncio_loop (nursery , * , task_status = trio .TASK_STATUS_IGNORED ):
320+ with trio .open_cancel_scope () as cancel_scope :
321+ try :
322+ async with trio_asyncio .open_loop ():
323+ # Starting a coroutine from here make it inherit the access
324+ # to the asyncio loop context manager
325+ await nursery .start (work_in_trio_no_matter_what )
326+ task_status .started (cancel_scope )
327+ await trio .sleep_forever ()
328+ finally :
329+ asyncio_loop_closed .set ()
330+
331+ import signal
332+ import threading
333+ with pytest .raises (KeyboardInterrupt ):
334+ async with trio .open_nursery () as nursery :
335+ await nursery .start (run_asyncio_loop , nursery )
336+ # Trigger KeyboardInterrupt that should propagate accross the coroutines
337+ signal .pthread_kill (threading .get_ident (), signal .SIGINT )
0 commit comments