Skip to content

Commit f2cacf6

Browse files
committed
Add async_callbacks() for use with async/await
1 parent 4f5f656 commit f2cacf6

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

pytest_twisted.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ class _instances:
2323

2424

2525
def pytest_namespace():
26-
return {"inlineCallbacks": inlineCallbacks, "blockon": blockon}
26+
return {
27+
"inlineCallbacks": inlineCallbacks,
28+
"async_callbacks": async_callbacks,
29+
"blockon": blockon,
30+
}
2731

2832

2933
def blockon(d):
@@ -65,6 +69,11 @@ def inlineCallbacks(fun, *args, **kw):
6569
return defer.inlineCallbacks(fun)(*args, **kw)
6670

6771

72+
@decorator.decorator
73+
def async_callbacks(fun, *args, **kw):
74+
return defer.ensureDeferred(fun(*args, **kw))
75+
76+
6877
def init_twisted_greenlet():
6978
if _instances.reactor is None or _instances.gr_twisted:
7079
return

testing/test_basic.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ def skip_if_reactor_not(expected_reactor):
3737
)
3838

3939

40+
def skip_if_no_async_await():
41+
return pytest.mark.skipif(
42+
sys.version_info < (3, 5),
43+
reason="async/await syntax not support on Python <3.5",
44+
)
45+
46+
4047
@pytest.fixture
4148
def cmd_opts(request):
4249
reactor = request.config.getoption("reactor", "default")
@@ -120,6 +127,28 @@ def test_succeed(foo):
120127
assert_outcomes(rr, {"passed": 2, "failed": 1})
121128

122129

130+
@skip_if_no_async_await()
131+
def test_async_callbacks(testdir, cmd_opts):
132+
test_file = """
133+
from twisted.internet import reactor, defer
134+
import pytest
135+
import pytest_twisted
136+
137+
@pytest.fixture(scope="module", params=["fs", "imap", "web"])
138+
def foo(request):
139+
return request.param
140+
141+
@pytest_twisted.async_callbacks
142+
async def test_succeed(foo):
143+
await defer.succeed(foo)
144+
if foo == "web":
145+
raise RuntimeError("baz")
146+
"""
147+
testdir.makepyfile(test_file)
148+
rr = testdir.run(sys.executable, "-m", "pytest", "-v", *cmd_opts)
149+
assert_outcomes(rr, {"passed": 2, "failed": 1})
150+
151+
123152
def test_twisted_greenlet(testdir, cmd_opts):
124153
test_file = """
125154
import pytest, greenlet
@@ -165,6 +194,32 @@ def test_succeed(foo):
165194
assert_outcomes(rr, {"passed": 2, "failed": 1})
166195

167196

197+
@skip_if_no_async_await()
198+
def test_blockon_in_fixture_async(testdir, cmd_opts):
199+
test_file = """
200+
from twisted.internet import reactor, defer
201+
import pytest
202+
import pytest_twisted
203+
204+
@pytest.fixture(scope="module", params=["fs", "imap", "web"])
205+
def foo(request):
206+
d1, d2 = defer.Deferred(), defer.Deferred()
207+
reactor.callLater(0.01, d1.callback, 1)
208+
reactor.callLater(0.02, d2.callback, request.param)
209+
pytest_twisted.blockon(d1)
210+
return d2
211+
212+
@pytest_twisted.async_callbacks
213+
async def test_succeed(foo):
214+
x = await foo
215+
if x == "web":
216+
raise RuntimeError("baz")
217+
"""
218+
testdir.makepyfile(test_file)
219+
rr = testdir.run(sys.executable, "-m", "pytest", "-v", *cmd_opts)
220+
assert_outcomes(rr, {"passed": 2, "failed": 1})
221+
222+
168223
@skip_if_reactor_not("default")
169224
def test_blockon_in_hook(testdir, cmd_opts):
170225
conftest_file = """

0 commit comments

Comments
 (0)