remove _fixturestack attribute now that we have a proper request->subrequest->subrequest chain.

This commit is contained in:
holger krekel 2013-11-21 13:15:32 +01:00
parent 238b890d9b
commit 2e90aaf7af
1 changed files with 31 additions and 24 deletions

View File

@ -10,6 +10,7 @@ import _pytest
cutdir = py.path.local(_pytest.__file__).dirpath()
NoneType = type(None)
NOTSET = object()
callable = py.builtin.callable
@ -943,18 +944,18 @@ class RaisesContext(object):
#
# the basic py.test Function item
#
_dummy = object()
class Function(FunctionMixin, pytest.Item, FuncargnamesCompatAttr):
""" a Function Item is responsible for setting up and executing a
Python test function.
"""
_genid = None
def __init__(self, name, parent, args=None, config=None,
callspec=None, callobj=_dummy, keywords=None, session=None):
callspec=None, callobj=NOTSET, keywords=None, session=None):
super(Function, self).__init__(name, parent, config=config,
session=session)
self._args = args
if callobj is not _dummy:
if callobj is not NOTSET:
self.obj = callobj
for name, val in (py.builtin._getfuncdict(self.obj) or {}).items():
@ -1088,7 +1089,6 @@ class FixtureRequest(FuncargnamesCompatAttr):
self._arg2index = {}
self.fixturenames = fixtureinfo.names_closure
self._fixturemanager = pyfuncitem.session._fixturemanager
self._fixturestack = []
@property
def node(self):
@ -1254,13 +1254,20 @@ class FixtureRequest(FuncargnamesCompatAttr):
if argname == "request":
return self
raise
self._fixturestack.append(fixturedef)
try:
result = self._getfuncargvalue(fixturedef)
self._funcargs[argname] = result
return result
finally:
self._fixturestack.pop()
result = self._getfuncargvalue(fixturedef)
self._funcargs[argname] = result
return result
def _get_fixturestack(self):
current = self
l = []
while 1:
fixturedef = getattr(current, "_fixturedef", None)
if fixturedef is None:
l.reverse()
return l
l.append(fixturedef)
current = current._parent_request
def _getfuncargvalue(self, fixturedef):
try:
@ -1275,7 +1282,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
try:
param = node.callspec.getparam(argname)
except (AttributeError, ValueError):
param = notset
param = NOTSET
else:
# if a parametrize invocation set a scope it will override
# the static scope defined with the fixture function
@ -1284,21 +1291,20 @@ class FixtureRequest(FuncargnamesCompatAttr):
paramscopenum != scopenum_subfunction:
scope = scopes[paramscopenum]
subrequest = SubRequest(self, scope, param, fixturedef)
# check if a higher-level scoped fixture accesses a lower level one
if scope is not None:
__tracebackhide__ = True
if scopemismatch(self.scope, scope):
# try to report something helpful
lines = self._factorytraceback()
lines = subrequest._factorytraceback()
raise ScopeMismatchError("You tried to access the %r scoped "
"fixture %r with a %r scoped request object, "
"involved factories\n%s" %(
(scope, argname, self.scope, "\n".join(lines))))
__tracebackhide__ = False
else:
scope = self.scope
subrequest = SubRequest(self, scope, param, fixturedef)
try:
# perform the fixture call
val = fixturedef.execute(request=subrequest)
@ -1317,7 +1323,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
def _factorytraceback(self):
lines = []
for fixturedef in self._fixturestack:
for fixturedef in self._get_fixturestack():
factory = fixturedef.func
fs, lineno = getfslineno(factory)
p = self._pyfuncitem.session.fspath.bestrelpath(fs)
@ -1344,16 +1350,17 @@ class FixtureRequest(FuncargnamesCompatAttr):
def __repr__(self):
return "<FixtureRequest for %r>" %(self.node)
notset = object()
class SubRequest(FixtureRequest):
""" a sub request for handling getting a fixture from a
test function/fixture. """
def __init__(self, request, scope, param, fixturedef):
self._parent_request = request
self.fixturename = fixturedef.argname
if param is not notset:
if param is not NOTSET:
self.param = param
self.scope = scope
self._fixturedef = fixturedef
self.addfinalizer = fixturedef.addfinalizer
self._pyfuncitem = request._pyfuncitem
self._funcargs = request._funcargs
@ -1361,10 +1368,10 @@ class SubRequest(FixtureRequest):
self._arg2index = request._arg2index
self.fixturenames = request.fixturenames
self._fixturemanager = request._fixturemanager
self._fixturestack = request._fixturestack
def __repr__(self):
return "<SubRequest %r for %r>" % (self.fixturename, self.node)
return "<SubRequest %r for %r>" % (self.fixturename, self._pyfuncitem)
class ScopeMismatchError(Exception):
""" A fixture function tries to use a different fixture function which
@ -1381,7 +1388,7 @@ class FixtureLookupError(LookupError):
def __init__(self, argname, request, msg=None):
self.argname = argname
self.request = request
self.fixturestack = list(request._fixturestack)
self.fixturestack = request._get_fixturestack()
self.msg = msg
def formatrepr(self):
@ -1619,8 +1626,8 @@ class FixtureManager:
for fin in reversed(l):
fin()
def parsefactories(self, node_or_obj, nodeid=_dummy, unittest=False):
if nodeid is not _dummy:
def parsefactories(self, node_or_obj, nodeid=NOTSET, unittest=False):
if nodeid is not NOTSET:
holderobj = node_or_obj
else:
holderobj = node_or_obj.obj