Skip to content

Commit 3ac4209

Browse files
committed
Require explicit async_fixture() or async_yield_fixture() decorator
1 parent 0eeb6c1 commit 3ac4209

File tree

2 files changed

+44
-21
lines changed

2 files changed

+44
-21
lines changed

pytest_twisted.py

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import functools
12
import inspect
23
import sys
34

@@ -96,18 +97,36 @@ def stop_twisted_greenlet():
9697
_instances.gr_twisted.switch()
9798

9899

99-
def is_coroutine(something):
100-
if ASYNC_AWAIT:
101-
return asyncio.iscoroutine(something)
100+
class _CoroutineWrapper:
101+
def __init__(self, coroutine, mark):
102+
self.coroutine = coroutine
103+
self.mark = mark
102104

103-
return False
104105

106+
def _marked_async_fixture(mark):
107+
def fixture(*args, **kwargs):
108+
def marker(f):
109+
@functools.wraps(f)
110+
def w(*args, **kwargs):
111+
return _CoroutineWrapper(
112+
coroutine=f(*args, **kwargs),
113+
mark=mark,
114+
)
115+
116+
return w
117+
118+
def decorator(f):
119+
result = pytest.fixture(*args, **kwargs)(marker(f))
120+
121+
return result
122+
123+
return decorator
124+
125+
return fixture
105126

106-
def is_async_generator(something):
107-
if ASYNC_GENERATORS:
108-
return inspect.isasyncgen(something)
109127

110-
return False
128+
async_fixture = _marked_async_fixture('async_fixture')
129+
async_yield_fixture = _marked_async_fixture('async_yield_fixture')
111130

112131

113132
@defer.inlineCallbacks
@@ -122,20 +141,23 @@ def _pytest_pyfunc_call(pyfuncitem):
122141
testargs = {}
123142
for arg in pyfuncitem._fixtureinfo.argnames:
124143
something = funcargs[arg]
125-
if is_coroutine(something):
126-
something = yield defer.ensureDeferred(something)
127-
elif is_async_generator(something):
128-
async_generators.append((arg, something))
129-
something = yield defer.ensureDeferred(
130-
something.__anext__(),
131-
)
144+
if isinstance(something, _CoroutineWrapper):
145+
if something.mark == 'async_fixture':
146+
something = yield defer.ensureDeferred(
147+
something.coroutine
148+
)
149+
elif something.mark == 'async_yield_fixture':
150+
async_generators.append((arg, something))
151+
something = yield defer.ensureDeferred(
152+
something.coroutine.__anext__(),
153+
)
132154
testargs[arg] = something
133155
else:
134156
testargs = funcargs
135157
result = yield testfunction(**testargs)
136158

137159
async_generator_deferreds = [
138-
(arg, defer.ensureDeferred(g.__anext__()))
160+
(arg, defer.ensureDeferred(g.coroutine.__anext__()))
139161
for arg, g in async_generators
140162
]
141163

testing/test_basic.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,8 @@ def test_async_fixture(testdir, cmd_opts):
188188
import pytest
189189
import pytest_twisted
190190
191-
@pytest.fixture(scope="function", params=["fs", "imap", "web"])
191+
@pytest_twisted.async_fixture(scope="function", params=["fs", "imap", "web"])
192+
@pytest.mark.redgreenblue
192193
async def foo(request):
193194
d1, d2 = defer.Deferred(), defer.Deferred()
194195
reactor.callLater(0.01, d1.callback, 1)
@@ -197,7 +198,7 @@ async def foo(request):
197198
return d2,
198199
199200
@pytest_twisted.inlineCallbacks
200-
def test_succeed(foo):
201+
def test_succeed_blue(foo):
201202
x = yield foo[0]
202203
if x == "web":
203204
raise RuntimeError("baz")
@@ -218,15 +219,15 @@ def test_async_fixture_concurrent_teardown(testdir, cmd_opts):
218219
here = defer.Deferred()
219220
there = defer.Deferred()
220221
221-
@pytest.fixture
222+
@pytest_twisted.async_yield_fixture()
222223
async def this():
223224
yield 42
224225
225226
there.callback(None)
226227
reactor.callLater(5, here.cancel)
227228
await here
228229
229-
@pytest.fixture
230+
@pytest_twisted.async_yield_fixture()
230231
async def that():
231232
yield 37
232233
@@ -251,7 +252,7 @@ def test_async_fixture_yield(testdir, cmd_opts):
251252
import pytest
252253
import pytest_twisted
253254
254-
@pytest.fixture(
255+
@pytest_twisted.async_yield_fixture(
255256
scope="function",
256257
params=["fs", "imap", "web", "gopher", "archie"],
257258
)

0 commit comments

Comments
 (0)