annotate mercurial/pycompat.py @ 43386:2247bf3cec76 stable

fsmonitor: remove pywatchman from exclusion rule The recently vendored pywatchman code base is now formatted with black. We can now remove pywatchman from our black exclusion rule. Differential Revision: https://phab.mercurial-scm.org/D7202
author Gregory Szorc <gregory.szorc@gmail.com>
date Sat, 02 Nov 2019 12:51:28 -0700
parents 579672b347d2
children 93f74a7d3f07
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
28818
6041fb8f2da8 pycompat: add empty and queue to handle py3 divergence
timeless <timeless@mozdev.org>
parents:
diff changeset
1 # pycompat.py - portability shim for python 3
6041fb8f2da8 pycompat: add empty and queue to handle py3 divergence
timeless <timeless@mozdev.org>
parents:
diff changeset
2 #
6041fb8f2da8 pycompat: add empty and queue to handle py3 divergence
timeless <timeless@mozdev.org>
parents:
diff changeset
3 # This software may be used and distributed according to the terms of the
6041fb8f2da8 pycompat: add empty and queue to handle py3 divergence
timeless <timeless@mozdev.org>
parents:
diff changeset
4 # GNU General Public License version 2 or any later version.
6041fb8f2da8 pycompat: add empty and queue to handle py3 divergence
timeless <timeless@mozdev.org>
parents:
diff changeset
5
6041fb8f2da8 pycompat: add empty and queue to handle py3 divergence
timeless <timeless@mozdev.org>
parents:
diff changeset
6 """Mercurial portability shim for python 3.
6041fb8f2da8 pycompat: add empty and queue to handle py3 divergence
timeless <timeless@mozdev.org>
parents:
diff changeset
7
6041fb8f2da8 pycompat: add empty and queue to handle py3 divergence
timeless <timeless@mozdev.org>
parents:
diff changeset
8 This contains aliases to hide python version-specific details from the core.
6041fb8f2da8 pycompat: add empty and queue to handle py3 divergence
timeless <timeless@mozdev.org>
parents:
diff changeset
9 """
6041fb8f2da8 pycompat: add empty and queue to handle py3 divergence
timeless <timeless@mozdev.org>
parents:
diff changeset
10
6041fb8f2da8 pycompat: add empty and queue to handle py3 divergence
timeless <timeless@mozdev.org>
parents:
diff changeset
11 from __future__ import absolute_import
6041fb8f2da8 pycompat: add empty and queue to handle py3 divergence
timeless <timeless@mozdev.org>
parents:
diff changeset
12
30578
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30500
diff changeset
13 import getopt
36178
646002338365 py3: introduce and use pycompat.getargspec
Augie Fackler <augie@google.com>
parents: 36045
diff changeset
14 import inspect
43380
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
15 import json
30302
3874ddba1ab4 py3: add a bytes version of os.name
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30300
diff changeset
16 import os
30678
caf7e1c5efe4 py3: have a bytes version of shlex.split()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30668
diff changeset
17 import shlex
29584
06587edd1233 pycompat: make pycompat demandimport friendly
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
18 import sys
38164
aac4be30e250 py3: wrap tempfile.mkstemp() to use bytes path
Yuya Nishihara <yuya@tcha.org>
parents: 37844
diff changeset
19 import tempfile
29584
06587edd1233 pycompat: make pycompat demandimport friendly
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
20
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
21 ispy3 = sys.version_info[0] >= 3
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
22 ispypy = r'__pypy__' in sys.builtin_module_names
30030
0f6d6fdd3c2a pycompat: provide 'ispy3' constant
Yuya Nishihara <yuya@tcha.org>
parents: 29801
diff changeset
23
0f6d6fdd3c2a pycompat: provide 'ispy3' constant
Yuya Nishihara <yuya@tcha.org>
parents: 29801
diff changeset
24 if not ispy3:
31934
12aca6770046 util: make cookielib module available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31843
diff changeset
25 import cookielib
29324
b501579147f1 py3: conditionalize cPickle import by adding in util
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28882
diff changeset
26 import cPickle as pickle
29455
0c741fd6158a py3: conditionalize httplib import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29433
diff changeset
27 import httplib
37844
8fb9985382be pycompat: export queue module instead of symbols in module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37669
diff changeset
28 import Queue as queue
29433
33770d2b6cf9 py3: conditionalize SocketServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29432
diff changeset
29 import SocketServer as socketserver
29432
34b914ac573e py3: conditionalize xmlrpclib import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29431
diff changeset
30 import xmlrpclib
37628
8da30ceae88f pycompat: export a handle on concurrent.futures
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37099
diff changeset
31
8da30ceae88f pycompat: export a handle on concurrent.futures
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37099
diff changeset
32 from .thirdparty.concurrent import futures
37669
1cb54e6193a6 py3: paper over differences in future exception handling
Augie Fackler <augie@google.com>
parents: 37628
diff changeset
33
1cb54e6193a6 py3: paper over differences in future exception handling
Augie Fackler <augie@google.com>
parents: 37628
diff changeset
34 def future_set_exception_info(f, exc_info):
1cb54e6193a6 py3: paper over differences in future exception handling
Augie Fackler <augie@google.com>
parents: 37628
diff changeset
35 f.set_exception_info(*exc_info)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
36
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
37
29584
06587edd1233 pycompat: make pycompat demandimport friendly
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
38 else:
37628
8da30ceae88f pycompat: export a handle on concurrent.futures
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37099
diff changeset
39 import concurrent.futures as futures
31942
bc0579a25f82 pycompat: import correct cookie module on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31934
diff changeset
40 import http.cookiejar as cookielib
29584
06587edd1233 pycompat: make pycompat demandimport friendly
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
41 import http.client as httplib
06587edd1233 pycompat: make pycompat demandimport friendly
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
42 import pickle
37844
8fb9985382be pycompat: export queue module instead of symbols in module (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37669
diff changeset
43 import queue as queue
29584
06587edd1233 pycompat: make pycompat demandimport friendly
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
44 import socketserver
29432
34b914ac573e py3: conditionalize xmlrpclib import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29431
diff changeset
45 import xmlrpc.client as xmlrpclib
29431
80880ad3fccd py3: conditionalize the urlparse import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29414
diff changeset
46
37669
1cb54e6193a6 py3: paper over differences in future exception handling
Augie Fackler <augie@google.com>
parents: 37628
diff changeset
47 def future_set_exception_info(f, exc_info):
1cb54e6193a6 py3: paper over differences in future exception handling
Augie Fackler <augie@google.com>
parents: 37628
diff changeset
48 f.set_exception(exc_info[0])
1cb54e6193a6 py3: paper over differences in future exception handling
Augie Fackler <augie@google.com>
parents: 37628
diff changeset
49
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
50
31774
7d2cbe11ae48 pycompat: introduce identity function as a compat stub
Yuya Nishihara <yuya@tcha.org>
parents: 31573
diff changeset
51 def identity(a):
7d2cbe11ae48 pycompat: introduce identity function as a compat stub
Yuya Nishihara <yuya@tcha.org>
parents: 31573
diff changeset
52 return a
7d2cbe11ae48 pycompat: introduce identity function as a compat stub
Yuya Nishihara <yuya@tcha.org>
parents: 31573
diff changeset
53
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
54
38575
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
55 def _rapply(f, xs):
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
56 if xs is None:
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
57 # assume None means non-value of optional data
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
58 return xs
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
59 if isinstance(xs, (list, set, tuple)):
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
60 return type(xs)(_rapply(f, x) for x in xs)
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
61 if isinstance(xs, dict):
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
62 return type(xs)((_rapply(f, k), _rapply(f, v)) for k, v in xs.items())
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
63 return f(xs)
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
64
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
65
38575
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
66 def rapply(f, xs):
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
67 """Apply function recursively to every item preserving the data structure
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
68
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
69 >>> def f(x):
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
70 ... return 'f(%s)' % x
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
71 >>> rapply(f, None) is None
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
72 True
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
73 >>> rapply(f, 'a')
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
74 'f(a)'
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
75 >>> rapply(f, {'a'}) == {'f(a)'}
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
76 True
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
77 >>> rapply(f, ['a', 'b', None, {'c': 'd'}, []])
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
78 ['f(a)', 'f(b)', None, {'f(c)': 'f(d)'}, []]
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
79
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
80 >>> xs = [object()]
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
81 >>> rapply(identity, xs) is xs
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
82 True
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
83 """
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
84 if f is identity:
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
85 # fast path mainly for py2
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
86 return xs
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
87 return _rapply(f, xs)
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38332
diff changeset
88
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
89
30030
0f6d6fdd3c2a pycompat: provide 'ispy3' constant
Yuya Nishihara <yuya@tcha.org>
parents: 29801
diff changeset
90 if ispy3:
29797
965c91bad9e3 py3: move xrange alias next to import lines
Yuya Nishihara <yuya@tcha.org>
parents: 29779
diff changeset
91 import builtins
43380
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
92 import codecs
29799
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29798
diff changeset
93 import functools
31372
06440ba06bc0 pycompat: move imports of cStringIO/io to where they are used
Yuya Nishihara <yuya@tcha.org>
parents: 31359
diff changeset
94 import io
31424
4acc49335a6e py3: optimize py3 compat.bytechr using Struct.pack
Martin von Zweigbergk <martinvonz@google.com>
parents: 31400
diff changeset
95 import struct
31372
06440ba06bc0 pycompat: move imports of cStringIO/io to where they are used
Yuya Nishihara <yuya@tcha.org>
parents: 31359
diff changeset
96
30119
f4a5e0e86a7e py3: add an os.fsencode backport to ease path handling
Martijn Pieters <mjpieters@fb.com>
parents: 30086
diff changeset
97 fsencode = os.fsencode
30300
42af0590f4b9 py3: add os.fsdecode() as pycompat.fsdecode()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30133
diff changeset
98 fsdecode = os.fsdecode
36648
6585ac350fd9 py3: make os.curdir a bytes
Yuya Nishihara <yuya@tcha.org>
parents: 36647
diff changeset
99 oscurdir = os.curdir.encode('ascii')
31775
8181f378b073 pycompat: provide bytes os.linesep
Yuya Nishihara <yuya@tcha.org>
parents: 31774
diff changeset
100 oslinesep = os.linesep.encode('ascii')
30302
3874ddba1ab4 py3: add a bytes version of os.name
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30300
diff changeset
101 osname = os.name.encode('ascii')
30303
ad40d307a9f0 py3: have pycompat.ospathsep and pycompat.ossep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30302
diff changeset
102 ospathsep = os.pathsep.encode('ascii')
36647
052351e3e1cd py3: make os.pardir a bytes
Yuya Nishihara <yuya@tcha.org>
parents: 36644
diff changeset
103 ospardir = os.pardir.encode('ascii')
30303
ad40d307a9f0 py3: have pycompat.ospathsep and pycompat.ossep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30302
diff changeset
104 ossep = os.sep.encode('ascii')
30623
c6026c20a3ce py3: have a bytes version of os.altsep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30579
diff changeset
105 osaltsep = os.altsep
c6026c20a3ce py3: have a bytes version of os.altsep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30579
diff changeset
106 if osaltsep:
c6026c20a3ce py3: have a bytes version of os.altsep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30579
diff changeset
107 osaltsep = osaltsep.encode('ascii')
39818
24e493ec2229 py3: rename pycompat.getcwd() to encoding.getcwd() (API)
Matt Harbison <matt_harbison@yahoo.com>
parents: 39642
diff changeset
108
30624
a82a6eee2613 py3: have a bytes version of sys.platform
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30623
diff changeset
109 sysplatform = sys.platform.encode('ascii')
30668
3fcaf0f660ce py3: have bytes version of sys.executable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30663
diff changeset
110 sysexecutable = sys.executable
3fcaf0f660ce py3: have bytes version of sys.executable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30663
diff changeset
111 if sysexecutable:
3fcaf0f660ce py3: have bytes version of sys.executable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30663
diff changeset
112 sysexecutable = os.fsencode(sysexecutable)
36958
644a02f6b34f util: prefer "bytesio" to "stringio"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36934
diff changeset
113 bytesio = io.BytesIO
644a02f6b34f util: prefer "bytesio" to "stringio"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36934
diff changeset
114 # TODO deprecate stringio name, as it is a lie on Python 3.
644a02f6b34f util: prefer "bytesio" to "stringio"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36934
diff changeset
115 stringio = bytesio
36934
dbae581010ea pycompat: name maplist() and ziplist() for better traceback message
Yuya Nishihara <yuya@tcha.org>
parents: 36648
diff changeset
116
dbae581010ea pycompat: name maplist() and ziplist() for better traceback message
Yuya Nishihara <yuya@tcha.org>
parents: 36648
diff changeset
117 def maplist(*args):
dbae581010ea pycompat: name maplist() and ziplist() for better traceback message
Yuya Nishihara <yuya@tcha.org>
parents: 36648
diff changeset
118 return list(map(*args))
dbae581010ea pycompat: name maplist() and ziplist() for better traceback message
Yuya Nishihara <yuya@tcha.org>
parents: 36648
diff changeset
119
37064
434e520adb8c annotate: do not construct attr.s object per line while computing history
Yuya Nishihara <yuya@tcha.org>
parents: 36958
diff changeset
120 def rangelist(*args):
434e520adb8c annotate: do not construct attr.s object per line while computing history
Yuya Nishihara <yuya@tcha.org>
parents: 36958
diff changeset
121 return list(range(*args))
434e520adb8c annotate: do not construct attr.s object per line while computing history
Yuya Nishihara <yuya@tcha.org>
parents: 36958
diff changeset
122
36934
dbae581010ea pycompat: name maplist() and ziplist() for better traceback message
Yuya Nishihara <yuya@tcha.org>
parents: 36648
diff changeset
123 def ziplist(*args):
dbae581010ea pycompat: name maplist() and ziplist() for better traceback message
Yuya Nishihara <yuya@tcha.org>
parents: 36648
diff changeset
124 return list(zip(*args))
dbae581010ea pycompat: name maplist() and ziplist() for better traceback message
Yuya Nishihara <yuya@tcha.org>
parents: 36648
diff changeset
125
33853
cfcfbe6c96f8 py3: select input or raw_input by pycompat
Yuya Nishihara <yuya@tcha.org>
parents: 33626
diff changeset
126 rawinput = input
36178
646002338365 py3: introduce and use pycompat.getargspec
Augie Fackler <augie@google.com>
parents: 36045
diff changeset
127 getargspec = inspect.getfullargspec
30334
19d8e19fde5b py3: document why os.fsencode() can be used to get back bytes argv
Yuya Nishihara <yuya@tcha.org>
parents: 30330
diff changeset
128
39456
8d858fbf2759 cbor: teach the encoder to handle python `long` type for Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39302
diff changeset
129 long = int
8d858fbf2759 cbor: teach the encoder to handle python `long` type for Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39302
diff changeset
130
30472
277f4fe6d01a py3: provide bytes stdin/out/err through util module
Yuya Nishihara <yuya@tcha.org>
parents: 30334
diff changeset
131 # TODO: .buffer might not exist if std streams were replaced; we'll need
277f4fe6d01a py3: provide bytes stdin/out/err through util module
Yuya Nishihara <yuya@tcha.org>
parents: 30334
diff changeset
132 # a silly wrapper to make a bytes stream backed by a unicode one.
277f4fe6d01a py3: provide bytes stdin/out/err through util module
Yuya Nishihara <yuya@tcha.org>
parents: 30334
diff changeset
133 stdin = sys.stdin.buffer
277f4fe6d01a py3: provide bytes stdin/out/err through util module
Yuya Nishihara <yuya@tcha.org>
parents: 30334
diff changeset
134 stdout = sys.stdout.buffer
277f4fe6d01a py3: provide bytes stdin/out/err through util module
Yuya Nishihara <yuya@tcha.org>
parents: 30334
diff changeset
135 stderr = sys.stderr.buffer
277f4fe6d01a py3: provide bytes stdin/out/err through util module
Yuya Nishihara <yuya@tcha.org>
parents: 30334
diff changeset
136
30334
19d8e19fde5b py3: document why os.fsencode() can be used to get back bytes argv
Yuya Nishihara <yuya@tcha.org>
parents: 30330
diff changeset
137 # Since Python 3 converts argv to wchar_t type by Py_DecodeLocale() on Unix,
19d8e19fde5b py3: document why os.fsencode() can be used to get back bytes argv
Yuya Nishihara <yuya@tcha.org>
parents: 30330
diff changeset
138 # we can use os.fsencode() to get back bytes argv.
19d8e19fde5b py3: document why os.fsencode() can be used to get back bytes argv
Yuya Nishihara <yuya@tcha.org>
parents: 30330
diff changeset
139 #
19d8e19fde5b py3: document why os.fsencode() can be used to get back bytes argv
Yuya Nishihara <yuya@tcha.org>
parents: 30330
diff changeset
140 # https://hg.python.org/cpython/file/v3.5.1/Programs/python.c#l55
19d8e19fde5b py3: document why os.fsencode() can be used to get back bytes argv
Yuya Nishihara <yuya@tcha.org>
parents: 30330
diff changeset
141 #
19d8e19fde5b py3: document why os.fsencode() can be used to get back bytes argv
Yuya Nishihara <yuya@tcha.org>
parents: 30330
diff changeset
142 # TODO: On Windows, the native argv is wchar_t, so we'll need a different
19d8e19fde5b py3: document why os.fsencode() can be used to get back bytes argv
Yuya Nishihara <yuya@tcha.org>
parents: 30330
diff changeset
143 # workaround to simulate the Python 2 (i.e. ANSI Win32 API) behavior.
31277
86cd1f2cfff5 pycompat: verify sys.argv exists before forwarding it (issue5493)
Augie Fackler <augie@google.com>
parents: 30820
diff changeset
144 if getattr(sys, 'argv', None) is not None:
86cd1f2cfff5 pycompat: verify sys.argv exists before forwarding it (issue5493)
Augie Fackler <augie@google.com>
parents: 30820
diff changeset
145 sysargv = list(map(os.fsencode, sys.argv))
29797
965c91bad9e3 py3: move xrange alias next to import lines
Yuya Nishihara <yuya@tcha.org>
parents: 29779
diff changeset
146
39642
a407f9009392 py3: byteify strings in pycompat
Matt Harbison <matt_harbison@yahoo.com>
parents: 39456
diff changeset
147 bytechr = struct.Struct(r'>B').pack
36265
b44fac3a49fb py3: factor out byterepr() which returns an asciified value on py3
Yuya Nishihara <yuya@tcha.org>
parents: 36178
diff changeset
148 byterepr = b'%r'.__mod__
31253
64596338ba10 py3: factor out bytechr() function
Yuya Nishihara <yuya@tcha.org>
parents: 31149
diff changeset
149
31439
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
150 class bytestr(bytes):
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
151 """A bytes which mostly acts as a Python 2 str
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
152
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
153 >>> bytestr(), bytestr(bytearray(b'foo')), bytestr(u'ascii'), bytestr(1)
35903
1a31111e6239 py3: always drop b'' prefix from repr() of bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 35405
diff changeset
154 ('', 'foo', 'ascii', '1')
31439
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
155 >>> s = bytestr(b'foo')
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
156 >>> assert s is bytestr(s)
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
157
32450
548478efc46c pycompat: try __bytes__() to convert object to bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 32186
diff changeset
158 __bytes__() should be called if provided:
548478efc46c pycompat: try __bytes__() to convert object to bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 32186
diff changeset
159
548478efc46c pycompat: try __bytes__() to convert object to bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 32186
diff changeset
160 >>> class bytesable(object):
548478efc46c pycompat: try __bytes__() to convert object to bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 32186
diff changeset
161 ... def __bytes__(self):
548478efc46c pycompat: try __bytes__() to convert object to bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 32186
diff changeset
162 ... return b'bytes'
548478efc46c pycompat: try __bytes__() to convert object to bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 32186
diff changeset
163 >>> bytestr(bytesable())
35903
1a31111e6239 py3: always drop b'' prefix from repr() of bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 35405
diff changeset
164 'bytes'
32450
548478efc46c pycompat: try __bytes__() to convert object to bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 32186
diff changeset
165
31439
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
166 There's no implicit conversion from non-ascii str as its encoding is
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
167 unknown:
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
168
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
169 >>> bytestr(chr(0x80)) # doctest: +ELLIPSIS
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
170 Traceback (most recent call last):
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
171 ...
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
172 UnicodeEncodeError: ...
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
173
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
174 Comparison between bytestr and bytes should work:
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
175
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
176 >>> assert bytestr(b'foo') == b'foo'
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
177 >>> assert b'foo' == bytestr(b'foo')
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
178 >>> assert b'f' in bytestr(b'foo')
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
179 >>> assert bytestr(b'f') in b'foo'
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
180
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
181 Sliced elements should be bytes, not integer:
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
182
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
183 >>> s[1], s[:2]
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
184 (b'o', b'fo')
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
185 >>> list(s), list(reversed(s))
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
186 ([b'f', b'o', b'o'], [b'o', b'o', b'f'])
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
187
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
188 As bytestr type isn't propagated across operations, you need to cast
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
189 bytes to bytestr explicitly:
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
190
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
191 >>> s = bytestr(b'foo').upper()
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
192 >>> t = bytestr(s)
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
193 >>> s[0], t[0]
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
194 (70, b'F')
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
195
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
196 Be careful to not pass a bytestr object to a function which expects
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
197 bytearray-like behavior.
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
198
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
199 >>> t = bytes(t) # cast to bytes
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
200 >>> assert type(t) is bytes
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
201 """
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
202
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
203 def __new__(cls, s=b''):
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
204 if isinstance(s, bytestr):
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
205 return s
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
206 if not isinstance(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
207 s, (bytes, bytearray)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
208 ) and not hasattr( # hasattr-py3-only
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
209 s, u'__bytes__'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
210 ):
43091
127cc1f72e70 py3: stop normalizing .encode()/.decode() arguments to unicode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43090
diff changeset
211 s = str(s).encode('ascii')
31439
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
212 return bytes.__new__(cls, s)
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
213
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
214 def __getitem__(self, key):
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
215 s = bytes.__getitem__(self, key)
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
216 if not isinstance(s, bytes):
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
217 s = bytechr(s)
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
218 return s
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
219
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
220 def __iter__(self):
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
221 return iterbytestr(bytes.__iter__(self))
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
222
35903
1a31111e6239 py3: always drop b'' prefix from repr() of bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 35405
diff changeset
223 def __repr__(self):
1a31111e6239 py3: always drop b'' prefix from repr() of bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 35405
diff changeset
224 return bytes.__repr__(self)[1:] # drop b''
1a31111e6239 py3: always drop b'' prefix from repr() of bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 35405
diff changeset
225
31382
c9fd842dc886 pycompat: add helper to iterate each char in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31372
diff changeset
226 def iterbytestr(s):
c9fd842dc886 pycompat: add helper to iterate each char in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31372
diff changeset
227 """Iterate bytes as if it were a str object of Python 2"""
31425
63a39d647888 py3: make py3 compat.iterbytestr simpler and faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 31424
diff changeset
228 return map(bytechr, s)
31382
c9fd842dc886 pycompat: add helper to iterate each char in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31372
diff changeset
229
35904
fc44c2657dc5 py3: drop b'' from repr() of smartset
Yuya Nishihara <yuya@tcha.org>
parents: 35903
diff changeset
230 def maybebytestr(s):
fc44c2657dc5 py3: drop b'' from repr() of smartset
Yuya Nishihara <yuya@tcha.org>
parents: 35903
diff changeset
231 """Promote bytes to bytestr"""
fc44c2657dc5 py3: drop b'' from repr() of smartset
Yuya Nishihara <yuya@tcha.org>
parents: 35903
diff changeset
232 if isinstance(s, bytes):
fc44c2657dc5 py3: drop b'' from repr() of smartset
Yuya Nishihara <yuya@tcha.org>
parents: 35903
diff changeset
233 return bytestr(s)
fc44c2657dc5 py3: drop b'' from repr() of smartset
Yuya Nishihara <yuya@tcha.org>
parents: 35903
diff changeset
234 return s
fc44c2657dc5 py3: drop b'' from repr() of smartset
Yuya Nishihara <yuya@tcha.org>
parents: 35903
diff changeset
235
31820
45761ef1bc93 py3: have registrar process docstrings in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31775
diff changeset
236 def sysbytes(s):
45761ef1bc93 py3: have registrar process docstrings in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31775
diff changeset
237 """Convert an internal str (e.g. keyword, __doc__) back to bytes
45761ef1bc93 py3: have registrar process docstrings in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31775
diff changeset
238
45761ef1bc93 py3: have registrar process docstrings in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31775
diff changeset
239 This never raises UnicodeEncodeError, but only ASCII characters
45761ef1bc93 py3: have registrar process docstrings in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31775
diff changeset
240 can be round-trip by sysstr(sysbytes(s)).
45761ef1bc93 py3: have registrar process docstrings in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31775
diff changeset
241 """
43091
127cc1f72e70 py3: stop normalizing .encode()/.decode() arguments to unicode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43090
diff changeset
242 return s.encode('utf-8')
31820
45761ef1bc93 py3: have registrar process docstrings in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31775
diff changeset
243
30032
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
244 def sysstr(s):
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
245 """Return a keyword str to be passed to Python functions such as
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
246 getattr() and str.encode()
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
247
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
248 This never raises UnicodeDecodeError. Non-ascii characters are
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
249 considered invalid and mapped to arbitrary but unique code points
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
250 such that 'sysstr(a) != sysstr(b)' for all 'a != b'.
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
251 """
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
252 if isinstance(s, builtins.str):
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
253 return s
43091
127cc1f72e70 py3: stop normalizing .encode()/.decode() arguments to unicode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43090
diff changeset
254 return s.decode('latin-1')
30032
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
255
32859
a05f3675c46a py3: add a new strurl() which will convert a bytes url to str
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32615
diff changeset
256 def strurl(url):
a05f3675c46a py3: add a new strurl() which will convert a bytes url to str
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32615
diff changeset
257 """Converts a bytes url back to str"""
36644
e2b87e19c6ef pycompat: prevent encoding or decoding values if not required
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36556
diff changeset
258 if isinstance(url, bytes):
43091
127cc1f72e70 py3: stop normalizing .encode()/.decode() arguments to unicode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43090
diff changeset
259 return url.decode('ascii')
36644
e2b87e19c6ef pycompat: prevent encoding or decoding values if not required
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36556
diff changeset
260 return url
32859
a05f3675c46a py3: add a new strurl() which will convert a bytes url to str
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32615
diff changeset
261
32860
f22f39d56bb5 py3: add a new bytesurl() to convert a str url into bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32859
diff changeset
262 def bytesurl(url):
f22f39d56bb5 py3: add a new bytesurl() to convert a str url into bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32859
diff changeset
263 """Converts a str url to bytes by encoding in ascii"""
36644
e2b87e19c6ef pycompat: prevent encoding or decoding values if not required
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36556
diff changeset
264 if isinstance(url, str):
43091
127cc1f72e70 py3: stop normalizing .encode()/.decode() arguments to unicode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43090
diff changeset
265 return url.encode('ascii')
36644
e2b87e19c6ef pycompat: prevent encoding or decoding values if not required
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36556
diff changeset
266 return url
32860
f22f39d56bb5 py3: add a new bytesurl() to convert a str url into bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32859
diff changeset
267
32186
76f9a0009b4b pycompat: extract helper to raise exception with traceback
Yuya Nishihara <yuya@tcha.org>
parents: 31942
diff changeset
268 def raisewithtb(exc, tb):
76f9a0009b4b pycompat: extract helper to raise exception with traceback
Yuya Nishihara <yuya@tcha.org>
parents: 31942
diff changeset
269 """Raise exception with the given traceback"""
76f9a0009b4b pycompat: extract helper to raise exception with traceback
Yuya Nishihara <yuya@tcha.org>
parents: 31942
diff changeset
270 raise exc.with_traceback(tb)
76f9a0009b4b pycompat: extract helper to raise exception with traceback
Yuya Nishihara <yuya@tcha.org>
parents: 31942
diff changeset
271
32615
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
272 def getdoc(obj):
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
273 """Get docstring as bytes; may be None so gettext() won't confuse it
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
274 with _('')"""
43103
c95b2f40db7c py3: stop normalizing 2nd argument of *attr() to unicode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43096
diff changeset
275 doc = getattr(obj, '__doc__', None)
32615
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
276 if doc is None:
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
277 return doc
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
278 return sysbytes(doc)
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
279
29799
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29798
diff changeset
280 def _wrapattrfunc(f):
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29798
diff changeset
281 @functools.wraps(f)
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29798
diff changeset
282 def w(object, name, *args):
30032
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
283 return f(object, sysstr(name), *args)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
284
29799
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29798
diff changeset
285 return w
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29798
diff changeset
286
29800
178c89e8519a py3: import builtin wrappers automagically by code transformer
Yuya Nishihara <yuya@tcha.org>
parents: 29799
diff changeset
287 # these wrappers are automagically imported by hgloader
29799
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29798
diff changeset
288 delattr = _wrapattrfunc(builtins.delattr)
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29798
diff changeset
289 getattr = _wrapattrfunc(builtins.getattr)
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29798
diff changeset
290 hasattr = _wrapattrfunc(builtins.hasattr)
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29798
diff changeset
291 setattr = _wrapattrfunc(builtins.setattr)
29800
178c89e8519a py3: import builtin wrappers automagically by code transformer
Yuya Nishihara <yuya@tcha.org>
parents: 29799
diff changeset
292 xrange = builtins.range
31843
526e4597cca5 py3: add pycompat.unicode and add it to importer
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31842
diff changeset
293 unicode = str
29799
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29798
diff changeset
294
39642
a407f9009392 py3: byteify strings in pycompat
Matt Harbison <matt_harbison@yahoo.com>
parents: 39456
diff changeset
295 def open(name, mode=b'r', buffering=-1, encoding=None):
36556
63fe5ca93b13 pycompat: add support for encoding argument to our wrapper
Augie Fackler <augie@google.com>
parents: 36334
diff changeset
296 return builtins.open(name, sysstr(mode), buffering, encoding)
31149
76a64c1e5439 py3: add pycompat.open and replace open() calls
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30820
diff changeset
297
37099
6ca5f825a0ca util: make safehasattr() a pycompat function
Yuya Nishihara <yuya@tcha.org>
parents: 37064
diff changeset
298 safehasattr = _wrapattrfunc(builtins.hasattr)
6ca5f825a0ca util: make safehasattr() a pycompat function
Yuya Nishihara <yuya@tcha.org>
parents: 37064
diff changeset
299
35226
5b569d512fbd fancyopts: use getopt.gnu_getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 34644
diff changeset
300 def _getoptbwrapper(orig, args, shortlist, namelist):
32864
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
301 """
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
302 Takes bytes arguments, converts them to unicode, pass them to
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
303 getopt.getopt(), convert the returned values back to bytes and then
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
304 return them for Python 3 compatibility as getopt.getopt() don't accepts
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
305 bytes on Python 3.
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
306 """
30578
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30500
diff changeset
307 args = [a.decode('latin-1') for a in args]
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30500
diff changeset
308 shortlist = shortlist.decode('latin-1')
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30500
diff changeset
309 namelist = [a.decode('latin-1') for a in namelist]
35226
5b569d512fbd fancyopts: use getopt.gnu_getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 34644
diff changeset
310 opts, args = orig(args, shortlist, namelist)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
311 opts = [(a[0].encode('latin-1'), a[1].encode('latin-1')) for a in opts]
30578
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30500
diff changeset
312 args = [a.encode('latin-1') for a in args]
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30500
diff changeset
313 return opts, args
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30500
diff changeset
314
30579
fbc3f73dc802 py3: utility functions to convert keys of kwargs to bytes/unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30578
diff changeset
315 def strkwargs(dic):
32864
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
316 """
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
317 Converts the keys of a python dictonary to str i.e. unicodes so that
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
318 they can be passed as keyword arguments as dictonaries with bytes keys
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
319 can't be passed as keyword arguments to functions on Python 3.
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
320 """
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43105
diff changeset
321 dic = dict((k.decode('latin-1'), v) for k, v in dic.items())
30579
fbc3f73dc802 py3: utility functions to convert keys of kwargs to bytes/unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30578
diff changeset
322 return dic
fbc3f73dc802 py3: utility functions to convert keys of kwargs to bytes/unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30578
diff changeset
323
fbc3f73dc802 py3: utility functions to convert keys of kwargs to bytes/unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30578
diff changeset
324 def byteskwargs(dic):
32864
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
325 """
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
326 Converts keys of python dictonaries to bytes as they were converted to
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
327 str to pass that dictonary as a keyword argument on Python 3.
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
328 """
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43105
diff changeset
329 dic = dict((k.encode('latin-1'), v) for k, v in dic.items())
30579
fbc3f73dc802 py3: utility functions to convert keys of kwargs to bytes/unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30578
diff changeset
330 return dic
fbc3f73dc802 py3: utility functions to convert keys of kwargs to bytes/unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30578
diff changeset
331
30678
caf7e1c5efe4 py3: have a bytes version of shlex.split()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30668
diff changeset
332 # TODO: handle shlex.shlex().
36334
4cd2d1cc2a31 pycompat: correct the shlex.split() proxy method signature in py3
Matt Harbison <matt_harbison@yahoo.com>
parents: 36265
diff changeset
333 def shlexsplit(s, comments=False, posix=True):
32864
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
334 """
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
335 Takes bytes argument, convert it to str i.e. unicodes, pass that into
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
336 shlex.split(), convert the returned value to bytes and return that for
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
337 Python 3 compatibility as shelx.split() don't accept bytes on Python 3.
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
338 """
36334
4cd2d1cc2a31 pycompat: correct the shlex.split() proxy method signature in py3
Matt Harbison <matt_harbison@yahoo.com>
parents: 36265
diff changeset
339 ret = shlex.split(s.decode('latin-1'), comments, posix)
30678
caf7e1c5efe4 py3: have a bytes version of shlex.split()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30668
diff changeset
340 return [a.encode('latin-1') for a in ret]
caf7e1c5efe4 py3: have a bytes version of shlex.split()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30668
diff changeset
341
43105
649d3ac37a12 py3: define and use pycompat.iteritems() for hgext/
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43104
diff changeset
342 iteritems = lambda x: x.items()
43104
74802979dd9d py3: define and use pycompat.itervalues()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43103
diff changeset
343 itervalues = lambda x: x.values()
43019
2cc453284d5c patchbomb: protect email addresses from shell
Floris Bruynooghe <flub@google.com>
parents: 40527
diff changeset
344
43380
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
345 # Python 3.5's json.load and json.loads require str. We polyfill its
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
346 # code for detecting encoding from bytes.
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
347 if sys.version_info[0:2] < (3, 6):
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
348
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
349 def _detect_encoding(b):
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
350 bstartswith = b.startswith
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
351 if bstartswith((codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE)):
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
352 return 'utf-32'
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
353 if bstartswith((codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE)):
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
354 return 'utf-16'
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
355 if bstartswith(codecs.BOM_UTF8):
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
356 return 'utf-8-sig'
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
357
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
358 if len(b) >= 4:
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
359 if not b[0]:
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
360 # 00 00 -- -- - utf-32-be
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
361 # 00 XX -- -- - utf-16-be
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
362 return 'utf-16-be' if b[1] else 'utf-32-be'
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
363 if not b[1]:
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
364 # XX 00 00 00 - utf-32-le
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
365 # XX 00 00 XX - utf-16-le
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
366 # XX 00 XX -- - utf-16-le
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
367 return 'utf-16-le' if b[2] or b[3] else 'utf-32-le'
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
368 elif len(b) == 2:
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
369 if not b[0]:
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
370 # 00 XX - utf-16-be
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
371 return 'utf-16-be'
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
372 if not b[1]:
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
373 # XX 00 - utf-16-le
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
374 return 'utf-16-le'
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
375 # default
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
376 return 'utf-8'
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
377
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
378 def json_loads(s, *args, **kwargs):
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
379 if isinstance(s, (bytes, bytearray)):
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
380 s = s.decode(_detect_encoding(s), 'surrogatepass')
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
381
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
382 return json.loads(s, *args, **kwargs)
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
383
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
384 else:
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
385 json_loads = json.loads
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
386
30032
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
387 else:
31372
06440ba06bc0 pycompat: move imports of cStringIO/io to where they are used
Yuya Nishihara <yuya@tcha.org>
parents: 31359
diff changeset
388 import cStringIO
06440ba06bc0 pycompat: move imports of cStringIO/io to where they are used
Yuya Nishihara <yuya@tcha.org>
parents: 31359
diff changeset
389
38782
7eba8f83129b pycompat: add xrange alias for Python 2
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38575
diff changeset
390 xrange = xrange
38312
79dd61a4554f py3: replace `unicode` with pycompat.unicode
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38166
diff changeset
391 unicode = unicode
31253
64596338ba10 py3: factor out bytechr() function
Yuya Nishihara <yuya@tcha.org>
parents: 31149
diff changeset
392 bytechr = chr
36265
b44fac3a49fb py3: factor out byterepr() which returns an asciified value on py3
Yuya Nishihara <yuya@tcha.org>
parents: 36178
diff changeset
393 byterepr = repr
31439
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
394 bytestr = str
31382
c9fd842dc886 pycompat: add helper to iterate each char in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31372
diff changeset
395 iterbytestr = iter
35904
fc44c2657dc5 py3: drop b'' from repr() of smartset
Yuya Nishihara <yuya@tcha.org>
parents: 35903
diff changeset
396 maybebytestr = identity
31820
45761ef1bc93 py3: have registrar process docstrings in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31775
diff changeset
397 sysbytes = identity
31774
7d2cbe11ae48 pycompat: introduce identity function as a compat stub
Yuya Nishihara <yuya@tcha.org>
parents: 31573
diff changeset
398 sysstr = identity
32859
a05f3675c46a py3: add a new strurl() which will convert a bytes url to str
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32615
diff changeset
399 strurl = identity
32860
f22f39d56bb5 py3: add a new bytesurl() to convert a str url into bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32859
diff changeset
400 bytesurl = identity
43085
eef9a2d67051 py3: manually import pycompat.open into files that need it
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
401 open = open
43090
1f339b503a40 py3: manually import pycompat.delattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43089
diff changeset
402 delattr = delattr
43089
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43088
diff changeset
403 getattr = getattr
43088
0d612db7047c py3: stop injecting pycompat.hasattr into modules
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43087
diff changeset
404 hasattr = hasattr
43087
66f2cc210a29 py3: manually import pycompat.setattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
405 setattr = setattr
30032
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
406
32186
76f9a0009b4b pycompat: extract helper to raise exception with traceback
Yuya Nishihara <yuya@tcha.org>
parents: 31942
diff changeset
407 # this can't be parsed on Python 3
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43106
diff changeset
408 exec(b'def raisewithtb(exc, tb):\n raise exc, None, tb\n')
32186
76f9a0009b4b pycompat: extract helper to raise exception with traceback
Yuya Nishihara <yuya@tcha.org>
parents: 31942
diff changeset
409
30133
f6dcda7505f9 pycompat: only accept a bytestring filepath in Python 2
Martijn Pieters <mjpieters@fb.com>
parents: 30119
diff changeset
410 def fsencode(filename):
32864
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
411 """
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
412 Partial backport from os.py in Python 3, which only accepts bytes.
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
413 In Python 2, our paths should only ever be bytes, a unicode path
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
414 indicates a bug.
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
415 """
30133
f6dcda7505f9 pycompat: only accept a bytestring filepath in Python 2
Martijn Pieters <mjpieters@fb.com>
parents: 30119
diff changeset
416 if isinstance(filename, str):
f6dcda7505f9 pycompat: only accept a bytestring filepath in Python 2
Martijn Pieters <mjpieters@fb.com>
parents: 30119
diff changeset
417 return filename
30119
f4a5e0e86a7e py3: add an os.fsencode backport to ease path handling
Martijn Pieters <mjpieters@fb.com>
parents: 30086
diff changeset
418 else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
419 raise TypeError(r"expect str, not %s" % type(filename).__name__)
30119
f4a5e0e86a7e py3: add an os.fsencode backport to ease path handling
Martijn Pieters <mjpieters@fb.com>
parents: 30086
diff changeset
420
30300
42af0590f4b9 py3: add os.fsdecode() as pycompat.fsdecode()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30133
diff changeset
421 # In Python 2, fsdecode() has a very chance to receive bytes. So it's
42af0590f4b9 py3: add os.fsdecode() as pycompat.fsdecode()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30133
diff changeset
422 # better not to touch Python 2 part as it's already working fine.
31774
7d2cbe11ae48 pycompat: introduce identity function as a compat stub
Yuya Nishihara <yuya@tcha.org>
parents: 31573
diff changeset
423 fsdecode = identity
30300
42af0590f4b9 py3: add os.fsdecode() as pycompat.fsdecode()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30133
diff changeset
424
32615
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
425 def getdoc(obj):
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
426 return getattr(obj, '__doc__', None)
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
427
37099
6ca5f825a0ca util: make safehasattr() a pycompat function
Yuya Nishihara <yuya@tcha.org>
parents: 37064
diff changeset
428 _notset = object()
6ca5f825a0ca util: make safehasattr() a pycompat function
Yuya Nishihara <yuya@tcha.org>
parents: 37064
diff changeset
429
6ca5f825a0ca util: make safehasattr() a pycompat function
Yuya Nishihara <yuya@tcha.org>
parents: 37064
diff changeset
430 def safehasattr(thing, attr):
6ca5f825a0ca util: make safehasattr() a pycompat function
Yuya Nishihara <yuya@tcha.org>
parents: 37064
diff changeset
431 return getattr(thing, attr, _notset) is not _notset
6ca5f825a0ca util: make safehasattr() a pycompat function
Yuya Nishihara <yuya@tcha.org>
parents: 37064
diff changeset
432
35226
5b569d512fbd fancyopts: use getopt.gnu_getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 34644
diff changeset
433 def _getoptbwrapper(orig, args, shortlist, namelist):
5b569d512fbd fancyopts: use getopt.gnu_getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 34644
diff changeset
434 return orig(args, shortlist, namelist)
30578
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30500
diff changeset
435
31774
7d2cbe11ae48 pycompat: introduce identity function as a compat stub
Yuya Nishihara <yuya@tcha.org>
parents: 31573
diff changeset
436 strkwargs = identity
7d2cbe11ae48 pycompat: introduce identity function as a compat stub
Yuya Nishihara <yuya@tcha.org>
parents: 31573
diff changeset
437 byteskwargs = identity
30579
fbc3f73dc802 py3: utility functions to convert keys of kwargs to bytes/unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30578
diff changeset
438
36648
6585ac350fd9 py3: make os.curdir a bytes
Yuya Nishihara <yuya@tcha.org>
parents: 36647
diff changeset
439 oscurdir = os.curdir
31775
8181f378b073 pycompat: provide bytes os.linesep
Yuya Nishihara <yuya@tcha.org>
parents: 31774
diff changeset
440 oslinesep = os.linesep
30302
3874ddba1ab4 py3: add a bytes version of os.name
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30300
diff changeset
441 osname = os.name
30303
ad40d307a9f0 py3: have pycompat.ospathsep and pycompat.ossep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30302
diff changeset
442 ospathsep = os.pathsep
36647
052351e3e1cd py3: make os.pardir a bytes
Yuya Nishihara <yuya@tcha.org>
parents: 36644
diff changeset
443 ospardir = os.pardir
30303
ad40d307a9f0 py3: have pycompat.ospathsep and pycompat.ossep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30302
diff changeset
444 ossep = os.sep
30623
c6026c20a3ce py3: have a bytes version of os.altsep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30579
diff changeset
445 osaltsep = os.altsep
39456
8d858fbf2759 cbor: teach the encoder to handle python `long` type for Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39302
diff changeset
446 long = long
30472
277f4fe6d01a py3: provide bytes stdin/out/err through util module
Yuya Nishihara <yuya@tcha.org>
parents: 30334
diff changeset
447 stdin = sys.stdin
277f4fe6d01a py3: provide bytes stdin/out/err through util module
Yuya Nishihara <yuya@tcha.org>
parents: 30334
diff changeset
448 stdout = sys.stdout
277f4fe6d01a py3: provide bytes stdin/out/err through util module
Yuya Nishihara <yuya@tcha.org>
parents: 30334
diff changeset
449 stderr = sys.stderr
31277
86cd1f2cfff5 pycompat: verify sys.argv exists before forwarding it (issue5493)
Augie Fackler <augie@google.com>
parents: 30820
diff changeset
450 if getattr(sys, 'argv', None) is not None:
86cd1f2cfff5 pycompat: verify sys.argv exists before forwarding it (issue5493)
Augie Fackler <augie@google.com>
parents: 30820
diff changeset
451 sysargv = sys.argv
30624
a82a6eee2613 py3: have a bytes version of sys.platform
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30623
diff changeset
452 sysplatform = sys.platform
30668
3fcaf0f660ce py3: have bytes version of sys.executable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30663
diff changeset
453 sysexecutable = sys.executable
30678
caf7e1c5efe4 py3: have a bytes version of shlex.split()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30668
diff changeset
454 shlexsplit = shlex.split
36958
644a02f6b34f util: prefer "bytesio" to "stringio"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36934
diff changeset
455 bytesio = cStringIO.StringIO
644a02f6b34f util: prefer "bytesio" to "stringio"
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36934
diff changeset
456 stringio = bytesio
31501
a1e40ceee640 pycompat: add maplist alias for old map behavior
Augie Fackler <augie@google.com>
parents: 31439
diff changeset
457 maplist = map
37064
434e520adb8c annotate: do not construct attr.s object per line while computing history
Yuya Nishihara <yuya@tcha.org>
parents: 36958
diff changeset
458 rangelist = range
35405
e66d6e938d2d py3: introduce pycompat.ziplist as zip is a generator on Python 3
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35226
diff changeset
459 ziplist = zip
33853
cfcfbe6c96f8 py3: select input or raw_input by pycompat
Yuya Nishihara <yuya@tcha.org>
parents: 33626
diff changeset
460 rawinput = raw_input
36178
646002338365 py3: introduce and use pycompat.getargspec
Augie Fackler <augie@google.com>
parents: 36045
diff changeset
461 getargspec = inspect.getargspec
43105
649d3ac37a12 py3: define and use pycompat.iteritems() for hgext/
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43104
diff changeset
462 iteritems = lambda x: x.iteritems()
43104
74802979dd9d py3: define and use pycompat.itervalues()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43103
diff changeset
463 itervalues = lambda x: x.itervalues()
43380
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
464 json_loads = json.loads
34639
a568a46751b6 selectors2: do not use platform.system()
Jun Wu <quark@fb.com>
parents: 34467
diff changeset
465
39642
a407f9009392 py3: byteify strings in pycompat
Matt Harbison <matt_harbison@yahoo.com>
parents: 39456
diff changeset
466 isjython = sysplatform.startswith(b'java')
34644
c0a6c19690ff pycompat: define operating system constants
Jun Wu <quark@fb.com>
parents: 34639
diff changeset
467
40527
1b49b84d5ed5 pycompat: adding Linux detection and fixing Mac
rdamazio@google.com
parents: 39818
diff changeset
468 isdarwin = sysplatform.startswith(b'darwin')
1b49b84d5ed5 pycompat: adding Linux detection and fixing Mac
rdamazio@google.com
parents: 39818
diff changeset
469 islinux = sysplatform.startswith(b'linux')
39642
a407f9009392 py3: byteify strings in pycompat
Matt Harbison <matt_harbison@yahoo.com>
parents: 39456
diff changeset
470 isposix = osname == b'posix'
a407f9009392 py3: byteify strings in pycompat
Matt Harbison <matt_harbison@yahoo.com>
parents: 39456
diff changeset
471 iswindows = osname == b'nt'
35226
5b569d512fbd fancyopts: use getopt.gnu_getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 34644
diff changeset
472
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
473
35226
5b569d512fbd fancyopts: use getopt.gnu_getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 34644
diff changeset
474 def getoptb(args, shortlist, namelist):
5b569d512fbd fancyopts: use getopt.gnu_getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 34644
diff changeset
475 return _getoptbwrapper(getopt.getopt, args, shortlist, namelist)
5b569d512fbd fancyopts: use getopt.gnu_getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 34644
diff changeset
476
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
477
35226
5b569d512fbd fancyopts: use getopt.gnu_getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 34644
diff changeset
478 def gnugetoptb(args, shortlist, namelist):
5b569d512fbd fancyopts: use getopt.gnu_getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 34644
diff changeset
479 return _getoptbwrapper(getopt.gnu_getopt, args, shortlist, namelist)
38164
aac4be30e250 py3: wrap tempfile.mkstemp() to use bytes path
Yuya Nishihara <yuya@tcha.org>
parents: 37844
diff changeset
480
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
481
38165
2ce60954b1b7 py3: wrap tempfile.mkdtemp() to use bytes path
Yuya Nishihara <yuya@tcha.org>
parents: 38164
diff changeset
482 def mkdtemp(suffix=b'', prefix=b'tmp', dir=None):
2ce60954b1b7 py3: wrap tempfile.mkdtemp() to use bytes path
Yuya Nishihara <yuya@tcha.org>
parents: 38164
diff changeset
483 return tempfile.mkdtemp(suffix, prefix, dir)
2ce60954b1b7 py3: wrap tempfile.mkdtemp() to use bytes path
Yuya Nishihara <yuya@tcha.org>
parents: 38164
diff changeset
484
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
485
38164
aac4be30e250 py3: wrap tempfile.mkstemp() to use bytes path
Yuya Nishihara <yuya@tcha.org>
parents: 37844
diff changeset
486 # text=True is not supported; use util.from/tonativeeol() instead
aac4be30e250 py3: wrap tempfile.mkstemp() to use bytes path
Yuya Nishihara <yuya@tcha.org>
parents: 37844
diff changeset
487 def mkstemp(suffix=b'', prefix=b'tmp', dir=None):
aac4be30e250 py3: wrap tempfile.mkstemp() to use bytes path
Yuya Nishihara <yuya@tcha.org>
parents: 37844
diff changeset
488 return tempfile.mkstemp(suffix, prefix, dir)
38166
cc9aa88792fe py3: wrap tempfile.NamedTemporaryFile() to return bytes fp.name
Yuya Nishihara <yuya@tcha.org>
parents: 38165
diff changeset
489
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
490
38166
cc9aa88792fe py3: wrap tempfile.NamedTemporaryFile() to return bytes fp.name
Yuya Nishihara <yuya@tcha.org>
parents: 38165
diff changeset
491 # mode must include 'b'ytes as encoding= is not supported
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
492 def namedtempfile(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
493 mode=b'w+b', bufsize=-1, suffix=b'', prefix=b'tmp', dir=None, delete=True
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
494 ):
38166
cc9aa88792fe py3: wrap tempfile.NamedTemporaryFile() to return bytes fp.name
Yuya Nishihara <yuya@tcha.org>
parents: 38165
diff changeset
495 mode = sysstr(mode)
cc9aa88792fe py3: wrap tempfile.NamedTemporaryFile() to return bytes fp.name
Yuya Nishihara <yuya@tcha.org>
parents: 38165
diff changeset
496 assert r'b' in mode
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
497 return tempfile.NamedTemporaryFile(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
498 mode, bufsize, suffix=suffix, prefix=prefix, dir=dir, delete=delete
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43019
diff changeset
499 )