@@ -251,15 +251,8 @@ def _preprocess_async_fixtures(
251251 or default_loop_scope
252252 or fixturedef .scope
253253 )
254- if scope == "function" :
255- event_loop_fixture_id : Optional [str ] = "event_loop"
256- else :
257- event_loop_node = _retrieve_scope_root (collector , scope )
258- event_loop_fixture_id = event_loop_node .stash .get (
259- # Type ignored because of non-optimal mypy inference.
260- _event_loop_fixture_id , # type: ignore[arg-type]
261- None ,
262- )
254+ if scope == "function" and "event_loop" not in fixturedef .argnames :
255+ fixturedef .argnames += ("event_loop" ,)
263256 _make_asyncio_fixture_function (func , scope )
264257 function_signature = inspect .signature (func )
265258 if "event_loop" in function_signature .parameters :
@@ -271,58 +264,35 @@ def _preprocess_async_fixtures(
271264 f"instead."
272265 )
273266 )
274- assert event_loop_fixture_id
275- _inject_fixture_argnames (
276- fixturedef ,
277- event_loop_fixture_id ,
278- )
279- _synchronize_async_fixture (
280- fixturedef ,
281- event_loop_fixture_id ,
282- )
267+ if "request" not in fixturedef .argnames :
268+ fixturedef .argnames += ("request" ,)
269+ _synchronize_async_fixture (fixturedef )
283270 assert _is_asyncio_fixture_function (fixturedef .func )
284271 processed_fixturedefs .add (fixturedef )
285272
286273
287- def _inject_fixture_argnames (
288- fixturedef : FixtureDef , event_loop_fixture_id : str
289- ) -> None :
290- """
291- Ensures that `request` and `event_loop` are arguments of the specified fixture.
292- """
293- to_add = []
294- for name in ("request" , event_loop_fixture_id ):
295- if name not in fixturedef .argnames :
296- to_add .append (name )
297- if to_add :
298- fixturedef .argnames += tuple (to_add )
299-
300-
301- def _synchronize_async_fixture (
302- fixturedef : FixtureDef , event_loop_fixture_id : str
303- ) -> None :
274+ def _synchronize_async_fixture (fixturedef : FixtureDef ) -> None :
304275 """
305276 Wraps the fixture function of an async fixture in a synchronous function.
306277 """
307278 if inspect .isasyncgenfunction (fixturedef .func ):
308- _wrap_asyncgen_fixture (fixturedef , event_loop_fixture_id )
279+ _wrap_asyncgen_fixture (fixturedef )
309280 elif inspect .iscoroutinefunction (fixturedef .func ):
310- _wrap_async_fixture (fixturedef , event_loop_fixture_id )
281+ _wrap_async_fixture (fixturedef )
311282
312283
313284def _add_kwargs (
314285 func : Callable [..., Any ],
315286 kwargs : Dict [str , Any ],
316- event_loop_fixture_id : str ,
317287 event_loop : asyncio .AbstractEventLoop ,
318288 request : FixtureRequest ,
319289) -> Dict [str , Any ]:
320290 sig = inspect .signature (func )
321291 ret = kwargs .copy ()
322292 if "request" in sig .parameters :
323293 ret ["request" ] = request
324- if event_loop_fixture_id in sig .parameters :
325- ret [event_loop_fixture_id ] = event_loop
294+ if "event_loop" in sig .parameters :
295+ ret ["event_loop" ] = event_loop
326296 return ret
327297
328298
@@ -345,17 +315,19 @@ def _perhaps_rebind_fixture_func(
345315 return func
346316
347317
348- def _wrap_asyncgen_fixture (fixturedef : FixtureDef , event_loop_fixture_id : str ) -> None :
318+ def _wrap_asyncgen_fixture (fixturedef : FixtureDef ) -> None :
349319 fixture = fixturedef .func
350320
351321 @functools .wraps (fixture )
352322 def _asyncgen_fixture_wrapper (request : FixtureRequest , ** kwargs : Any ):
353323 unittest = fixturedef .unittest if hasattr (fixturedef , "unittest" ) else False
354324 func = _perhaps_rebind_fixture_func (fixture , request .instance , unittest )
355- event_loop = kwargs .pop (event_loop_fixture_id )
356- gen_obj = func (
357- ** _add_kwargs (func , kwargs , event_loop_fixture_id , event_loop , request )
325+ event_loop_fixture_id = _get_event_loop_fixture_id_for_async_fixture (
326+ request , func
358327 )
328+ event_loop = request .getfixturevalue (event_loop_fixture_id )
329+ kwargs .pop (event_loop_fixture_id , None )
330+ gen_obj = func (** _add_kwargs (func , kwargs , event_loop , request ))
359331
360332 async def setup ():
361333 res = await gen_obj .__anext__ ()
@@ -383,26 +355,48 @@ async def async_finalizer() -> None:
383355 fixturedef .func = _asyncgen_fixture_wrapper
384356
385357
386- def _wrap_async_fixture (fixturedef : FixtureDef , event_loop_fixture_id : str ) -> None :
358+ def _wrap_async_fixture (fixturedef : FixtureDef ) -> None :
387359 fixture = fixturedef .func
388360
389361 @functools .wraps (fixture )
390362 def _async_fixture_wrapper (request : FixtureRequest , ** kwargs : Any ):
391363 unittest = False if pytest .version_tuple >= (8 , 2 ) else fixturedef .unittest
392364 func = _perhaps_rebind_fixture_func (fixture , request .instance , unittest )
393- event_loop = kwargs .pop (event_loop_fixture_id )
365+ event_loop_fixture_id = _get_event_loop_fixture_id_for_async_fixture (
366+ request , func
367+ )
368+ event_loop = request .getfixturevalue (event_loop_fixture_id )
369+ kwargs .pop (event_loop_fixture_id , None )
394370
395371 async def setup ():
396- res = await func (
397- ** _add_kwargs (func , kwargs , event_loop_fixture_id , event_loop , request )
398- )
372+ res = await func (** _add_kwargs (func , kwargs , event_loop , request ))
399373 return res
400374
401375 return event_loop .run_until_complete (setup ())
402376
403377 fixturedef .func = _async_fixture_wrapper
404378
405379
380+ def _get_event_loop_fixture_id_for_async_fixture (
381+ request : FixtureRequest , func : Any
382+ ) -> str :
383+ default_loop_scope = request .config .getini ("asyncio_default_fixture_loop_scope" )
384+ loop_scope = (
385+ getattr (func , "_loop_scope" , None ) or default_loop_scope or request .scope
386+ )
387+ if loop_scope == "function" :
388+ event_loop_fixture_id = "event_loop"
389+ else :
390+ event_loop_node = _retrieve_scope_root (request ._pyfuncitem , loop_scope )
391+ event_loop_fixture_id = event_loop_node .stash .get (
392+ # Type ignored because of non-optimal mypy inference.
393+ _event_loop_fixture_id , # type: ignore[arg-type]
394+ "" ,
395+ )
396+ assert event_loop_fixture_id
397+ return event_loop_fixture_id
398+
399+
406400class PytestAsyncioFunction (Function ):
407401 """Base class for all test functions managed by pytest-asyncio."""
408402
0 commit comments