Skip to content

Commit 46a0888

Browse files
authored
Fix pytest.raises handling of unicode exceptions in Python 2 (#5479)
Fix pytest.raises handling of unicode exceptions in Python 2
2 parents 2301fa6 + 34b4e21 commit 46a0888

File tree

3 files changed

+54
-3
lines changed

3 files changed

+54
-3
lines changed

changelog/5478.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix encode error when using unicode strings in exceptions with ``pytest.raises``.

src/_pytest/_code/code.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -572,8 +572,13 @@ def match(self, regexp):
572572
raised.
573573
"""
574574
__tracebackhide__ = True
575-
if not re.search(regexp, str(self.value)):
576-
assert 0, "Pattern '{!s}' not found in '{!s}'".format(regexp, self.value)
575+
value = (
576+
text_type(self.value) if isinstance(regexp, text_type) else str(self.value)
577+
)
578+
if not re.search(regexp, value):
579+
raise AssertionError(
580+
u"Pattern {!r} not found in {!r}".format(regexp, value)
581+
)
577582
return True
578583

579584

testing/python/raises.py

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import six
55

66
import pytest
7+
from _pytest.compat import dummy_context_manager
78
from _pytest.outcomes import Failed
89
from _pytest.warning_types import PytestDeprecationWarning
910

@@ -220,7 +221,7 @@ def test_raises_match(self):
220221
int("asdf")
221222

222223
msg = "with base 16"
223-
expr = r"Pattern '{}' not found in 'invalid literal for int\(\) with base 10: 'asdf''".format(
224+
expr = r"Pattern '{}' not found in \"invalid literal for int\(\) with base 10: 'asdf'\"".format(
224225
msg
225226
)
226227
with pytest.raises(AssertionError, match=expr):
@@ -278,3 +279,47 @@ def __class__(self):
278279
with pytest.raises(CrappyClass()):
279280
pass
280281
assert "via __class__" in excinfo.value.args[0]
282+
283+
284+
class TestUnicodeHandling:
285+
"""Test various combinations of bytes and unicode with pytest.raises (#5478)
286+
287+
https://github.com/pytest-dev/pytest/pull/5479#discussion_r298852433
288+
"""
289+
290+
success = dummy_context_manager
291+
py2_only = pytest.mark.skipif(
292+
six.PY3, reason="bytes in raises only supported in Python 2"
293+
)
294+
295+
@pytest.mark.parametrize(
296+
"message, match, expectation",
297+
[
298+
(u"\u2603", u"\u2603", success()),
299+
(u"\u2603", u"\u2603foo", pytest.raises(AssertionError)),
300+
pytest.param(b"hello", b"hello", success(), marks=py2_only),
301+
pytest.param(
302+
b"hello", b"world", pytest.raises(AssertionError), marks=py2_only
303+
),
304+
pytest.param(u"hello", b"hello", success(), marks=py2_only),
305+
pytest.param(
306+
u"hello", b"world", pytest.raises(AssertionError), marks=py2_only
307+
),
308+
pytest.param(
309+
u"😊".encode("UTF-8"),
310+
b"world",
311+
pytest.raises(AssertionError),
312+
marks=py2_only,
313+
),
314+
pytest.param(
315+
u"world",
316+
u"😊".encode("UTF-8"),
317+
pytest.raises(AssertionError),
318+
marks=py2_only,
319+
),
320+
],
321+
)
322+
def test_handling(self, message, match, expectation):
323+
with expectation:
324+
with pytest.raises(RuntimeError, match=match):
325+
raise RuntimeError(message)

0 commit comments

Comments
 (0)