##// END OF EJS Templates
pycompat: name maplist() and ziplist() for better traceback message
Yuya Nishihara -
r36952:dbae5810 default
parent child Browse files
Show More
@@ -1,361 +1,366
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 getopt
13 import getopt
14 import inspect
14 import inspect
15 import os
15 import os
16 import shlex
16 import shlex
17 import sys
17 import sys
18
18
19 ispy3 = (sys.version_info[0] >= 3)
19 ispy3 = (sys.version_info[0] >= 3)
20 ispypy = (r'__pypy__' in sys.builtin_module_names)
20 ispypy = (r'__pypy__' in sys.builtin_module_names)
21
21
22 if not ispy3:
22 if not ispy3:
23 import cookielib
23 import cookielib
24 import cPickle as pickle
24 import cPickle as pickle
25 import httplib
25 import httplib
26 import Queue as _queue
26 import Queue as _queue
27 import SocketServer as socketserver
27 import SocketServer as socketserver
28 import xmlrpclib
28 import xmlrpclib
29 else:
29 else:
30 import http.cookiejar as cookielib
30 import http.cookiejar as cookielib
31 import http.client as httplib
31 import http.client as httplib
32 import pickle
32 import pickle
33 import queue as _queue
33 import queue as _queue
34 import socketserver
34 import socketserver
35 import xmlrpc.client as xmlrpclib
35 import xmlrpc.client as xmlrpclib
36
36
37 empty = _queue.Empty
37 empty = _queue.Empty
38 queue = _queue.Queue
38 queue = _queue.Queue
39
39
40 def identity(a):
40 def identity(a):
41 return a
41 return a
42
42
43 if ispy3:
43 if ispy3:
44 import builtins
44 import builtins
45 import functools
45 import functools
46 import io
46 import io
47 import struct
47 import struct
48
48
49 fsencode = os.fsencode
49 fsencode = os.fsencode
50 fsdecode = os.fsdecode
50 fsdecode = os.fsdecode
51 oscurdir = os.curdir.encode('ascii')
51 oscurdir = os.curdir.encode('ascii')
52 oslinesep = os.linesep.encode('ascii')
52 oslinesep = os.linesep.encode('ascii')
53 osname = os.name.encode('ascii')
53 osname = os.name.encode('ascii')
54 ospathsep = os.pathsep.encode('ascii')
54 ospathsep = os.pathsep.encode('ascii')
55 ospardir = os.pardir.encode('ascii')
55 ospardir = os.pardir.encode('ascii')
56 ossep = os.sep.encode('ascii')
56 ossep = os.sep.encode('ascii')
57 osaltsep = os.altsep
57 osaltsep = os.altsep
58 if osaltsep:
58 if osaltsep:
59 osaltsep = osaltsep.encode('ascii')
59 osaltsep = osaltsep.encode('ascii')
60 # os.getcwd() on Python 3 returns string, but it has os.getcwdb() which
60 # os.getcwd() on Python 3 returns string, but it has os.getcwdb() which
61 # returns bytes.
61 # returns bytes.
62 getcwd = os.getcwdb
62 getcwd = os.getcwdb
63 sysplatform = sys.platform.encode('ascii')
63 sysplatform = sys.platform.encode('ascii')
64 sysexecutable = sys.executable
64 sysexecutable = sys.executable
65 if sysexecutable:
65 if sysexecutable:
66 sysexecutable = os.fsencode(sysexecutable)
66 sysexecutable = os.fsencode(sysexecutable)
67 stringio = io.BytesIO
67 stringio = io.BytesIO
68 maplist = lambda *args: list(map(*args))
68
69 ziplist = lambda *args: list(zip(*args))
69 def maplist(*args):
70 return list(map(*args))
71
72 def ziplist(*args):
73 return list(zip(*args))
74
70 rawinput = input
75 rawinput = input
71 getargspec = inspect.getfullargspec
76 getargspec = inspect.getfullargspec
72
77
73 # TODO: .buffer might not exist if std streams were replaced; we'll need
78 # TODO: .buffer might not exist if std streams were replaced; we'll need
74 # a silly wrapper to make a bytes stream backed by a unicode one.
79 # a silly wrapper to make a bytes stream backed by a unicode one.
75 stdin = sys.stdin.buffer
80 stdin = sys.stdin.buffer
76 stdout = sys.stdout.buffer
81 stdout = sys.stdout.buffer
77 stderr = sys.stderr.buffer
82 stderr = sys.stderr.buffer
78
83
79 # Since Python 3 converts argv to wchar_t type by Py_DecodeLocale() on Unix,
84 # Since Python 3 converts argv to wchar_t type by Py_DecodeLocale() on Unix,
80 # we can use os.fsencode() to get back bytes argv.
85 # we can use os.fsencode() to get back bytes argv.
81 #
86 #
82 # https://hg.python.org/cpython/file/v3.5.1/Programs/python.c#l55
87 # https://hg.python.org/cpython/file/v3.5.1/Programs/python.c#l55
83 #
88 #
84 # TODO: On Windows, the native argv is wchar_t, so we'll need a different
89 # TODO: On Windows, the native argv is wchar_t, so we'll need a different
85 # workaround to simulate the Python 2 (i.e. ANSI Win32 API) behavior.
90 # workaround to simulate the Python 2 (i.e. ANSI Win32 API) behavior.
86 if getattr(sys, 'argv', None) is not None:
91 if getattr(sys, 'argv', None) is not None:
87 sysargv = list(map(os.fsencode, sys.argv))
92 sysargv = list(map(os.fsencode, sys.argv))
88
93
89 bytechr = struct.Struct('>B').pack
94 bytechr = struct.Struct('>B').pack
90 byterepr = b'%r'.__mod__
95 byterepr = b'%r'.__mod__
91
96
92 class bytestr(bytes):
97 class bytestr(bytes):
93 """A bytes which mostly acts as a Python 2 str
98 """A bytes which mostly acts as a Python 2 str
94
99
95 >>> bytestr(), bytestr(bytearray(b'foo')), bytestr(u'ascii'), bytestr(1)
100 >>> bytestr(), bytestr(bytearray(b'foo')), bytestr(u'ascii'), bytestr(1)
96 ('', 'foo', 'ascii', '1')
101 ('', 'foo', 'ascii', '1')
97 >>> s = bytestr(b'foo')
102 >>> s = bytestr(b'foo')
98 >>> assert s is bytestr(s)
103 >>> assert s is bytestr(s)
99
104
100 __bytes__() should be called if provided:
105 __bytes__() should be called if provided:
101
106
102 >>> class bytesable(object):
107 >>> class bytesable(object):
103 ... def __bytes__(self):
108 ... def __bytes__(self):
104 ... return b'bytes'
109 ... return b'bytes'
105 >>> bytestr(bytesable())
110 >>> bytestr(bytesable())
106 'bytes'
111 'bytes'
107
112
108 There's no implicit conversion from non-ascii str as its encoding is
113 There's no implicit conversion from non-ascii str as its encoding is
109 unknown:
114 unknown:
110
115
111 >>> bytestr(chr(0x80)) # doctest: +ELLIPSIS
116 >>> bytestr(chr(0x80)) # doctest: +ELLIPSIS
112 Traceback (most recent call last):
117 Traceback (most recent call last):
113 ...
118 ...
114 UnicodeEncodeError: ...
119 UnicodeEncodeError: ...
115
120
116 Comparison between bytestr and bytes should work:
121 Comparison between bytestr and bytes should work:
117
122
118 >>> assert bytestr(b'foo') == b'foo'
123 >>> assert bytestr(b'foo') == b'foo'
119 >>> assert b'foo' == bytestr(b'foo')
124 >>> assert b'foo' == bytestr(b'foo')
120 >>> assert b'f' in bytestr(b'foo')
125 >>> assert b'f' in bytestr(b'foo')
121 >>> assert bytestr(b'f') in b'foo'
126 >>> assert bytestr(b'f') in b'foo'
122
127
123 Sliced elements should be bytes, not integer:
128 Sliced elements should be bytes, not integer:
124
129
125 >>> s[1], s[:2]
130 >>> s[1], s[:2]
126 (b'o', b'fo')
131 (b'o', b'fo')
127 >>> list(s), list(reversed(s))
132 >>> list(s), list(reversed(s))
128 ([b'f', b'o', b'o'], [b'o', b'o', b'f'])
133 ([b'f', b'o', b'o'], [b'o', b'o', b'f'])
129
134
130 As bytestr type isn't propagated across operations, you need to cast
135 As bytestr type isn't propagated across operations, you need to cast
131 bytes to bytestr explicitly:
136 bytes to bytestr explicitly:
132
137
133 >>> s = bytestr(b'foo').upper()
138 >>> s = bytestr(b'foo').upper()
134 >>> t = bytestr(s)
139 >>> t = bytestr(s)
135 >>> s[0], t[0]
140 >>> s[0], t[0]
136 (70, b'F')
141 (70, b'F')
137
142
138 Be careful to not pass a bytestr object to a function which expects
143 Be careful to not pass a bytestr object to a function which expects
139 bytearray-like behavior.
144 bytearray-like behavior.
140
145
141 >>> t = bytes(t) # cast to bytes
146 >>> t = bytes(t) # cast to bytes
142 >>> assert type(t) is bytes
147 >>> assert type(t) is bytes
143 """
148 """
144
149
145 def __new__(cls, s=b''):
150 def __new__(cls, s=b''):
146 if isinstance(s, bytestr):
151 if isinstance(s, bytestr):
147 return s
152 return s
148 if (not isinstance(s, (bytes, bytearray))
153 if (not isinstance(s, (bytes, bytearray))
149 and not hasattr(s, u'__bytes__')): # hasattr-py3-only
154 and not hasattr(s, u'__bytes__')): # hasattr-py3-only
150 s = str(s).encode(u'ascii')
155 s = str(s).encode(u'ascii')
151 return bytes.__new__(cls, s)
156 return bytes.__new__(cls, s)
152
157
153 def __getitem__(self, key):
158 def __getitem__(self, key):
154 s = bytes.__getitem__(self, key)
159 s = bytes.__getitem__(self, key)
155 if not isinstance(s, bytes):
160 if not isinstance(s, bytes):
156 s = bytechr(s)
161 s = bytechr(s)
157 return s
162 return s
158
163
159 def __iter__(self):
164 def __iter__(self):
160 return iterbytestr(bytes.__iter__(self))
165 return iterbytestr(bytes.__iter__(self))
161
166
162 def __repr__(self):
167 def __repr__(self):
163 return bytes.__repr__(self)[1:] # drop b''
168 return bytes.__repr__(self)[1:] # drop b''
164
169
165 def iterbytestr(s):
170 def iterbytestr(s):
166 """Iterate bytes as if it were a str object of Python 2"""
171 """Iterate bytes as if it were a str object of Python 2"""
167 return map(bytechr, s)
172 return map(bytechr, s)
168
173
169 def maybebytestr(s):
174 def maybebytestr(s):
170 """Promote bytes to bytestr"""
175 """Promote bytes to bytestr"""
171 if isinstance(s, bytes):
176 if isinstance(s, bytes):
172 return bytestr(s)
177 return bytestr(s)
173 return s
178 return s
174
179
175 def sysbytes(s):
180 def sysbytes(s):
176 """Convert an internal str (e.g. keyword, __doc__) back to bytes
181 """Convert an internal str (e.g. keyword, __doc__) back to bytes
177
182
178 This never raises UnicodeEncodeError, but only ASCII characters
183 This never raises UnicodeEncodeError, but only ASCII characters
179 can be round-trip by sysstr(sysbytes(s)).
184 can be round-trip by sysstr(sysbytes(s)).
180 """
185 """
181 return s.encode(u'utf-8')
186 return s.encode(u'utf-8')
182
187
183 def sysstr(s):
188 def sysstr(s):
184 """Return a keyword str to be passed to Python functions such as
189 """Return a keyword str to be passed to Python functions such as
185 getattr() and str.encode()
190 getattr() and str.encode()
186
191
187 This never raises UnicodeDecodeError. Non-ascii characters are
192 This never raises UnicodeDecodeError. Non-ascii characters are
188 considered invalid and mapped to arbitrary but unique code points
193 considered invalid and mapped to arbitrary but unique code points
189 such that 'sysstr(a) != sysstr(b)' for all 'a != b'.
194 such that 'sysstr(a) != sysstr(b)' for all 'a != b'.
190 """
195 """
191 if isinstance(s, builtins.str):
196 if isinstance(s, builtins.str):
192 return s
197 return s
193 return s.decode(u'latin-1')
198 return s.decode(u'latin-1')
194
199
195 def strurl(url):
200 def strurl(url):
196 """Converts a bytes url back to str"""
201 """Converts a bytes url back to str"""
197 if isinstance(url, bytes):
202 if isinstance(url, bytes):
198 return url.decode(u'ascii')
203 return url.decode(u'ascii')
199 return url
204 return url
200
205
201 def bytesurl(url):
206 def bytesurl(url):
202 """Converts a str url to bytes by encoding in ascii"""
207 """Converts a str url to bytes by encoding in ascii"""
203 if isinstance(url, str):
208 if isinstance(url, str):
204 return url.encode(u'ascii')
209 return url.encode(u'ascii')
205 return url
210 return url
206
211
207 def raisewithtb(exc, tb):
212 def raisewithtb(exc, tb):
208 """Raise exception with the given traceback"""
213 """Raise exception with the given traceback"""
209 raise exc.with_traceback(tb)
214 raise exc.with_traceback(tb)
210
215
211 def getdoc(obj):
216 def getdoc(obj):
212 """Get docstring as bytes; may be None so gettext() won't confuse it
217 """Get docstring as bytes; may be None so gettext() won't confuse it
213 with _('')"""
218 with _('')"""
214 doc = getattr(obj, u'__doc__', None)
219 doc = getattr(obj, u'__doc__', None)
215 if doc is None:
220 if doc is None:
216 return doc
221 return doc
217 return sysbytes(doc)
222 return sysbytes(doc)
218
223
219 def _wrapattrfunc(f):
224 def _wrapattrfunc(f):
220 @functools.wraps(f)
225 @functools.wraps(f)
221 def w(object, name, *args):
226 def w(object, name, *args):
222 return f(object, sysstr(name), *args)
227 return f(object, sysstr(name), *args)
223 return w
228 return w
224
229
225 # these wrappers are automagically imported by hgloader
230 # these wrappers are automagically imported by hgloader
226 delattr = _wrapattrfunc(builtins.delattr)
231 delattr = _wrapattrfunc(builtins.delattr)
227 getattr = _wrapattrfunc(builtins.getattr)
232 getattr = _wrapattrfunc(builtins.getattr)
228 hasattr = _wrapattrfunc(builtins.hasattr)
233 hasattr = _wrapattrfunc(builtins.hasattr)
229 setattr = _wrapattrfunc(builtins.setattr)
234 setattr = _wrapattrfunc(builtins.setattr)
230 xrange = builtins.range
235 xrange = builtins.range
231 unicode = str
236 unicode = str
232
237
233 def open(name, mode='r', buffering=-1, encoding=None):
238 def open(name, mode='r', buffering=-1, encoding=None):
234 return builtins.open(name, sysstr(mode), buffering, encoding)
239 return builtins.open(name, sysstr(mode), buffering, encoding)
235
240
236 def _getoptbwrapper(orig, args, shortlist, namelist):
241 def _getoptbwrapper(orig, args, shortlist, namelist):
237 """
242 """
238 Takes bytes arguments, converts them to unicode, pass them to
243 Takes bytes arguments, converts them to unicode, pass them to
239 getopt.getopt(), convert the returned values back to bytes and then
244 getopt.getopt(), convert the returned values back to bytes and then
240 return them for Python 3 compatibility as getopt.getopt() don't accepts
245 return them for Python 3 compatibility as getopt.getopt() don't accepts
241 bytes on Python 3.
246 bytes on Python 3.
242 """
247 """
243 args = [a.decode('latin-1') for a in args]
248 args = [a.decode('latin-1') for a in args]
244 shortlist = shortlist.decode('latin-1')
249 shortlist = shortlist.decode('latin-1')
245 namelist = [a.decode('latin-1') for a in namelist]
250 namelist = [a.decode('latin-1') for a in namelist]
246 opts, args = orig(args, shortlist, namelist)
251 opts, args = orig(args, shortlist, namelist)
247 opts = [(a[0].encode('latin-1'), a[1].encode('latin-1'))
252 opts = [(a[0].encode('latin-1'), a[1].encode('latin-1'))
248 for a in opts]
253 for a in opts]
249 args = [a.encode('latin-1') for a in args]
254 args = [a.encode('latin-1') for a in args]
250 return opts, args
255 return opts, args
251
256
252 def strkwargs(dic):
257 def strkwargs(dic):
253 """
258 """
254 Converts the keys of a python dictonary to str i.e. unicodes so that
259 Converts the keys of a python dictonary to str i.e. unicodes so that
255 they can be passed as keyword arguments as dictonaries with bytes keys
260 they can be passed as keyword arguments as dictonaries with bytes keys
256 can't be passed as keyword arguments to functions on Python 3.
261 can't be passed as keyword arguments to functions on Python 3.
257 """
262 """
258 dic = dict((k.decode('latin-1'), v) for k, v in dic.iteritems())
263 dic = dict((k.decode('latin-1'), v) for k, v in dic.iteritems())
259 return dic
264 return dic
260
265
261 def byteskwargs(dic):
266 def byteskwargs(dic):
262 """
267 """
263 Converts keys of python dictonaries to bytes as they were converted to
268 Converts keys of python dictonaries to bytes as they were converted to
264 str to pass that dictonary as a keyword argument on Python 3.
269 str to pass that dictonary as a keyword argument on Python 3.
265 """
270 """
266 dic = dict((k.encode('latin-1'), v) for k, v in dic.iteritems())
271 dic = dict((k.encode('latin-1'), v) for k, v in dic.iteritems())
267 return dic
272 return dic
268
273
269 # TODO: handle shlex.shlex().
274 # TODO: handle shlex.shlex().
270 def shlexsplit(s, comments=False, posix=True):
275 def shlexsplit(s, comments=False, posix=True):
271 """
276 """
272 Takes bytes argument, convert it to str i.e. unicodes, pass that into
277 Takes bytes argument, convert it to str i.e. unicodes, pass that into
273 shlex.split(), convert the returned value to bytes and return that for
278 shlex.split(), convert the returned value to bytes and return that for
274 Python 3 compatibility as shelx.split() don't accept bytes on Python 3.
279 Python 3 compatibility as shelx.split() don't accept bytes on Python 3.
275 """
280 """
276 ret = shlex.split(s.decode('latin-1'), comments, posix)
281 ret = shlex.split(s.decode('latin-1'), comments, posix)
277 return [a.encode('latin-1') for a in ret]
282 return [a.encode('latin-1') for a in ret]
278
283
279 def emailparser(*args, **kwargs):
284 def emailparser(*args, **kwargs):
280 import email.parser
285 import email.parser
281 return email.parser.BytesParser(*args, **kwargs)
286 return email.parser.BytesParser(*args, **kwargs)
282
287
283 else:
288 else:
284 import cStringIO
289 import cStringIO
285
290
286 bytechr = chr
291 bytechr = chr
287 byterepr = repr
292 byterepr = repr
288 bytestr = str
293 bytestr = str
289 iterbytestr = iter
294 iterbytestr = iter
290 maybebytestr = identity
295 maybebytestr = identity
291 sysbytes = identity
296 sysbytes = identity
292 sysstr = identity
297 sysstr = identity
293 strurl = identity
298 strurl = identity
294 bytesurl = identity
299 bytesurl = identity
295
300
296 # this can't be parsed on Python 3
301 # this can't be parsed on Python 3
297 exec('def raisewithtb(exc, tb):\n'
302 exec('def raisewithtb(exc, tb):\n'
298 ' raise exc, None, tb\n')
303 ' raise exc, None, tb\n')
299
304
300 def fsencode(filename):
305 def fsencode(filename):
301 """
306 """
302 Partial backport from os.py in Python 3, which only accepts bytes.
307 Partial backport from os.py in Python 3, which only accepts bytes.
303 In Python 2, our paths should only ever be bytes, a unicode path
308 In Python 2, our paths should only ever be bytes, a unicode path
304 indicates a bug.
309 indicates a bug.
305 """
310 """
306 if isinstance(filename, str):
311 if isinstance(filename, str):
307 return filename
312 return filename
308 else:
313 else:
309 raise TypeError(
314 raise TypeError(
310 "expect str, not %s" % type(filename).__name__)
315 "expect str, not %s" % type(filename).__name__)
311
316
312 # In Python 2, fsdecode() has a very chance to receive bytes. So it's
317 # In Python 2, fsdecode() has a very chance to receive bytes. So it's
313 # better not to touch Python 2 part as it's already working fine.
318 # better not to touch Python 2 part as it's already working fine.
314 fsdecode = identity
319 fsdecode = identity
315
320
316 def getdoc(obj):
321 def getdoc(obj):
317 return getattr(obj, '__doc__', None)
322 return getattr(obj, '__doc__', None)
318
323
319 def _getoptbwrapper(orig, args, shortlist, namelist):
324 def _getoptbwrapper(orig, args, shortlist, namelist):
320 return orig(args, shortlist, namelist)
325 return orig(args, shortlist, namelist)
321
326
322 strkwargs = identity
327 strkwargs = identity
323 byteskwargs = identity
328 byteskwargs = identity
324
329
325 oscurdir = os.curdir
330 oscurdir = os.curdir
326 oslinesep = os.linesep
331 oslinesep = os.linesep
327 osname = os.name
332 osname = os.name
328 ospathsep = os.pathsep
333 ospathsep = os.pathsep
329 ospardir = os.pardir
334 ospardir = os.pardir
330 ossep = os.sep
335 ossep = os.sep
331 osaltsep = os.altsep
336 osaltsep = os.altsep
332 stdin = sys.stdin
337 stdin = sys.stdin
333 stdout = sys.stdout
338 stdout = sys.stdout
334 stderr = sys.stderr
339 stderr = sys.stderr
335 if getattr(sys, 'argv', None) is not None:
340 if getattr(sys, 'argv', None) is not None:
336 sysargv = sys.argv
341 sysargv = sys.argv
337 sysplatform = sys.platform
342 sysplatform = sys.platform
338 getcwd = os.getcwd
343 getcwd = os.getcwd
339 sysexecutable = sys.executable
344 sysexecutable = sys.executable
340 shlexsplit = shlex.split
345 shlexsplit = shlex.split
341 stringio = cStringIO.StringIO
346 stringio = cStringIO.StringIO
342 maplist = map
347 maplist = map
343 ziplist = zip
348 ziplist = zip
344 rawinput = raw_input
349 rawinput = raw_input
345 getargspec = inspect.getargspec
350 getargspec = inspect.getargspec
346
351
347 def emailparser(*args, **kwargs):
352 def emailparser(*args, **kwargs):
348 import email.parser
353 import email.parser
349 return email.parser.Parser(*args, **kwargs)
354 return email.parser.Parser(*args, **kwargs)
350
355
351 isjython = sysplatform.startswith('java')
356 isjython = sysplatform.startswith('java')
352
357
353 isdarwin = sysplatform == 'darwin'
358 isdarwin = sysplatform == 'darwin'
354 isposix = osname == 'posix'
359 isposix = osname == 'posix'
355 iswindows = osname == 'nt'
360 iswindows = osname == 'nt'
356
361
357 def getoptb(args, shortlist, namelist):
362 def getoptb(args, shortlist, namelist):
358 return _getoptbwrapper(getopt.getopt, args, shortlist, namelist)
363 return _getoptbwrapper(getopt.getopt, args, shortlist, namelist)
359
364
360 def gnugetoptb(args, shortlist, namelist):
365 def gnugetoptb(args, shortlist, namelist):
361 return _getoptbwrapper(getopt.gnu_getopt, args, shortlist, namelist)
366 return _getoptbwrapper(getopt.gnu_getopt, args, shortlist, namelist)
General Comments 0
You need to be logged in to leave comments. Login now