|
28 | 28 | Literal,
|
29 | 29 | TypeVar,
|
30 | 30 | Union,
|
| 31 | + cast, |
31 | 32 | overload,
|
32 | 33 | )
|
33 | 34 |
|
@@ -437,12 +438,23 @@ def _can_substitute(item: Function) -> bool:
|
437 | 438 | """Returns whether the specified function can be replaced by this class"""
|
438 | 439 | raise NotImplementedError()
|
439 | 440 |
|
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 | + """ |
441 | 451 | marker = self.get_closest_marker("asyncio")
|
442 | 452 | assert marker is not None
|
443 | 453 | 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" |
446 | 458 | runner = self._request.getfixturevalue(runner_fixture_id)
|
447 | 459 | context = contextvars.copy_context()
|
448 | 460 | synchronized_obj = _synchronize_coroutine(
|
@@ -684,11 +696,10 @@ def inner(*args, **kwargs):
|
684 | 696 |
|
685 | 697 | def pytest_runtest_setup(item: pytest.Item) -> None:
|
686 | 698 | marker = item.get_closest_marker("asyncio")
|
687 |
| - if marker is None: |
| 699 | + if marker is None or not is_async_test(item): |
688 | 700 | 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" |
692 | 703 | fixturenames = item.fixturenames # type: ignore[attr-defined]
|
693 | 704 | if runner_fixture_id not in fixturenames:
|
694 | 705 | fixturenames.append(runner_fixture_id)
|
|
0 commit comments