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