Skip to content

Commit afae52f

Browse files
committed
feat: Async fixture wrappers determine the event loop scope dynamically, rather than relying on event_loop_id_mapping.
1 parent 09e49ef commit afae52f

File tree

1 file changed

+26
-15
lines changed

1 file changed

+26
-15
lines changed

pytest_asyncio/plugin.py

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -352,20 +352,27 @@ def _wrap_asyncgen_fixture(
352352
) -> None:
353353
fixture = fixturedef.func
354354

355-
event_loop_id_mapping = getattr(fixture, "_event_loop_id_mapping", {})
356-
event_loop_id_mapping[event_loop_fixture_name] = event_loop_fixture_id
357-
event_loop_id_mapping["function"] = event_loop_fixture_id
358-
359355
if getattr(fixture, "_async_fixture", False):
360356
return fixture
361357

362358
@functools.wraps(fixture)
363359
def _asyncgen_fixture_wrapper(request: FixtureRequest, **kwargs: Any):
364360
unittest = fixturedef.unittest if hasattr(fixturedef, "unittest") else False
365361
func = _perhaps_rebind_fixture_func(fixture, request.instance, unittest)
366-
event_loop_fixture_id = event_loop_id_mapping.get(
367-
request.node.name, event_loop_id_mapping["function"]
362+
default_loop_scope = request.config.getini("asyncio_default_fixture_loop_scope")
363+
loop_scope = (
364+
getattr(func, "_loop_scope", None) or default_loop_scope or request.scope
368365
)
366+
if loop_scope == "function":
367+
event_loop_fixture_id = "event_loop"
368+
else:
369+
event_loop_node = _retrieve_scope_root(request._pyfuncitem, loop_scope)
370+
event_loop_fixture_id = event_loop_node.stash.get(
371+
# Type ignored because of non-optimal mypy inference.
372+
_event_loop_fixture_id, # type: ignore[arg-type]
373+
"",
374+
)
375+
assert event_loop_fixture_id
369376
event_loop = request.getfixturevalue(event_loop_fixture_id)
370377
kwargs.pop(event_loop_fixture_id, None)
371378
gen_obj = func(**_add_kwargs(func, kwargs, event_loop, request))
@@ -393,7 +400,6 @@ async def async_finalizer() -> None:
393400
request.addfinalizer(finalizer)
394401
return result
395402

396-
setattr(_asyncgen_fixture_wrapper, "_event_loop_id_mapping", event_loop_id_mapping)
397403
setattr(_asyncgen_fixture_wrapper, "_async_fixture", True)
398404

399405
fixturedef.func = _asyncgen_fixture_wrapper
@@ -404,21 +410,27 @@ def _wrap_async_fixture(
404410
) -> None:
405411
fixture = fixturedef.func
406412

407-
event_loop_id_mapping = getattr(fixture, "_event_loop_id_mapping", {})
408-
event_loop_id_mapping[event_loop_fixture_name] = event_loop_fixture_id
409-
event_loop_id_mapping["function"] = event_loop_fixture_id
410-
print(fixturedef, event_loop_id_mapping)
411-
412413
if getattr(fixture, "_async_fixture", False):
413414
return fixture
414415

415416
@functools.wraps(fixture)
416417
def _async_fixture_wrapper(request: FixtureRequest, **kwargs: Any):
417418
unittest = False if pytest.version_tuple >= (8, 2) else fixturedef.unittest
418419
func = _perhaps_rebind_fixture_func(fixture, request.instance, unittest)
419-
event_loop_fixture_id = event_loop_id_mapping.get(
420-
request.node.name, event_loop_id_mapping["function"]
420+
default_loop_scope = request.config.getini("asyncio_default_fixture_loop_scope")
421+
loop_scope = (
422+
getattr(func, "_loop_scope", None) or default_loop_scope or request.scope
421423
)
424+
if loop_scope == "function":
425+
event_loop_fixture_id = "event_loop"
426+
else:
427+
event_loop_node = _retrieve_scope_root(request._pyfuncitem, loop_scope)
428+
event_loop_fixture_id = event_loop_node.stash.get(
429+
# Type ignored because of non-optimal mypy inference.
430+
_event_loop_fixture_id, # type: ignore[arg-type]
431+
"",
432+
)
433+
assert event_loop_fixture_id
422434
event_loop = request.getfixturevalue(event_loop_fixture_id)
423435
kwargs.pop(event_loop_fixture_id, None)
424436

@@ -428,7 +440,6 @@ async def setup():
428440

429441
return event_loop.run_until_complete(setup())
430442

431-
setattr(_async_fixture_wrapper, "_event_loop_id_mapping", event_loop_id_mapping)
432443
setattr(_async_fixture_wrapper, "_async_fixture", True)
433444

434445
fixturedef.func = _async_fixture_wrapper

0 commit comments

Comments
 (0)