introduce --confcutdir option to early-inhibit lookup of conftest files above a certain directory.

--HG--
branch : trunk
This commit is contained in:
holger krekel 2009-12-31 15:10:32 +01:00
parent eb4249322e
commit 2752168a58
5 changed files with 90 additions and 9 deletions

View File

@ -10,6 +10,9 @@ Changes between 1.X and 1.1.1
- new option: --ignore will prevent specified path from collection. - new option: --ignore will prevent specified path from collection.
Can be specified multiple times. Can be specified multiple times.
- new option: --confcutdir=dir will make py.test only consider conftest
files that are relative to the specified dir.
- install 'py.test' and `py.which` with a ``-$VERSION`` suffix to - install 'py.test' and `py.which` with a ``-$VERSION`` suffix to
disambiguate between Python3, python2.X, Jython and PyPy installed versions. disambiguate between Python3, python2.X, Jython and PyPy installed versions.

View File

@ -8,10 +8,11 @@ class Conftest(object):
Note that triggering Conftest instances to import Note that triggering Conftest instances to import
conftest.py files may result in added cmdline options. conftest.py files may result in added cmdline options.
""" """
def __init__(self, onimport=None): def __init__(self, onimport=None, confcutdir=None):
self._path2confmods = {} self._path2confmods = {}
self._onimport = onimport self._onimport = onimport
self._conftestpath2mod = {} self._conftestpath2mod = {}
self._confcutdir = confcutdir
def setinitial(self, args): def setinitial(self, args):
""" try to find a first anchor path for looking up global values """ try to find a first anchor path for looking up global values
@ -23,6 +24,17 @@ class Conftest(object):
bootstrapped ... bootstrapped ...
""" """
current = py.path.local() current = py.path.local()
opt = '--confcutdir'
for i in range(len(args)):
opt1 = str(args[i])
if opt1.startswith(opt):
if opt1 == opt:
if len(args) > i:
p = current.join(args[i+1], abs=True)
elif opt1.startswith(opt + "="):
p = current.join(opt1[len(opt)+1:], abs=1)
self._confcutdir = p
break
for arg in args + [current]: for arg in args + [current]:
anchor = current.join(arg, abs=1) anchor = current.join(arg, abs=1)
if anchor.check(): # we found some file object if anchor.check(): # we found some file object
@ -37,16 +49,20 @@ class Conftest(object):
clist = self._path2confmods[path] clist = self._path2confmods[path]
except KeyError: except KeyError:
if path is None: if path is None:
raise ValueError("missing default conftest.") raise ValueError("missing default confest.")
dp = path.dirpath() dp = path.dirpath()
if dp == path: if dp == path:
clist = self._path2confmods[path] = [] clist = []
else: else:
cutdir = self._confcutdir
clist = self.getconftestmodules(dp) clist = self.getconftestmodules(dp)
conftestpath = path.join("conftest.py") if cutdir and path != cutdir and not path.relto(cutdir):
if conftestpath.check(file=1): pass
clist.append(self.importconftest(conftestpath)) else:
self._path2confmods[path] = clist conftestpath = path.join("conftest.py")
if conftestpath.check(file=1):
clist.append(self.importconftest(conftestpath))
self._path2confmods[path] = clist
# be defensive: avoid changes from caller side to # be defensive: avoid changes from caller side to
# affect us by always returning a copy of the actual list # affect us by always returning a copy of the actual list
return clist[:] return clist[:]
@ -77,8 +93,14 @@ class Conftest(object):
mod = conftestpath.pyimport(modname=modname) mod = conftestpath.pyimport(modname=modname)
else: else:
mod = conftestpath.pyimport() mod = conftestpath.pyimport()
self._postimport(mod)
self._conftestpath2mod[conftestpath] = mod self._conftestpath2mod[conftestpath] = mod
dirpath = conftestpath.dirpath()
if dirpath in self._path2confmods:
for path, mods in self._path2confmods.items():
if path and path.relto(dirpath) or path == dirpath:
assert mod not in mods
mods.append(mod)
self._postimport(mod)
return mod return mod
def _postimport(self, mod): def _postimport(self, mod):

View File

@ -73,7 +73,9 @@ def pytest_addoption(parser):
"test process debugging and configuration") "test process debugging and configuration")
group.addoption('--basetemp', dest="basetemp", default=None, metavar="dir", group.addoption('--basetemp', dest="basetemp", default=None, metavar="dir",
help="base temporary directory for this test run.") help="base temporary directory for this test run.")
group.addoption('--confcutdir', dest="confcutdir", default=None,
metavar="dir",
help="only load conftest.py's relative to specified dir.")
if execnet: if execnet:
add_dist_options(parser) add_dist_options(parser)
else: else:

View File

@ -92,3 +92,14 @@ def test_pytest_report_iteminfo():
res = pytest_report_iteminfo(FakeItem()) res = pytest_report_iteminfo(FakeItem())
assert res == "-reportinfo-" assert res == "-reportinfo-"
def test_conftest_confcutdir(testdir):
testdir.makeconftest("assert 0")
x = testdir.mkdir("x")
x.join("conftest.py").write(py.code.Source("""
def pytest_addoption(parser):
parser.addoption("--xyz", action="store_true")
"""))
result = testdir.runpytest("-h", "--confcutdir=%s" % x, x)
assert result.stdout.fnmatch_lines(["*--xyz*"])

View File

@ -89,3 +89,46 @@ class TestConftestValueAccessGlobal:
path = py.path.local(mod.__file__) path = py.path.local(mod.__file__)
assert path.dirpath() == basedir.join("adir", "b") assert path.dirpath() == basedir.join("adir", "b")
assert path.purebasename == "conftest" assert path.purebasename == "conftest"
def test_conftestcutdir(testdir):
conf = testdir.makeconftest("")
p = testdir.mkdir("x")
conftest = Conftest(confcutdir=p)
conftest.setinitial([testdir.tmpdir])
l = conftest.getconftestmodules(p)
assert len(l) == 0
l = conftest.getconftestmodules(conf.dirpath())
assert len(l) == 0
assert conf not in conftest._conftestpath2mod
# but we can still import a conftest directly
conftest.importconftest(conf)
l = conftest.getconftestmodules(conf.dirpath())
assert l[0].__file__.startswith(str(conf))
# and all sub paths get updated properly
l = conftest.getconftestmodules(p)
assert len(l) == 1
assert l[0].__file__.startswith(str(conf))
def test_conftestcutdir_inplace_considered(testdir):
conf = testdir.makeconftest("")
conftest = Conftest(confcutdir=conf.dirpath())
conftest.setinitial([conf.dirpath()])
l = conftest.getconftestmodules(conf.dirpath())
assert len(l) == 1
assert l[0].__file__.startswith(str(conf))
def test_setinitial_confcut(testdir):
conf = testdir.makeconftest("")
sub = testdir.mkdir("sub")
sub.chdir()
for opts in (["--confcutdir=%s" % sub, sub],
[sub, "--confcutdir=%s" % sub],
["--confcutdir=.", sub],
[sub, "--confcutdir", sub],
[str(sub), "--confcutdir", "."],
):
conftest = Conftest()
conftest.setinitial(opts)
assert conftest._confcutdir == sub
assert conftest.getconftestmodules(sub) == []
assert conftest.getconftestmodules(conf.dirpath()) == []