##// END OF EJS Templates
pycompat: remove first not ispy3 block...
Gregory Szorc -
r49724:57b58413 default
parent child Browse files
Show More
@@ -1,540 +1,527 b''
1 # pycompat.py - portability shim for python 3
1 # pycompat.py - portability shim for python 3
2 #
2 #
3 # This software may be used and distributed according to the terms of the
3 # This software may be used and distributed according to the terms of the
4 # GNU General Public License version 2 or any later version.
4 # GNU General Public License version 2 or any later version.
5
5
6 """Mercurial portability shim for python 3.
6 """Mercurial portability shim for python 3.
7
7
8 This contains aliases to hide python version-specific details from the core.
8 This contains aliases to hide python version-specific details from the core.
9 """
9 """
10
10
11 from __future__ import absolute_import
11 from __future__ import absolute_import
12
12
13 import builtins
14 import concurrent.futures as futures
13 import getopt
15 import getopt
16 import http.client as httplib
17 import http.cookiejar as cookielib
14 import inspect
18 import inspect
15 import json
19 import json
16 import os
20 import os
21 import pickle
22 import queue
17 import shlex
23 import shlex
24 import socketserver
18 import sys
25 import sys
19 import tempfile
26 import tempfile
27 import xmlrpc.client as xmlrpclib
20
28
21 ispy3 = sys.version_info[0] >= 3
29 ispy3 = sys.version_info[0] >= 3
22 ispypy = '__pypy__' in sys.builtin_module_names
30 ispypy = '__pypy__' in sys.builtin_module_names
23 TYPE_CHECKING = False
31 TYPE_CHECKING = False
24
32
25 if not globals(): # hide this from non-pytype users
33 if not globals(): # hide this from non-pytype users
26 import typing
34 import typing
27
35
28 TYPE_CHECKING = typing.TYPE_CHECKING
36 TYPE_CHECKING = typing.TYPE_CHECKING
29
37
30 if not ispy3:
31 import cookielib
32 import cPickle as pickle
33 import httplib
34 import Queue as queue
35 import SocketServer as socketserver
36 import xmlrpclib
37
38 def future_set_exception_info(f, exc_info):
39 f.set_exception_info(*exc_info)
40
41 # this is close enough for our usage
42 FileNotFoundError = OSError
43
38
44 else:
39 def future_set_exception_info(f, exc_info):
45 import builtins
40 f.set_exception(exc_info[0])
46 import http.cookiejar as cookielib
47 import http.client as httplib
48 import pickle
49 import queue as queue
50 import socketserver
51 import xmlrpc.client as xmlrpclib
52
41
53 def future_set_exception_info(f, exc_info):
54 f.set_exception(exc_info[0])
55
42
56 FileNotFoundError = builtins.FileNotFoundError
43 FileNotFoundError = builtins.FileNotFoundError
57
44
58
45
59 def identity(a):
46 def identity(a):
60 return a
47 return a
61
48
62
49
63 def _rapply(f, xs):
50 def _rapply(f, xs):
64 if xs is None:
51 if xs is None:
65 # assume None means non-value of optional data
52 # assume None means non-value of optional data
66 return xs
53 return xs
67 if isinstance(xs, (list, set, tuple)):
54 if isinstance(xs, (list, set, tuple)):
68 return type(xs)(_rapply(f, x) for x in xs)
55 return type(xs)(_rapply(f, x) for x in xs)
69 if isinstance(xs, dict):
56 if isinstance(xs, dict):
70 return type(xs)((_rapply(f, k), _rapply(f, v)) for k, v in xs.items())
57 return type(xs)((_rapply(f, k), _rapply(f, v)) for k, v in xs.items())
71 return f(xs)
58 return f(xs)
72
59
73
60
74 def rapply(f, xs):
61 def rapply(f, xs):
75 """Apply function recursively to every item preserving the data structure
62 """Apply function recursively to every item preserving the data structure
76
63
77 >>> def f(x):
64 >>> def f(x):
78 ... return 'f(%s)' % x
65 ... return 'f(%s)' % x
79 >>> rapply(f, None) is None
66 >>> rapply(f, None) is None
80 True
67 True
81 >>> rapply(f, 'a')
68 >>> rapply(f, 'a')
82 'f(a)'
69 'f(a)'
83 >>> rapply(f, {'a'}) == {'f(a)'}
70 >>> rapply(f, {'a'}) == {'f(a)'}
84 True
71 True
85 >>> rapply(f, ['a', 'b', None, {'c': 'd'}, []])
72 >>> rapply(f, ['a', 'b', None, {'c': 'd'}, []])
86 ['f(a)', 'f(b)', None, {'f(c)': 'f(d)'}, []]
73 ['f(a)', 'f(b)', None, {'f(c)': 'f(d)'}, []]
87
74
88 >>> xs = [object()]
75 >>> xs = [object()]
89 >>> rapply(identity, xs) is xs
76 >>> rapply(identity, xs) is xs
90 True
77 True
91 """
78 """
92 if f is identity:
79 if f is identity:
93 # fast path mainly for py2
80 # fast path mainly for py2
94 return xs
81 return xs
95 return _rapply(f, xs)
82 return _rapply(f, xs)
96
83
97
84
98 if ispy3:
85 if ispy3:
99 import builtins
86 import builtins
100 import codecs
87 import codecs
101 import functools
88 import functools
102 import io
89 import io
103 import struct
90 import struct
104
91
105 if os.name == r'nt' and sys.version_info >= (3, 6):
92 if os.name == r'nt' and sys.version_info >= (3, 6):
106 # MBCS (or ANSI) filesystem encoding must be used as before.
93 # MBCS (or ANSI) filesystem encoding must be used as before.
107 # Otherwise non-ASCII filenames in existing repositories would be
94 # Otherwise non-ASCII filenames in existing repositories would be
108 # corrupted.
95 # corrupted.
109 # This must be set once prior to any fsencode/fsdecode calls.
96 # This must be set once prior to any fsencode/fsdecode calls.
110 sys._enablelegacywindowsfsencoding() # pytype: disable=module-attr
97 sys._enablelegacywindowsfsencoding() # pytype: disable=module-attr
111
98
112 fsencode = os.fsencode
99 fsencode = os.fsencode
113 fsdecode = os.fsdecode
100 fsdecode = os.fsdecode
114 oscurdir = os.curdir.encode('ascii')
101 oscurdir = os.curdir.encode('ascii')
115 oslinesep = os.linesep.encode('ascii')
102 oslinesep = os.linesep.encode('ascii')
116 osname = os.name.encode('ascii')
103 osname = os.name.encode('ascii')
117 ospathsep = os.pathsep.encode('ascii')
104 ospathsep = os.pathsep.encode('ascii')
118 ospardir = os.pardir.encode('ascii')
105 ospardir = os.pardir.encode('ascii')
119 ossep = os.sep.encode('ascii')
106 ossep = os.sep.encode('ascii')
120 osaltsep = os.altsep
107 osaltsep = os.altsep
121 if osaltsep:
108 if osaltsep:
122 osaltsep = osaltsep.encode('ascii')
109 osaltsep = osaltsep.encode('ascii')
123 osdevnull = os.devnull.encode('ascii')
110 osdevnull = os.devnull.encode('ascii')
124
111
125 sysplatform = sys.platform.encode('ascii')
112 sysplatform = sys.platform.encode('ascii')
126 sysexecutable = sys.executable
113 sysexecutable = sys.executable
127 if sysexecutable:
114 if sysexecutable:
128 sysexecutable = os.fsencode(sysexecutable)
115 sysexecutable = os.fsencode(sysexecutable)
129 bytesio = io.BytesIO
116 bytesio = io.BytesIO
130 # TODO deprecate stringio name, as it is a lie on Python 3.
117 # TODO deprecate stringio name, as it is a lie on Python 3.
131 stringio = bytesio
118 stringio = bytesio
132
119
133 def maplist(*args):
120 def maplist(*args):
134 return list(map(*args))
121 return list(map(*args))
135
122
136 def rangelist(*args):
123 def rangelist(*args):
137 return list(range(*args))
124 return list(range(*args))
138
125
139 def ziplist(*args):
126 def ziplist(*args):
140 return list(zip(*args))
127 return list(zip(*args))
141
128
142 rawinput = input
129 rawinput = input
143 getargspec = inspect.getfullargspec
130 getargspec = inspect.getfullargspec
144
131
145 long = int
132 long = int
146
133
147 if getattr(sys, 'argv', None) is not None:
134 if getattr(sys, 'argv', None) is not None:
148 # On POSIX, the char** argv array is converted to Python str using
135 # On POSIX, the char** argv array is converted to Python str using
149 # Py_DecodeLocale(). The inverse of this is Py_EncodeLocale(), which
136 # Py_DecodeLocale(). The inverse of this is Py_EncodeLocale(), which
150 # isn't directly callable from Python code. In practice, os.fsencode()
137 # isn't directly callable from Python code. In practice, os.fsencode()
151 # can be used instead (this is recommended by Python's documentation
138 # can be used instead (this is recommended by Python's documentation
152 # for sys.argv).
139 # for sys.argv).
153 #
140 #
154 # On Windows, the wchar_t **argv is passed into the interpreter as-is.
141 # On Windows, the wchar_t **argv is passed into the interpreter as-is.
155 # Like POSIX, we need to emulate what Py_EncodeLocale() would do. But
142 # Like POSIX, we need to emulate what Py_EncodeLocale() would do. But
156 # there's an additional wrinkle. What we really want to access is the
143 # there's an additional wrinkle. What we really want to access is the
157 # ANSI codepage representation of the arguments, as this is what
144 # ANSI codepage representation of the arguments, as this is what
158 # `int main()` would receive if Python 3 didn't define `int wmain()`
145 # `int main()` would receive if Python 3 didn't define `int wmain()`
159 # (this is how Python 2 worked). To get that, we encode with the mbcs
146 # (this is how Python 2 worked). To get that, we encode with the mbcs
160 # encoding, which will pass CP_ACP to the underlying Windows API to
147 # encoding, which will pass CP_ACP to the underlying Windows API to
161 # produce bytes.
148 # produce bytes.
162 if os.name == r'nt':
149 if os.name == r'nt':
163 sysargv = [a.encode("mbcs", "ignore") for a in sys.argv]
150 sysargv = [a.encode("mbcs", "ignore") for a in sys.argv]
164 else:
151 else:
165 sysargv = [fsencode(a) for a in sys.argv]
152 sysargv = [fsencode(a) for a in sys.argv]
166
153
167 bytechr = struct.Struct('>B').pack
154 bytechr = struct.Struct('>B').pack
168 byterepr = b'%r'.__mod__
155 byterepr = b'%r'.__mod__
169
156
170 class bytestr(bytes):
157 class bytestr(bytes):
171 """A bytes which mostly acts as a Python 2 str
158 """A bytes which mostly acts as a Python 2 str
172
159
173 >>> bytestr(), bytestr(bytearray(b'foo')), bytestr(u'ascii'), bytestr(1)
160 >>> bytestr(), bytestr(bytearray(b'foo')), bytestr(u'ascii'), bytestr(1)
174 ('', 'foo', 'ascii', '1')
161 ('', 'foo', 'ascii', '1')
175 >>> s = bytestr(b'foo')
162 >>> s = bytestr(b'foo')
176 >>> assert s is bytestr(s)
163 >>> assert s is bytestr(s)
177
164
178 __bytes__() should be called if provided:
165 __bytes__() should be called if provided:
179
166
180 >>> class bytesable(object):
167 >>> class bytesable(object):
181 ... def __bytes__(self):
168 ... def __bytes__(self):
182 ... return b'bytes'
169 ... return b'bytes'
183 >>> bytestr(bytesable())
170 >>> bytestr(bytesable())
184 'bytes'
171 'bytes'
185
172
186 There's no implicit conversion from non-ascii str as its encoding is
173 There's no implicit conversion from non-ascii str as its encoding is
187 unknown:
174 unknown:
188
175
189 >>> bytestr(chr(0x80)) # doctest: +ELLIPSIS
176 >>> bytestr(chr(0x80)) # doctest: +ELLIPSIS
190 Traceback (most recent call last):
177 Traceback (most recent call last):
191 ...
178 ...
192 UnicodeEncodeError: ...
179 UnicodeEncodeError: ...
193
180
194 Comparison between bytestr and bytes should work:
181 Comparison between bytestr and bytes should work:
195
182
196 >>> assert bytestr(b'foo') == b'foo'
183 >>> assert bytestr(b'foo') == b'foo'
197 >>> assert b'foo' == bytestr(b'foo')
184 >>> assert b'foo' == bytestr(b'foo')
198 >>> assert b'f' in bytestr(b'foo')
185 >>> assert b'f' in bytestr(b'foo')
199 >>> assert bytestr(b'f') in b'foo'
186 >>> assert bytestr(b'f') in b'foo'
200
187
201 Sliced elements should be bytes, not integer:
188 Sliced elements should be bytes, not integer:
202
189
203 >>> s[1], s[:2]
190 >>> s[1], s[:2]
204 (b'o', b'fo')
191 (b'o', b'fo')
205 >>> list(s), list(reversed(s))
192 >>> list(s), list(reversed(s))
206 ([b'f', b'o', b'o'], [b'o', b'o', b'f'])
193 ([b'f', b'o', b'o'], [b'o', b'o', b'f'])
207
194
208 As bytestr type isn't propagated across operations, you need to cast
195 As bytestr type isn't propagated across operations, you need to cast
209 bytes to bytestr explicitly:
196 bytes to bytestr explicitly:
210
197
211 >>> s = bytestr(b'foo').upper()
198 >>> s = bytestr(b'foo').upper()
212 >>> t = bytestr(s)
199 >>> t = bytestr(s)
213 >>> s[0], t[0]
200 >>> s[0], t[0]
214 (70, b'F')
201 (70, b'F')
215
202
216 Be careful to not pass a bytestr object to a function which expects
203 Be careful to not pass a bytestr object to a function which expects
217 bytearray-like behavior.
204 bytearray-like behavior.
218
205
219 >>> t = bytes(t) # cast to bytes
206 >>> t = bytes(t) # cast to bytes
220 >>> assert type(t) is bytes
207 >>> assert type(t) is bytes
221 """
208 """
222
209
223 # Trick pytype into not demanding Iterable[int] be passed to __new__(),
210 # Trick pytype into not demanding Iterable[int] be passed to __new__(),
224 # since the appropriate bytes format is done internally.
211 # since the appropriate bytes format is done internally.
225 #
212 #
226 # https://github.com/google/pytype/issues/500
213 # https://github.com/google/pytype/issues/500
227 if TYPE_CHECKING:
214 if TYPE_CHECKING:
228
215
229 def __init__(self, s=b''):
216 def __init__(self, s=b''):
230 pass
217 pass
231
218
232 def __new__(cls, s=b''):
219 def __new__(cls, s=b''):
233 if isinstance(s, bytestr):
220 if isinstance(s, bytestr):
234 return s
221 return s
235 if not isinstance(
222 if not isinstance(
236 s, (bytes, bytearray)
223 s, (bytes, bytearray)
237 ) and not hasattr( # hasattr-py3-only
224 ) and not hasattr( # hasattr-py3-only
238 s, u'__bytes__'
225 s, u'__bytes__'
239 ):
226 ):
240 s = str(s).encode('ascii')
227 s = str(s).encode('ascii')
241 return bytes.__new__(cls, s)
228 return bytes.__new__(cls, s)
242
229
243 def __getitem__(self, key):
230 def __getitem__(self, key):
244 s = bytes.__getitem__(self, key)
231 s = bytes.__getitem__(self, key)
245 if not isinstance(s, bytes):
232 if not isinstance(s, bytes):
246 s = bytechr(s)
233 s = bytechr(s)
247 return s
234 return s
248
235
249 def __iter__(self):
236 def __iter__(self):
250 return iterbytestr(bytes.__iter__(self))
237 return iterbytestr(bytes.__iter__(self))
251
238
252 def __repr__(self):
239 def __repr__(self):
253 return bytes.__repr__(self)[1:] # drop b''
240 return bytes.__repr__(self)[1:] # drop b''
254
241
255 def iterbytestr(s):
242 def iterbytestr(s):
256 """Iterate bytes as if it were a str object of Python 2"""
243 """Iterate bytes as if it were a str object of Python 2"""
257 return map(bytechr, s)
244 return map(bytechr, s)
258
245
259 def maybebytestr(s):
246 def maybebytestr(s):
260 """Promote bytes to bytestr"""
247 """Promote bytes to bytestr"""
261 if isinstance(s, bytes):
248 if isinstance(s, bytes):
262 return bytestr(s)
249 return bytestr(s)
263 return s
250 return s
264
251
265 def sysbytes(s):
252 def sysbytes(s):
266 """Convert an internal str (e.g. keyword, __doc__) back to bytes
253 """Convert an internal str (e.g. keyword, __doc__) back to bytes
267
254
268 This never raises UnicodeEncodeError, but only ASCII characters
255 This never raises UnicodeEncodeError, but only ASCII characters
269 can be round-trip by sysstr(sysbytes(s)).
256 can be round-trip by sysstr(sysbytes(s)).
270 """
257 """
271 if isinstance(s, bytes):
258 if isinstance(s, bytes):
272 return s
259 return s
273 return s.encode('utf-8')
260 return s.encode('utf-8')
274
261
275 def sysstr(s):
262 def sysstr(s):
276 """Return a keyword str to be passed to Python functions such as
263 """Return a keyword str to be passed to Python functions such as
277 getattr() and str.encode()
264 getattr() and str.encode()
278
265
279 This never raises UnicodeDecodeError. Non-ascii characters are
266 This never raises UnicodeDecodeError. Non-ascii characters are
280 considered invalid and mapped to arbitrary but unique code points
267 considered invalid and mapped to arbitrary but unique code points
281 such that 'sysstr(a) != sysstr(b)' for all 'a != b'.
268 such that 'sysstr(a) != sysstr(b)' for all 'a != b'.
282 """
269 """
283 if isinstance(s, builtins.str):
270 if isinstance(s, builtins.str):
284 return s
271 return s
285 return s.decode('latin-1')
272 return s.decode('latin-1')
286
273
287 def strurl(url):
274 def strurl(url):
288 """Converts a bytes url back to str"""
275 """Converts a bytes url back to str"""
289 if isinstance(url, bytes):
276 if isinstance(url, bytes):
290 return url.decode('ascii')
277 return url.decode('ascii')
291 return url
278 return url
292
279
293 def bytesurl(url):
280 def bytesurl(url):
294 """Converts a str url to bytes by encoding in ascii"""
281 """Converts a str url to bytes by encoding in ascii"""
295 if isinstance(url, str):
282 if isinstance(url, str):
296 return url.encode('ascii')
283 return url.encode('ascii')
297 return url
284 return url
298
285
299 def raisewithtb(exc, tb):
286 def raisewithtb(exc, tb):
300 """Raise exception with the given traceback"""
287 """Raise exception with the given traceback"""
301 raise exc.with_traceback(tb)
288 raise exc.with_traceback(tb)
302
289
303 def getdoc(obj):
290 def getdoc(obj):
304 """Get docstring as bytes; may be None so gettext() won't confuse it
291 """Get docstring as bytes; may be None so gettext() won't confuse it
305 with _('')"""
292 with _('')"""
306 doc = getattr(obj, '__doc__', None)
293 doc = getattr(obj, '__doc__', None)
307 if doc is None:
294 if doc is None:
308 return doc
295 return doc
309 return sysbytes(doc)
296 return sysbytes(doc)
310
297
311 def _wrapattrfunc(f):
298 def _wrapattrfunc(f):
312 @functools.wraps(f)
299 @functools.wraps(f)
313 def w(object, name, *args):
300 def w(object, name, *args):
314 return f(object, sysstr(name), *args)
301 return f(object, sysstr(name), *args)
315
302
316 return w
303 return w
317
304
318 # these wrappers are automagically imported by hgloader
305 # these wrappers are automagically imported by hgloader
319 delattr = _wrapattrfunc(builtins.delattr)
306 delattr = _wrapattrfunc(builtins.delattr)
320 getattr = _wrapattrfunc(builtins.getattr)
307 getattr = _wrapattrfunc(builtins.getattr)
321 hasattr = _wrapattrfunc(builtins.hasattr)
308 hasattr = _wrapattrfunc(builtins.hasattr)
322 setattr = _wrapattrfunc(builtins.setattr)
309 setattr = _wrapattrfunc(builtins.setattr)
323 xrange = builtins.range
310 xrange = builtins.range
324 unicode = str
311 unicode = str
325
312
326 def open(name, mode=b'r', buffering=-1, encoding=None):
313 def open(name, mode=b'r', buffering=-1, encoding=None):
327 return builtins.open(name, sysstr(mode), buffering, encoding)
314 return builtins.open(name, sysstr(mode), buffering, encoding)
328
315
329 safehasattr = _wrapattrfunc(builtins.hasattr)
316 safehasattr = _wrapattrfunc(builtins.hasattr)
330
317
331 def _getoptbwrapper(orig, args, shortlist, namelist):
318 def _getoptbwrapper(orig, args, shortlist, namelist):
332 """
319 """
333 Takes bytes arguments, converts them to unicode, pass them to
320 Takes bytes arguments, converts them to unicode, pass them to
334 getopt.getopt(), convert the returned values back to bytes and then
321 getopt.getopt(), convert the returned values back to bytes and then
335 return them for Python 3 compatibility as getopt.getopt() don't accepts
322 return them for Python 3 compatibility as getopt.getopt() don't accepts
336 bytes on Python 3.
323 bytes on Python 3.
337 """
324 """
338 args = [a.decode('latin-1') for a in args]
325 args = [a.decode('latin-1') for a in args]
339 shortlist = shortlist.decode('latin-1')
326 shortlist = shortlist.decode('latin-1')
340 namelist = [a.decode('latin-1') for a in namelist]
327 namelist = [a.decode('latin-1') for a in namelist]
341 opts, args = orig(args, shortlist, namelist)
328 opts, args = orig(args, shortlist, namelist)
342 opts = [(a[0].encode('latin-1'), a[1].encode('latin-1')) for a in opts]
329 opts = [(a[0].encode('latin-1'), a[1].encode('latin-1')) for a in opts]
343 args = [a.encode('latin-1') for a in args]
330 args = [a.encode('latin-1') for a in args]
344 return opts, args
331 return opts, args
345
332
346 def strkwargs(dic):
333 def strkwargs(dic):
347 """
334 """
348 Converts the keys of a python dictonary to str i.e. unicodes so that
335 Converts the keys of a python dictonary to str i.e. unicodes so that
349 they can be passed as keyword arguments as dictionaries with bytes keys
336 they can be passed as keyword arguments as dictionaries with bytes keys
350 can't be passed as keyword arguments to functions on Python 3.
337 can't be passed as keyword arguments to functions on Python 3.
351 """
338 """
352 dic = {k.decode('latin-1'): v for k, v in dic.items()}
339 dic = {k.decode('latin-1'): v for k, v in dic.items()}
353 return dic
340 return dic
354
341
355 def byteskwargs(dic):
342 def byteskwargs(dic):
356 """
343 """
357 Converts keys of python dictionaries to bytes as they were converted to
344 Converts keys of python dictionaries to bytes as they were converted to
358 str to pass that dictonary as a keyword argument on Python 3.
345 str to pass that dictonary as a keyword argument on Python 3.
359 """
346 """
360 dic = {k.encode('latin-1'): v for k, v in dic.items()}
347 dic = {k.encode('latin-1'): v for k, v in dic.items()}
361 return dic
348 return dic
362
349
363 # TODO: handle shlex.shlex().
350 # TODO: handle shlex.shlex().
364 def shlexsplit(s, comments=False, posix=True):
351 def shlexsplit(s, comments=False, posix=True):
365 """
352 """
366 Takes bytes argument, convert it to str i.e. unicodes, pass that into
353 Takes bytes argument, convert it to str i.e. unicodes, pass that into
367 shlex.split(), convert the returned value to bytes and return that for
354 shlex.split(), convert the returned value to bytes and return that for
368 Python 3 compatibility as shelx.split() don't accept bytes on Python 3.
355 Python 3 compatibility as shelx.split() don't accept bytes on Python 3.
369 """
356 """
370 ret = shlex.split(s.decode('latin-1'), comments, posix)
357 ret = shlex.split(s.decode('latin-1'), comments, posix)
371 return [a.encode('latin-1') for a in ret]
358 return [a.encode('latin-1') for a in ret]
372
359
373 iteritems = lambda x: x.items()
360 iteritems = lambda x: x.items()
374 itervalues = lambda x: x.values()
361 itervalues = lambda x: x.values()
375
362
376 # Python 3.5's json.load and json.loads require str. We polyfill its
363 # Python 3.5's json.load and json.loads require str. We polyfill its
377 # code for detecting encoding from bytes.
364 # code for detecting encoding from bytes.
378 if sys.version_info[0:2] < (3, 6):
365 if sys.version_info[0:2] < (3, 6):
379
366
380 def _detect_encoding(b):
367 def _detect_encoding(b):
381 bstartswith = b.startswith
368 bstartswith = b.startswith
382 if bstartswith((codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE)):
369 if bstartswith((codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE)):
383 return 'utf-32'
370 return 'utf-32'
384 if bstartswith((codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE)):
371 if bstartswith((codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE)):
385 return 'utf-16'
372 return 'utf-16'
386 if bstartswith(codecs.BOM_UTF8):
373 if bstartswith(codecs.BOM_UTF8):
387 return 'utf-8-sig'
374 return 'utf-8-sig'
388
375
389 if len(b) >= 4:
376 if len(b) >= 4:
390 if not b[0]:
377 if not b[0]:
391 # 00 00 -- -- - utf-32-be
378 # 00 00 -- -- - utf-32-be
392 # 00 XX -- -- - utf-16-be
379 # 00 XX -- -- - utf-16-be
393 return 'utf-16-be' if b[1] else 'utf-32-be'
380 return 'utf-16-be' if b[1] else 'utf-32-be'
394 if not b[1]:
381 if not b[1]:
395 # XX 00 00 00 - utf-32-le
382 # XX 00 00 00 - utf-32-le
396 # XX 00 00 XX - utf-16-le
383 # XX 00 00 XX - utf-16-le
397 # XX 00 XX -- - utf-16-le
384 # XX 00 XX -- - utf-16-le
398 return 'utf-16-le' if b[2] or b[3] else 'utf-32-le'
385 return 'utf-16-le' if b[2] or b[3] else 'utf-32-le'
399 elif len(b) == 2:
386 elif len(b) == 2:
400 if not b[0]:
387 if not b[0]:
401 # 00 XX - utf-16-be
388 # 00 XX - utf-16-be
402 return 'utf-16-be'
389 return 'utf-16-be'
403 if not b[1]:
390 if not b[1]:
404 # XX 00 - utf-16-le
391 # XX 00 - utf-16-le
405 return 'utf-16-le'
392 return 'utf-16-le'
406 # default
393 # default
407 return 'utf-8'
394 return 'utf-8'
408
395
409 def json_loads(s, *args, **kwargs):
396 def json_loads(s, *args, **kwargs):
410 if isinstance(s, (bytes, bytearray)):
397 if isinstance(s, (bytes, bytearray)):
411 s = s.decode(_detect_encoding(s), 'surrogatepass')
398 s = s.decode(_detect_encoding(s), 'surrogatepass')
412
399
413 return json.loads(s, *args, **kwargs)
400 return json.loads(s, *args, **kwargs)
414
401
415 else:
402 else:
416 json_loads = json.loads
403 json_loads = json.loads
417
404
418 else:
405 else:
419 import cStringIO
406 import cStringIO
420
407
421 xrange = xrange
408 xrange = xrange
422 unicode = unicode
409 unicode = unicode
423 bytechr = chr
410 bytechr = chr
424 byterepr = repr
411 byterepr = repr
425 bytestr = str
412 bytestr = str
426 iterbytestr = iter
413 iterbytestr = iter
427 maybebytestr = identity
414 maybebytestr = identity
428 sysbytes = identity
415 sysbytes = identity
429 sysstr = identity
416 sysstr = identity
430 strurl = identity
417 strurl = identity
431 bytesurl = identity
418 bytesurl = identity
432 open = open
419 open = open
433 delattr = delattr
420 delattr = delattr
434 getattr = getattr
421 getattr = getattr
435 hasattr = hasattr
422 hasattr = hasattr
436 setattr = setattr
423 setattr = setattr
437
424
438 # this can't be parsed on Python 3
425 # this can't be parsed on Python 3
439 exec(b'def raisewithtb(exc, tb):\n raise exc, None, tb\n')
426 exec(b'def raisewithtb(exc, tb):\n raise exc, None, tb\n')
440
427
441 def fsencode(filename):
428 def fsencode(filename):
442 """
429 """
443 Partial backport from os.py in Python 3, which only accepts bytes.
430 Partial backport from os.py in Python 3, which only accepts bytes.
444 In Python 2, our paths should only ever be bytes, a unicode path
431 In Python 2, our paths should only ever be bytes, a unicode path
445 indicates a bug.
432 indicates a bug.
446 """
433 """
447 if isinstance(filename, str):
434 if isinstance(filename, str):
448 return filename
435 return filename
449 else:
436 else:
450 raise TypeError("expect str, not %s" % type(filename).__name__)
437 raise TypeError("expect str, not %s" % type(filename).__name__)
451
438
452 # In Python 2, fsdecode() has a very chance to receive bytes. So it's
439 # In Python 2, fsdecode() has a very chance to receive bytes. So it's
453 # better not to touch Python 2 part as it's already working fine.
440 # better not to touch Python 2 part as it's already working fine.
454 fsdecode = identity
441 fsdecode = identity
455
442
456 def getdoc(obj):
443 def getdoc(obj):
457 return getattr(obj, '__doc__', None)
444 return getattr(obj, '__doc__', None)
458
445
459 _notset = object()
446 _notset = object()
460
447
461 def safehasattr(thing, attr):
448 def safehasattr(thing, attr):
462 return getattr(thing, attr, _notset) is not _notset
449 return getattr(thing, attr, _notset) is not _notset
463
450
464 def _getoptbwrapper(orig, args, shortlist, namelist):
451 def _getoptbwrapper(orig, args, shortlist, namelist):
465 return orig(args, shortlist, namelist)
452 return orig(args, shortlist, namelist)
466
453
467 strkwargs = identity
454 strkwargs = identity
468 byteskwargs = identity
455 byteskwargs = identity
469
456
470 oscurdir = os.curdir
457 oscurdir = os.curdir
471 oslinesep = os.linesep
458 oslinesep = os.linesep
472 osname = os.name
459 osname = os.name
473 ospathsep = os.pathsep
460 ospathsep = os.pathsep
474 ospardir = os.pardir
461 ospardir = os.pardir
475 ossep = os.sep
462 ossep = os.sep
476 osaltsep = os.altsep
463 osaltsep = os.altsep
477 osdevnull = os.devnull
464 osdevnull = os.devnull
478 long = long
465 long = long
479 if getattr(sys, 'argv', None) is not None:
466 if getattr(sys, 'argv', None) is not None:
480 sysargv = sys.argv
467 sysargv = sys.argv
481 sysplatform = sys.platform
468 sysplatform = sys.platform
482 sysexecutable = sys.executable
469 sysexecutable = sys.executable
483 shlexsplit = shlex.split
470 shlexsplit = shlex.split
484 bytesio = cStringIO.StringIO
471 bytesio = cStringIO.StringIO
485 stringio = bytesio
472 stringio = bytesio
486 maplist = map
473 maplist = map
487 rangelist = range
474 rangelist = range
488 ziplist = zip
475 ziplist = zip
489 rawinput = raw_input
476 rawinput = raw_input
490 getargspec = inspect.getargspec
477 getargspec = inspect.getargspec
491 iteritems = lambda x: x.iteritems()
478 iteritems = lambda x: x.iteritems()
492 itervalues = lambda x: x.itervalues()
479 itervalues = lambda x: x.itervalues()
493 json_loads = json.loads
480 json_loads = json.loads
494
481
495 isjython = sysplatform.startswith(b'java')
482 isjython = sysplatform.startswith(b'java')
496
483
497 isdarwin = sysplatform.startswith(b'darwin')
484 isdarwin = sysplatform.startswith(b'darwin')
498 islinux = sysplatform.startswith(b'linux')
485 islinux = sysplatform.startswith(b'linux')
499 isposix = osname == b'posix'
486 isposix = osname == b'posix'
500 iswindows = osname == b'nt'
487 iswindows = osname == b'nt'
501
488
502
489
503 def getoptb(args, shortlist, namelist):
490 def getoptb(args, shortlist, namelist):
504 return _getoptbwrapper(getopt.getopt, args, shortlist, namelist)
491 return _getoptbwrapper(getopt.getopt, args, shortlist, namelist)
505
492
506
493
507 def gnugetoptb(args, shortlist, namelist):
494 def gnugetoptb(args, shortlist, namelist):
508 return _getoptbwrapper(getopt.gnu_getopt, args, shortlist, namelist)
495 return _getoptbwrapper(getopt.gnu_getopt, args, shortlist, namelist)
509
496
510
497
511 def mkdtemp(suffix=b'', prefix=b'tmp', dir=None):
498 def mkdtemp(suffix=b'', prefix=b'tmp', dir=None):
512 return tempfile.mkdtemp(suffix, prefix, dir)
499 return tempfile.mkdtemp(suffix, prefix, dir)
513
500
514
501
515 # text=True is not supported; use util.from/tonativeeol() instead
502 # text=True is not supported; use util.from/tonativeeol() instead
516 def mkstemp(suffix=b'', prefix=b'tmp', dir=None):
503 def mkstemp(suffix=b'', prefix=b'tmp', dir=None):
517 return tempfile.mkstemp(suffix, prefix, dir)
504 return tempfile.mkstemp(suffix, prefix, dir)
518
505
519
506
520 # TemporaryFile does not support an "encoding=" argument on python2.
507 # TemporaryFile does not support an "encoding=" argument on python2.
521 # This wrapper file are always open in byte mode.
508 # This wrapper file are always open in byte mode.
522 def unnamedtempfile(mode=None, *args, **kwargs):
509 def unnamedtempfile(mode=None, *args, **kwargs):
523 if mode is None:
510 if mode is None:
524 mode = 'w+b'
511 mode = 'w+b'
525 else:
512 else:
526 mode = sysstr(mode)
513 mode = sysstr(mode)
527 assert 'b' in mode
514 assert 'b' in mode
528 return tempfile.TemporaryFile(mode, *args, **kwargs)
515 return tempfile.TemporaryFile(mode, *args, **kwargs)
529
516
530
517
531 # NamedTemporaryFile does not support an "encoding=" argument on python2.
518 # NamedTemporaryFile does not support an "encoding=" argument on python2.
532 # This wrapper file are always open in byte mode.
519 # This wrapper file are always open in byte mode.
533 def namedtempfile(
520 def namedtempfile(
534 mode=b'w+b', bufsize=-1, suffix=b'', prefix=b'tmp', dir=None, delete=True
521 mode=b'w+b', bufsize=-1, suffix=b'', prefix=b'tmp', dir=None, delete=True
535 ):
522 ):
536 mode = sysstr(mode)
523 mode = sysstr(mode)
537 assert 'b' in mode
524 assert 'b' in mode
538 return tempfile.NamedTemporaryFile(
525 return tempfile.NamedTemporaryFile(
539 mode, bufsize, suffix=suffix, prefix=prefix, dir=dir, delete=delete
526 mode, bufsize, suffix=suffix, prefix=prefix, dir=dir, delete=delete
540 )
527 )
General Comments 0
You need to be logged in to leave comments. Login now