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): def pytest_generate_tests(self, metafunc):
funcargnames = list(metafunc.funcargnames) funcargnames = list(metafunc.funcargnames)
setuplist, allargnames = self.getsetuplist(metafunc.parentid) _, allargnames = self.getsetuplist(metafunc.parentid)
#print "setuplist, allargnames", setuplist, allargnames #print "setuplist, allargnames", setuplist, allargnames
funcargnames.extend(allargnames) funcargnames.extend(allargnames)
seen = set() seen = set()
@ -529,7 +529,9 @@ class FuncargManager:
# no funcargs. check if we have a setup function. # no funcargs. check if we have a setup function.
setup = getattr(obj, "setup", None) setup = getattr(obj, "setup", None)
if setup is not None and isinstance(setup, MarkInfo): 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 continue
faclist = self.arg2facspec.setdefault(argname, []) faclist = self.arg2facspec.setdefault(argname, [])
faclist.append((nodeid, obj)) faclist.append((nodeid, obj))
@ -537,12 +539,10 @@ class FuncargManager:
def getsetuplist(self, nodeid): def getsetuplist(self, nodeid):
l = [] l = []
allargnames = set() allargnames = set()
for baseid, setup in self.setuplist: for setupcall in self.setuplist:
#print "check", baseid, setup if nodeid.startswith(setupcall.baseid):
if nodeid.startswith(baseid): l.append(setupcall)
funcargnames = getfuncargnames(setup) allargnames.update(setupcall.funcargnames)
l.append((setup, funcargnames))
allargnames.update(funcargnames)
return l, allargnames return l, allargnames
@ -575,6 +575,33 @@ class FuncargManager:
raise FuncargLookupError(function, msg) 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): class NoMatch(Exception):
""" raised if matching cannot locate a matching names. """ """ raised if matching cannot locate a matching names. """
@ -853,3 +880,8 @@ def getfuncargnames(function, startindex=None):
if numdefaults: if numdefaults:
return argnames[startindex:-numdefaults] return argnames[startindex:-numdefaults]
return argnames[startindex:] 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 inspect
import sys import sys
import pytest import pytest
from _pytest.main import getfslineno, getfuncargnames from _pytest.main import getfslineno, getfuncargnames, readscope
from _pytest.monkeypatch import monkeypatch from _pytest.monkeypatch import monkeypatch
import _pytest import _pytest
@ -1003,21 +1003,21 @@ class FuncargRequest:
setuplist, allnames = self.funcargmanager.getsetuplist( setuplist, allnames = self.funcargmanager.getsetuplist(
self._pyfuncitem.nodeid) self._pyfuncitem.nodeid)
mp = monkeypatch() mp = monkeypatch()
for setupfunc, funcargnames in setuplist: for setupcall in setuplist:
kwargs = {} kwargs = {}
for name in funcargnames: for name in setupcall.funcargnames:
if name == "request": if name == "request":
kwargs[name] = self kwargs[name] = self
else: else:
kwargs[name] = self.getfuncargvalue(name) kwargs[name] = self.getfuncargvalue(name)
scope = readscope(setupfunc, "setup") mp.setattr(self, 'scope', setupcall.scope)
mp.setattr(self, 'scope', scope)
try: try:
if scope is None: if setupcall.scope is None:
setupfunc(**kwargs) setupcall.execute(kwargs)
else: else:
self.cached_setup(lambda: setupfunc(**kwargs), scope=scope) self.cached_setup(lambda: setupcall.execute(kwargs),
scope=setupcall.scope)
finally: finally:
mp.undo() mp.undo()
@ -1140,7 +1140,3 @@ def slice_kwargs(names, kwargs):
new_kwargs[name] = kwargs[name] new_kwargs[name] = kwargs[name]
return new_kwargs 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(""" testdir.makeconftest("""
import pytest import pytest
@pytest.mark.setup @pytest.mark.setup
def perfunction(request): def perfunction(request, tmpdir):
pass
@pytest.mark.funcarg
def arg1(request, tmpdir):
pass pass
@pytest.mark.setup @pytest.mark.setup
def perfunction2(request): def perfunction2(request, arg1):
pass pass
def pytest_funcarg__fm(request): def pytest_funcarg__fm(request):
@ -1769,12 +1773,16 @@ class TestSetupDiscovery:
def test_parsefactories_conftest(self, testdir): def test_parsefactories_conftest(self, testdir):
testdir.makepyfile(""" testdir.makepyfile("""
def test_check_setup(item, fm): def test_check_setup(item, fm):
setuplist, allnames = fm.getsetuplist(item.nodeid) setupcalls, allnames = fm.getsetuplist(item.nodeid)
assert len(setuplist) == 2 assert len(setupcalls) == 2
assert setuplist[0][0].__name__ == "perfunction" assert setupcalls[0].func.__name__ == "perfunction"
assert "request" in setuplist[0][1] assert "request" in setupcalls[0].funcargnames
assert setuplist[1][0].__name__ == "perfunction2" assert "tmpdir" in setupcalls[0].funcargnames
assert "request" in setuplist[1][1] 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 = testdir.inline_run("-s")
reprec.assertoutcome(passed=1) reprec.assertoutcome(passed=1)