1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import six
from collections import OrderedDict
try:
from collections.abc import Iterable
except ImportError:
from collections import Iterable
from sure.terminal import red, green, yellow
if six.PY2:
def compat_repr(object_repr):
# compat_repr is designed to return all reprs with leading 'u's
# inserted to make all strings look like unicode strings.
# This makes testing between py2 and py3 much easier.
result = ''
in_quote = False
curr_quote = None
for char in object_repr:
if char in ['"', "'"] and (
not curr_quote or char == curr_quote):
if in_quote:
# Closing quote
curr_quote = None
in_quote = False
else:
# Opening quote
curr_quote = char
result += 'u'
in_quote = True
result += char
return result
else:
def compat_repr(object_repr):
return object_repr
# FIXME: move FakeOrderedDict to another module since it
# does not have anything todo with compat.
# The safe_repr function should already get a
# FakeOrderedDict instance. Maybe the _obj_with_safe_repr
# function should be part of the FakeOrderedDict
# classes __repr__ method.
class FakeOrderedDict(OrderedDict):
""" OrderedDict that has the repr of a normal dict
We must return a string whether in py2 or py3.
"""
def __unicode__(self):
if not self:
return '{}'
key_values = []
for key, value in self.items():
key, value = repr(key), repr(value)
if isinstance(value, six.binary_type) and six.PY2:
value = value.decode("utf-8")
key_values.append("{0}: {1}".format(key, value))
res = "{{{0}}}".format(", ".join(key_values))
return res
if six.PY2:
def __repr__(self):
return self.__unicode__().encode('utf-8')
else:
def __repr__(self):
return self.__unicode__()
def _obj_with_safe_repr(obj):
if isinstance(obj, dict):
ret = FakeOrderedDict()
try:
keys = sorted(obj.keys())
except TypeError: # happens for obj types which are not orderable, like ``Enum``
keys = obj.keys()
for key in keys:
ret[_obj_with_safe_repr(key)] = _obj_with_safe_repr(obj[key])
elif isinstance(obj, list):
ret = []
for x in obj:
if isinstance(x, dict):
ret.append(_obj_with_safe_repr(x))
else:
ret.append(x)
else:
ret = obj
return ret
def safe_repr(val):
try:
if isinstance(val, dict):
# We special case dicts to have a sorted repr. This makes testing
# significantly easier
val = _obj_with_safe_repr(val)
ret = repr(val)
if six.PY2:
ret = ret.decode('utf-8')
except UnicodeEncodeError:
ret = red('a %r that cannot be represented' % type(val))
else:
ret = green(ret)
return ret
text_type_name = six.text_type().__class__.__name__
|