Thanks Holger, It is clearer now.
Vyacheslav On Fri, Jun 3, 2011 at 1:38 PM, holger krekel <hol...@merlinux.eu> wrote: > 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