[py-dev] Decorators and funcargs in py.test

holger krekel holger at merlinux.eu
Wed Jun 1 22:40:01 CEST 2011


On Wed, Jun 01, 2011 at 12:31 -0400, Vyacheslav Rafalskiy wrote:
> Gentlemen!
> 
> Thanks for your input. I really appreciate it.
> 
> @Ronny
> 1. I do agree that creating a new data convention is a big deal.
> What I tried to suggest is using something that already exists in
> _pytest.core.varnames(). A comment in _pytest.python.getfuncargnames()
> indicates that the two functions may merge. If they do, and towards
> the former, my original suggestion will *just work*.
> 
> 2. Using decorators is a great deal for me. They are powerful and
> expressive. I understand however the reluctance to open a can of worms
> here. The replacement using pytest.mark below seems acceptable to me.
> It still uses the same decorator function, just at a different place.
> 
> @Holger, Ronny
> Here is what I came up with:
> 
> #---------->>  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'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)

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?

best,
holger



More information about the Pytest-dev mailing list