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