Skip to content

Commit b8a2a5c

Browse files
committed
@inlineCallbacks/@ensureDeferred mark, pytest_pyfunc_call processes
1 parent 7de9416 commit b8a2a5c

File tree

1 file changed

+43
-16
lines changed

1 file changed

+43
-16
lines changed

pytest_twisted.py

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -107,19 +107,29 @@ def block_from_thread(d):
107107
return blockingCallFromThread(_instances.reactor, lambda x: x, d)
108108

109109

110-
@decorator.decorator
111-
def inlineCallbacks(fun, *args, **kw):
112-
# TODO: it presumably doesn't matter but i really dislike how this
113-
# creates a new inlineCallbacks for each call. but, that's
114-
# a pretty irrelevant concern given that 1) it is just a function
115-
# call overhead and 2) lots of tests are only called once anyways.
116-
# but, this gets the feeling out of my head...
117-
return defer.inlineCallbacks(fun)(*args, **kw)
110+
def decorator_apply(dec, func):
111+
"""
112+
Decorate a function by preserving the signature even if dec
113+
is not a signature-preserving decorator.
118114
115+
https://github.com/micheles/decorator/blob/55a68b5ef1951614c5c37a6d201b1f3b804dbce6/docs/documentation.md#dealing-with-third-party-decorators
116+
"""
117+
return decorator.FunctionMaker.create(
118+
func, 'return decfunc(%(signature)s)',
119+
dict(decfunc=dec(func)), __wrapped__=func)
119120

120-
@decorator.decorator
121-
def ensureDeferred(fun, *args, **kw):
122-
return defer.ensureDeferred(fun(*args, **kw))
121+
122+
def inlineCallbacks(f):
123+
decorated = decorator_apply(defer.inlineCallbacks, f)
124+
_set_mark(o=decorated, mark='inline_callbacks_test')
125+
126+
return decorated
127+
128+
129+
def ensureDeferred(f):
130+
_set_mark(o=f, mark='async_test')
131+
132+
return f
123133

124134

125135
def init_twisted_greenlet():
@@ -140,6 +150,14 @@ def stop_twisted_greenlet():
140150
_instances.gr_twisted.switch()
141151

142152

153+
def _get_mark(o, default=None):
154+
return getattr(o, _mark_attribute_name, default)
155+
156+
157+
def _set_mark(o, mark):
158+
setattr(o, _mark_attribute_name, mark)
159+
160+
143161
def _marked_async_fixture(mark):
144162
@functools.wraps(pytest.fixture)
145163
def fixture(*args, **kwargs):
@@ -154,7 +172,7 @@ def fixture(*args, **kwargs):
154172
raise AsyncFixtureUnsupportedScopeError.from_scope(scope=scope)
155173

156174
def decorator(f):
157-
setattr(f, _mark_attribute_name, mark)
175+
_set_mark(f, mark)
158176
result = pytest.fixture(*args, **kwargs)(f)
159177

160178
return result
@@ -172,15 +190,15 @@ def decorator(f):
172190
def pytest_fixture_setup(fixturedef, request):
173191
"""Interface pytest to async setup for async and async yield fixtures."""
174192
# TODO: what about _adding_ inlineCallbacks fixture support?
175-
maybe_mark = getattr(fixturedef.func, _mark_attribute_name, None)
193+
maybe_mark = _get_mark(fixturedef.func)
176194
if maybe_mark is None:
177195
return None
178196

179197
mark = maybe_mark
180198

181199
run_inline_callbacks(_async_pytest_fixture_setup, fixturedef, request, mark)
182200

183-
return True
201+
return not None
184202

185203

186204
@defer.inlineCallbacks
@@ -284,7 +302,7 @@ def pytest_pyfunc_call(pyfuncitem):
284302
"""Interface to async test call handler."""
285303
# TODO: only handle 'our' tests? what is the point of handling others?
286304
run_inline_callbacks(_async_pytest_pyfunc_call, pyfuncitem)
287-
return True
305+
return not None
288306

289307

290308
@defer.inlineCallbacks
@@ -295,7 +313,16 @@ def _async_pytest_pyfunc_call(pyfuncitem):
295313
for name, value in pyfuncitem.funcargs.items()
296314
if name in pyfuncitem._fixtureinfo.argnames
297315
}
298-
result = yield pyfuncitem.obj(**kwargs)
316+
317+
maybe_mark = _get_mark(pyfuncitem.obj)
318+
if maybe_mark == 'async_test':
319+
result = yield defer.ensureDeferred(pyfuncitem.obj(**kwargs))
320+
elif maybe_mark == 'inline_callbacks_test':
321+
result = yield pyfuncitem.obj(**kwargs)
322+
else:
323+
# TODO: maybe deprecate this
324+
result = yield pyfuncitem.obj(**kwargs)
325+
299326
defer.returnValue(result)
300327

301328

0 commit comments

Comments
 (0)