diff --git a/_pytest/python.py b/_pytest/python.py index db5d2cca2..daaf727ef 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1472,8 +1472,7 @@ class FixtureManager: def pytest_plugin_registered(self, plugin): if plugin in self._seenplugins: return - #print "plugin_registered", plugin - nodeid = "" + nodeid = None try: p = py.path.local(plugin.__file__) except AttributeError: @@ -1580,8 +1579,8 @@ class FixtureManager: for fin in reversed(l): fin() - def parsefactories(self, node_or_obj, nodeid=None, unittest=False): - if nodeid is not None: + def parsefactories(self, node_or_obj, nodeid=_dummy, unittest=False): + if nodeid is not _dummy: holderobj = node_or_obj else: holderobj = node_or_obj.obj @@ -1612,7 +1611,15 @@ class FixtureManager: marker.scope, marker.params, unittest=unittest) faclist = self._arg2fixturedefs.setdefault(name, []) - faclist.append(fixturedef) + if not fixturedef.has_location: + # All Nones are at the front so this inserts the + # current fixturedef after the existing fixturedefs + # from external plugins but before the fixturedefs + # provided in conftests. + i = faclist.count(None) + else: + i = len(faclist) # append + faclist.insert(i, fixturedef) if marker.autouse: autousenames.append(name) if autousenames: @@ -1670,7 +1677,8 @@ class FixtureDef: def __init__(self, fixturemanager, baseid, argname, func, scope, params, unittest=False): self._fixturemanager = fixturemanager - self.baseid = baseid + self.baseid = baseid or '' + self.has_location = baseid is not None self.func = func self.argname = argname self.scope = scope @@ -1721,7 +1729,8 @@ class FixtureDef: return result def __repr__(self): - return "" % (self.argname, self.scope) + return ("" % + (self.argname, self.scope, self.baseid, self.func.__module__)) def getfuncargnames(function, startindex=None): # XXX merge with main.py's varnames diff --git a/testing/python/fixture.py b/testing/python/fixture.py index 87cd4f928..357e08f4b 100644 --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -173,6 +173,31 @@ class TestFillFixtures: result = testdir.runpytest(testfile) result.stdout.fnmatch_lines(["*1 passed*"]) + def test_extend_fixture_conftest_plugin(request, testdir): + testdir.makepyfile(testplugin=""" + import pytest + + @pytest.fixture + def foo(): + return 7 + """) + testdir.syspathinsert() + testdir.makeconftest(""" + import pytest + + pytest_plugins = 'testplugin' + + @pytest.fixture + def foo(foo): + return foo + 7 + """) + testdir.makepyfile(""" + def test_foo(foo): + assert foo == 14 + """) + result = testdir.runpytest('-s') + assert result.ret == 0 + def test_funcarg_lookup_error(self, testdir): p = testdir.makepyfile(""" def test_lookup_error(unknown):