Skip to content

Commit 7d6af9a

Browse files
committed
feat: Allow use of "loop_scope" kwarg in asyncio markers.
1 parent 1fbc4c2 commit 7d6af9a

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

pytest_asyncio/plugin.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -991,9 +991,21 @@ def pytest_runtest_setup(item: pytest.Item) -> None:
991991
)
992992

993993

994+
_DUPLICATE_LOOP_SCOPE_DEFINITION_ERROR = """\
995+
An asyncio pytest marker defines both "scope" and "loop_scope", \
996+
but it should only use "loop_scope".
997+
"""
998+
999+
9941000
def _get_marked_loop_scope(asyncio_marker: Mark) -> _ScopeName:
9951001
assert asyncio_marker.name == "asyncio"
996-
return asyncio_marker.kwargs.get("scope", "function")
1002+
if "scope" in asyncio_marker.kwargs and "loop_scope" in asyncio_marker.kwargs:
1003+
raise pytest.UsageError(_DUPLICATE_LOOP_SCOPE_DEFINITION_ERROR)
1004+
scope = asyncio_marker.kwargs.get("loop_scope") or asyncio_marker.kwargs.get(
1005+
"scope", "function"
1006+
)
1007+
assert scope in {"function", "class", "module", "package", "session"}
1008+
return scope
9971009

9981010

9991011
def _retrieve_scope_root(item: Union[Collector, Item], scope: str) -> Collector:

tests/markers/test_function_scope.py

+41
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,47 @@ async def test_does_not_run_in_same_loop():
2828
result.assert_outcomes(passed=2)
2929

3030

31+
def test_loop_scope_function_provides_function_scoped_event_loop(pytester: Pytester):
32+
pytester.makepyfile(
33+
dedent(
34+
"""\
35+
import asyncio
36+
import pytest
37+
38+
pytestmark = pytest.mark.asyncio(loop_scope="function")
39+
40+
loop: asyncio.AbstractEventLoop
41+
42+
async def test_remember_loop():
43+
global loop
44+
loop = asyncio.get_running_loop()
45+
46+
async def test_does_not_run_in_same_loop():
47+
global loop
48+
assert asyncio.get_running_loop() is not loop
49+
"""
50+
)
51+
)
52+
result = pytester.runpytest("--asyncio-mode=strict")
53+
result.assert_outcomes(passed=2)
54+
55+
56+
def test_raises_when_scope_and_loop_scope_arguments_are_present(pytester: Pytester):
57+
pytester.makepyfile(
58+
dedent(
59+
"""\
60+
import pytest
61+
62+
@pytest.mark.asyncio(scope="function", loop_scope="function")
63+
async def test_raises():
64+
...
65+
"""
66+
)
67+
)
68+
result = pytester.runpytest("--asyncio-mode=strict")
69+
result.assert_outcomes(errors=1)
70+
71+
3172
def test_function_scope_supports_explicit_event_loop_fixture_request(
3273
pytester: Pytester,
3374
):

0 commit comments

Comments
 (0)