[py-dev] Resource providers

holger krekel holger at merlinux.eu
Mon Jun 25 17:23:51 CEST 2012

On Mon, Jun 25, 2012 at 15:21 +0100, Floris Bruynooghe wrote:
> On 25 June 2012 14:29, holger krekel <holger at merlinux.eu> wrote:
> > On Mon, Jun 25, 2012 at 10:55 +0100, Floris Bruynooghe wrote:
> >> The concrete example I have now is that it could be nice in
> >> pytest-django to be able to request e.g. "Users" which is a model
> >> class used to access the User table in the database.  Currently this
> >> is only possible by someone explicitly defining pytest_funcarg__Users,
> >> but Django allows you to dynamically look up all the models in the
> >> database so there is no reason this can't be build automatically.
> >>
> >> I think this is what the API you proposed was for, but as I said I
> >> can't remember the details.  And in this case I might be less
> >> enthusiastic in postponing it's implementation to a later release ;-)
> >
> > It's probably true that we could invent an register-factory API for this.
> >
> > However, what about a single "models" object (done traditionally
> > with a pytest_funcarg__models definition) which itself provides
> > an API to give "Users" or others data?
> Yes of course, that is what I currently have in my conftest.py.  But
> it would still be a nice thing to be able to do and a nice example of
> functionality I have wished I had before.  Hence I was wondering if
> the API you talked about yesterday would support it.

I guess it could, for example, look like this::

    def pytest_configure(config):  # [1]
        def createmodel(name, node):
            """ return django model object. """
            # node can be None, Directory, Module, Class, Item, etc.
            # (code to compute model)
            return model

        for name in modelnames:
            config.register_factory(name, createmodel)

Getting a resource would work like this::

The "--funcargs" option would (remain) able to show the docstring
and location of the createmodel function.

Another interesting bit is how to use register_factory
to connect the existing "pytest_funcarg__..." factories
which have a certain scope.  I guess something like this::

    config.register_factory(name, factoryfunc, node)

would suffice - it would restrict the scope of the factory
function to the specified node and all of its descendents.
It could be called from Directory, Module, Class's setup methods
to register the respective "pytest_funcarg__" functions scoped as
per-directory (conftest.py), per-module or per-class factories.

Note that the "node" passed to the createmodel factory function
above is probably neccessary for this case because existing
funcarg-factories operate on Items (or in the future Nodes).

getfuncargvalue() would then be implemented in terms of a
call to config.getresource(name, node).

In general, register_factory needs to be callable multiple
times with the same name.  accept multiple factories for
the same resource will One little issues is that we want to 

This new resource registration/lookup could work much
more efficiently than the current scheme which - upon every getfuncargvalue() -
iterates over all plugins, modules and classes to discover matching 
pytest_funcarg__ factories.

hope this all makes some sense.


[1] We really need a new hook like pytest_runtest_init() which
    is called once before the runtest loop actually starts it work.
    pytest_configure() usually works but it is also called on the
    xdist-master process for which setting up resources makes no sense.

> Floris
> -- 
> Debian GNU/Linux -- The Power of Freedom
> www.debian.org | www.gnu.org | www.kernel.org

More information about the Pytest-dev mailing list