Fix UnicodeDecodeError in assertion with mixed non-ascii bytes repr + text
This commit is contained in:
parent
29dac03314
commit
7122fa5613
|
@ -0,0 +1 @@
|
||||||
|
Fix ``UnicodeDecodeError`` in python2.x when a class returns a non-ascii binary ``__repr__`` in an assertion which also contains non-ascii text.
|
|
@ -8,6 +8,7 @@ import marshal
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import six
|
import six
|
||||||
|
import string
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import types
|
import types
|
||||||
|
@ -466,10 +467,14 @@ def _saferepr(obj):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
r = py.io.saferepr(obj)
|
r = py.io.saferepr(obj)
|
||||||
if isinstance(r, six.text_type):
|
# only occurs in python2.x, repr must return text in python3+
|
||||||
return r.replace(u"\n", u"\\n")
|
if isinstance(r, bytes):
|
||||||
else:
|
# Represent unprintable bytes as `\x##`
|
||||||
return r.replace(b"\n", b"\\n")
|
r = u"".join(
|
||||||
|
u"\\x{:x}".format(ord(c)) if c not in string.printable else c.decode()
|
||||||
|
for c in r
|
||||||
|
)
|
||||||
|
return r.replace(u"\n", u"\\n")
|
||||||
|
|
||||||
|
|
||||||
from _pytest.assertion.util import format_explanation as _format_explanation # noqa
|
from _pytest.assertion.util import format_explanation as _format_explanation # noqa
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import absolute_import, division, print_function
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import glob
|
import glob
|
||||||
|
@ -57,7 +58,7 @@ def getmsg(f, extra_ns=None, must_pass=False):
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
if must_pass:
|
if must_pass:
|
||||||
pytest.fail("shouldn't have raised")
|
pytest.fail("shouldn't have raised")
|
||||||
s = str(sys.exc_info()[1])
|
s = six.text_type(sys.exc_info()[1])
|
||||||
if not s.startswith("assert"):
|
if not s.startswith("assert"):
|
||||||
return "AssertionError: " + s
|
return "AssertionError: " + s
|
||||||
return s
|
return s
|
||||||
|
@ -608,6 +609,21 @@ class TestAssertionRewrite(object):
|
||||||
|
|
||||||
assert r"where 1 = \n{ \n~ \n}.a" in util._format_lines([getmsg(f)])[0]
|
assert r"where 1 = \n{ \n~ \n}.a" in util._format_lines([getmsg(f)])[0]
|
||||||
|
|
||||||
|
def test_custom_repr_non_ascii(self):
|
||||||
|
def f():
|
||||||
|
class A(object):
|
||||||
|
name = u"ä"
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return self.name.encode("UTF-8") # only legal in python2
|
||||||
|
|
||||||
|
a = A()
|
||||||
|
assert not a.name
|
||||||
|
|
||||||
|
msg = getmsg(f)
|
||||||
|
assert "UnicodeDecodeError" not in msg
|
||||||
|
assert "UnicodeEncodeError" not in msg
|
||||||
|
|
||||||
|
|
||||||
class TestRewriteOnImport(object):
|
class TestRewriteOnImport(object):
|
||||||
def test_pycache_is_a_file(self, testdir):
|
def test_pycache_is_a_file(self, testdir):
|
||||||
|
|
Loading…
Reference in New Issue