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:
		
						commit
						c08cff3770
					
				
							
								
								
									
										1
									
								
								AUTHORS
								
								
								
								
							
							
						
						
									
										1
									
								
								AUTHORS
								
								
								
								
							| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					Prevent crashing and provide a user-friendly error when a marker expression (-m) invoking of eval() raises any exception.
 | 
				
			||||||
| 
						 | 
					@ -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):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue