diff --git a/CHANGELOG b/CHANGELOG index ad1799b11..4478439c6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -18,6 +18,10 @@ - Fix issue #411: Add __eq__ method to assertion comparison example. Thanks Ben Webb. +- fix issue 877: propperly handle assertion explanations with non-ascii repr + Thanks Mathieu Agopian for the report and Ronny Pfannschmidt for the PR. + + 2.8.0 ----------------------------- diff --git a/_pytest/assertion/util.py b/_pytest/assertion/util.py index fb5f9be0e..ca54f1692 100644 --- a/_pytest/assertion/util.py +++ b/_pytest/assertion/util.py @@ -129,7 +129,16 @@ def assertrepr_compare(config, op, left, right): width = 80 - 15 - len(op) - 2 # 15 chars indentation, 1 space around op left_repr = py.io.saferepr(left, maxsize=int(width/2)) right_repr = py.io.saferepr(right, maxsize=width-len(left_repr)) - summary = u('%s %s %s') % (left_repr, op, right_repr) + + # the re-encoding is needed for python2 repr + # with non-ascii characters (see issue 877) + def ecu(s): + try: + return u(s, 'utf-8', 'replace') + except TypeError: + return s + + summary = u('%s %s %s') % (ecu(left_repr), op, ecu(right_repr)) issequence = lambda x: (isinstance(x, (list, tuple, Sequence)) and not isinstance(x, basestring)) diff --git a/testing/test_assertion.py b/testing/test_assertion.py index a25788307..914feddf7 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -231,6 +231,17 @@ class TestAssert_reprcompare: assert expl[1] == py.builtin._totext('- £€', 'utf-8') assert expl[2] == py.builtin._totext('+ £', 'utf-8') + def test_nonascii_text(self): + """ + :issue: 877 + non ascii python2 str caused a UnicodeDecodeError + """ + class A(str): + def __repr__(self): + return '\xff' + expl = callequal(A(), '1') + assert expl + def test_mojibake(self): # issue 429 left = 'e'