Print inifile and rootdir when there's usage errors

Related to #821
This commit is contained in:
Bruno Oliveira 2015-07-08 21:22:08 -03:00
parent 65c56d4c00
commit 8a6aa5e17e
3 changed files with 37 additions and 5 deletions

View File

@ -1,6 +1,11 @@
2.8.0.dev (compared to 2.7.X)
-----------------------------
- rootdir and inifile are now displayed during usage errors to help
users diagnose problems such as unexpected ini files which add
unknown options being picked up by pytest. Thanks to Pavel Savchenko for
bringing the problem to attention in #821 and Bruno Oliveira for the PR.
- Summary bar now is colored yellow for warning
situations such as: all tests either were skipped or xpass/xfailed,
or no tests were run at all (this is a partial fix for issue500).

View File

@ -382,7 +382,11 @@ class PytestPluginManager(PluginManager):
class Parser:
""" Parser for command line arguments and ini-file values. """
""" Parser for command line arguments and ini-file values.
:ivar extra_info: dict of generic param -> value to display in case
there's an error processing the command line arguments.
"""
def __init__(self, usage=None, processopt=None):
self._anonymous = OptionGroup("custom options", parser=self)
@ -391,6 +395,7 @@ class Parser:
self._usage = usage
self._inidict = {}
self._ininames = []
self.extra_info = {}
def processoption(self, option):
if self._processopt:
@ -444,7 +449,7 @@ class Parser:
def _getparser(self):
from _pytest._argcomplete import filescompleter
optparser = MyOptionParser(self)
optparser = MyOptionParser(self, self.extra_info)
groups = self._groups + [self._anonymous]
for group in groups:
if group.options:
@ -669,10 +674,15 @@ class OptionGroup:
class MyOptionParser(argparse.ArgumentParser):
def __init__(self, parser):
def __init__(self, parser, extra_info=None):
if not extra_info:
extra_info = {}
self._parser = parser
argparse.ArgumentParser.__init__(self, usage=parser._usage,
add_help=False, formatter_class=DropShorterLongHelpFormatter)
# extra_info is a dict of (param -> value) to display if there's
# an usage error to provide more contextual information to the user
self.extra_info = extra_info
def parse_args(self, args=None, namespace=None):
"""allow splitting of positional arguments"""
@ -680,8 +690,10 @@ class MyOptionParser(argparse.ArgumentParser):
if argv:
for arg in argv:
if arg and arg[0] == '-':
msg = argparse._('unrecognized arguments: %s')
self.error(msg % ' '.join(argv))
lines = ['unrecognized arguments: %s' % (' '.join(argv))]
for k, v in sorted(self.extra_info.items()):
lines.append(' %s: %s' % (k, v))
self.error('\n'.join(lines))
getattr(args, FILE_OR_DIR).extend(argv)
return args
@ -863,6 +875,8 @@ class Config(object):
parsed_args = self._parser.parse_known_args(args)
r = determine_setup(parsed_args.inifilename, parsed_args.file_or_dir)
self.rootdir, self.inifile, self.inicfg = r
self._parser.extra_info['rootdir'] = self.rootdir
self._parser.extra_info['inifile'] = self.inifile
self.invocation_dir = py.path.local()
self._parser.addini('addopts', 'extra command line options', 'args')
self._parser.addini('minversion', 'minimally required pytest version')

View File

@ -326,6 +326,19 @@ def test_cmdline_processargs_simple(testdir):
"*-h*",
])
def test_invalid_options_show_extra_information(testdir):
"""display extra information when pytest exits due to unrecognized
options in the command-line"""
testdir.makeini("""
[pytest]
addopts = --invalid-option
""")
result = testdir.runpytest()
result.stderr.fnmatch_lines([
"*error: unrecognized arguments: --invalid-option*",
"* inifile: %s*" % testdir.tmpdir.join('tox.ini'),
"* rootdir: %s*" % testdir.tmpdir,
])
@pytest.mark.skipif("sys.platform == 'win32'")
def test_toolongargs_issue224(testdir):