From 49c99a41ea8f705fb5ef1ac180f0e22925f0bec5 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Sat, 25 Jul 2015 10:16:05 +0200 Subject: [PATCH] reencode non-ascii python2 assertion reprs, fixes #877 i decided against using a warning since the problem goes away with python3 the support code can be removed once we drop python2 in 10 years or so --- CHANGELOG | 3 +++ _pytest/assertion/util.py | 9 ++++++++- testing/test_assertion.py | 11 +++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index b97fc0355..2a17c01ab 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -193,6 +193,9 @@ 2.7.3 (compared to 2.7.2) ----------------------------- +- fix issue 877: propperly handle assertion explanations with non-ascii repr + Thanks Mathieu Agopian for the report + - Allow 'dev', 'rc', or other non-integer version strings in `importorskip`. Thanks to Eric Hunsberger for the PR. diff --git a/_pytest/assertion/util.py b/_pytest/assertion/util.py index fb5f9be0e..6193b4a10 100644 --- a/_pytest/assertion/util.py +++ b/_pytest/assertion/util.py @@ -129,7 +129,14 @@ 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 reencoding is needed for python2 repr + # with non-ascii characters (see isssue 877) + summary = u('%s %s %s') % ( + u(left_repr, 'utf-8', 'replace'), + op, + u(right_repr, 'utf-8', 'replace'), + ) 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'