introduce norecursedirs config option, remove recfilter()
This commit is contained in:
parent
5251653fc3
commit
fed8f19156
|
@ -10,10 +10,6 @@ def pytest_cmdline_parse(pluginmanager, args):
|
||||||
config.parse(args)
|
config.parse(args)
|
||||||
return config
|
return config
|
||||||
|
|
||||||
def pytest_addoption(parser):
|
|
||||||
parser.addini('addopts', 'default command line arguments')
|
|
||||||
parser.addini('minversion', 'minimally required pytest version')
|
|
||||||
|
|
||||||
class Parser:
|
class Parser:
|
||||||
""" Parser for command line arguments. """
|
""" Parser for command line arguments. """
|
||||||
|
|
||||||
|
@ -72,9 +68,10 @@ class Parser:
|
||||||
setattr(option, name, value)
|
setattr(option, name, value)
|
||||||
return args
|
return args
|
||||||
|
|
||||||
def addini(self, name, description, type=None):
|
def addini(self, name, help, type=None, default=None):
|
||||||
""" add an ini-file option with the given name and description. """
|
""" add an ini-file option with the given name and description. """
|
||||||
self._inidict[name] = (description, type)
|
assert type in (None, "pathlist", "args")
|
||||||
|
self._inidict[name] = (help, type, default)
|
||||||
|
|
||||||
class OptionGroup:
|
class OptionGroup:
|
||||||
def __init__(self, name, description="", parser=None):
|
def __init__(self, name, description="", parser=None):
|
||||||
|
@ -293,13 +290,15 @@ class Config(object):
|
||||||
sys.stderr.write(err)
|
sys.stderr.write(err)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def _preparse(self, args, addopts=True):
|
def _initini(self, args):
|
||||||
self.inicfg = {}
|
|
||||||
self.inicfg = getcfg(args, ["setup.cfg", "tox.ini",])
|
self.inicfg = getcfg(args, ["setup.cfg", "tox.ini",])
|
||||||
if self.inicfg and addopts:
|
self._parser.addini('addopts', 'extra command line options', 'args')
|
||||||
newargs = self.inicfg.get("addopts", None)
|
self._parser.addini('minversion', 'minimally required pytest version')
|
||||||
if newargs:
|
|
||||||
args[:] = py.std.shlex.split(newargs) + args
|
def _preparse(self, args, addopts=True):
|
||||||
|
self._initini(args)
|
||||||
|
if addopts:
|
||||||
|
args[:] = self.getini("addopts") + args
|
||||||
self._checkversion()
|
self._checkversion()
|
||||||
self.pluginmanager.consider_setuptools_entrypoints()
|
self.pluginmanager.consider_setuptools_entrypoints()
|
||||||
self.pluginmanager.consider_env()
|
self.pluginmanager.consider_env()
|
||||||
|
@ -358,20 +357,25 @@ class Config(object):
|
||||||
specified name hasn't been registered through a prior ``parse.addini``
|
specified name hasn't been registered through a prior ``parse.addini``
|
||||||
call (usually from a plugin), a ValueError is raised. """
|
call (usually from a plugin), a ValueError is raised. """
|
||||||
try:
|
try:
|
||||||
description, type = self._parser._inidict[name]
|
description, type, default = self._parser._inidict[name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise ValueError("unknown configuration value: %r" %(name,))
|
raise ValueError("unknown configuration value: %r" %(name,))
|
||||||
try:
|
try:
|
||||||
value = self.inicfg[name]
|
value = self.inicfg[name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return # None indicates nothing found
|
if default is not None:
|
||||||
|
return default
|
||||||
|
return {'pathlist': [], 'args': [], None: ''}.get(type)
|
||||||
if type == "pathlist":
|
if type == "pathlist":
|
||||||
dp = py.path.local(self.inicfg.config.path).dirpath()
|
dp = py.path.local(self.inicfg.config.path).dirpath()
|
||||||
l = []
|
l = []
|
||||||
for relpath in py.std.shlex.split(value):
|
for relpath in py.std.shlex.split(value):
|
||||||
l.append(dp.join(relpath, abs=True))
|
l.append(dp.join(relpath, abs=True))
|
||||||
return l
|
return l
|
||||||
|
elif type == "args":
|
||||||
|
return py.std.shlex.split(value)
|
||||||
else:
|
else:
|
||||||
|
assert type is None
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def _getconftest_pathlist(self, name, path=None):
|
def _getconftest_pathlist(self, name, path=None):
|
||||||
|
|
|
@ -44,8 +44,11 @@ def showhelp(config):
|
||||||
tw.line("setup.cfg or tox.ini options to be put into [pytest] section:")
|
tw.line("setup.cfg or tox.ini options to be put into [pytest] section:")
|
||||||
tw.line()
|
tw.line()
|
||||||
|
|
||||||
for name, (help, type) in sorted(config._parser._inidict.items()):
|
for name, (help, type, default) in sorted(config._parser._inidict.items()):
|
||||||
line = " %-15s %s" %(name, help)
|
if type is None:
|
||||||
|
type = "string"
|
||||||
|
spec = "%s (%s)" % (name, type)
|
||||||
|
line = " %-24s %s" %(spec, help)
|
||||||
tw.line(line[:tw.fullwidth])
|
tw.line(line[:tw.fullwidth])
|
||||||
|
|
||||||
tw.line() ; tw.line()
|
tw.line() ; tw.line()
|
||||||
|
|
|
@ -16,7 +16,8 @@ EXIT_INTERNALERROR = 3
|
||||||
EXIT_NOHOSTS = 4
|
EXIT_NOHOSTS = 4
|
||||||
|
|
||||||
def pytest_addoption(parser):
|
def pytest_addoption(parser):
|
||||||
|
parser.addini("norecursedirs", "directory patterns to avoid for recursion",
|
||||||
|
type="args", default=('.*', 'CVS', '_darcs', '{arch}'))
|
||||||
group = parser.getgroup("general", "running and selection options")
|
group = parser.getgroup("general", "running and selection options")
|
||||||
group._addoption('-x', '--exitfirst', action="store_true", default=False,
|
group._addoption('-x', '--exitfirst', action="store_true", default=False,
|
||||||
dest="exitfirst",
|
dest="exitfirst",
|
||||||
|
@ -107,13 +108,15 @@ def pytest_ignore_collect(path, config):
|
||||||
return path in ignore_paths
|
return path in ignore_paths
|
||||||
|
|
||||||
def pytest_collect_directory(path, parent):
|
def pytest_collect_directory(path, parent):
|
||||||
if not parent.recfilter(path): # by default special ".cvs", ...
|
# check if cmdline specified this dir or a subdir directly
|
||||||
# check if cmdline specified this dir or a subdir directly
|
for arg in parent.collection._argfspaths:
|
||||||
for arg in parent.collection._argfspaths:
|
if path == arg or arg.relto(path):
|
||||||
if path == arg or arg.relto(path):
|
break
|
||||||
break
|
else:
|
||||||
else:
|
patterns = parent.config.getini("norecursedirs")
|
||||||
return
|
for pat in patterns or []:
|
||||||
|
if path.check(fnmatch=pat):
|
||||||
|
return
|
||||||
return Directory(path, parent=parent)
|
return Directory(path, parent=parent)
|
||||||
|
|
||||||
class Session(object):
|
class Session(object):
|
||||||
|
@ -465,10 +468,6 @@ class File(FSCollector):
|
||||||
""" base class for collecting tests from a file. """
|
""" base class for collecting tests from a file. """
|
||||||
|
|
||||||
class Directory(FSCollector):
|
class Directory(FSCollector):
|
||||||
def recfilter(self, path):
|
|
||||||
if path.check(dir=1, dotfile=0):
|
|
||||||
return path.basename not in ('CVS', '_darcs', '{arch}')
|
|
||||||
|
|
||||||
def collect(self):
|
def collect(self):
|
||||||
l = []
|
l = []
|
||||||
for path in self.fspath.listdir(sort=True):
|
for path in self.fspath.listdir(sort=True):
|
||||||
|
|
|
@ -99,14 +99,25 @@ class TestCollectFS:
|
||||||
tmpdir.ensure(".whatever", 'test_notfound.py')
|
tmpdir.ensure(".whatever", 'test_notfound.py')
|
||||||
tmpdir.ensure(".bzr", 'test_notfound.py')
|
tmpdir.ensure(".bzr", 'test_notfound.py')
|
||||||
tmpdir.ensure("normal", 'test_found.py')
|
tmpdir.ensure("normal", 'test_found.py')
|
||||||
tmpdir.ensure('test_found.py')
|
|
||||||
|
|
||||||
col = testdir.getnode(testdir.parseconfig(tmpdir), tmpdir)
|
result = testdir.runpytest("--collectonly")
|
||||||
items = col.collect()
|
s = result.stdout.str()
|
||||||
names = [x.name for x in items]
|
assert "test_notfound" not in s
|
||||||
assert len(items) == 2
|
assert "test_found" in s
|
||||||
assert 'normal' in names
|
|
||||||
assert 'test_found.py' in names
|
def test_custom_norecursedirs(self, testdir):
|
||||||
|
testdir.makeini("""
|
||||||
|
[pytest]
|
||||||
|
norecursedirs = mydir xyz*
|
||||||
|
""")
|
||||||
|
tmpdir = testdir.tmpdir
|
||||||
|
tmpdir.ensure("mydir", "test_hello.py").write("def test_1(): pass")
|
||||||
|
tmpdir.ensure("xyz123", "test_2.py").write("def test_2(): 0/0")
|
||||||
|
tmpdir.ensure("xy", "test_ok.py").write("def test_3(): pass")
|
||||||
|
rec = testdir.inline_run()
|
||||||
|
rec.assertoutcome(passed=1)
|
||||||
|
rec = testdir.inline_run("xyz123/test_2.py")
|
||||||
|
rec.assertoutcome(failed=1)
|
||||||
|
|
||||||
def test_found_certain_testfiles(self, testdir):
|
def test_found_certain_testfiles(self, testdir):
|
||||||
p1 = testdir.makepyfile(test_found = "pass", found_test="pass")
|
p1 = testdir.makepyfile(test_found = "pass", found_test="pass")
|
||||||
|
|
|
@ -152,6 +152,23 @@ class TestConfigAPI:
|
||||||
assert l[1] == p.dirpath('world/sub.py')
|
assert l[1] == p.dirpath('world/sub.py')
|
||||||
py.test.raises(ValueError, config.getini, 'other')
|
py.test.raises(ValueError, config.getini, 'other')
|
||||||
|
|
||||||
|
def test_addini_args(self, testdir):
|
||||||
|
testdir.makeconftest("""
|
||||||
|
def pytest_addoption(parser):
|
||||||
|
parser.addini("args", "new args", type="args")
|
||||||
|
parser.addini("a2", "", "args", default="1 2 3".split())
|
||||||
|
""")
|
||||||
|
p = testdir.makeini("""
|
||||||
|
[pytest]
|
||||||
|
args=123 "123 hello" "this"
|
||||||
|
""")
|
||||||
|
config = testdir.parseconfig()
|
||||||
|
l = config.getini("args")
|
||||||
|
assert len(l) == 3
|
||||||
|
assert l == ["123", "123 hello", "this"]
|
||||||
|
l = config.getini("a2")
|
||||||
|
assert l == list("123")
|
||||||
|
|
||||||
def test_options_on_small_file_do_not_blow_up(testdir):
|
def test_options_on_small_file_do_not_blow_up(testdir):
|
||||||
def runfiletest(opts):
|
def runfiletest(opts):
|
||||||
reprec = testdir.inline_run(*opts)
|
reprec = testdir.inline_run(*opts)
|
||||||
|
|
Loading…
Reference in New Issue