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