1#!/usr/local/bin/python3.8
2# vim:fileencoding=utf-8
3# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
4
5import os
6import sys
7
8is_py3 = sys.version_info.major >= 3
9native_string_type = str
10iterkeys = iter
11
12
13def hasenv(x):
14    return getenv(x) is not None
15
16
17def as_bytes(x, encoding='utf-8'):
18    if isinstance(x, unicode_type):
19        return x.encode(encoding)
20    if isinstance(x, bytes):
21        return x
22    if isinstance(x, bytearray):
23        return bytes(x)
24    if isinstance(x, memoryview):
25        return x.tobytes()
26    ans = unicode_type(x)
27    if isinstance(ans, unicode_type):
28        ans = ans.encode(encoding)
29    return ans
30
31
32def as_unicode(x, encoding='utf-8', errors='strict'):
33    if isinstance(x, bytes):
34        return x.decode(encoding, errors)
35    return unicode_type(x)
36
37
38def only_unicode_recursive(x, encoding='utf-8', errors='strict'):
39    # Convert any bytestrings in sets/lists/tuples/dicts to unicode
40    if isinstance(x, bytes):
41        return x.decode(encoding, errors)
42    if isinstance(x, unicode_type):
43        return x
44    if isinstance(x, (set, list, tuple, frozenset)):
45        return type(x)(only_unicode_recursive(i, encoding, errors) for i in x)
46    if isinstance(x, dict):
47        return {
48            only_unicode_recursive(k, encoding, errors):
49            only_unicode_recursive(v, encoding, errors)
50            for k, v in iteritems(x)
51        }
52    return x
53
54
55def reraise(tp, value, tb=None):
56    try:
57        if value is None:
58            value = tp()
59        if value.__traceback__ is not tb:
60            raise value.with_traceback(tb)
61        raise value
62    finally:
63        value = None
64        tb = None
65
66
67import builtins
68
69zip = builtins.zip
70map = builtins.map
71filter = builtins.filter
72range = builtins.range
73
74codepoint_to_chr = chr
75unicode_type = str
76string_or_bytes = str, bytes
77string_or_unicode = str
78long_type = int
79raw_input = input
80getcwd = os.getcwd
81getenv = os.getenv
82
83
84def error_message(exc):
85    args = getattr(exc, 'args', None)
86    if args and isinstance(args[0], unicode_type):
87        return args[0]
88    return unicode_type(exc)
89
90
91def iteritems(d):
92    return iter(d.items())
93
94
95def itervalues(d):
96    return iter(d.values())
97
98
99def environ_item(x):
100    if isinstance(x, bytes):
101        x = x.decode('utf-8')
102    return x
103
104
105def exec_path(path, ctx=None):
106    ctx = ctx or {}
107    with open(path, 'rb') as f:
108        code = f.read()
109    code = compile(code, f.name, 'exec')
110    exec(code, ctx)
111
112
113def cmp(a, b):
114    return (a > b) - (a < b)
115
116
117def int_to_byte(x):
118    return bytes((x, ))
119
120
121def reload(module):
122    import importlib
123    return importlib.reload(module)
124
125
126def print_to_binary_file(fileobj, encoding='utf-8'):
127
128    def print(*a, **kw):
129        f = kw.get('file', fileobj)
130        if a:
131            sep = as_bytes(kw.get('sep', ' '), encoding)
132            for x in a:
133                x = as_bytes(x, encoding)
134                f.write(x)
135                if x is not a[-1]:
136                    f.write(sep)
137        f.write(as_bytes(kw.get('end', '\n')))
138
139    return print
140