introduce a SetupCall, holding meta information and setup calling state

This commit is contained in:
holger krekel 2012-07-30 11:51:50 +02:00
parent d68c65b493
commit b57fb9fd47
3 changed files with 64 additions and 28 deletions

View File

@ -448,7 +448,7 @@ class FuncargManager:
def pytest_generate_tests(self, metafunc):
funcargnames = list(metafunc.funcargnames)
setuplist, allargnames = self.getsetuplist(metafunc.parentid)
_, allargnames = self.getsetuplist(metafunc.parentid)
#print "setuplist, allargnames", setuplist, allargnames
funcargnames.extend(allargnames)
seen = set()
@ -529,7 +529,9 @@ class FuncargManager:
# no funcargs. check if we have a setup function.
setup = getattr(obj, "setup", None)
if setup is not None and isinstance(setup, MarkInfo):
self.setuplist.append((nodeid, obj))
scope = setup.kwargs.get("scope")
sf = SetupCall(self, nodeid, obj, scope)
self.setuplist.append(sf)
continue
faclist = self.arg2facspec.setdefault(argname, [])
faclist.append((nodeid, obj))
@ -537,12 +539,10 @@ class FuncargManager:
def getsetuplist(self, nodeid):
l = []
allargnames = set()
for baseid, setup in self.setuplist:
#print "check", baseid, setup
if nodeid.startswith(baseid):
funcargnames = getfuncargnames(setup)
l.append((setup, funcargnames))
allargnames.update(funcargnames)
for setupcall in self.setuplist:
if nodeid.startswith(setupcall.baseid):
l.append(setupcall)
allargnames.update(setupcall.funcargnames)
return l, allargnames
@ -575,6 +575,33 @@ class FuncargManager:
raise FuncargLookupError(function, msg)
class SetupCall:
""" a container/helper for managing calls to setup functions. """
def __init__(self, funcargmanager, baseid, func, scope):
self.funcargmanager = funcargmanager
self.baseid = baseid
self.func = func
self.funcargnames = getfuncargnames(func)
self.scope = scope
self.active = False
self._finalizer = []
def execute(self, kwargs):
#assert not self.active
self.active = True
mp = monkeypatch()
#if "request" in kwargs:
# request = kwargs["request"]
# def addfinalizer(func):
# #scopeitem = request._getscopeitem(scope)
# self._finalizer.append(func)
# mp.setattr(request, "addfinalizer", addfinalizer)
try:
self.func(**kwargs)
finally:
mp.undo()
class NoMatch(Exception):
""" raised if matching cannot locate a matching names. """
@ -853,3 +880,8 @@ def getfuncargnames(function, startindex=None):
if numdefaults:
return argnames[startindex:-numdefaults]
return argnames[startindex:]
def readscope(func, markattr):
marker = getattr(func, markattr, None)
if marker is not None:
return marker.kwargs.get("scope")

View File

@ -3,7 +3,7 @@ import py
import inspect
import sys
import pytest
from _pytest.main import getfslineno, getfuncargnames
from _pytest.main import getfslineno, getfuncargnames, readscope
from _pytest.monkeypatch import monkeypatch
import _pytest
@ -1003,21 +1003,21 @@ class FuncargRequest:
setuplist, allnames = self.funcargmanager.getsetuplist(
self._pyfuncitem.nodeid)
mp = monkeypatch()
for setupfunc, funcargnames in setuplist:
for setupcall in setuplist:
kwargs = {}
for name in funcargnames:
for name in setupcall.funcargnames:
if name == "request":
kwargs[name] = self
else:
kwargs[name] = self.getfuncargvalue(name)
scope = readscope(setupfunc, "setup")
mp.setattr(self, 'scope', scope)
mp.setattr(self, 'scope', setupcall.scope)
try:
if scope is None:
setupfunc(**kwargs)
if setupcall.scope is None:
setupcall.execute(kwargs)
else:
self.cached_setup(lambda: setupfunc(**kwargs), scope=scope)
self.cached_setup(lambda: setupcall.execute(kwargs),
scope=setupcall.scope)
finally:
mp.undo()
@ -1140,7 +1140,3 @@ def slice_kwargs(names, kwargs):
new_kwargs[name] = kwargs[name]
return new_kwargs
def readscope(func, markattr):
marker = getattr(func, markattr, None)
if marker is not None:
return marker.kwargs.get("scope")

View File

@ -1752,10 +1752,14 @@ class TestSetupDiscovery:
testdir.makeconftest("""
import pytest
@pytest.mark.setup
def perfunction(request):
def perfunction(request, tmpdir):
pass
@pytest.mark.funcarg
def arg1(request, tmpdir):
pass
@pytest.mark.setup
def perfunction2(request):
def perfunction2(request, arg1):
pass
def pytest_funcarg__fm(request):
@ -1769,12 +1773,16 @@ class TestSetupDiscovery:
def test_parsefactories_conftest(self, testdir):
testdir.makepyfile("""
def test_check_setup(item, fm):
setuplist, allnames = fm.getsetuplist(item.nodeid)
assert len(setuplist) == 2
assert setuplist[0][0].__name__ == "perfunction"
assert "request" in setuplist[0][1]
assert setuplist[1][0].__name__ == "perfunction2"
assert "request" in setuplist[1][1]
setupcalls, allnames = fm.getsetuplist(item.nodeid)
assert len(setupcalls) == 2
assert setupcalls[0].func.__name__ == "perfunction"
assert "request" in setupcalls[0].funcargnames
assert "tmpdir" in setupcalls[0].funcargnames
assert setupcalls[1].func.__name__ == "perfunction2"
assert "request" in setupcalls[1].funcargnames
assert "arg1" in setupcalls[1].funcargnames
assert "tmpdir" not in setupcalls[1].funcargnames
#assert "tmpdir" in setupcalls[1].depfuncargs
""")
reprec = testdir.inline_run("-s")
reprec.assertoutcome(passed=1)