Skip to content

Commit 8585040

Browse files
committed
fix: Centralize logic for determining the loop scope of an item.
This fixes a bug that lead to multiple deprecation warnings being emitted.
1 parent 695d1e6 commit 8585040

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

pytest_asyncio/plugin.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
Literal,
2929
TypeVar,
3030
Union,
31+
cast,
3132
overload,
3233
)
3334

@@ -437,12 +438,23 @@ def _can_substitute(item: Function) -> bool:
437438
"""Returns whether the specified function can be replaced by this class"""
438439
raise NotImplementedError()
439440

440-
def runtest(self) -> None:
441+
@functools.cached_property
442+
def loop_scope(self) -> _ScopeName:
443+
"""
444+
Return the scope of the asyncio event loop this item is run in.
445+
446+
The effective scope is determined lazily. It is identical to to the
447+
`loop_scope` value of the closest `asyncio` pytest marker. If no such
448+
marker is present, the the loop scope is determined by the configuration
449+
value of `asyncio_default_test_loop_scope`, instead.
450+
"""
441451
marker = self.get_closest_marker("asyncio")
442452
assert marker is not None
443453
default_loop_scope = _get_default_test_loop_scope(self.config)
444-
loop_scope = _get_marked_loop_scope(marker, default_loop_scope)
445-
runner_fixture_id = f"_{loop_scope}_scoped_runner"
454+
return _get_marked_loop_scope(marker, default_loop_scope)
455+
456+
def runtest(self) -> None:
457+
runner_fixture_id = f"_{self.loop_scope}_scoped_runner"
446458
runner = self._request.getfixturevalue(runner_fixture_id)
447459
context = contextvars.copy_context()
448460
synchronized_obj = _synchronize_coroutine(
@@ -684,11 +696,10 @@ def inner(*args, **kwargs):
684696

685697
def pytest_runtest_setup(item: pytest.Item) -> None:
686698
marker = item.get_closest_marker("asyncio")
687-
if marker is None:
699+
if marker is None or not is_async_test(item):
688700
return
689-
default_loop_scope = _get_default_test_loop_scope(item.config)
690-
loop_scope = _get_marked_loop_scope(marker, default_loop_scope)
691-
runner_fixture_id = f"_{loop_scope}_scoped_runner"
701+
item = cast(PytestAsyncioFunction, item)
702+
runner_fixture_id = f"_{item.loop_scope}_scoped_runner"
692703
fixturenames = item.fixturenames # type: ignore[attr-defined]
693704
if runner_fixture_id not in fixturenames:
694705
fixturenames.append(runner_fixture_id)

0 commit comments

Comments
 (0)