[py-dev] RFC: draft new resource management API (v1)

holger krekel holger at merlinux.eu
Wed Jun 27 20:41:47 CEST 2012


On Wed, Jun 27, 2012 at 18:32 +0200, Ronny Pfannschmidt wrote:
> i noticed that there is no way to name items in those lists

could you insert this comment in context?

If you refer to the resourcefactory(multi=True) example, then
the name is known at factory-list construction time.

A a sidenote, i now notice that it's unclear how this whole api
discussion relates to the recently introduced @parametrize decorator and
the pytest_generate_tests hook and metafunc.parametrize() call.

hum'ly yours,
holger



> On 06/27/2012 06:15 PM, holger krekel wrote:
> > On Wed, Jun 27, 2012 at 08:43 -0600, Carl Meyer wrote:
> >> I like it! In particular the parametrization support by passing a list
> >> is a quite intuitive extension of the API.
> >>
> >> "atnode" seems like an opaque arg name - what's wrong with "scope"? The
> >> latter name seems more intuitive to me. Would this arg have a default value?
> >
> > "scope" makes sense - it's just that in the current API scope is a
> > "class", "module", ... string.  Existing users might easily get a bit of
> > type clash - especially if you have a mixed funcarg/resource scenario.
> > Maybe "scopenode"?
> >
> > The default scopenode would be the one on which you are calling
> > "register_factory".  So in the first documented example call:
> >
> >      session.register_factory("db", createdb, scopenode=session)
> >
> > the "scopenode" call would actually be superfluous.  (Sidenote: the session
> > object is also a node - the root node from which all collection and item
> > nodes are descendants.  Each node has a ".session" reference back to this
> > root node).
> >
> >> In the long run, if funcarg-style is considered a useful shortcut and
> >> will not be deprecated, it would be nice if there were a bit more naming
> >> and API consistency between funcarg-style and new-style resource
> >> handling -- it would make them feel more aspects of one system rather
> >> than two different systems. I think this would really just require
> >> switching from pytest_funcarg__foo to pytest_resource__foo, renaming
> >> cached_setup to register_factory (and having it use the same API), and
> >> renaming getfuncargvalue to getresource. Of course I don't know whether
> >> this consistency is really worth the backwards-compatibility/deprecation
> >> hassles.
> >
> > * getresource/getfuncargvalue: makes sense to me to go for advertising and
> >    documenting getresource() instead of getfuncargvalue() and keeping
> >    the latter as an alias with or without deprecation.
> >
> > * addfinalizer would remain unmodified - it's just that the "request"
> >    object passed to funcarg-factories adds finalizers with test function
> >    invocation scope, whereas node.addfinalizer() does it for the respective
> >    node scope (so e.g. called from a Class node it would register a per-class
> >    finalizer)
> >
> > * cached_setup: i hope that we do not need to offer this method anymore
> >    other than for compatibility.  It's internal caching-key is not easy
> >    to explain and more than once users have stumbled about understanding it.
> >    cached_setup is required as long as pytest_funcarg__ factories are called
> >    _each_ time a resource is requested. (By contrast the new getresource()
> >    only triggers a factory call once for the registered scope - thus
> >    the factory implementation itself does not need to care for caching).
> >
> >    Note that register_factory is a different beast than cached_setup:
> >    it does not create a value, just registers a factory. So i don't see
> >    how we can unify this.
> >
> > As to a possible resource-factory auto-discovery, i can imagine it to
> > work with introducing a marker::
> >
> >      # example content in a test module or in a conftest.py file
> >
> >      @pytest.mark.resourcefactory("db", scope=pytest.Class)
> >      def myfactory(name, node):
> >          # factory called once per each requesting class (methods
> >          # on this class will share the returned value)
> >
> > this declaration would trigger a register_factory("db", myfactory) call.
> > If we want to extend this to parametrization (multiple db factories)
> > we probably need something like this::
> >
> >      @pytest.mark.resourcefactory("db", scope=pytest.Class, multi=True)
> >      def make_db_factories(name, node):
> >          factoryfuncs = [compute list of factory funcs]
> >          return factoryfuncs
> >
> > This would be called at collection time and the scope and the number
> > of to-be-created values would be known in advance.  It's basically
> > equivalent to a classnode.register_factory([list of factory funcs]) call.
> > (we could auto-magically recognize yield-generating functions but i'd
> > like to avoid it).
> >
> > To go the full circle, the signature of factory functions could rather
> > accept a "request" object instead of (name, node). Actually today, a
> > request object has this internal state anyway. pytest_funcarg__ would thus
> > only look slighly special in that it skips the marker and has a fixed scope
> > of "pytest.Function".
> >
> > Hope this thought train makes some sense :)
> > holger
> > _______________________________________________
> > py-dev mailing list
> > py-dev at codespeak.net
> > http://codespeak.net/mailman/listinfo/py-dev
> 
> _______________________________________________
> py-dev mailing list
> py-dev at codespeak.net
> http://codespeak.net/mailman/listinfo/py-dev
> 



More information about the Pytest-dev mailing list