[py-dev] Decorators and funcargs in py.test
Vyacheslav Rafalskiy
rafalskiy at gmail.com
Wed Jun 1 23:16:43 CEST 2011
>> #---------->> in test_1.py
>> @pytest.mark.timeout(10)
>> def test_f1():
>> # test here
>>
>> #---------->> in conftest.py
>> def pytest_runtest_call(item):
>> if hasattr(item.obj, 'timeout'):
>> timeout = item.obj.timeout.args[0]
>> item.obj = run_with_timeout(timeout)(item.obj)
>>
>> Your comments are welcome.
>
> it's basically ok but there are some bits that could
> be improved. You are actually implementing the general
> test item call. Also I am not sure why you assign
> "item.obj = ...".
I replace (or so I think) the original test function by the decorated
one. It gets called elsewhere.
>
> I'd probably write something like this:
>
> @pytest.mark.tryfirst
> def pytest_pyfunc_call(pyfuncitem, __multicall__):
> if 'timeout' in pyfuncitem.keywords:
> timeout = pyfuncitem.keywords['timeout'].args[0]
> run_with_timeout(timeout)(__multicall__.execute)
this will take a while to digest
> main differences:
>
> * only applies to python test function calls
> * hook invocation will be "tried first" before other
> pytest_pyfunc_call hook impls and it will call those
> other hooks through the "__multicall__" bit
> which actually represents the ongoing hook call
> * will call other hook implementations
>
> How do you actually implement run_with_timeout, btw?
def run_with_timeout(timeout=None):
def _decorator(f):
def _wrapper(*args, **kwargs):
def _f(*args, **kwargs):
try:
_result = f(*args, **kwargs)
except Exception as e:
thread._exception = e
else:
thread._result = _result
thread = threading.Thread(target=_f, args=args, kwargs=kwargs)
thread.daemon = True
thread._exception = None
thread.start()
thread.join(timeout=timeout)
if thread.isAlive():
raise RuntimeError('function *%s* exceeded configured
timeout of %ss' % (f.__name__, timeout))
if thread._exception is None:
return thread._result
else:
raise thread._exception
_wrapper.__name__ = f.__name__
return _wrapper
return _decorator
>
> best,
> holger
>
Vyacheslav
More information about the Pytest-dev
mailing list