Skip to content

Commit f724fab

Browse files
committed
fix: Fixed double wrapping of inherited Hypothesis tests.
Pytest-asyncio identifies Hypothesis test cases by their `is_hypothesis_test` flag. When setting up an async Hypothesis test pytest-asyncio replaces the function's `hypothesis.inner_test` attribute. The the top level function never changes. When a Hypothesis test case is defined in a base class and inherited by subclasses, the test is collected in each subclass. Since the top-level Hypothesis test never changes, its inner test will be wrapped multiple times. Double wrapping leads to execution errors caused by stale (closed) event loops in all test executions after the first. This change adds an `original_test_function` attribute to the async function wrapper, in order to keep track of the original Hypothesis test. When re-wrapping would occur in subclasses pytest-asyncio wraps the original test function rather than the wrapper function. Closes #231 Signed-off-by: Michael Seifert <[email protected]>
1 parent c1e11fb commit f724fab

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

README.rst

+1
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ Changelog
175175
~~~~~~~~~~~~~~~~~~~
176176
- `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>`_
177177
- Drop support for Python 3.6
178+
- Fixed an issue that prevented inherited asynchronous Hypothesis tests from working. `#231 <https://github.com/pytest-dev/pytest-asyncio/issues/231>`_
178179

179180
0.16.0 (2021-10-16)
180181
~~~~~~~~~~~~~~~~~~~

pytest_asyncio/plugin.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ def wrap_in_sync(func, _loop):
176176
# if the function is already wrapped, we rewrap using the original one
177177
# not using __wrapped__ because the original function may already be
178178
# a wrapped one
179-
if hasattr(func, '_raw_test_func'):
179+
if hasattr(func, "_raw_test_func"):
180180
func = func._raw_test_func
181181

182182
@functools.wraps(func)
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import hypothesis.strategies as st
2+
from hypothesis import given
3+
import pytest
4+
5+
6+
class BaseClass:
7+
@pytest.mark.asyncio
8+
@given(value=st.integers())
9+
async def test_hypothesis(self, value: int) -> None:
10+
assert True
11+
12+
13+
class TestOne(BaseClass):
14+
"""During the first execution the Hypothesis test is wrapped in a synchronous function."""
15+
16+
pass
17+
18+
19+
class TestTwo(BaseClass):
20+
"""Execute the test a second time to ensure that the test receives a fresh event loop."""
21+
22+
pass

0 commit comments

Comments
 (0)