aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/future/past/builtins/misc.py
blob: 3600695c0aa3f90388311b5e64c49ac6c5451710 (plain) (blame)
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
from __future__ import unicode_literals

import inspect
import math
import numbers

from future.utils import PY2, PY3, exec_

if PY2:
    from collections import Mapping
else:
    from collections.abc import Mapping

if PY3:
    import builtins
    from collections.abc import Mapping

    def apply(f, *args, **kw):
        return f(*args, **kw)

    from past.builtins import str as oldstr

    def chr(i):
        """
        Return a byte-string of one character with ordinal i; 0 <= i <= 256
        """
        return oldstr(bytes((i,)))

    def cmp(x, y):
        """
        cmp(x, y) -> integer

        Return negative if x<y, zero if x==y, positive if x>y.
        Python2 had looser comparison allowing cmp None and non Numerical types and collections.
        Try to match the old behavior
        """
        if isinstance(x, set) and isinstance(y, set):
            raise TypeError('cannot compare sets using cmp()',)
        try:
            if isinstance(x, numbers.Number) and math.isnan(x):
                if not isinstance(y, numbers.Number):
                    raise TypeError('cannot compare float("nan"), {type_y} with cmp'.format(type_y=type(y)))
                if isinstance(y, int):
                    return 1
                else:
                    return -1
            if isinstance(y, numbers.Number) and math.isnan(y):
                if not isinstance(x, numbers.Number):
                    raise TypeError('cannot compare {type_x}, float("nan") with cmp'.format(type_x=type(x)))
                if isinstance(x, int):
                    return -1
                else:
                    return 1
            return (x > y) - (x < y)
        except TypeError:
            if x == y:
                return 0
            type_order = [
                type(None),
                numbers.Number,
                dict, list,
                set,
                (str, bytes),
            ]
            x_type_index = y_type_index = None
            for i, type_match in enumerate(type_order):
                if isinstance(x, type_match):
                    x_type_index = i
                if isinstance(y, type_match):
                    y_type_index = i
            if cmp(x_type_index, y_type_index) == 0:
                if isinstance(x, bytes) and isinstance(y, str):
                    return cmp(x.decode('ascii'), y)
                if isinstance(y, bytes) and isinstance(x, str):
                    return cmp(x, y.decode('ascii'))
                elif isinstance(x, list):
                    # if both arguments are lists take the comparison of the first non equal value
                    for x_elem, y_elem in zip(x, y):
                        elem_cmp_val = cmp(x_elem, y_elem)
                        if elem_cmp_val != 0:
                            return elem_cmp_val
                    # if all elements are equal, return equal/0
                    return 0
                elif isinstance(x, dict):
                    if len(x) != len(y):
                        return cmp(len(x), len(y))
                    else:
                        x_key = min(a for a in x if a not in y or x[a] != y[a])
                        y_key = min(b for b in y if b not in x or x[b] != y[b])
                        if x_key != y_key:
                            return cmp(x_key, y_key)
                        else:
                            return cmp(x[x_key], y[y_key])
            return cmp(x_type_index, y_type_index)

    from sys import intern

    def oct(number):
        """oct(number) -> string

        Return the octal representation of an integer
        """
        return '0' + builtins.oct(number)[2:]

    raw_input = input

    try:
        from importlib import reload
    except ImportError:
        # for python2, python3 <= 3.4
        from imp import reload

    unicode = str
    unichr = chr
    xrange = range
else:
    import __builtin__
    from collections import Mapping
    apply = __builtin__.apply
    chr = __builtin__.chr
    cmp = __builtin__.cmp
    execfile = __builtin__.execfile
    intern = __builtin__.intern
    oct = __builtin__.oct
    raw_input = __builtin__.raw_input
    reload = __builtin__.reload
    unicode = __builtin__.unicode
    unichr = __builtin__.unichr
    xrange = __builtin__.xrange


if PY3:
    def execfile(filename, myglobals=None, mylocals=None):
        """
        Read and execute a Python script from a file in the given namespaces.
        The globals and locals are dictionaries, defaulting to the current
        globals and locals. If only globals is given, locals defaults to it.
        """
        if myglobals is None:
            # There seems to be no alternative to frame hacking here.
            caller_frame = inspect.stack()[1]
            myglobals = caller_frame[0].f_globals
            mylocals = caller_frame[0].f_locals
        elif mylocals is None:
            # Only if myglobals is given do we set mylocals to it.
            mylocals = myglobals
        if not isinstance(myglobals, Mapping):
            raise TypeError('globals must be a mapping')
        if not isinstance(mylocals, Mapping):
            raise TypeError('locals must be a mapping')
        with open(filename, "rb") as fin:
            source = fin.read()
        code = compile(source, filename, "exec")
        exec_(code, myglobals, mylocals)


if PY3:
    __all__ = ['apply', 'chr', 'cmp', 'execfile', 'intern', 'raw_input',
               'reload', 'unichr', 'unicode', 'xrange']
else:
    __all__ = []