File: compat.py

package info (click to toggle)
pysdl2 0.9.17%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,328 kB
  • sloc: python: 24,685; makefile: 36; sh: 8
file content (176 lines) | stat: -rw-r--r-- 5,001 bytes parent folder | download
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import sys
import warnings
try:
	from collections.abc import Callable, Iterable
except ImportError:
	from collections import Callable, Iterable

__all__ = ["ISPYTHON2", "ISPYTHON3", "utf8", "stringify", "byteify",
           "isiterable", "platform_is_64bit", "deprecated", "deprecation",
           "UnsupportedError", "ExperimentalWarning", "experimental",
           ]

ISPYTHON2 = False
ISPYTHON3 = False

if sys.version_info[0] < 3:
    ISPYTHON2 = True
else:
    __all__ += ["long", "unichr", "callable", "unicode"]
    ISPYTHON3 = True
    long = int
    unichr = chr
    callable = lambda x: isinstance(x, Callable)
    unicode = str


def _to_unicode(x, enc):
    if ISPYTHON2:
        if type(x) in (str, bytes):
            return x.decode(enc)
        else:
            return unicode(x)
    else:
        if type(x) == bytes:
            return x.decode(enc)
        else:
            return str(x)


def _is_text(x):
    return isinstance(x, (str, bytes, unicode))


def utf8(x):
    """Converts input to a unicode string in a Python 2/3 agnostic manner.

    If a :obj:`bytes` object is passed, it will be decoded as UTF-8. This
    function returns :obj:`unicode` for Python 2 and :obj:`str` for Python 3.

    Args:
        x: Input to convert to a unicode string.

    Returns:
        :obj:`str` on Python 3.x, or :obj:`unicode` on Python 2.7.

    """
    return _to_unicode(x, 'utf-8')


def stringify(x, enc='utf-8'):
    """Converts input to a :obj:`str` in a Python 2/3 agnostic manner.

    If the input is :obj:`unicode` and the Python version is 2.7, the ``enc``
    parameter indicates the encoding to use when converting the input to
    a non-unicode string. If the input is :obj:`bytes` and the Python version
    is 3.x, the ``enc`` parameter indicates the encoding to use to decode the
    input into a unicode string.
    
    Args:
        x: Input to convert to a :obj:`str`.
        enc (str, optional): The encoding type used to encode or decode the
            input, depending on the input type and the major Python version.
            Defaults to UTF-8.

    """
    if ISPYTHON2:
        if type(x) == unicode:
            return x.encode(enc)
        else:
            return str(x)
    else:
        return _to_unicode(x, enc)


def byteify(x, enc='utf-8'):
    """Converts input to :obj:`bytes` in a Python 2/3 agnostic manner.

    If the input is a unicode string, the ``enc`` parameter indicates
    the encoding to use when encoding the input to :obj:`bytes`.
    
    Args:
        x: Input to convert to :obj:`bytes`.
        enc (str, optional): The encoding type used to encode any unicode
            string input. Defaults to UTF-8.

    """
    unicode_str = unicode if ISPYTHON2 else str
    if type(x) == unicode_str:
        return x.encode(enc)
    else:
        return bytes(x)


def isiterable(x):
    """Checks whether the input is a non-string iterable.

    Args:
        x: The object to check for iterability.

    Returns:
        bool: True if the input is a valid iterable, otherwise False.

    """
    return hasattr(x, "__iter__") and not hasattr(x, "upper")


def platform_is_64bit():
    """Checks whether the Python interpreter is 64-bit.
    
    Returns:
        bool: True if running on 64-bit Python, otherwise False.

    """
    return sys.maxsize > 2 ** 32


def deprecated(func):
    # A simple decorator to mark functions and methods as deprecated
    def wrapper(*fargs, **kw):
        warnings.warn("%s is deprecated." % func.__name__,
                      category=DeprecationWarning, stacklevel=2)
        return func(*fargs, **kw)
    wrapper.__name__ = func.__name__
    wrapper.__doc__ = func.__doc__
    wrapper.__dict__.update(func.__dict__)
    return wrapper


def deprecation(message):
    # Prints a deprecation message
    warnings.warn(message, category=DeprecationWarning, stacklevel=2)


class UnsupportedError(RuntimeError):
    # Indicates that a certain class, function or behaviour is not supported
    pass


class ExperimentalWarning(Warning):
    # Indicates that a certain class, function or behaviour is experimental
    def __init__(self, obj, msg=None):
        """Creates a ExperimentalWarning for the specified obj.

        If a message is passed in msg, it will be printed instead of the
        default message.
        """
        super(ExperimentalWarning, self).__init__()
        self.obj = obj
        self.msg = msg

    def __str__(self):
        if self.msg is None:
            return "%s is in an experimental state." % repr(self.obj)
        return repr(self.msg)


def experimental(func):
    # A simple decorator to mark functions and methods as experimental
    def wrapper(*fargs, **kw):
        warnings.warn("%s" % func.__name__, category=ExperimentalWarning,
                      stacklevel=2)
        return func(*fargs, **kw)
    wrapper.__name__ = func.__name__
    wrapper.__doc__ = func.__doc__
    wrapper.__dict__.update(func.__dict__)
    return wrapper