Merge pull request #3121 from feuillemorte/2953-keyword-expressions-error

#2953 show a simple and easy error when keyword expressions trigger a syntax error
This commit is contained in:
Florian Bruhin 2018-01-17 19:00:22 +01:00 committed by GitHub
commit 1fd67c9000
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 2 deletions

View File

@ -60,8 +60,9 @@ def main(args=None, plugins=None):
finally: finally:
config._ensure_unconfigure() config._ensure_unconfigure()
except UsageError as e: except UsageError as e:
tw = py.io.TerminalWriter(sys.stderr)
for msg in e.args: for msg in e.args:
sys.stderr.write("ERROR: %s\n" % (msg,)) tw.line("ERROR: {}\n".format(msg), red=True)
return 4 return 4

View File

@ -2,11 +2,14 @@
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
import inspect import inspect
import keyword
import warnings import warnings
import attr import attr
from collections import namedtuple from collections import namedtuple
from operator import attrgetter from operator import attrgetter
from six.moves import map from six.moves import map
from _pytest.config import UsageError
from .deprecated import MARK_PARAMETERSET_UNPACKING from .deprecated import MARK_PARAMETERSET_UNPACKING
from .compat import NOTSET, getfslineno from .compat import NOTSET, getfslineno
@ -222,6 +225,9 @@ class KeywordMapping(object):
return False return False
python_keywords_allowed_list = ["or", "and", "not"]
def matchmark(colitem, markexpr): def matchmark(colitem, markexpr):
"""Tries to match on any marker names, attached to the given colitem.""" """Tries to match on any marker names, attached to the given colitem."""
return eval(markexpr, {}, MarkMapping.from_keywords(colitem.keywords)) return eval(markexpr, {}, MarkMapping.from_keywords(colitem.keywords))
@ -259,7 +265,13 @@ def matchkeyword(colitem, keywordexpr):
return mapping[keywordexpr] return mapping[keywordexpr]
elif keywordexpr.startswith("not ") and " " not in keywordexpr[4:]: elif keywordexpr.startswith("not ") and " " not in keywordexpr[4:]:
return not mapping[keywordexpr[4:]] return not mapping[keywordexpr[4:]]
for kwd in keywordexpr.split():
if keyword.iskeyword(kwd) and kwd not in python_keywords_allowed_list:
raise UsageError("Python keyword '{}' not accepted in expressions passed to '-k'".format(kwd))
try:
return eval(keywordexpr, {}, mapping) return eval(keywordexpr, {}, mapping)
except SyntaxError:
raise UsageError("Wrong expression passed to '-k': {}".format(keywordexpr))
def pytest_configure(config): def pytest_configure(config):

1
changelog/2953.trivial Normal file
View File

@ -0,0 +1 @@
Show a simple and easy error when keyword expressions trigger a syntax error (for example, ``"-k foo and import"`` will show an error that you can not use the ``import`` keyword in expressions).

View File

@ -344,6 +344,21 @@ def test_keyword_option_parametrize(spec, testdir):
assert list(passed) == list(passed_result) assert list(passed) == list(passed_result)
@pytest.mark.parametrize("spec", [
("foo or import", "ERROR: Python keyword 'import' not accepted in expressions passed to '-k'"),
("foo or", "ERROR: Wrong expression passed to '-k': foo or")
])
def test_keyword_option_wrong_arguments(spec, testdir, capsys):
testdir.makepyfile("""
def test_func(arg):
pass
""")
opt, expected_result = spec
testdir.inline_run("-k", opt)
out = capsys.readouterr().err
assert expected_result in out
def test_parametrized_collected_from_command_line(testdir): def test_parametrized_collected_from_command_line(testdir):
"""Parametrized test not collected if test named specified """Parametrized test not collected if test named specified
in command line issue#649. in command line issue#649.