@@ -590,21 +590,11 @@ def scoped_event_loop(
590590 event_loop_policy ,
591591 ) -> Iterator [asyncio .AbstractEventLoop ]:
592592 new_loop_policy = event_loop_policy
593- old_loop_policy = asyncio .get_event_loop_policy ()
594- old_loop = asyncio .get_event_loop ()
595- asyncio .set_event_loop_policy (new_loop_policy )
596- loop = asyncio .new_event_loop ()
597- asyncio .set_event_loop (loop )
598- yield loop
599- loop .close ()
600- asyncio .set_event_loop_policy (old_loop_policy )
601- # When a test uses both a scoped event loop and the event_loop fixture,
602- # the "_provide_clean_event_loop" finalizer of the event_loop fixture
603- # will already have installed a fresh event loop, in order to shield
604- # subsequent tests from side-effects. We close this loop before restoring
605- # the old loop to avoid ResourceWarnings.
606- asyncio .get_event_loop ().close ()
607- asyncio .set_event_loop (old_loop )
593+ with _temporary_event_loop_policy (new_loop_policy ):
594+ loop = asyncio .new_event_loop ()
595+ asyncio .set_event_loop (loop )
596+ yield loop
597+ loop .close ()
608598
609599 # @pytest.fixture does not register the fixture anywhere, so pytest doesn't
610600 # know it exists. We work around this by attaching the fixture function to the
@@ -630,6 +620,24 @@ def _removesuffix(s: str, suffix: str) -> str:
630620 return s .removesuffix (suffix )
631621
632622
623+ @contextlib .contextmanager
624+ def _temporary_event_loop_policy (policy : AbstractEventLoopPolicy ) -> Iterator [None ]:
625+ old_loop_policy = asyncio .get_event_loop_policy ()
626+ old_loop = asyncio .get_event_loop ()
627+ asyncio .set_event_loop_policy (policy )
628+ try :
629+ yield
630+ finally :
631+ asyncio .set_event_loop_policy (old_loop_policy )
632+ # When a test uses both a scoped event loop and the event_loop fixture,
633+ # the "_provide_clean_event_loop" finalizer of the event_loop fixture
634+ # will already have installed a fresh event loop, in order to shield
635+ # subsequent tests from side-effects. We close this loop before restoring
636+ # the old loop to avoid ResourceWarnings.
637+ asyncio .get_event_loop ().close ()
638+ asyncio .set_event_loop (old_loop )
639+
640+
633641def pytest_collection_modifyitems (
634642 session : Session , config : Config , items : List [Item ]
635643) -> None :
@@ -958,21 +966,11 @@ def _session_event_loop(
958966 request : FixtureRequest , event_loop_policy : AbstractEventLoopPolicy
959967) -> Iterator [asyncio .AbstractEventLoop ]:
960968 new_loop_policy = event_loop_policy
961- old_loop_policy = asyncio .get_event_loop_policy ()
962- old_loop = asyncio .get_event_loop ()
963- asyncio .set_event_loop_policy (new_loop_policy )
964- loop = asyncio .new_event_loop ()
965- asyncio .set_event_loop (loop )
966- yield loop
967- loop .close ()
968- asyncio .set_event_loop_policy (old_loop_policy )
969- # When a test uses both a scoped event loop and the event_loop fixture,
970- # the "_provide_clean_event_loop" finalizer of the event_loop fixture
971- # will already have installed a fresh event loop, in order to shield
972- # subsequent tests from side-effects. We close this loop before restoring
973- # the old loop to avoid ResourceWarnings.
974- asyncio .get_event_loop ().close ()
975- asyncio .set_event_loop (old_loop )
969+ with _temporary_event_loop_policy (new_loop_policy ):
970+ loop = asyncio .new_event_loop ()
971+ asyncio .set_event_loop (loop )
972+ yield loop
973+ loop .close ()
976974
977975
978976@pytest .fixture (scope = "session" , autouse = True )
0 commit comments