|
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