Handle `match` with `pytest.raises()` (#6753)
Fixes https://github.com/pytest-dev/pytest/issues/6752.
This commit is contained in:
parent
68fe0eb8f3
commit
c8b4a1a471
|
@ -0,0 +1,3 @@
|
|||
When :py:func:`pytest.raises` is used as a function (as opposed to a context manager),
|
||||
a `match` keyword argument is now passed through to the tested function. Previously
|
||||
it was swallowed and ignored (regression in pytest 5.1.0).
|
|
@ -557,18 +557,16 @@ def raises( # noqa: F811
|
|||
expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]],
|
||||
func: Callable,
|
||||
*args: Any,
|
||||
match: Optional[str] = ...,
|
||||
**kwargs: Any
|
||||
) -> Optional[_pytest._code.ExceptionInfo[_E]]:
|
||||
) -> _pytest._code.ExceptionInfo[_E]:
|
||||
... # pragma: no cover
|
||||
|
||||
|
||||
def raises( # noqa: F811
|
||||
expected_exception: Union["Type[_E]", Tuple["Type[_E]", ...]],
|
||||
*args: Any,
|
||||
match: Optional[Union[str, "Pattern"]] = None,
|
||||
**kwargs: Any
|
||||
) -> Union["RaisesContext[_E]", Optional[_pytest._code.ExceptionInfo[_E]]]:
|
||||
) -> Union["RaisesContext[_E]", _pytest._code.ExceptionInfo[_E]]:
|
||||
r"""
|
||||
Assert that a code block/function call raises ``expected_exception``
|
||||
or raise a failure exception otherwise.
|
||||
|
@ -579,8 +577,12 @@ def raises( # noqa: F811
|
|||
string that may contain `special characters`__, the pattern can
|
||||
first be escaped with ``re.escape``.
|
||||
|
||||
__ https://docs.python.org/3/library/re.html#regular-expression-syntax
|
||||
(This is only used when ``pytest.raises`` is used as a context manager,
|
||||
and passed through to the function otherwise.
|
||||
When using ``pytest.raises`` as a function, you can use:
|
||||
``pytest.raises(Exc, func, match="passed on").match("my pattern")``.)
|
||||
|
||||
__ https://docs.python.org/3/library/re.html#regular-expression-syntax
|
||||
|
||||
.. currentmodule:: _pytest._code
|
||||
|
||||
|
@ -684,6 +686,7 @@ def raises( # noqa: F811
|
|||
message = "DID NOT RAISE {}".format(expected_exception)
|
||||
|
||||
if not args:
|
||||
match = kwargs.pop("match", None)
|
||||
if kwargs:
|
||||
msg = "Unexpected keyword arguments passed to pytest.raises: "
|
||||
msg += ", ".join(sorted(kwargs))
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import re
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
@ -154,7 +155,7 @@ class TestRaises:
|
|||
else:
|
||||
assert False, "Expected pytest.raises.Exception"
|
||||
|
||||
@pytest.mark.parametrize("method", ["function", "with"])
|
||||
@pytest.mark.parametrize("method", ["function", "function_match", "with"])
|
||||
def test_raises_cyclic_reference(self, method):
|
||||
"""
|
||||
Ensure pytest.raises does not leave a reference cycle (#1965).
|
||||
|
@ -175,6 +176,8 @@ class TestRaises:
|
|||
|
||||
if method == "function":
|
||||
pytest.raises(ValueError, t)
|
||||
elif method == "function_match":
|
||||
pytest.raises(ValueError, t).match("^$")
|
||||
else:
|
||||
with pytest.raises(ValueError):
|
||||
t()
|
||||
|
@ -184,7 +187,7 @@ class TestRaises:
|
|||
|
||||
assert refcount == len(gc.get_referrers(t))
|
||||
|
||||
def test_raises_match(self):
|
||||
def test_raises_match(self) -> None:
|
||||
msg = r"with base \d+"
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
int("asdf")
|
||||
|
@ -194,13 +197,27 @@ class TestRaises:
|
|||
int("asdf")
|
||||
|
||||
msg = "with base 16"
|
||||
expr = r"Pattern '{}' does not match \"invalid literal for int\(\) with base 10: 'asdf'\"".format(
|
||||
expr = "Pattern {!r} does not match \"invalid literal for int() with base 10: 'asdf'\"".format(
|
||||
msg
|
||||
)
|
||||
with pytest.raises(AssertionError, match=expr):
|
||||
with pytest.raises(AssertionError, match=re.escape(expr)):
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
int("asdf", base=10)
|
||||
|
||||
# "match" without context manager.
|
||||
pytest.raises(ValueError, int, "asdf").match("invalid literal")
|
||||
with pytest.raises(AssertionError) as excinfo:
|
||||
pytest.raises(ValueError, int, "asdf").match(msg)
|
||||
assert str(excinfo.value) == expr
|
||||
|
||||
pytest.raises(TypeError, int, match="invalid")
|
||||
|
||||
def tfunc(match):
|
||||
raise ValueError("match={}".format(match))
|
||||
|
||||
pytest.raises(ValueError, tfunc, match="asdf").match("match=asdf")
|
||||
pytest.raises(ValueError, tfunc, match="").match("match=")
|
||||
|
||||
def test_match_failure_string_quoting(self):
|
||||
with pytest.raises(AssertionError) as excinfo:
|
||||
with pytest.raises(AssertionError, match="'foo"):
|
||||
|
|
Loading…
Reference in New Issue