diff --git a/_pytest/mark.py b/_pytest/mark.py index 3f1f01b1a..da11fc563 100644 --- a/_pytest/mark.py +++ b/_pytest/mark.py @@ -222,6 +222,12 @@ class KeywordMapping(object): return False +# python keywords except or, and, not +python_keywords_list = ["False", "None", "True", "as", "assert", "break", "class", "continue", "def", "del", + "elif", "else", "except", "finally", "for", "from", "global", "if", "import", "in", "is", + "lambda", "nonlocal", "pass", "raise", "return", "try", "while", "with", "yield"] + + def matchmark(colitem, markexpr): """Tries to match on any marker names, attached to the given colitem.""" return eval(markexpr, {}, MarkMapping.from_keywords(colitem.keywords)) @@ -259,7 +265,13 @@ def matchkeyword(colitem, keywordexpr): return mapping[keywordexpr] elif keywordexpr.startswith("not ") and " " not in keywordexpr[4:]: return not mapping[keywordexpr[4:]] - return eval(keywordexpr, {}, mapping) + for keyword in keywordexpr.split(): + if keyword in python_keywords_list: + raise AttributeError("Python keyword '{}' not accepted in expressions passed to '-k'".format(keyword)) + try: + return eval(keywordexpr, {}, mapping) + except SyntaxError: + raise AttributeError("Wrong expression passed to '-k': {}".format(keywordexpr)) def pytest_configure(config): diff --git a/testing/test_mark.py b/testing/test_mark.py index 46bf0b0e7..f3a7af1d1 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -344,6 +344,21 @@ def test_keyword_option_parametrize(spec, testdir): assert list(passed) == list(passed_result) +@pytest.mark.parametrize("spec", [ + ("foo or import", "AttributeError: Python keyword 'import' not accepted in expressions passed to '-k'"), + ("foo or", "AttributeError: 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()[0] + assert expected_result in out + + def test_parametrized_collected_from_command_line(testdir): """Parametrized test not collected if test named specified in command line issue#649.