[py-dev] new resource API nearing completion including impl

holger krekel holger at merlinux.eu
Thu Aug 2 22:03:03 CEST 2012

On Thu, Aug 02, 2012 at 19:47 +0100, Floris Bruynooghe wrote:
> On 2 August 2012 18:24, holger krekel <holger at merlinux.eu> wrote:
> > On Thu, Aug 02, 2012 at 13:50 +0100, Floris Bruynooghe wrote:
> >> On 2 August 2012 11:44, holger krekel <holger at merlinux.eu> wrote:
> >> >     http://pytest.org/dev/setup.html
> >> >
> >> > Hope the latter begins to make more sense.
> >>
> >> Yes, it does.  I now see the power @setup.  One thing you might want
> >> to add is compare the module-global setting to simply using the
> >> "global" statement inside the setup function.
> >
> > Do you mean that in the case where the global-setting happens in the
> > conftest.py using "global" does not work?
> They both work, I meant:
> @pytest.setup(scope='module')
> def mysetup():
>     global myvariable
>     myvariable = 42
> vs:
> @pytest.setup(scope='module')
> def mysetup(testcontext):
>     testcontext.module.myvariable = 42
> Intuitively I would go for the first option and I think most python
> developers would as well since it is what they know.  I know the
> second option, which you demonstrate, is possible from inside a plugin
> or a conftest.py but I probably would consider this a bad practice
> since they are not logical places to inject globals.  Actually
> injecting globals seems weird to me, I used to do this when having
> plain old unittest but ever since funcargs I just type in the argument
> and find that much clearer.  So in short, while it is nice you can do
> this I don't think it is a great example as, IMHO, it encourages a bad
> practice.

I was guided by having seen questions which ask for things like this.
But it's not good as a primary example, i agree.

> Would a better example be checking for a mark on the function and
> doing some special setup based on that?  Maybe the special setup is
> requesting another funcarg/resource?  (But there doesn't seem to be an
> API on the testcontext to request a custom funcarg/resource.  Is this
> meant to be disallowed?)

setup based on markers is a good example, yes, not sure it's good as a first
basic example, though, because it introduces several examples at once.

And yes, testcontext does not provide getfuncargvalue()/cached_setup on
purpose.  It's breaks parametrization because factory-func bodies are
opaque so pytest cannot know that you are using a parametrized resource.
I basically aim to design the new API to be totally safe.  Other than
that, testcontext can grow functionality ...
> Which brings me onto the next topic, the testcontext object provides
> access to .function, which you can use to check marks etc.  But when
> you had merged items/requests we had access to the item and you where
> even talking about having item.applymarker() and a specific API for
> inspecting markers.  Would it not be nice to have these APIs on
> testcontext (if the sope is "function")?

... Yes ... Maybe a "testcontext.getmarker(name)" returning
None if it doesn't exist.  And a testcontext.applymarker() as with
the request object.  The latter is maybe a bit harder to implement
because testcontext has a scope whereas "request" was always function-scoped.
And e.g. a @setup(scope=module) function calling 
testcontext.applymarker(pytest.mark.xfail) would probably expect to
have it applied to all of its tests.  Of course, we could restrict
applymarker to "function" scope initially.
> >> Btw, is it a bug in the assertion that when using a global variable
> >> the assert-printing does not seem to show the value of that global
> >> variable?
> >
> > I noticed this as well and consider it a bug, yes.
> https://bitbucket.org/hpk42/pytest/issue/171/global-variables-are-not-explained-on

Oh, bitbucket has a new interface, nice (i think)!

> >> > I also uploaded a new package pytest-2.3.0.dev8 to be installed
> >> > via:
> >> >
> >> >     pip install -i http://pypi.testrun.org -U pytest
> >>
> >> I was playing with this over lunch and discovered this doesn't work:
> >>
> >> @pytest.factory(scope='session')
> >> def pytest_funcarg__foo():
> >>     return 42
> >>
> >> Would it not make sense to allow this (or at least provide a clearer
> >> error)?  I still like that form because of the grep-ability (doing a
> >> 2-line grep is much harder and would still not cover ppl doing "from
> >> pytest import factory" etc).
> >
> > Grepability is an argument.  Would adding a "name=..." parameter for
> > the factory-decorator help enough?  Allowing and advertising
> > pytest_funcarg__foo feels strange to somehow taking a fresh look i think.
> I would argue the opposite, allowing the @factory decroator on
> pytest_funcarg__* seems like a more gentle progression giving more the
> impression that it is simply funcargs evolved.  To a newcomer it might
> otherwise look like funcargs where not thought out fully yet and make
> them think py.test just isn't stable enough yet.

But when using the factory decorator on pytest_funcarg__ named functions,
they shall at least not be able to receive "request" anymore, right?
(The current implementation probably allows it but i feel uneasy about it).

> >> Also doing this results in setup_module being called twice:
> >>
> >> @pytest.setup(scope='module')
> >> def setup_module():
> >>     print 'setting up module'
> >>
> >> I'm not sure what the correct behaviour should be here.
> >
> > Hum, I think the decorator "consumes" the function and it should not
> > be considered for anything else. Do you agree?
> Yes, that's probably the best option.

Can you open an issue about it as well?
I don't think i get too much implementation time before going on vacation ...


More information about the Pytest-dev mailing list