diff --git a/py/test/pycollect.py b/py/test/pycollect.py index 0d50ae04e..5c45e5e71 100644 --- a/py/test/pycollect.py +++ b/py/test/pycollect.py @@ -415,15 +415,30 @@ class Function(FunctionMixin, py.test.collect.Item): class FuncargRequest: + class Error(LookupError): + """ error on performing funcarg request. """ + def __init__(self, pyfuncitem, argname): self.pyfuncitem = pyfuncitem self.argname = argname - funcargname = "pytest_funcarg__" + str(argname) - pm = self.pyfuncitem.config.pluginmanager + self.function = pyfuncitem.obj + self.config = pyfuncitem.config extra = [] current = pyfuncitem while not isinstance(current, Module): current = current.parent if isinstance(current, (Instance, Module)): extra.insert(0, current.obj) - self._methods = pm.listattr(funcargname, extra=extra) + self._methods = self.pyfuncitem.config.pluginmanager.listattr( + "pytest_funcarg__" + str(argname), + extra=extra, + ) + + def call_next_provider(self): + if not self._methods: + raise self.Error("no provider methods left") + nextmethod = self._methods.pop() + return nextmethod(request=self) + + def addfinalizer(self, finalizer): + self.pyfuncitem.addfinalizer(finalizer) diff --git a/py/test/testing/test_funcargs.py b/py/test/testing/test_funcargs.py index 582520f4f..56ba76b22 100644 --- a/py/test/testing/test_funcargs.py +++ b/py/test/testing/test_funcargs.py @@ -84,6 +84,16 @@ class TestFuncargs: assert not modcol.config.pluginmanager.isregistered(modcol.obj) class TestRequest: + def test_request_attributes(self, testdir): + item = testdir.getitem(""" + def pytest_funcarg__something(request): pass + def test_func(something): pass + """) + req = item.getrequest("other") + assert req.argname == "other" + assert req.function == item.obj + assert req.config == item.config + def test_request_contains_funcargs_methods(self, testdir): modcol = testdir.getmodulecol(""" def pytest_funcarg__something(request): @@ -101,3 +111,23 @@ class TestRequest: method1, method2 = methods assert not hasattr(method1, 'im_self') assert method2.im_self is not None + + def test_request_call_next_provider(self, testdir): + item = testdir.getitem(""" + def pytest_funcarg__something(request): pass + def test_func(something): pass + """) + req = item.getrequest("something") + val = req.call_next_provider() + assert val is None + py.test.raises(req.Error, "req.call_next_provider()") + + def test_request_addfinalizer(self, testdir): + item = testdir.getitem(""" + def pytest_funcarg__something(request): pass + def test_func(something): pass + """) + req = item.getrequest("something") + l = [1] + req.addfinalizer(l.pop) + item.teardown()