Skip to content

Commit

Permalink
Fix pytest.raises handling of unicode exceptions in Python 2 (#5479)
Browse files Browse the repository at this point in the history
Fix pytest.raises handling of unicode exceptions in Python 2
  • Loading branch information
nicoddemus authored Jul 4, 2019
2 parents 2301fa6 + 34b4e21 commit 46a0888
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
1 change: 1 addition & 0 deletions changelog/5478.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix encode error when using unicode strings in exceptions with ``pytest.raises``.
9 changes: 7 additions & 2 deletions src/_pytest/_code/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,8 +572,13 @@ def match(self, regexp):
raised.
"""
__tracebackhide__ = True
if not re.search(regexp, str(self.value)):
assert 0, "Pattern '{!s}' not found in '{!s}'".format(regexp, self.value)
value = (
text_type(self.value) if isinstance(regexp, text_type) else str(self.value)
)
if not re.search(regexp, value):
raise AssertionError(
u"Pattern {!r} not found in {!r}".format(regexp, value)
)
return True


Expand Down
47 changes: 46 additions & 1 deletion testing/python/raises.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import six

import pytest
from _pytest.compat import dummy_context_manager
from _pytest.outcomes import Failed
from _pytest.warning_types import PytestDeprecationWarning

Expand Down Expand Up @@ -220,7 +221,7 @@ def test_raises_match(self):
int("asdf")

msg = "with base 16"
expr = r"Pattern '{}' not found in 'invalid literal for int\(\) with base 10: 'asdf''".format(
expr = r"Pattern '{}' not found in \"invalid literal for int\(\) with base 10: 'asdf'\"".format(
msg
)
with pytest.raises(AssertionError, match=expr):
Expand Down Expand Up @@ -278,3 +279,47 @@ def __class__(self):
with pytest.raises(CrappyClass()):
pass
assert "via __class__" in excinfo.value.args[0]


class TestUnicodeHandling:
"""Test various combinations of bytes and unicode with pytest.raises (#5478)
https://github.com/pytest-dev/pytest/pull/5479#discussion_r298852433
"""

success = dummy_context_manager
py2_only = pytest.mark.skipif(
six.PY3, reason="bytes in raises only supported in Python 2"
)

@pytest.mark.parametrize(
"message, match, expectation",
[
(u"\u2603", u"\u2603", success()),
(u"\u2603", u"\u2603foo", pytest.raises(AssertionError)),
pytest.param(b"hello", b"hello", success(), marks=py2_only),
pytest.param(
b"hello", b"world", pytest.raises(AssertionError), marks=py2_only
),
pytest.param(u"hello", b"hello", success(), marks=py2_only),
pytest.param(
u"hello", b"world", pytest.raises(AssertionError), marks=py2_only
),
pytest.param(
u"😊".encode("UTF-8"),
b"world",
pytest.raises(AssertionError),
marks=py2_only,
),
pytest.param(
u"world",
u"😊".encode("UTF-8"),
pytest.raises(AssertionError),
marks=py2_only,
),
],
)
def test_handling(self, message, match, expectation):
with expectation:
with pytest.raises(RuntimeError, match=match):
raise RuntimeError(message)

0 comments on commit 46a0888

Please sign in to comment.