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 Serhii Mozghovyi
Seth Junot Seth Junot
Simon Gomizelj Simon Gomizelj
Simon Kerr
Skylar Downes Skylar Downes
Srinivas Reddy Thatiparthy Srinivas Reddy Thatiparthy
Stefan Farmbauer 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.""" """Tries to match on any marker names, attached to the given colitem."""
try: try:
return eval(markexpr, {}, MarkMapping.from_item(colitem)) return eval(markexpr, {}, MarkMapping.from_item(colitem))
except SyntaxError as e: except Exception:
raise SyntaxError(str(e) + "\nMarker expression must be valid Python!") raise UsageError("Wrong expression passed to '-m': {}".format(markexpr))
def matchkeyword(colitem, keywordexpr): def matchkeyword(colitem, keywordexpr):

View File

@ -601,18 +601,6 @@ class TestFunctional:
deselected_tests = dlist[0].items deselected_tests = dlist[0].items
assert len(deselected_tests) == 2 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): def test_keywords_at_node_level(self, testdir):
testdir.makepyfile( testdir.makepyfile(
""" """
@ -1022,3 +1010,20 @@ def test_pytest_param_id_requires_string():
@pytest.mark.parametrize("s", (None, "hello world")) @pytest.mark.parametrize("s", (None, "hello world"))
def test_pytest_param_id_allows_none_or_string(s): def test_pytest_param_id_allows_none_or_string(s):
assert pytest.param(id=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