[py-dev] Decorators and funcargs in py.test
Vyacheslav Rafalskiy
rafalskiy at gmail.com
Fri Jun 3 18:06:06 CEST 2011
On Thu, Jun 2, 2011 at 12:46 AM, holger krekel <holger at merlinux.eu> wrote:
> On Wed, Jun 01, 2011 at 17:16 -0400, Vyacheslav Rafalskiy wrote:
>> >> #---------->> 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.
>
> ah, of course :)
>
>> > 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
>
> it's actually wrong if run_with_timeout is only decorating
> but not running the function. I think it makes sense to
> rather directly call a helper which calls the function
> (note that __multicall__.execute() will execute the remainder
> of the hook chain one of which will actually execute the
> function). Such a helper would look like
> call_with_timeout(timeout, func) i guess.
To call the function I need to know what arguments to give it to.
The following seems to work, but this is just a guess:
def pytest_runtest_call(item):
if hasattr(item.obj, 'timeout'):
timeout = item.obj.timeout.args[0]
run_with_timeout(timeout)(item.obj)(**item.funcargs)
I still don't quite get your example, specifically the
__multicall__.execute part.
Btw, the pytest_pyfunc_call() parameters seem to be in the wrong order
based on _pytest.python.py and the prototype in _pytest.hookspec.py
only lists one parameter.
Vyacheslav
More information about the Pytest-dev
mailing list