On Fri, Jun 03, 2011 at 12:06 -0400, Vyacheslav Rafalskiy wrote: > On Thu, Jun 2, 2011 at 12:46 AM, holger krekel <hol...@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.
A few things that might help you to understand: * There can be multiple hook functions implementing the same hook. * MultiCall instances manage the calling into a list of hook implementation functions. * A hook impl function can use zero or any number of available arguments. i.e. if a hookspec is "pyest_myfunc(x,y,z)" then a hook impl function can just receive only one of them "pytest_myfunc(x)" This slicing is done from the MultiCall class. * the actual call to a hook impl function is always done by passing keyword arguments (i.e. **kwargs) and thus ordering of parameters is irrelevant. * a hook impl function can receive a "__multicall__" parameter which is its managing class and which it can use to call __multicall__.execute() to execute the rest of the hook implementations. * with all this in mind the few lines of code in _pytest.core.MultiCall hopefully make more sense :) best, holger > 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 > _______________________________________________ py-dev mailing list py-dev@codespeak.net http://codespeak.net/mailman/listinfo/py-dev