diff --git a/_pytest/compat.py b/_pytest/compat.py index edb68c075..e93cf6c2a 100644 --- a/_pytest/compat.py +++ b/_pytest/compat.py @@ -7,6 +7,7 @@ import inspect import types import re import functools +import codecs import py @@ -126,6 +127,19 @@ if _PY3: STRING_TYPES = bytes, str UNICODE_TYPES = str, + if PY35: + def _bytes_to_ascii(val): + return val.decode('ascii', 'backslashreplace') + else: + def _bytes_to_ascii(val): + if val: + # source: http://goo.gl/bGsnwC + encoded_bytes, _ = codecs.escape_encode(val) + return encoded_bytes.decode('ascii') + else: + # empty bytes crashes codecs.escape_encode (#1087) + return '' + def _ascii_escaped(val): """If val is pure ascii, returns it as a str(). Otherwise, escapes bytes objects into a sequence of escaped bytes: @@ -145,7 +159,7 @@ if _PY3: """ if isinstance(val, bytes): - return val.decode('ascii', 'backslashreplace') + return _bytes_to_ascii(val) else: return val.encode('unicode_escape').decode('ascii') else: