@@ -708,11 +708,12 @@ def scoped_event_loop(
708
708
event_loop_policy ,
709
709
) -> Iterator [asyncio .AbstractEventLoop ]:
710
710
new_loop_policy = event_loop_policy
711
- with _temporary_event_loop_policy (new_loop_policy ):
712
- loop = _make_pytest_asyncio_loop (asyncio .new_event_loop ())
711
+ with (
712
+ _temporary_event_loop_policy (new_loop_policy ),
713
+ _provide_event_loop () as loop ,
714
+ ):
713
715
asyncio .set_event_loop (loop )
714
716
yield loop
715
- loop .close ()
716
717
717
718
# @pytest.fixture does not register the fixture anywhere, so pytest doesn't
718
719
# know it exists. We work around this by attaching the fixture function to the
@@ -1147,28 +1148,36 @@ def _retrieve_scope_root(item: Collector | Item, scope: str) -> Collector:
1147
1148
def event_loop (request : FixtureRequest ) -> Iterator [asyncio .AbstractEventLoop ]:
1148
1149
"""Create an instance of the default event loop for each test case."""
1149
1150
new_loop_policy = request .getfixturevalue (event_loop_policy .__name__ )
1150
- with _temporary_event_loop_policy (new_loop_policy ):
1151
- loop = asyncio .get_event_loop_policy ().new_event_loop ()
1152
- # Add a magic value to the event loop, so pytest-asyncio can determine if the
1153
- # event_loop fixture was overridden. Other implementations of event_loop don't
1154
- # set this value.
1155
- # The magic value must be set as part of the function definition, because pytest
1156
- # seems to have multiple instances of the same FixtureDef or fixture function
1157
- loop = _make_pytest_asyncio_loop (loop )
1151
+ with _temporary_event_loop_policy (new_loop_policy ), _provide_event_loop () as loop :
1158
1152
yield loop
1159
- loop .close ()
1153
+
1154
+
1155
+ @contextlib .contextmanager
1156
+ def _provide_event_loop () -> Iterator [asyncio .AbstractEventLoop ]:
1157
+ loop = asyncio .get_event_loop_policy ().new_event_loop ()
1158
+ # Add a magic value to the event loop, so pytest-asyncio can determine if the
1159
+ # event_loop fixture was overridden. Other implementations of event_loop don't
1160
+ # set this value.
1161
+ # The magic value must be set as part of the function definition, because pytest
1162
+ # seems to have multiple instances of the same FixtureDef or fixture function
1163
+ loop = _make_pytest_asyncio_loop (loop )
1164
+ try :
1165
+ yield loop
1166
+ finally :
1167
+ try :
1168
+ loop .run_until_complete (loop .shutdown_asyncgens ())
1169
+ finally :
1170
+ loop .close ()
1160
1171
1161
1172
1162
1173
@pytest .fixture (scope = "session" )
1163
1174
def _session_event_loop (
1164
1175
request : FixtureRequest , event_loop_policy : AbstractEventLoopPolicy
1165
1176
) -> Iterator [asyncio .AbstractEventLoop ]:
1166
1177
new_loop_policy = event_loop_policy
1167
- with _temporary_event_loop_policy (new_loop_policy ):
1168
- loop = _make_pytest_asyncio_loop (asyncio .new_event_loop ())
1178
+ with _temporary_event_loop_policy (new_loop_policy ), _provide_event_loop () as loop :
1169
1179
asyncio .set_event_loop (loop )
1170
1180
yield loop
1171
- loop .close ()
1172
1181
1173
1182
1174
1183
@pytest .fixture (scope = "session" , autouse = True )
0 commit comments