Skip to content

Commit

Permalink
_format_assertmsg: use safeformat instead of saferepr
Browse files Browse the repository at this point in the history
Custom assertion messages should not get shortened via `saferepr`.

Via #125.
Fixes pytest-dev#5199.
  • Loading branch information
blueyed committed Nov 18, 2019
1 parent 64d8910 commit dbb26a3
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 13 deletions.
7 changes: 3 additions & 4 deletions src/_pytest/assertion/rewrite.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from typing import Set
from typing import Tuple

from _pytest._io.saferepr import safeformat
from _pytest._io.saferepr import saferepr
from _pytest._version import version
from _pytest.assertion import util
Expand Down Expand Up @@ -381,17 +382,15 @@ def _format_assertmsg(obj):
For strings this simply replaces newlines with '\n~' so that
util.format_explanation() will preserve them instead of escaping
newlines. For other objects saferepr() is used first.
newlines. For other objects ``safeformat()`` is used first.
"""
# reprlib appears to have a bug which means that if a string
# contains a newline it gets escaped, however if an object has a
# .__repr__() which contains newlines it does not get escaped.
# However in either case we want to preserve the newline.
replaces = [("\n", "\n~"), ("%", "%%")]
if not isinstance(obj, str):
obj = saferepr(obj)
replaces.append(("\\n", "\n~"))
obj = safeformat(obj).replace("\\n", "\n~")

for r1, r2 in replaces:
obj = obj.replace(r1, r2)
Expand Down
34 changes: 25 additions & 9 deletions testing/test_assertion.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,11 @@ def test_dummy_failure(testdir): # how meta!
result = testdir.runpytest_subprocess()
result.stdout.fnmatch_lines(
[
"E * AssertionError: ([[][]], [[][]], [[]<TestReport *>[]])*",
"E * assert"
" {'failed': 1, 'passed': 0, 'skipped': 0} =="
" {'failed': 0, 'passed': 1, 'skipped': 0}",
"> r.assertoutcome(passed=1)",
"E AssertionError: ([],",
"E [],",
"E [<TestReport 'test_dummy_failure.py::test' when='call' outcome='failed'>])",
"E assert {'failed': 1, 'passed': 0, 'skipped': 0} == {'failed': 0, 'passed': 1, 'skipped': 0}",
]
)

Expand Down Expand Up @@ -1287,15 +1288,30 @@ def test_AssertionError_message(testdir):
def test_hello():
x,y = 1,2
assert 0, (x,y)
def test_bytes():
assert 0, b'b' * 80
"""
)
result = testdir.runpytest()
result.stdout.fnmatch_lines(
"""
*def test_hello*
*assert 0, (x,y)*
*AssertionError: (1, 2)*
"""
[
" def test_hello():",
" x,y = 1,2",
"> assert 0, (x,y)",
"E AssertionError: (1, 2)",
"E assert 0",
"",
"test_AssertionError_message.py:3: AssertionError",
" def test_bytes():",
"> assert 0, b'b' * 80",
"E AssertionError: (b'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'",
"E b'bbbb')",
"E assert 0",
"",
"test_AssertionError_message.py:6: AssertionError",
"*= 2 failed in *",
]
)


Expand Down

0 comments on commit dbb26a3

Please sign in to comment.