diff --git a/_pytest/python.py b/_pytest/python.py index fa0e7fb02..7611708d4 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -266,6 +266,18 @@ class PyobjMixin(PyobjContext): return fspath, lineno, modpath class PyCollector(PyobjMixin, pytest.Collector): + def _fixturemapper(): + def get(self): + try: + return self._fixturemapper_memo + except AttributeError: + self._fixturemapper_memo = FixtureMapper(self, funcargs=False) + return self._fixturemapper_memo + def set(self, val): + assert not hasattr(self, "_fixturemapper_memo") + self._fixturemapper_memo = val + return property(get, set) + _fixturemapper = _fixturemapper() def funcnamefilter(self, name): for prefix in self.config.getini("python_functions"): @@ -309,7 +321,7 @@ class PyCollector(PyobjMixin, pytest.Collector): clscol = self.getparent(Class) cls = clscol and clscol.obj or None transfer_markers(funcobj, cls, module) - if not hasattr(self, "_fixturemapper"): + if not hasattr(self, "_fixturemapper_memo"): self._fixturemapper = FixtureMapper(self) fixtureinfo = self._fixturemapper.getfixtureinfo(funcobj, cls) metafunc = Metafunc(funcobj, fixtureinfo, self.config, @@ -331,17 +343,21 @@ class PyCollector(PyobjMixin, pytest.Collector): keywords={callspec.id:True}) class FixtureMapper: - def __init__(self, node): + def __init__(self, node, funcargs=True): self.node = node self.fm = node.session._fixturemanager self._name2fixtureinfo = {} + self.hasfuncargs = funcargs def getfixtureinfo(self, func, cls): try: return self._name2fixtureinfo[func] except KeyError: pass - argnames = getfuncargnames(func, int(cls is not None)) + if self.hasfuncargs: + argnames = getfuncargnames(func, int(cls is not None)) + else: + argnames = () usefixtures = getattr(func, "usefixtures", None) if usefixtures is not None: argnames = usefixtures.args + argnames @@ -929,17 +945,9 @@ class Function(FunctionMixin, pytest.Item, FuncargnamesCompatAttr): for name, val in keywords.items(): setattr(self.markers, name, val) - # contstruct a list of all neccessary fixtures for this test function - try: - usefixtures = self.markers.usefixtures.args - except AttributeError: - usefixtures = () - self.fixturenames = (self.session._fixturemanager.getdefaultfixtures() + - usefixtures + self._getfuncargnames()) - - def _getfuncargnames(self): - startindex = int(self.cls is not None) - return getfuncargnames(self.obj, startindex=startindex) + fixtureinfo = self.parent._fixturemapper.getfixtureinfo(self.obj, + self.cls) + self.fixturenames = fixtureinfo.names_closure @property def function(self): diff --git a/_pytest/unittest.py b/_pytest/unittest.py index 6e19281b4..05c823a6c 100644 --- a/_pytest/unittest.py +++ b/_pytest/unittest.py @@ -20,6 +20,7 @@ def pytest_pycollect_makeitem(collector, name, obj): return UnitTestCase(name, parent=collector) class UnitTestCase(pytest.Class): + def collect(self): self.session._fixturemanager._parsefactories(self.obj, self.nodeid, unittest=True) @@ -52,9 +53,6 @@ class UnitTestCase(pytest.Class): class TestCaseFunction(pytest.Function): _excinfo = None - def _getfuncargnames(self): - return () - def setup(self): self._testcase = self.parent.obj(self.name) self._obj = getattr(self._testcase, self.name) diff --git a/testing/test_python.py b/testing/test_python.py index 165713474..74ea337a9 100644 --- a/testing/test_python.py +++ b/testing/test_python.py @@ -280,6 +280,7 @@ class TestFunction: config = testdir.parseconfigure() session = testdir.Session(config) session._fixturemanager = FixtureManager(session) + session._fixturemapper = funcargs.FixtureMapper(session, funcargs=False) def func1(): pass def func2(): @@ -579,6 +580,7 @@ class TestFillFixtures: pass """) funcargs.fillfixtures(item) + del item.funcargs["request"] assert len(item.funcargs) == 2 assert item.funcargs['some'] == "test_func" assert item.funcargs['other'] == 42 @@ -685,7 +687,9 @@ class TestRequest: val2 = req.getfuncargvalue("other") # see about caching assert val2 == 2 pytest._fillfuncargs(item) - assert item.funcargs == {'something': 1} + assert item.funcargs["something"] == 1 + assert len(item.funcargs) == 2 + assert "request" in item.funcargs #assert item.funcargs == {'something': 1, "other": 2} def test_request_addfinalizer(self, testdir):