|
8 | 8 | import socket |
9 | 9 | import warnings |
10 | 10 | from asyncio import AbstractEventLoopPolicy |
| 11 | +from itertools import dropwhile |
11 | 12 | from textwrap import dedent |
12 | 13 | from typing import ( |
13 | 14 | Any, |
@@ -958,18 +959,26 @@ def _retrieve_scope_root(item: Union[Collector, Item], scope: str) -> Collector: |
958 | 959 | "package": Package, |
959 | 960 | "session": Session, |
960 | 961 | } |
| 962 | + collectors = _iter_collectors(item) |
961 | 963 | scope_root_type = node_type_by_scope[scope] |
962 | | - for node in reversed(item.listchain()): |
963 | | - if isinstance(node, scope_root_type): |
964 | | - assert isinstance(node, pytest.Collector) |
965 | | - return node |
| 964 | + collector_with_specified_scope = next( |
| 965 | + dropwhile(lambda c: not isinstance(c, scope_root_type), collectors), None |
| 966 | + ) |
| 967 | + if collector_with_specified_scope: |
| 968 | + return collector_with_specified_scope |
966 | 969 | error_message = ( |
967 | 970 | f"{item.name} is marked to be run in an event loop with scope {scope}, " |
968 | 971 | f"but is not part of any {scope}." |
969 | 972 | ) |
970 | 973 | raise pytest.UsageError(error_message) |
971 | 974 |
|
972 | 975 |
|
| 976 | +def _iter_collectors(item: Union[Collector, Item]) -> Iterable[Collector]: |
| 977 | + for node in reversed(item.listchain()): |
| 978 | + if isinstance(node, pytest.Collector): |
| 979 | + yield node |
| 980 | + |
| 981 | + |
973 | 982 | @pytest.fixture |
974 | 983 | def event_loop(request: FixtureRequest) -> Iterator[asyncio.AbstractEventLoop]: |
975 | 984 | """Create an instance of the default event loop for each test case.""" |
|
0 commit comments