Skip to content

Commit 1bb4299

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

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

Diff for: pytest_asyncio/plugin.py

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

992992

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

9971009

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

Diff for: 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)