File: compat.py

package info (click to toggle)
python-sure 2.0.1%2Bgit.2023.02.06.3aef950b7c-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 744 kB
  • sloc: python: 3,512; makefile: 255; sh: 12
file content (112 lines) | stat: -rw-r--r-- 3,319 bytes parent folder | download | duplicates (2)
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__