Skip to content

Commit

Permalink
Print inifile and rootdir when there's usage errors
Browse files Browse the repository at this point in the history
Related to pytest-dev#821
  • Loading branch information
nicoddemus committed Jul 11, 2015
1 parent 65c56d4 commit 8a6aa5e
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 5 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -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).
Expand Down
24 changes: 19 additions & 5 deletions _pytest/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,11 @@ def import_plugin(self, modname):


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)
Expand All @@ -391,6 +395,7 @@ def __init__(self, usage=None, processopt=None):
self._usage = usage
self._inidict = {}
self._ininames = []
self.extra_info = {}

def processoption(self, option):
if self._processopt:
Expand Down Expand Up @@ -444,7 +449,7 @@ def parse(self, args):

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:
Expand Down Expand Up @@ -669,19 +674,26 @@ def _addoption_instance(self, option, shortupper=False):


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"""
args, argv = self.parse_known_args(args, namespace)
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

Expand Down Expand Up @@ -863,6 +875,8 @@ def _initini(self, args):
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')
Expand Down
13 changes: 13 additions & 0 deletions testing/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,19 @@ def pytest_cmdline_preparse(args):
"*-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):
Expand Down

0 comments on commit 8a6aa5e

Please sign in to comment.