rename a number of internal and externally visible variables to use the fixture name

rather than funcargs.  Introduce .funcargnames compatibility attribute for backward compat.
This commit is contained in:
holger krekel
2012-10-05 14:24:44 +02:00
parent 8282efbb40
commit bb07ba7807
33 changed files with 281 additions and 261 deletions

View File

@@ -44,18 +44,7 @@ defaultfuncargprefixmarker = fixture()
# XXX remove in favour of fixture(autoactive=True)
def setup(scope="function"):
""" return a decorator to mark a function as providing a fixture for
a testcontext. A fixture function is executed for each scope and may
receive funcargs which allows it to initialise and provide implicit
test state. A fixture function may receive the "testcontext" object
and register a finalizer via "testcontext.addfinalizer(finalizer)"
which will be called when the last test in the testcontext has
executed.
:arg scope: the scope for which the setup function will be active, one
of "function", "class", "module", "session".
Defaults to "function".
"""
""" alias for fixture(scope, autoactive=True) """
return FixtureFunctionMarker(scope, params=None, autoactive=True)
def cached_property(f):
@@ -85,9 +74,9 @@ def pyobj_property(name):
def pytest_addoption(parser):
group = parser.getgroup("general")
group.addoption('--funcargs',
action="store_true", dest="showfuncargs", default=False,
help="show available function arguments, sorted by plugin")
group.addoption('--fixtures', '--fixtures',
action="store_true", dest="showfixtures", default=False,
help="show available fixtures, sorted by plugin appearance")
parser.addini("python_files", type="args",
default=('test_*.py', '*_test.py'),
help="glob-style file patterns for Python test module discovery")
@@ -97,8 +86,8 @@ def pytest_addoption(parser):
help="prefixes for Python test function and method discovery")
def pytest_cmdline_main(config):
if config.option.showfuncargs:
showfuncargs(config)
if config.option.showfixtures:
showfixtures(config)
return 0
@@ -119,7 +108,7 @@ def pytest_configure(config):
)
def pytest_sessionstart(session):
session.funcargmanager = FuncargManager(session)
session._fixturemanager = FixtureManager(session)
@pytest.mark.trylast
def pytest_namespace():
@@ -131,10 +120,11 @@ def pytest_namespace():
'collect': {
'Module': Module, 'Class': Class, 'Instance': Instance,
'Function': Function, 'Generator': Generator,
'_fillfuncargs': fillfuncargs}
'_fillfuncargs': fillfixtures}
}
def pytest_funcarg__pytestconfig(request):
@fixture()
def pytestconfig(request):
""" the pytest config object with access to command line opts."""
return request.config
@@ -146,12 +136,12 @@ def pytest_pyfunc_call(__multicall__, pyfuncitem):
testfunction(*pyfuncitem._args)
else:
try:
funcargnames = pyfuncitem.funcargnames
fixturenames = pyfuncitem.fixturenames
except AttributeError:
funcargs = pyfuncitem.funcargs
else:
funcargs = {}
for name in funcargnames:
for name in fixturenames:
funcargs[name] = pyfuncitem.funcargs[name]
testfunction(**funcargs)
@@ -352,7 +342,7 @@ class Module(pytest.File, PyCollector):
return self._memoizedcall('_obj', self._importtestmodule)
def collect(self):
self.session.funcargmanager._parsefactories(self.obj, self.nodeid)
self.session._fixturemanager._parsefactories(self.obj, self.nodeid)
return super(Module, self).collect()
def _importtestmodule(self):
@@ -425,7 +415,7 @@ class Instance(PyCollector):
return obj
def collect(self):
self.session.funcargmanager._parsefactories(self.obj, self.nodeid)
self.session._fixturemanager._parsefactories(self.obj, self.nodeid)
return super(Instance, self).collect()
def newinstance(self):
@@ -534,14 +524,14 @@ def hasinit(obj):
def fillfuncargs(function):
def fillfixtures(function):
""" fill missing funcargs for a test function. """
if getattr(function, "_args", None) is None: # not a yielded function
try:
request = function._request
except AttributeError:
request = function._request = FuncargRequest(function)
request._fillfuncargs()
request = function._request = FixtureRequest(function)
request._fillfixtures()
_notexists = object()
@@ -605,21 +595,30 @@ class CallSpec2(object):
self._globalparam = param
class Metafunc:
class FuncargnamesCompatAttr:
""" helper class so that Metafunc, Function and FixtureRequest
don't need to each define the "funcargnames" compatibility attribute.
"""
@property
def funcargnames(self):
""" alias attribute for ``fixturenames`` for pre-2.3 compatibility"""
return self.fixturenames
class Metafunc(FuncargnamesCompatAttr):
def __init__(self, function, config=None, cls=None, module=None,
parentnode=None):
self.config = config
self.module = module
self.function = function
self.parentnode = parentnode
self.parentid = getattr(parentnode, "nodeid", "")
self._parentid = getattr(parentnode, "nodeid", "")
argnames = getfuncargnames(function, startindex=int(cls is not None))
if parentnode is not None:
fm = parentnode.session.funcargmanager
self.funcargnames, self._arg2facdeflist = fm.getallfuncargnames(
fm = parentnode.session._fixturemanager
self.fixturenames, self._arg2fixturedeflist = fm.getfixtureclosure(
argnames, parentnode)
else:
self.funcargnames = argnames
self.fixturenames = argnames
self.cls = cls
self.module = module
self._calls = []
@@ -631,7 +630,7 @@ class Metafunc:
""" Add new invocations to the underlying test function using the list
of argvalues for the given argnames. Parametrization is performed
during the collection phase. If you need to setup expensive resources
you may pass indirect=True and implement a funcarg factory which can
you may pass indirect=True and implement a fixture function which can
perform the expensive setup just before a test is actually run.
:arg argnames: an argument name or a list of argument names
@@ -640,7 +639,7 @@ class Metafunc:
values for the list of argument names.
:arg indirect: if True each argvalue corresponding to an argument will
be passed as request.param to its respective funcarg factory so
be passed as request.param to its respective fixture function so
that it can perform more expensive setups during the setup phase of
a test rather than at collection time.
@@ -657,7 +656,7 @@ class Metafunc:
if not indirect:
#XXX should we also check for the opposite case?
for arg in argnames:
if arg not in self.funcargnames:
if arg not in self.fixturenames:
raise ValueError("%r has no argument %r" %(self.function, arg))
valtype = indirect and "params" or "funcargs"
if not ids:
@@ -686,13 +685,13 @@ class Metafunc:
:arg id: used for reporting and identification purposes. If you
don't supply an `id` an automatic unique id will be generated.
:arg param: a parameter which will be exposed to a later funcarg factory
:arg param: a parameter which will be exposed to a later fixture function
invocation through the ``request.param`` attribute.
"""
assert funcargs is None or isinstance(funcargs, dict)
if funcargs is not None:
for name in funcargs:
if name not in self.funcargnames:
if name not in self.fixturenames:
pytest.fail("funcarg %r not used in this function." % name)
else:
funcargs = {}
@@ -722,11 +721,11 @@ class IDMaker:
return "-".join(l)
def showfuncargs(config):
def showfixtures(config):
from _pytest.main import wrap_session
return wrap_session(config, _showfuncargs_main)
return wrap_session(config, _showfixtures_main)
def _showfuncargs_main(config, session):
def _showfixtures_main(config, session):
session.perform_collect()
if session.items:
plugins = session.items[0].getplugins()
@@ -735,7 +734,7 @@ def _showfuncargs_main(config, session):
curdir = py.path.local()
tw = py.io.TerminalWriter()
verbose = config.getvalue("verbose")
argprefix = session.funcargmanager._argprefix
argprefix = session._fixturemanager._argprefix
for plugin in plugins:
available = []
for name, factory in vars(plugin).items():
@@ -854,7 +853,7 @@ class RaisesContext(object):
# the basic py.test Function item
#
_dummy = object()
class Function(FunctionMixin, pytest.Item):
class Function(FunctionMixin, pytest.Item, FuncargnamesCompatAttr):
""" a Function Item is responsible for setting up and executing a
Python test function.
"""
@@ -876,11 +875,11 @@ class Function(FunctionMixin, pytest.Item):
self.param = callspec.param
else:
self.funcargs = {}
self._request = req = FuncargRequest(self)
self._request = req = FixtureRequest(self)
#req._discoverfactories()
if callobj is not _dummy:
self.obj = callobj
self.funcargnames = self._getfixturenames()
self.fixturenames = self._getfuncargnames()
for name, val in (py.builtin._getfuncdict(self.obj) or {}).items():
setattr(self.markers, name, val)
@@ -888,9 +887,10 @@ class Function(FunctionMixin, pytest.Item):
for name, val in keywords.items():
setattr(self.markers, name, val)
def _getfixturenames(self):
def _getfuncargnames(self):
startindex = int(self.cls is not None)
return (self.session.funcargmanager._autofixtures +
return (self.session._fixturemanager._autofixtures +
getfuncargnames(self.obj, startindex=startindex))
@property
@@ -921,7 +921,7 @@ class Function(FunctionMixin, pytest.Item):
super(Function, self).setup()
#if hasattr(self, "_request"):
# self._request._callsetup()
fillfuncargs(self)
fillfixtures(self)
def __eq__(self, other):
try:
@@ -960,8 +960,8 @@ def scopeproperty(name=None, doc=None):
return decoratescope
class FuncargRequest:
""" A request for function arguments from a test or setup function.
class FixtureRequest(FuncargnamesCompatAttr):
""" A request for fixtures from a test or setup function.
A request object gives access to attributes of the requesting
test context. It has an optional ``param`` attribute in case
@@ -976,38 +976,38 @@ class FuncargRequest:
self.scope = "function"
self.getparent = pyfuncitem.getparent
self._funcargs = self._pyfuncitem.funcargs.copy()
self._name2factory = {}
self.funcargmanager = pyfuncitem.session.funcargmanager
self._arg2fixturedeflist = {}
self._fixturemanager = pyfuncitem.session._fixturemanager
self._currentarg = None
self.parentid = pyfuncitem.parent.nodeid
self.funcargnames, self._arg2facdeflist_ = \
self.funcargmanager.getallfuncargnames(
self._parentid = pyfuncitem.parent.nodeid
self.fixturenames, self._arg2fixturedeflist_ = \
self._fixturemanager.getfixtureclosure(
getfuncargnames(self.function), # XXX _pyfuncitem...
pyfuncitem.parent)
self._factorystack = []
self._fixturestack = []
@property
def node(self):
""" underlying collection node (depends on request scope)"""
return self._getscopeitem(self.scope)
def _getfaclist(self, argname):
facdeflist = self._name2factory.get(argname, None)
getfactb = None
def _getfixturedeflist(self, argname):
fixturedeflist = self._arg2fixturedeflist.get(argname, None)
getfixturetb = None
function = None
if facdeflist is None:
if self._factorystack:
function = self._factorystack[-1].func
getfactb = lambda: self._factorystack[:-1]
if fixturedeflist is None:
if self._fixturestack:
function = self._fixturestack[-1].func
getfixturetb = lambda: self._fixturestack[:-1]
else:
function = self.function
facdeflist = self.funcargmanager.getfactorylist(
argname, self.parentid)
self._name2factory[argname] = facdeflist
if not facdeflist:
self.funcargmanager._raiselookupfailed(argname, function,
self.parentid, getfactb)
return facdeflist
fixturedeflist = self._fixturemanager.getfixturedeflist(
argname, self._parentid)
self._arg2fixturedeflist[argname] = fixturedeflist
if not fixturedeflist:
self._fixturemanager._raiselookupfailed(argname, function,
self._parentid, getfixturetb)
return fixturedeflist
@property
def config(self):
@@ -1060,7 +1060,7 @@ class FuncargRequest:
"""add finalizer/teardown function to be called after the
last test within the requesting test context finished
execution. """
# XXX usually this method is shadowed by factorydef specific ones
# XXX usually this method is shadowed by fixturedef specific ones
self._addfinalizer(finalizer, scope=self.scope)
def _addfinalizer(self, finalizer, scope):
@@ -1084,15 +1084,15 @@ class FuncargRequest:
self.node.applymarker(marker)
def raiseerror(self, msg):
""" raise a FuncargLookupError with the given message. """
raise self.funcargmanager.FuncargLookupError(self.function, msg)
""" raise a FixtureLookupError with the given message. """
raise self._fixturemanager.FixtureLookupError(self.function, msg)
def _fillfuncargs(self):
def _fillfixtures(self):
item = self._pyfuncitem
funcargnames = getattr(item, "funcargnames", self.funcargnames)
fixturenames = getattr(item, "fixturenames", self.fixturenames)
for argname in funcargnames:
for argname in fixturenames:
if argname not in item.funcargs:
item.funcargs[argname] = self.getfuncargvalue(argname)
@@ -1100,9 +1100,9 @@ class FuncargRequest:
""" (deprecated) Return a testing resource managed by ``setup`` &
``teardown`` calls. ``scope`` and ``extrakey`` determine when the
``teardown`` function will be called so that subsequent calls to
``setup`` would recreate the resource. With pytest-2.3 you
``setup`` would recreate the resource. With pytest-2.3 you often
do not need ``cached_setup()`` as you can directly declare a scope
on a funcarg factory and register a finalizer through
on a fixture function and register a finalizer through
``request.addfinalizer()``.
:arg teardown: function receiving a previously setup resource.
@@ -1151,27 +1151,27 @@ class FuncargRequest:
except KeyError:
pass
try:
factorydeflist = self._getfaclist(argname)
except FuncargLookupError:
fixturedeflist = self._getfixturedeflist(argname)
except FixtureLookupError:
if argname == "request":
return self
raise
factorydef = factorydeflist.pop()
self._factorystack.append(factorydef)
fixturedef = fixturedeflist.pop()
self._fixturestack.append(fixturedef)
try:
result = self._getfuncargvalue(factorydef)
result = self._getfuncargvalue(fixturedef)
self._funcargs[argname] = result
return result
finally:
self._factorystack.pop()
self._fixturestack.pop()
def _getfuncargvalue(self, factorydef):
if factorydef.active:
return factorydef.cached_result
def _getfuncargvalue(self, fixturedef):
if fixturedef.active:
return fixturedef.cached_result
# prepare request scope and param attributes before
# calling into factory
argname = factorydef.argname
argname = fixturedef.argname
node = self._pyfuncitem
mp = monkeypatch()
mp.setattr(self, '_currentarg', argname)
@@ -1181,7 +1181,7 @@ class FuncargRequest:
pass
else:
mp.setattr(self, 'param', param, raising=False)
scope = factorydef.scope
scope = fixturedef.scope
if scope is not None:
__tracebackhide__ = True
if scopemismatch(self.scope, scope):
@@ -1195,20 +1195,20 @@ class FuncargRequest:
mp.setattr(self, "scope", scope)
# prepare finalization according to scope
self.session._setupstate.addfinalizer(factorydef.finish, self.node)
self.funcargmanager.addargfinalizer(factorydef.finish, argname)
for subargname in factorydef.funcargnames: # XXX all deps?
self.funcargmanager.addargfinalizer(factorydef.finish, subargname)
mp.setattr(self, "addfinalizer", factorydef.addfinalizer)
self.session._setupstate.addfinalizer(fixturedef.finish, self.node)
self._fixturemanager.addargfinalizer(fixturedef.finish, argname)
for subargname in fixturedef.fixturenames: # XXX all deps?
self._fixturemanager.addargfinalizer(fixturedef.finish, subargname)
mp.setattr(self, "addfinalizer", fixturedef.addfinalizer)
# finally perform the factory call
val = factorydef.execute(request=self)
val = fixturedef.execute(request=self)
mp.undo()
return val
def _factorytraceback(self):
lines = []
for factorydef in self._factorystack:
factory = factorydef.func
for fixturedef in self._fixturestack:
factory = fixturedef.func
fs, lineno = getfslineno(factory)
p = self._pyfuncitem.session.fspath.bestrelpath(fs)
args = inspect.formatargspec(*inspect.getargspec(factory))
@@ -1232,10 +1232,10 @@ class FuncargRequest:
raise ValueError("unknown finalization scope %r" %(scope,))
def __repr__(self):
return "<FuncargRequest for %r>" %(self._pyfuncitem)
return "<FixtureRequest for %r>" %(self._pyfuncitem)
class ScopeMismatchError(Exception):
""" A funcarg factory tries to access a funcargvalue/factory
""" A fixture function tries to use a different fixture function which
which has a lower scope (e.g. a Session one calls a function one)
"""
@@ -1249,14 +1249,14 @@ def slice_kwargs(names, kwargs):
new_kwargs[name] = kwargs[name]
return new_kwargs
class FuncargLookupError(LookupError):
class FixtureLookupError(LookupError):
""" could not find a factory. """
def __init__(self, function, msg, factblines=None):
self.function = function
self.msg = msg
self.factblines = factblines
class FuncargLookupErrorRepr(TerminalRepr):
class FixtureLookupErrorRepr(TerminalRepr):
def __init__(self, filename, firstlineno, deflines, errorstring, factblines):
self.deflines = deflines
self.errorstring = errorstring
@@ -1268,10 +1268,10 @@ class FuncargLookupErrorRepr(TerminalRepr):
tw.line()
if self.factblines:
tw.line(' dependency of:')
for factorydef in self.factblines:
for fixturedef in self.factblines:
tw.line(' %s in %s' % (
factorydef.argname,
factorydef.baseid,
fixturedef.argname,
fixturedef.baseid,
))
tw.line()
for line in self.deflines:
@@ -1281,15 +1281,15 @@ class FuncargLookupErrorRepr(TerminalRepr):
tw.line()
tw.line("%s:%d" % (self.filename, self.firstlineno+1))
class FuncargManager:
class FixtureManager:
_argprefix = "pytest_funcarg__"
FuncargLookupError = FuncargLookupError
FuncargLookupErrorRepr = FuncargLookupErrorRepr
FixtureLookupError = FixtureLookupError
FixtureLookupErrorRepr = FixtureLookupErrorRepr
def __init__(self, session):
self.session = session
self.config = session.config
self.arg2facspec = {}
self.arg2fixturedeflist = {}
self._seenplugins = set()
self._holderobjseen = set()
self._arg2finish = {}
@@ -1319,41 +1319,44 @@ class FuncargManager:
for plugin in plugins:
self.pytest_plugin_registered(plugin)
def getallfuncargnames(self, funcargnames, parentnode):
# collect the closure of all funcargs, starting with
# funcargnames as the initial set
# we populate and return a arg2facdeflist mapping
# so that the caller can reuse it and does not have to re-discover
# factories again for each funcargname
def getfixtureclosure(self, fixturenames, parentnode):
# collect the closure of all funcargs, starting with the given
# fixturenames as the initial set. As we have to visit all
# factory definitions anyway, we also return a arg2fixturedeflist
# mapping so that the caller can reuse it and does not have
# to re-discover fixturedefs again for each fixturename
# (discovering matching fixtures for a given name/node is expensive)
parentid = parentnode.nodeid
funcargnames = self._autofixtures + list(funcargnames)
fixturenames_closure = list(self._autofixtures)
def merge(otherlist):
for arg in otherlist:
if arg not in funcargnames:
funcargnames.append(arg)
arg2facdeflist = {}
if arg not in fixturenames_closure:
fixturenames_closure.append(arg)
merge(fixturenames)
arg2fixturedeflist = {}
lastlen = -1
while lastlen != len(funcargnames):
lastlen = len(funcargnames)
for argname in list(funcargnames):
if argname in arg2facdeflist:
while lastlen != len(fixturenames_closure):
lastlen = len(fixturenames_closure)
for argname in fixturenames_closure:
if argname in arg2fixturedeflist:
continue
facdeflist = self.getfactorylist(argname, parentid)
arg2facdeflist[argname] = facdeflist
if facdeflist is not None:
for facdef in facdeflist:
merge(facdef.funcargnames)
return funcargnames, arg2facdeflist
fixturedeflist = self.getfixturedeflist(argname, parentid)
arg2fixturedeflist[argname] = fixturedeflist
if fixturedeflist is not None:
for fixturedef in fixturedeflist:
merge(fixturedef.fixturenames)
return fixturenames_closure, arg2fixturedeflist
def pytest_generate_tests(self, metafunc):
for argname in metafunc.funcargnames:
faclist = metafunc._arg2facdeflist[argname]
for argname in metafunc.fixturenames:
faclist = metafunc._arg2fixturedeflist[argname]
if faclist is None:
continue # will raise FuncargLookupError at setup time
for facdef in faclist:
if facdef.params is not None:
metafunc.parametrize(argname, facdef.params, indirect=True,
scope=facdef.scope)
continue # will raise FixtureLookupError at setup time
for fixturedef in faclist:
if fixturedef.params is not None:
metafunc.parametrize(argname, fixturedef.params, indirect=True,
scope=fixturedef.scope)
def pytest_collection_modifyitems(self, items):
# separate parametrized setups
@@ -1394,7 +1397,7 @@ class FuncargManager:
obj = getattr(holderobj, name)
if not callable(obj):
continue
# fixture functions have a pytest_funcarg__ prefix
# fixture functions have a pytest_funcarg__ prefix (pre-2.3 style)
# or are "@pytest.fixture" marked
marker = getattr(obj, "_pytestfixturefunction", None)
if marker is None:
@@ -1408,42 +1411,42 @@ class FuncargManager:
continue
else:
assert not name.startswith(self._argprefix)
factorydef = FactoryDef(self, nodeid, name, obj,
fixturedef = FixtureDef(self, nodeid, name, obj,
marker.scope, marker.params,
unittest=unittest)
faclist = self.arg2facspec.setdefault(name, [])
faclist.append(factorydef)
faclist = self.arg2fixturedeflist.setdefault(name, [])
faclist.append(fixturedef)
if marker.autoactive:
# make sure the self._autofixtures list is always sorted
# by scope, scopenum 0 is session
self._autofixtures.append(name)
self._autofixtures.sort(
key=lambda x: self.arg2facspec[x][-1].scopenum)
key=lambda x: self.arg2fixturedeflist[x][-1].scopenum)
def getfactorylist(self, argname, nodeid):
def getfixturedeflist(self, argname, nodeid):
try:
factorydeflist = self.arg2facspec[argname]
fixturedeflist = self.arg2fixturedeflist[argname]
except KeyError:
return None
else:
return list(self._matchfactories(factorydeflist, nodeid))
return list(self._matchfactories(fixturedeflist, nodeid))
def _matchfactories(self, factorydeflist, nodeid):
for factorydef in factorydeflist:
if nodeid.startswith(factorydef.baseid):
yield factorydef
def _matchfactories(self, fixturedeflist, nodeid):
for fixturedef in fixturedeflist:
if nodeid.startswith(fixturedef.baseid):
yield fixturedef
def _raiselookupfailed(self, argname, function, nodeid, getfactb=None):
def _raiselookupfailed(self, argname, function, nodeid, getfixturetb=None):
available = []
for name, facdef in self.arg2facspec.items():
faclist = list(self._matchfactories(facdef, nodeid))
for name, fixturedef in self.arg2fixturedeflist.items():
faclist = list(self._matchfactories(fixturedef, nodeid))
if faclist:
available.append(name)
msg = "LookupError: no factory found for argument %r" % (argname,)
msg += "\n available funcargs: %s" %(", ".join(available),)
msg += "\n use 'py.test --funcargs [testpath]' for help on them."
lines = getfactb and getfactb() or []
raise FuncargLookupError(function, msg, lines)
msg += "\n use 'py.test --fixtures [testpath]' for help on them."
lines = getfixturetb and getfixturetb() or []
raise FixtureLookupError(function, msg, lines)
def addargfinalizer(self, finalizer, argname):
l = self._arg2finish.setdefault(argname, [])
@@ -1456,11 +1459,11 @@ class FuncargManager:
except ValueError:
pass
class FactoryDef:
class FixtureDef:
""" A container for a factory definition. """
def __init__(self, funcargmanager, baseid, argname, func, scope, params,
def __init__(self, fixturenanager, baseid, argname, func, scope, params,
unittest=False):
self.funcargmanager = funcargmanager
self._fixturemanager = fixturenanager
self.baseid = baseid
self.func = func
self.argname = argname
@@ -1468,7 +1471,7 @@ class FactoryDef:
self.scopenum = scopes.index(scope or "function")
self.params = params
startindex = unittest and 1 or None
self.funcargnames = getfuncargnames(func, startindex=startindex)
self.fixturenames = getfuncargnames(func, startindex=startindex)
self.unittest = unittest
self.active = False
self._finalizer = []
@@ -1481,14 +1484,14 @@ class FactoryDef:
func = self._finalizer.pop()
func()
# check neccesity of next commented call
self.funcargmanager.removefinalizer(self.finish)
self._fixturemanager.removefinalizer(self.finish)
self.active = False
#print "finished", self
#del self.cached_result
def execute(self, request):
kwargs = {}
for newname in self.funcargnames:
for newname in self.fixturenames:
kwargs[newname] = request.getfuncargvalue(newname)
if self.unittest:
result = self.func(request.instance, **kwargs)
@@ -1499,7 +1502,7 @@ class FactoryDef:
return result
def __repr__(self):
return "<FactoryDef name=%r scope=%r>" % (self.argname, self.scope)
return "<FixtureDef name=%r scope=%r>" % (self.argname, self.scope)
def getfuncargnames(function, startindex=None):
# XXX merge with main.py's varnames