Skip to content

Commit 1fd67c9

Browse files
authored
Merge pull request #3121 from feuillemorte/2953-keyword-expressions-error
#2953 show a simple and easy error when keyword expressions trigger a syntax error
2 parents 01e37fe + e3406e0 commit 1fd67c9

File tree

4 files changed

+31
-2
lines changed

4 files changed

+31
-2
lines changed

_pytest/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,9 @@ def main(args=None, plugins=None):
6060
finally:
6161
config._ensure_unconfigure()
6262
except UsageError as e:
63+
tw = py.io.TerminalWriter(sys.stderr)
6364
for msg in e.args:
64-
sys.stderr.write("ERROR: %s\n" % (msg,))
65+
tw.line("ERROR: {}\n".format(msg), red=True)
6566
return 4
6667

6768

_pytest/mark.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22
from __future__ import absolute_import, division, print_function
33

44
import inspect
5+
import keyword
56
import warnings
67
import attr
78
from collections import namedtuple
89
from operator import attrgetter
910
from six.moves import map
11+
12+
from _pytest.config import UsageError
1013
from .deprecated import MARK_PARAMETERSET_UNPACKING
1114
from .compat import NOTSET, getfslineno
1215

@@ -222,6 +225,9 @@ def __getitem__(self, subname):
222225
return False
223226

224227

228+
python_keywords_allowed_list = ["or", "and", "not"]
229+
230+
225231
def matchmark(colitem, markexpr):
226232
"""Tries to match on any marker names, attached to the given colitem."""
227233
return eval(markexpr, {}, MarkMapping.from_keywords(colitem.keywords))
@@ -259,7 +265,13 @@ def matchkeyword(colitem, keywordexpr):
259265
return mapping[keywordexpr]
260266
elif keywordexpr.startswith("not ") and " " not in keywordexpr[4:]:
261267
return not mapping[keywordexpr[4:]]
262-
return eval(keywordexpr, {}, mapping)
268+
for kwd in keywordexpr.split():
269+
if keyword.iskeyword(kwd) and kwd not in python_keywords_allowed_list:
270+
raise UsageError("Python keyword '{}' not accepted in expressions passed to '-k'".format(kwd))
271+
try:
272+
return eval(keywordexpr, {}, mapping)
273+
except SyntaxError:
274+
raise UsageError("Wrong expression passed to '-k': {}".format(keywordexpr))
263275

264276

265277
def pytest_configure(config):

changelog/2953.trivial

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
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).

testing/test_mark.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,21 @@ def test_func(arg):
344344
assert list(passed) == list(passed_result)
345345

346346

347+
@pytest.mark.parametrize("spec", [
348+
("foo or import", "ERROR: Python keyword 'import' not accepted in expressions passed to '-k'"),
349+
("foo or", "ERROR: Wrong expression passed to '-k': foo or")
350+
])
351+
def test_keyword_option_wrong_arguments(spec, testdir, capsys):
352+
testdir.makepyfile("""
353+
def test_func(arg):
354+
pass
355+
""")
356+
opt, expected_result = spec
357+
testdir.inline_run("-k", opt)
358+
out = capsys.readouterr().err
359+
assert expected_result in out
360+
361+
347362
def test_parametrized_collected_from_command_line(testdir):
348363
"""Parametrized test not collected if test named specified
349364
in command line issue#649.

0 commit comments

Comments
 (0)