* remove redundant call_next_provider method, thus generalizing Request object

* refine according documentation

--HG--
branch : trunk
This commit is contained in:
holger krekel 2009-06-11 19:49:25 +02:00
parent 3f50470c6a
commit a59d602bce
6 changed files with 32 additions and 53 deletions

View File

@ -174,8 +174,10 @@ object that is to be closed when the test function finishes.
requesting values of other funcargs requesting values of other funcargs
--------------------------------------------- ---------------------------------------------
While setting up one function argument you may Inside a funcarg provider, you sometimes may want to use a
want to retrieve another function argument. different function argument which may be specified with
the test function or not. For such purposes you can
dynamically request a funcarg value:
.. sourcecode:: python .. sourcecode:: python
@ -184,26 +186,10 @@ want to retrieve another function argument.
Each function argument is only requested once per function setup. Each function argument is only requested once per function setup.
""" """
Note that it does not matter if the test function You can also use this function if you want to `decorate a funcarg`_
specifies the requested function argument. locally, i.e. you want to provide the normal value but add/do something
extra. If a provider cannot be found a ``request.Error`` exception will be
decorating other funcarg providers raised.
++++++++++++++++++++++++++++++++++++++++
If you want to **decorate a function argument** that is
provided elsewhere you can ask the request object
to provide the "next" value:
.. sourcecode:: python
def pytest_funcarg__myfile(self, request):
myfile = request.call_next_provider()
# do something extra
return myfile
This will raise a ``request.Error`` exception if there
is no next provider left. See the `decorator example`_
for a use of this method.
.. _`test generators`: .. _`test generators`:
@ -516,7 +502,7 @@ to your AcceptFuncarg and drive running of tools or
applications and provide ways to do assertions about applications and provide ways to do assertions about
the output. the output.
.. _`decorator example`: .. _`decorate a funcarg`:
example: decorating a funcarg in a test module example: decorating a funcarg in a test module
-------------------------------------------------------------- --------------------------------------------------------------
@ -528,7 +514,7 @@ extend the `accept example`_ by putting this in our test class:
.. sourcecode:: python .. sourcecode:: python
def pytest_funcarg__accept(self, request): def pytest_funcarg__accept(self, request):
arg = request.call_next_provider() arg = request.getfuncargvalue("accept") # call the next provider
# create a special layout in our tempdir # create a special layout in our tempdir
arg.tmpdir.mkdir("special") arg.tmpdir.mkdir("special")
return arg return arg

View File

@ -116,33 +116,21 @@ class FuncargRequest:
self.addfinalizer(lambda: teardown(val), scope=scope) self.addfinalizer(lambda: teardown(val), scope=scope)
return val return val
def call_next_provider(self):
if not self._provider[self._argname]:
raise self.Error("no provider methods left for %r" % self._argname)
next_provider = self._provider[self._argname].pop()
return next_provider(request=self)
def getfuncargvalue(self, argname): def getfuncargvalue(self, argname):
try: try:
return self._funcargs[argname] return self._funcargs[argname]
except KeyError: except KeyError:
pass pass
assert argname not in self._provider if argname not in self._provider:
self._provider[argname] = self.config.pluginmanager.listattr( self._provider[argname] = self.config.pluginmanager.listattr(
plugins=self._plugins, plugins=self._plugins,
attrname=self._argprefix + str(argname) attrname=self._argprefix + str(argname)
) )
# during call_next_provider() we keep state about the current #else: we are called recursively
# argument on the request object - we may go for instantiating if not self._provider[argname]:
# request objects per each funcargname if neccessary
oldname = self._argname
self._argname = argname
try:
self._funcargs[argname] = res = self.call_next_provider()
except self.Error:
self._raiselookupfailed(argname) self._raiselookupfailed(argname)
if oldname: funcargprovider = self._provider[argname].pop()
self._argname = oldname self._funcargs[argname] = res = funcargprovider(request=self)
return res return res
def _getscopeitem(self, scope): def _getscopeitem(self, scope):

View File

@ -9,7 +9,7 @@ def pytest_collect_file(path, parent):
# decorate testdir to contain plugin under test # decorate testdir to contain plugin under test
def pytest_funcarg__testdir(request): def pytest_funcarg__testdir(request):
testdir = request.call_next_provider() testdir = request.getfuncargvalue("testdir")
#for obj in (request.cls, request.module): #for obj in (request.cls, request.module):
# if hasattr(obj, 'testplugin'): # if hasattr(obj, 'testplugin'):
# testdir.plugins.append(obj.testplugin) # testdir.plugins.append(obj.testplugin)

View File

@ -391,7 +391,7 @@ class TestApigenLinkRole:
class TestDoctest: class TestDoctest:
def pytest_funcarg__testdir(self, request): def pytest_funcarg__testdir(self, request):
testdir = request.call_next_provider() testdir = request.getfuncargvalue("testdir")
assert request.module.__name__ == __name__ assert request.module.__name__ == __name__
testdir.makepyfile(confrest="from py.__.misc.rest import Project") testdir.makepyfile(confrest="from py.__.misc.rest import Project")
for p in testdir.plugins: for p in testdir.plugins:

View File

@ -128,15 +128,20 @@ class TestRequest:
assert len(provider) == 1 assert len(provider) == 1
assert provider[0].__name__ == "pytest_funcarg__something" assert provider[0].__name__ == "pytest_funcarg__something"
def test_request_call_next_provider(self, testdir): def test_getfuncargvalue_recursive(self, testdir):
testdir.makeconftest("""
def pytest_funcarg__something(request):
return 1
""")
item = testdir.getitem(""" item = testdir.getitem("""
def pytest_funcarg__something(request): return 1 def pytest_funcarg__something(request):
def test_func(something): pass return request.getfuncargvalue("something") + 1
def test_func(something):
assert something == 2
""") """)
req = funcargs.FuncargRequest(item) req = funcargs.FuncargRequest(item)
val = req.getfuncargvalue("something") val = req.getfuncargvalue("something")
assert val == 1 assert val == 2
py.test.raises(req.Error, "req.call_next_provider()")
def test_getfuncargvalue(self, testdir): def test_getfuncargvalue(self, testdir):
item = testdir.getitem(""" item = testdir.getitem("""

View File

@ -14,7 +14,7 @@ def setglobals(request):
def pytest_funcarg__testdir(request): def pytest_funcarg__testdir(request):
setglobals(request) setglobals(request)
return request.call_next_provider() return request.getfuncargvalue("testdir")
class ImmutablePickleTransport: class ImmutablePickleTransport:
def __init__(self, request): def __init__(self, request):