Merge pull request #7082 from symonk/4583-better-ux-with-eval-fails

Gracefully handle eval() failure(s) for marker expressions
This commit is contained in:
Ran Benita 2020-04-13 17:03:37 +03:00 committed by GitHub
commit c08cff3770
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 14 deletions

View File

@ -246,6 +246,7 @@ Segev Finer
Serhii Mozghovyi
Seth Junot
Simon Gomizelj
Simon Kerr
Skylar Downes
Srinivas Reddy Thatiparthy
Stefan Farmbauer

View File

@ -0,0 +1 @@
Prevent crashing and provide a user-friendly error when a marker expression (-m) invoking of eval() raises any exception.

View File

@ -84,8 +84,8 @@ def matchmark(colitem, markexpr):
"""Tries to match on any marker names, attached to the given colitem."""
try:
return eval(markexpr, {}, MarkMapping.from_item(colitem))
except SyntaxError as e:
raise SyntaxError(str(e) + "\nMarker expression must be valid Python!")
except Exception:
raise UsageError("Wrong expression passed to '-m': {}".format(markexpr))
def matchkeyword(colitem, keywordexpr):

View File

@ -601,18 +601,6 @@ class TestFunctional:
deselected_tests = dlist[0].items
assert len(deselected_tests) == 2
def test_invalid_m_option(self, testdir):
testdir.makepyfile(
"""
def test_a():
pass
"""
)
result = testdir.runpytest("-m bogus/")
result.stdout.fnmatch_lines(
["INTERNALERROR> Marker expression must be valid Python!"]
)
def test_keywords_at_node_level(self, testdir):
testdir.makepyfile(
"""
@ -1022,3 +1010,20 @@ def test_pytest_param_id_requires_string():
@pytest.mark.parametrize("s", (None, "hello world"))
def test_pytest_param_id_allows_none_or_string(s):
assert pytest.param(id=s)
@pytest.mark.parametrize("expr", ("NOT internal_err", "NOT (internal_err)", "bogus/"))
def test_marker_expr_eval_failure_handling(testdir, expr):
foo = testdir.makepyfile(
"""
import pytest
@pytest.mark.internal_err
def test_foo():
pass
"""
)
expected = "ERROR: Wrong expression passed to '-m': {}".format(expr)
result = testdir.runpytest(foo, "-m", expr)
result.stderr.fnmatch_lines([expected])
assert result.ret == ExitCode.USAGE_ERROR