##// END OF EJS Templates
remove no-longer-accurate comment...
MinRK -
Show More
@@ -1,244 +1,241 b''
1 1 # coding: utf-8
2 2 """Compatibility tricks for Python 3. Mainly to do with unicode."""
3 3 import functools
4 4 import os
5 5 import sys
6 6 import re
7 7 import types
8 8
9 9 from .encoding import DEFAULT_ENCODING
10 10
11 11 orig_open = open
12 12
13 13 def no_code(x, encoding=None):
14 14 return x
15 15
16 16 def decode(s, encoding=None):
17 17 encoding = encoding or DEFAULT_ENCODING
18 18 return s.decode(encoding, "replace")
19 19
20 20 def encode(u, encoding=None):
21 21 encoding = encoding or DEFAULT_ENCODING
22 22 return u.encode(encoding, "replace")
23 23
24 24
25 25 def cast_unicode(s, encoding=None):
26 26 if isinstance(s, bytes):
27 27 return decode(s, encoding)
28 28 return s
29 29
30 30 def cast_bytes(s, encoding=None):
31 31 if not isinstance(s, bytes):
32 32 return encode(s, encoding)
33 33 return s
34 34
35 35 def _modify_str_or_docstring(str_change_func):
36 36 @functools.wraps(str_change_func)
37 37 def wrapper(func_or_str):
38 38 if isinstance(func_or_str, string_types):
39 39 func = None
40 40 doc = func_or_str
41 41 else:
42 42 func = func_or_str
43 43 doc = func.__doc__
44 44
45 45 doc = str_change_func(doc)
46 46
47 47 if func:
48 48 func.__doc__ = doc
49 49 return func
50 50 return doc
51 51 return wrapper
52 52
53 53 def safe_unicode(e):
54 54 """unicode(e) with various fallbacks. Used for exceptions, which may not be
55 55 safe to call unicode() on.
56 56 """
57 57 try:
58 58 return unicode_type(e)
59 59 except UnicodeError:
60 60 pass
61 61
62 62 try:
63 63 return str_to_unicode(str(e))
64 64 except UnicodeError:
65 65 pass
66 66
67 67 try:
68 68 return str_to_unicode(repr(e))
69 69 except UnicodeError:
70 70 pass
71 71
72 72 return u'Unrecoverably corrupt evalue'
73 73
74 74 if sys.version_info[0] >= 3:
75 75 PY3 = True
76 76
77 77 input = input
78 78 builtin_mod_name = "builtins"
79 79 import builtins as builtin_mod
80 80
81 81 str_to_unicode = no_code
82 82 unicode_to_str = no_code
83 83 str_to_bytes = encode
84 84 bytes_to_str = decode
85 85 cast_bytes_py2 = no_code
86 86 cast_unicode_py2 = no_code
87 87
88 88 string_types = (str,)
89 89 unicode_type = str
90 90
91 91 def isidentifier(s, dotted=False):
92 92 if dotted:
93 93 return all(isidentifier(a) for a in s.split("."))
94 94 return s.isidentifier()
95 95
96 96 open = orig_open
97 97 xrange = range
98 98 def iteritems(d): return iter(d.items())
99 99 def itervalues(d): return iter(d.values())
100 100 getcwd = os.getcwd
101 101
102 102 MethodType = types.MethodType
103 103
104 104 def execfile(fname, glob, loc=None):
105 105 loc = loc if (loc is not None) else glob
106 106 with open(fname, 'rb') as f:
107 107 exec(compile(f.read(), fname, 'exec'), glob, loc)
108 108
109 109 # Refactor print statements in doctests.
110 110 _print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE)
111 111 def _print_statement_sub(match):
112 112 expr = match.groups('expr')
113 113 return "print(%s)" % expr
114 114
115 115 @_modify_str_or_docstring
116 116 def doctest_refactor_print(doc):
117 117 """Refactor 'print x' statements in a doctest to print(x) style. 2to3
118 118 unfortunately doesn't pick up on our doctests.
119 119
120 120 Can accept a string or a function, so it can be used as a decorator."""
121 121 return _print_statement_re.sub(_print_statement_sub, doc)
122 122
123 123 # Abstract u'abc' syntax:
124 124 @_modify_str_or_docstring
125 125 def u_format(s):
126 126 """"{u}'abc'" --> "'abc'" (Python 3)
127 127
128 128 Accepts a string or a function, so it can be used as a decorator."""
129 129 return s.format(u='')
130 130
131 131 else:
132 132 PY3 = False
133 133
134 134 input = raw_input
135 135 builtin_mod_name = "__builtin__"
136 136 import __builtin__ as builtin_mod
137 137
138 138 str_to_unicode = decode
139 139 unicode_to_str = encode
140 140 str_to_bytes = no_code
141 141 bytes_to_str = no_code
142 142 cast_bytes_py2 = cast_bytes
143 143 cast_unicode_py2 = cast_unicode
144 144
145 145 string_types = (str, unicode)
146 146 unicode_type = unicode
147 147
148 148 import re
149 149 _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
150 150 def isidentifier(s, dotted=False):
151 151 if dotted:
152 152 return all(isidentifier(a) for a in s.split("."))
153 153 return bool(_name_re.match(s))
154 154
155 155 class open(object):
156 156 """Wrapper providing key part of Python 3 open() interface."""
157 157 def __init__(self, fname, mode="r", encoding="utf-8"):
158 158 self.f = orig_open(fname, mode)
159 159 self.enc = encoding
160 160
161 161 def write(self, s):
162 162 return self.f.write(s.encode(self.enc))
163 163
164 164 def read(self, size=-1):
165 165 return self.f.read(size).decode(self.enc)
166 166
167 167 def close(self):
168 168 return self.f.close()
169 169
170 170 def __enter__(self):
171 171 return self
172 172
173 173 def __exit__(self, etype, value, traceback):
174 174 self.f.close()
175 175
176 176 xrange = xrange
177 177 def iteritems(d): return d.iteritems()
178 178 def itervalues(d): return d.itervalues()
179 179 getcwd = os.getcwdu
180 180
181 181 def MethodType(func, instance):
182 182 return types.MethodType(func, instance, type(instance))
183 183
184 # don't override system execfile on 2.x:
185 execfile = execfile
186
187 184 def doctest_refactor_print(func_or_str):
188 185 return func_or_str
189 186
190 187
191 188 # Abstract u'abc' syntax:
192 189 @_modify_str_or_docstring
193 190 def u_format(s):
194 191 """"{u}'abc'" --> "u'abc'" (Python 2)
195 192
196 193 Accepts a string or a function, so it can be used as a decorator."""
197 194 return s.format(u='u')
198 195
199 196 if sys.platform == 'win32':
200 197 def execfile(fname, glob=None, loc=None):
201 198 loc = loc if (loc is not None) else glob
202 199 # The rstrip() is necessary b/c trailing whitespace in files will
203 200 # cause an IndentationError in Python 2.6 (this was fixed in 2.7,
204 201 # but we still support 2.6). See issue 1027.
205 202 scripttext = builtin_mod.open(fname).read().rstrip() + '\n'
206 203 # compile converts unicode filename to str assuming
207 204 # ascii. Let's do the conversion before calling compile
208 205 if isinstance(fname, unicode):
209 206 filename = unicode_to_str(fname)
210 207 else:
211 208 filename = fname
212 209 exec(compile(scripttext, filename, 'exec'), glob, loc)
213 210 else:
214 211 def execfile(fname, *where):
215 212 if isinstance(fname, unicode):
216 213 filename = fname.encode(sys.getfilesystemencoding())
217 214 else:
218 215 filename = fname
219 216 builtin_mod.execfile(filename, *where)
220 217
221 218 # Parts below taken from six:
222 219 # Copyright (c) 2010-2013 Benjamin Peterson
223 220 #
224 221 # Permission is hereby granted, free of charge, to any person obtaining a copy
225 222 # of this software and associated documentation files (the "Software"), to deal
226 223 # in the Software without restriction, including without limitation the rights
227 224 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
228 225 # copies of the Software, and to permit persons to whom the Software is
229 226 # furnished to do so, subject to the following conditions:
230 227 #
231 228 # The above copyright notice and this permission notice shall be included in all
232 229 # copies or substantial portions of the Software.
233 230 #
234 231 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
235 232 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
236 233 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
237 234 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
238 235 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
239 236 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
240 237 # SOFTWARE.
241 238
242 239 def with_metaclass(meta, *bases):
243 240 """Create a base class with a metaclass."""
244 241 return meta("_NewBase", bases, {})
General Comments 0
You need to be logged in to leave comments. Login now