Skip to content

Commit e2bd784

Browse files
committed
Check marker arguments
1 parent 97bd934 commit e2bd784

File tree

2 files changed

+110
-1
lines changed

2 files changed

+110
-1
lines changed

pytest_asyncio/plugin.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,8 @@ def pytest_generate_tests(metafunc: Metafunc) -> None:
700700
marker = metafunc.definition.get_closest_marker("asyncio")
701701
if not marker:
702702
return
703+
if marker.args or (marker.kwargs and list(marker.kwargs) != ["scope"]):
704+
raise ValueError("mark.asyncio accepts only a keyword argument 'scope'.")
703705
scope = marker.kwargs.get("scope", "function")
704706
if scope == "function":
705707
return
@@ -959,7 +961,10 @@ def _retrieve_scope_root(item: Union[Collector, Item], scope: str) -> Collector:
959961
"package": Package,
960962
"session": Session,
961963
}
962-
scope_root_type = node_type_by_scope[scope]
964+
try:
965+
scope_root_type = node_type_by_scope[scope]
966+
except KeyError as error:
967+
raise ValueError(f"Invalid scope {scope!r}.") from error
963968
for node in reversed(item.listchain()):
964969
if isinstance(node, scope_root_type):
965970
assert isinstance(node, pytest.Collector)
+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
from textwrap import dedent
2+
3+
import pytest
4+
5+
6+
def test_no_error_when_scope_passed_as_sole_keyword_argument(
7+
pytester: pytest.Pytester,
8+
):
9+
pytester.makepyfile(
10+
dedent(
11+
"""\
12+
import pytest
13+
14+
@pytest.mark.asyncio(scope="session")
15+
async def test_anything():
16+
pass
17+
"""
18+
)
19+
)
20+
result = pytester.runpytest_subprocess()
21+
result.assert_outcomes(passed=1)
22+
result.stdout.no_fnmatch_line("*ValueError*")
23+
24+
25+
def test_error_when_scope_passed_as_positional_argument(
26+
pytester: pytest.Pytester,
27+
):
28+
pytester.makepyfile(
29+
dedent(
30+
"""\
31+
import pytest
32+
33+
@pytest.mark.asyncio("session")
34+
async def test_anything():
35+
pass
36+
"""
37+
)
38+
)
39+
result = pytester.runpytest_subprocess()
40+
result.assert_outcomes(errors=1)
41+
result.stdout.fnmatch_lines(
42+
["*ValueError: mark.asyncio accepts only a keyword argument*"]
43+
)
44+
45+
46+
def test_error_when_wrong_keyword_argument_is_passed(
47+
pytester: pytest.Pytester,
48+
):
49+
pytester.makepyfile(
50+
dedent(
51+
"""\
52+
import pytest
53+
54+
@pytest.mark.asyncio(cope="session")
55+
async def test_anything():
56+
pass
57+
"""
58+
)
59+
)
60+
result = pytester.runpytest_subprocess()
61+
result.assert_outcomes(errors=1)
62+
result.stdout.fnmatch_lines(
63+
["*ValueError: mark.asyncio accepts only a keyword argument 'scope'*"]
64+
)
65+
66+
67+
def test_error_when_additional_keyword_arguments_are_passed(
68+
pytester: pytest.Pytester,
69+
):
70+
pytester.makepyfile(
71+
dedent(
72+
"""\
73+
import pytest
74+
75+
@pytest.mark.asyncio(scope="session", more="stuff")
76+
async def test_anything():
77+
pass
78+
"""
79+
)
80+
)
81+
result = pytester.runpytest_subprocess()
82+
result.assert_outcomes(errors=1)
83+
result.stdout.fnmatch_lines(
84+
["*ValueError: mark.asyncio accepts only a keyword argument*"]
85+
)
86+
87+
88+
def test_error_when_an_invalid_scope_is_passed(
89+
pytester: pytest.Pytester,
90+
):
91+
pytester.makepyfile(
92+
dedent(
93+
"""\
94+
import pytest
95+
96+
@pytest.mark.asyncio(scope="stuff")
97+
async def test_anything():
98+
pass
99+
"""
100+
)
101+
)
102+
result = pytester.runpytest_subprocess()
103+
result.assert_outcomes(errors=1)
104+
result.stdout.fnmatch_lines(["*ValueError: Invalid scope 'stuff'*"])

0 commit comments

Comments
 (0)