@@ -793,6 +793,59 @@ async def mycoro():
793793 assert not loop .is_running ()
794794
795795
796+ @pytest .mark .parametrize (
797+ "async_wrap, expect_async_called, expect_exception" ,
798+ [(False , False , True ), (True , True , False )],
799+ )
800+ def test_async_wrap (
801+ loop , application , async_wrap , expect_async_called , expect_exception
802+ ):
803+ """
804+ Re-entering the event loop from a Task will fail if there is another
805+ runnable task.
806+ """
807+ async_called = False
808+ main_called = False
809+
810+ async def async_job ():
811+ nonlocal async_called
812+ async_called = True
813+
814+ def sync_callback ():
815+ coro = async_job ()
816+ asyncio .create_task (coro )
817+ assert not async_called
818+ application .processEvents ()
819+ assert async_called if expect_async_called else not async_called
820+ return 1 , coro
821+
822+ async def main ():
823+ nonlocal main_called
824+ if async_wrap :
825+ res , coro = await qasync .asyncWrap (sync_callback )
826+ else :
827+ res , coro = sync_callback ()
828+ if expect_exception :
829+ await coro # avoid warnings about unawaited coroutines
830+ assert res == 1
831+ main_called = True
832+
833+
834+ exceptions = []
835+ loop .set_exception_handler (lambda loop , context : exceptions .append (context ))
836+
837+ loop .run_until_complete (main ())
838+ assert main_called , "The main function should have been called"
839+
840+ if expect_exception :
841+ # We will now have an error in there, because the task 'async_job' could not
842+ # be entered, because the task 'main' was still being executed by the event loop.
843+ assert len (exceptions ) == 1
844+ assert isinstance (exceptions [0 ]["exception" ], RuntimeError )
845+ else :
846+ assert len (exceptions ) == 0
847+
848+
796849def test_slow_callback_duration_logging (loop , caplog ):
797850 async def mycoro ():
798851 time .sleep (1 )
0 commit comments