Skip to content

Commit bd8f210

Browse files
committed
fix: Fixes a bug that prevents async Hypothesis tests from working without explicit "asyncio" marker when "--asyncio-mode=auto" is set.
The option --asyncio-mode=auto marks all async functions with the asyncio mark during the collection phase. However, when pytest collects the Hypothesis test, the @given decorator has already been applied and the Hypothesis test function is no longer a coroutine. This commit extends the "pytest_pycollect_makeitem" hook to mark Hypothesis tests whose function body is a coroutine. Closes #258 Signed-off-by: Michael Seifert <[email protected]>
1 parent 694ebe2 commit bd8f210

File tree

3 files changed

+32
-1
lines changed

3 files changed

+32
-1
lines changed

README.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,10 @@ or an async framework such as `asynctest <https://asynctest.readthedocs.io/en/la
256256

257257
Changelog
258258
---------
259+
0.17.1 (UNRELEASED)
260+
~~~~~~~~~~~~~~~~~~~
261+
- Fixes a bug that prevents async Hypothesis tests from working without explicit ``asyncio`` marker when ``--asyncio-mode=auto`` is set. `#258 <https://github.com/pytest-dev/pytest-asyncio/issues/258>`_
262+
259263
0.17.0 (22-01-13)
260264
~~~~~~~~~~~~~~~~~~~
261265
- `pytest-asyncio` no longer alters existing event loop policies. `#168 <https://github.com/pytest-dev/pytest-asyncio/issues/168>`_, `#188 <https://github.com/pytest-dev/pytest-asyncio/issues/168>`_

pytest_asyncio/plugin.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,13 @@ def pytest_configure(config):
115115
@pytest.mark.tryfirst
116116
def pytest_pycollect_makeitem(collector, name, obj):
117117
"""A pytest hook to collect asyncio coroutines."""
118-
if collector.funcnamefilter(name) and _is_coroutine(obj):
118+
if not collector.funcnamefilter(name):
119+
return
120+
if (
121+
_is_coroutine(obj)
122+
or _is_hypothesis_test(obj)
123+
and _hypothesis_test_wraps_coroutine(obj)
124+
):
119125
item = pytest.Function.from_parent(collector, name=name)
120126
if "asyncio" in item.keywords:
121127
return list(collector._genfunctions(name, obj))
@@ -128,6 +134,10 @@ def pytest_pycollect_makeitem(collector, name, obj):
128134
return ret
129135

130136

137+
def _hypothesis_test_wraps_coroutine(function):
138+
return _is_coroutine(function.hypothesis.inner_test)
139+
140+
131141
class FixtureStripper:
132142
"""Include additional Fixture, and then strip them"""
133143

tests/hypothesis/test_base.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import pytest
77
from hypothesis import given, strategies as st
88

9+
from pytest_asyncio.plugin import Mode
10+
911

1012
@pytest.fixture(scope="module")
1113
def event_loop():
@@ -26,6 +28,21 @@ async def test_mark_outer(n):
2628
assert isinstance(n, int)
2729

2830

31+
@given(n=st.integers())
32+
async def test_async_auto_marked(pytestconfig, n: int):
33+
assert pytestconfig.inicfg["asyncio_mode"] == Mode.AUTO
34+
assert isinstance(n, int)
35+
36+
37+
@given(n=st.integers())
38+
def test_sync_not_auto_marked(pytestconfig, request, n: int):
39+
"""Assert that synchronous Hypothesis functions are not marked with asyncio"""
40+
assert pytestconfig.inicfg["asyncio_mode"] == Mode.AUTO
41+
markers = [marker.name for marker in request.node.own_markers]
42+
assert "asyncio" not in markers
43+
assert isinstance(n, int)
44+
45+
2946
@pytest.mark.parametrize("y", [1, 2])
3047
@given(x=st.none())
3148
@pytest.mark.asyncio

0 commit comments

Comments
 (0)