--- a/mercurial/util.py Sun Oct 06 09:45:02 2019 -0400
+++ b/mercurial/util.py Sun Oct 06 09:48:39 2019 -0400
@@ -151,7 +151,7 @@
# python 2.6 still have deprecation warning enabled by default. We do not want
# to display anything to standard user so detect if we are running test and
# only use python deprecation warning in this case.
-_dowarn = bool(encoding.environ.get('HGEMITWARNINGS'))
+_dowarn = bool(encoding.environ.get(b'HGEMITWARNINGS'))
if _dowarn:
# explicitly unfilter our warning for python 2.7
#
@@ -186,19 +186,19 @@
"""
if _dowarn:
msg += (
- "\n(compatibility will be dropped after Mercurial-%s,"
- " update your code.)"
+ b"\n(compatibility will be dropped after Mercurial-%s,"
+ b" update your code.)"
) % version
warnings.warn(pycompat.sysstr(msg), DeprecationWarning, stacklevel + 1)
DIGESTS = {
- 'md5': hashlib.md5,
- 'sha1': hashlib.sha1,
- 'sha512': hashlib.sha512,
+ b'md5': hashlib.md5,
+ b'sha1': hashlib.sha1,
+ b'sha512': hashlib.sha512,
}
# List of digest types from strongest to weakest
-DIGESTS_BY_STRENGTH = ['sha512', 'sha1', 'md5']
+DIGESTS_BY_STRENGTH = [b'sha512', b'sha1', b'md5']
for k in DIGESTS_BY_STRENGTH:
assert k in DIGESTS
@@ -221,11 +221,11 @@
'sha1'
"""
- def __init__(self, digests, s=''):
+ def __init__(self, digests, s=b''):
self._hashes = {}
for k in digests:
if k not in DIGESTS:
- raise error.Abort(_('unknown digest type: %s') % k)
+ raise error.Abort(_(b'unknown digest type: %s') % k)
self._hashes[k] = DIGESTS[k]()
if s:
self.update(s)
@@ -236,7 +236,7 @@
def __getitem__(self, key):
if key not in DIGESTS:
- raise error.Abort(_('unknown digest type: %s') % k)
+ raise error.Abort(_(b'unknown digest type: %s') % k)
return nodemod.hex(self._hashes[key].digest())
def __iter__(self):
@@ -277,14 +277,14 @@
def validate(self):
if self._size != self._got:
raise error.Abort(
- _('size mismatch: expected %d, got %d')
+ _(b'size mismatch: expected %d, got %d')
% (self._size, self._got)
)
for k, v in self._digests.items():
if v != self._digester[k]:
# i18n: first parameter is a digest name
raise error.Abort(
- _('%s mismatch: expected %s, got %s')
+ _(b'%s mismatch: expected %s, got %s')
% (k, v, self._digester[k])
)
@@ -363,15 +363,15 @@
if len(self._buffer) > 1:
# this should not happen because both read and readline end with a
# _frombuffer call that collapse it.
- self._buffer = [''.join(self._buffer)]
+ self._buffer = [b''.join(self._buffer)]
self._lenbuf = len(self._buffer[0])
lfi = -1
if self._buffer:
- lfi = self._buffer[-1].find('\n')
+ lfi = self._buffer[-1].find(b'\n')
while (not self._eof) and lfi < 0:
self._fillbuffer()
if self._buffer:
- lfi = self._buffer[-1].find('\n')
+ lfi = self._buffer[-1].find(b'\n')
size = lfi + 1
if lfi < 0: # end of file
size = self._lenbuf
@@ -385,10 +385,10 @@
The data are removed from the buffer."""
if size == 0 or not self._buffer:
- return ''
+ return b''
buf = self._buffer[0]
if len(self._buffer) > 1:
- buf = ''.join(self._buffer)
+ buf = b''.join(self._buffer)
data = buf[:size]
buf = buf[len(data) :]
@@ -420,7 +420,7 @@
# Empty files cannot be mmapped, but mmapread should still work. Check
# if the file is empty, and if so, return an empty buffer.
if os.fstat(fd).st_size == 0:
- return ''
+ return b''
raise
@@ -787,29 +787,29 @@
def _writedata(self, data):
if not self.logdata:
if self.logdataapis:
- self.fh.write('\n')
+ self.fh.write(b'\n')
self.fh.flush()
return
# Simple case writes all data on a single line.
if b'\n' not in data:
if self.logdataapis:
- self.fh.write(': %s\n' % stringutil.escapestr(data))
+ self.fh.write(b': %s\n' % stringutil.escapestr(data))
else:
self.fh.write(
- '%s> %s\n' % (self.name, stringutil.escapestr(data))
+ b'%s> %s\n' % (self.name, stringutil.escapestr(data))
)
self.fh.flush()
return
# Data with newlines is written to multiple lines.
if self.logdataapis:
- self.fh.write(':\n')
+ self.fh.write(b':\n')
lines = data.splitlines(True)
for line in lines:
self.fh.write(
- '%s> %s\n' % (self.name, stringutil.escapestr(line))
+ b'%s> %s\n' % (self.name, stringutil.escapestr(line))
)
self.fh.flush()
@@ -832,9 +832,9 @@
return
# Python 3 can return None from reads at EOF instead of empty strings.
if res is None:
- res = ''
-
- if size == -1 and res == '':
+ res = b''
+
+ if size == -1 and res == b'':
# Suppress pointless read(-1) calls that return
# nothing. These happen _a lot_ on Python 3, and there
# doesn't seem to be a better workaround to have matching
@@ -842,7 +842,7 @@
return
if self.logdataapis:
- self.fh.write('%s> read(%d) -> %d' % (self.name, size, len(res)))
+ self.fh.write(b'%s> read(%d) -> %d' % (self.name, size, len(res)))
self._writedata(res)
@@ -851,7 +851,7 @@
return
if self.logdataapis:
- self.fh.write('%s> readline() -> %d' % (self.name, len(res)))
+ self.fh.write(b'%s> readline() -> %d' % (self.name, len(res)))
self._writedata(res)
@@ -861,7 +861,7 @@
if self.logdataapis:
self.fh.write(
- '%s> readinto(%d) -> %r' % (self.name, len(dest), res)
+ b'%s> readinto(%d) -> %r' % (self.name, len(dest), res)
)
data = dest[0:res] if res is not None else b''
@@ -883,7 +883,7 @@
res = len(data)
if self.logdataapis:
- self.fh.write('%s> write(%d) -> %r' % (self.name, len(data), res))
+ self.fh.write(b'%s> write(%d) -> %r' % (self.name, len(data), res))
self._writedata(data)
@@ -891,7 +891,7 @@
if not self.writes:
return
- self.fh.write('%s> flush() -> %r\n' % (self.name, res))
+ self.fh.write(b'%s> flush() -> %r\n' % (self.name, res))
# For observedbufferedinputpipe.
def bufferedread(self, res, size):
@@ -900,7 +900,7 @@
if self.logdataapis:
self.fh.write(
- '%s> bufferedread(%d) -> %d' % (self.name, size, len(res))
+ b'%s> bufferedread(%d) -> %d' % (self.name, size, len(res))
)
self._writedata(res)
@@ -911,7 +911,7 @@
if self.logdataapis:
self.fh.write(
- '%s> bufferedreadline() -> %d' % (self.name, len(res))
+ b'%s> bufferedreadline() -> %d' % (self.name, len(res))
)
self._writedata(res)
@@ -958,7 +958,7 @@
if not self.states:
return
- self.fh.write('%s> makefile(%r, %r)\n' % (self.name, mode, bufsize))
+ self.fh.write(b'%s> makefile(%r, %r)\n' % (self.name, mode, bufsize))
def recv(self, res, size, flags=0):
if not self.reads:
@@ -966,7 +966,7 @@
if self.logdataapis:
self.fh.write(
- '%s> recv(%d, %d) -> %d' % (self.name, size, flags, len(res))
+ b'%s> recv(%d, %d) -> %d' % (self.name, size, flags, len(res))
)
self._writedata(res)
@@ -976,7 +976,7 @@
if self.logdataapis:
self.fh.write(
- '%s> recvfrom(%d, %d) -> %d'
+ b'%s> recvfrom(%d, %d) -> %d'
% (self.name, size, flags, len(res[0]))
)
@@ -988,7 +988,7 @@
if self.logdataapis:
self.fh.write(
- '%s> recvfrom_into(%d, %d) -> %d'
+ b'%s> recvfrom_into(%d, %d) -> %d'
% (self.name, size, flags, res[0])
)
@@ -1000,7 +1000,7 @@
if self.logdataapis:
self.fh.write(
- '%s> recv_into(%d, %d) -> %d' % (self.name, size, flags, res)
+ b'%s> recv_into(%d, %d) -> %d' % (self.name, size, flags, res)
)
self._writedata(buf[0:res])
@@ -1010,7 +1010,7 @@
return
self.fh.write(
- '%s> send(%d, %d) -> %d' % (self.name, len(data), flags, len(res))
+ b'%s> send(%d, %d) -> %d' % (self.name, len(data), flags, len(res))
)
self._writedata(data)
@@ -1020,7 +1020,9 @@
if self.logdataapis:
# Returns None on success. So don't bother reporting return value.
- self.fh.write('%s> sendall(%d, %d)' % (self.name, len(data), flags))
+ self.fh.write(
+ b'%s> sendall(%d, %d)' % (self.name, len(data), flags)
+ )
self._writedata(data)
@@ -1035,7 +1037,7 @@
if self.logdataapis:
self.fh.write(
- '%s> sendto(%d, %d, %r) -> %d'
+ b'%s> sendto(%d, %d, %r) -> %d'
% (self.name, len(data), flags, address, res)
)
@@ -1045,26 +1047,26 @@
if not self.states:
return
- self.fh.write('%s> setblocking(%r)\n' % (self.name, flag))
+ self.fh.write(b'%s> setblocking(%r)\n' % (self.name, flag))
def settimeout(self, res, value):
if not self.states:
return
- self.fh.write('%s> settimeout(%r)\n' % (self.name, value))
+ self.fh.write(b'%s> settimeout(%r)\n' % (self.name, value))
def gettimeout(self, res):
if not self.states:
return
- self.fh.write('%s> gettimeout() -> %f\n' % (self.name, res))
+ self.fh.write(b'%s> gettimeout() -> %f\n' % (self.name, res))
def setsockopt(self, res, level, optname, value):
if not self.states:
return
self.fh.write(
- '%s> setsockopt(%r, %r, %r) -> %r\n'
+ b'%s> setsockopt(%r, %r, %r) -> %r\n'
% (self.name, level, optname, value, res)
)
@@ -1100,7 +1102,7 @@
return __version__.version
except ImportError:
- return 'unknown'
+ return b'unknown'
def versiontuple(v=None, n=4):
@@ -1162,14 +1164,14 @@
v = version()
m = remod.match(br'(\d+(?:\.\d+){,2})[\+-]?(.*)', v)
if not m:
- vparts, extra = '', v
+ vparts, extra = b'', v
elif m.group(2):
vparts, extra = m.groups()
else:
vparts, extra = m.group(1), None
vints = []
- for i in vparts.split('.'):
+ for i in vparts.split(b'.'):
try:
vints.append(int(i))
except ValueError:
@@ -1744,11 +1746,11 @@
min = nmin
if min > max:
min = max
- yield ''.join(buf)
+ yield b''.join(buf)
blen = 0
buf = []
if buf:
- yield ''.join(buf)
+ yield b''.join(buf)
def always(fn):
@@ -1806,19 +1808,19 @@
if os.path.isabs(n1):
if os.path.splitdrive(root)[0] != os.path.splitdrive(n1)[0]:
return os.path.join(root, localpath(n2))
- n2 = '/'.join((pconvert(root), n2))
- a, b = splitpath(n1), n2.split('/')
+ n2 = b'/'.join((pconvert(root), n2))
+ a, b = splitpath(n1), n2.split(b'/')
a.reverse()
b.reverse()
while a and b and a[-1] == b[-1]:
a.pop()
b.pop()
b.reverse()
- return pycompat.ossep.join((['..'] * len(a)) + b) or '.'
+ return pycompat.ossep.join(([b'..'] * len(a)) + b) or b'.'
# the location of data files matching the source code
-if procutil.mainfrozen() and getattr(sys, 'frozen', None) != 'macosx_app':
+if procutil.mainfrozen() and getattr(sys, 'frozen', None) != b'macosx_app':
# executable version (py2exe) doesn't support __file__
datapath = os.path.dirname(pycompat.sysexecutable)
else:
@@ -1843,19 +1845,19 @@
# a whilelist of known filesystems where hardlink works reliably
_hardlinkfswhitelist = {
- 'apfs',
- 'btrfs',
- 'ext2',
- 'ext3',
- 'ext4',
- 'hfs',
- 'jfs',
- 'NTFS',
- 'reiserfs',
- 'tmpfs',
- 'ufs',
- 'xfs',
- 'zfs',
+ b'apfs',
+ b'btrfs',
+ b'ext2',
+ b'ext3',
+ b'ext4',
+ b'hfs',
+ b'jfs',
+ b'NTFS',
+ b'reiserfs',
+ b'tmpfs',
+ b'ufs',
+ b'xfs',
+ b'zfs',
}
@@ -1920,7 +1922,7 @@
def settopic():
if progress:
- progress.topic = _('linking') if hardlink else _('copying')
+ progress.topic = _(b'linking') if hardlink else _(b'copying')
if os.path.isdir(src):
if hardlink is None:
@@ -1958,30 +1960,30 @@
_winreservednames = {
- 'con',
- 'prn',
- 'aux',
- 'nul',
- 'com1',
- 'com2',
- 'com3',
- 'com4',
- 'com5',
- 'com6',
- 'com7',
- 'com8',
- 'com9',
- 'lpt1',
- 'lpt2',
- 'lpt3',
- 'lpt4',
- 'lpt5',
- 'lpt6',
- 'lpt7',
- 'lpt8',
- 'lpt9',
+ b'con',
+ b'prn',
+ b'aux',
+ b'nul',
+ b'com1',
+ b'com2',
+ b'com3',
+ b'com4',
+ b'com5',
+ b'com6',
+ b'com7',
+ b'com8',
+ b'com9',
+ b'lpt1',
+ b'lpt2',
+ b'lpt3',
+ b'lpt4',
+ b'lpt5',
+ b'lpt6',
+ b'lpt7',
+ b'lpt8',
+ b'lpt9',
}
-_winreservedchars = ':*?"<>|'
+_winreservedchars = b':*?"<>|'
def checkwinfilename(path):
@@ -2008,33 +2010,39 @@
>>> checkwinfilename(b"foo\\/bar")
"directory name ends with '\\', which is invalid on Windows"
'''
- if path.endswith('\\'):
- return _("filename ends with '\\', which is invalid on Windows")
- if '\\/' in path:
- return _("directory name ends with '\\', which is invalid on Windows")
- for n in path.replace('\\', '/').split('/'):
+ if path.endswith(b'\\'):
+ return _(b"filename ends with '\\', which is invalid on Windows")
+ if b'\\/' in path:
+ return _(b"directory name ends with '\\', which is invalid on Windows")
+ for n in path.replace(b'\\', b'/').split(b'/'):
if not n:
continue
for c in _filenamebytestr(n):
if c in _winreservedchars:
return (
- _("filename contains '%s', which is reserved " "on Windows")
+ _(
+ b"filename contains '%s', which is reserved "
+ b"on Windows"
+ )
% c
)
if ord(c) <= 31:
return _(
- "filename contains '%s', which is invalid " "on Windows"
+ b"filename contains '%s', which is invalid " b"on Windows"
) % stringutil.escapestr(c)
- base = n.split('.')[0]
+ base = n.split(b'.')[0]
if base and base.lower() in _winreservednames:
return (
- _("filename contains '%s', which is reserved " "on Windows")
+ _(b"filename contains '%s', which is reserved " b"on Windows")
% base
)
t = n[-1:]
- if t in '. ' and n not in '..':
+ if t in b'. ' and n not in b'..':
return (
- _("filename ends with '%s', which is not allowed " "on Windows")
+ _(
+ b"filename ends with '%s', which is not allowed "
+ b"on Windows"
+ )
% t
)
@@ -2078,7 +2086,7 @@
raise
except AttributeError: # no symlink in os
pass
- with posixfile(pathname, 'rb') as fp:
+ with posixfile(pathname, b'rb') as fp:
return fp.read()
@@ -2130,7 +2138,7 @@
global _re2
try:
# check if match works, see issue3964
- _re2 = bool(re2.match(r'\[([^\[]+)\]', '[ui]'))
+ _re2 = bool(re2.match(r'\[([^\[]+)\]', b'[ui]'))
except ImportError:
_re2 = False
@@ -2144,9 +2152,9 @@
self._checkre2()
if _re2 and (flags & ~(remod.IGNORECASE | remod.MULTILINE)) == 0:
if flags & remod.IGNORECASE:
- pat = '(?i)' + pat
+ pat = b'(?i)' + pat
if flags & remod.MULTILINE:
- pat = '(?m)' + pat
+ pat = b'(?m)' + pat
try:
return re2.compile(pat)
except re2.error:
@@ -2192,7 +2200,7 @@
if pycompat.osaltsep:
seps = seps + pycompat.osaltsep
# Protect backslashes. This gets silly very quickly.
- seps.replace('\\', '\\\\')
+ seps.replace(b'\\', b'\\\\')
pattern = remod.compile(br'([^%s]+)|([%s]+)' % (seps, seps))
dir = os.path.normpath(root)
result = []
@@ -2215,7 +2223,7 @@
result.append(found or part)
dir = os.path.join(dir, part)
- return ''.join(result)
+ return b''.join(result)
def checknlink(testfile):
@@ -2226,12 +2234,12 @@
f1, f2, fp = None, None, None
try:
fd, f1 = pycompat.mkstemp(
- prefix='.%s-' % os.path.basename(testfile),
- suffix='1~',
+ prefix=b'.%s-' % os.path.basename(testfile),
+ suffix=b'1~',
dir=os.path.dirname(testfile),
)
os.close(fd)
- f2 = '%s2~' % f1[:-2]
+ f2 = b'%s2~' % f1[:-2]
oslink(f1, f2)
# nlinks() may behave differently for files on Windows shares if
@@ -2280,7 +2288,7 @@
Returns the name of the temporary file.
"""
d, fn = os.path.split(name)
- fd, temp = pycompat.mkstemp(prefix='.%s-' % fn, suffix='~', dir=d)
+ fd, temp = pycompat.mkstemp(prefix=b'.%s-' % fn, suffix=b'~', dir=d)
os.close(fd)
# Temporary files are created with mode 0600, which is usually not
# what we want. If the original file already exists, just copy
@@ -2291,14 +2299,14 @@
return temp
try:
try:
- ifp = posixfile(name, "rb")
+ ifp = posixfile(name, b"rb")
except IOError as inst:
if inst.errno == errno.ENOENT:
return temp
if not getattr(inst, 'filename', None):
inst.filename = name
raise
- ofp = posixfile(temp, "wb")
+ ofp = posixfile(temp, b"wb")
for chunk in filechunkiter(ifp):
ofp.write(chunk)
ifp.close()
@@ -2432,13 +2440,13 @@
or repo.wlock).
'''
- def __init__(self, name, mode='w+b', createmode=None, checkambig=False):
+ def __init__(self, name, mode=b'w+b', createmode=None, checkambig=False):
self.__name = name # permanent name
self._tempname = mktempcopy(
name,
- emptyok=('w' in mode),
+ emptyok=(b'w' in mode),
createmode=createmode,
- enforcewritable=('w' in mode),
+ enforcewritable=(b'w' in mode),
)
self._fp = posixfile(self._tempname, mode)
@@ -2541,17 +2549,17 @@
def readfile(path):
- with open(path, 'rb') as fp:
+ with open(path, b'rb') as fp:
return fp.read()
def writefile(path, text):
- with open(path, 'wb') as fp:
+ with open(path, b'wb') as fp:
fp.write(text)
def appendfile(path, text):
- with open(path, 'ab') as fp:
+ with open(path, b'ab') as fp:
fp.write(text)
@@ -2583,7 +2591,7 @@
If size parameter is omitted, read everything"""
if l is None:
- return ''.join(self.iter)
+ return b''.join(self.iter)
left = l
buf = []
@@ -2635,7 +2643,7 @@
self._chunkoffset += left
left -= chunkremaining
- return ''.join(buf)
+ return b''.join(buf)
def filechunkiter(f, size=131072, limit=None):
@@ -2727,23 +2735,23 @@
ParseError: fromline must be strictly positive
"""
if toline - fromline < 0:
- raise error.ParseError(_("line range must be positive"))
+ raise error.ParseError(_(b"line range must be positive"))
if fromline < 1:
- raise error.ParseError(_("fromline must be strictly positive"))
+ raise error.ParseError(_(b"fromline must be strictly positive"))
return fromline - 1, toline
bytecount = unitcountfn(
- (100, 1 << 30, _('%.0f GB')),
- (10, 1 << 30, _('%.1f GB')),
- (1, 1 << 30, _('%.2f GB')),
- (100, 1 << 20, _('%.0f MB')),
- (10, 1 << 20, _('%.1f MB')),
- (1, 1 << 20, _('%.2f MB')),
- (100, 1 << 10, _('%.0f KB')),
- (10, 1 << 10, _('%.1f KB')),
- (1, 1 << 10, _('%.2f KB')),
- (1, 1, _('%.0f bytes')),
+ (100, 1 << 30, _(b'%.0f GB')),
+ (10, 1 << 30, _(b'%.1f GB')),
+ (1, 1 << 30, _(b'%.2f GB')),
+ (100, 1 << 20, _(b'%.0f MB')),
+ (10, 1 << 20, _(b'%.1f MB')),
+ (1, 1 << 20, _(b'%.2f MB')),
+ (100, 1 << 10, _(b'%.0f KB')),
+ (10, 1 << 10, _(b'%.1f KB')),
+ (1, 1 << 10, _(b'%.2f KB')),
+ (1, 1, _(b'%.0f bytes')),
)
@@ -2771,18 +2779,18 @@
def tolf(s):
- return _eolre.sub('\n', s)
+ return _eolre.sub(b'\n', s)
def tocrlf(s):
- return _eolre.sub('\r\n', s)
+ return _eolre.sub(b'\r\n', s)
def _crlfwriter(fp):
return transformingwriter(fp, tocrlf)
-if pycompat.oslinesep == '\r\n':
+if pycompat.oslinesep == b'\r\n':
tonativeeol = tocrlf
fromnativeeol = tolf
nativeeolwriter = _crlfwriter
@@ -2791,7 +2799,7 @@
fromnativeeol = pycompat.identity
nativeeolwriter = pycompat.identity
-if pyplatform.python_implementation() == 'CPython' and sys.version_info < (
+if pyplatform.python_implementation() == b'CPython' and sys.version_info < (
3,
0,
):
@@ -2822,14 +2830,14 @@
if sys.version_info >= (2, 7, 4):
# fp.readline deals with EINTR correctly, use it as a workaround.
def _safeiterfile(fp):
- return iter(fp.readline, '')
+ return iter(fp.readline, b'')
else:
# fp.read* are broken too, manually deal with EINTR in a stupid way.
# note: this may block longer than necessary because of bufsize.
def _safeiterfile(fp, bufsize=4096):
fd = fp.fileno()
- line = ''
+ line = b''
while True:
try:
buf = os.read(fd, bufsize)
@@ -2840,11 +2848,11 @@
else:
raise
line += buf
- if '\n' in buf:
+ if b'\n' in buf:
splitted = line.splitlines(True)
- line = ''
+ line = b''
for l in splitted:
- if l[-1] == '\n':
+ if l[-1] == b'\n':
yield l
else:
line = l
@@ -2893,9 +2901,9 @@
its escaping.
"""
fn = fn or (lambda s: s)
- patterns = '|'.join(mapping.keys())
+ patterns = b'|'.join(mapping.keys())
if escape_prefix:
- patterns += '|' + prefix
+ patterns += b'|' + prefix
if len(prefix) > 1:
prefix_char = prefix[1:]
else:
@@ -2921,7 +2929,7 @@
return socket.getservbyname(pycompat.sysstr(port))
except socket.error:
raise error.Abort(
- _("no port number associated with service '%s'") % port
+ _(b"no port number associated with service '%s'") % port
)
@@ -2999,38 +3007,38 @@
<url scheme: 'http'>
"""
- _safechars = "!~*'()+"
- _safepchars = "/!~*'()+:\\"
- _matchscheme = remod.compile('^[a-zA-Z0-9+.\\-]+:').match
+ _safechars = b"!~*'()+"
+ _safepchars = b"/!~*'()+:\\"
+ _matchscheme = remod.compile(b'^[a-zA-Z0-9+.\\-]+:').match
def __init__(self, path, parsequery=True, parsefragment=True):
# We slowly chomp away at path until we have only the path left
self.scheme = self.user = self.passwd = self.host = None
self.port = self.path = self.query = self.fragment = None
self._localpath = True
- self._hostport = ''
+ self._hostport = b''
self._origpath = path
- if parsefragment and '#' in path:
- path, self.fragment = path.split('#', 1)
+ if parsefragment and b'#' in path:
+ path, self.fragment = path.split(b'#', 1)
# special case for Windows drive letters and UNC paths
- if hasdriveletter(path) or path.startswith('\\\\'):
+ if hasdriveletter(path) or path.startswith(b'\\\\'):
self.path = path
return
# For compatibility reasons, we can't handle bundle paths as
# normal URLS
- if path.startswith('bundle:'):
- self.scheme = 'bundle'
+ if path.startswith(b'bundle:'):
+ self.scheme = b'bundle'
path = path[7:]
- if path.startswith('//'):
+ if path.startswith(b'//'):
path = path[2:]
self.path = path
return
if self._matchscheme(path):
- parts = path.split(':', 1)
+ parts = path.split(b':', 1)
if parts[0]:
self.scheme, path = parts
self._localpath = False
@@ -3038,23 +3046,23 @@
if not path:
path = None
if self._localpath:
- self.path = ''
+ self.path = b''
return
else:
if self._localpath:
self.path = path
return
- if parsequery and '?' in path:
- path, self.query = path.split('?', 1)
+ if parsequery and b'?' in path:
+ path, self.query = path.split(b'?', 1)
if not path:
path = None
if not self.query:
self.query = None
# // is required to specify a host/authority
- if path and path.startswith('//'):
- parts = path[2:].split('/', 1)
+ if path and path.startswith(b'//'):
+ parts = path[2:].split(b'/', 1)
if len(parts) > 1:
self.host, path = parts
else:
@@ -3065,37 +3073,41 @@
# path of file:///d is /d
# path of file:///d:/ is d:/, not /d:/
if path and not hasdriveletter(path):
- path = '/' + path
-
- if self.host and '@' in self.host:
- self.user, self.host = self.host.rsplit('@', 1)
- if ':' in self.user:
- self.user, self.passwd = self.user.split(':', 1)
+ path = b'/' + path
+
+ if self.host and b'@' in self.host:
+ self.user, self.host = self.host.rsplit(b'@', 1)
+ if b':' in self.user:
+ self.user, self.passwd = self.user.split(b':', 1)
if not self.host:
self.host = None
# Don't split on colons in IPv6 addresses without ports
if (
self.host
- and ':' in self.host
- and not (self.host.startswith('[') and self.host.endswith(']'))
+ and b':' in self.host
+ and not (
+ self.host.startswith(b'[') and self.host.endswith(b']')
+ )
):
self._hostport = self.host
- self.host, self.port = self.host.rsplit(':', 1)
+ self.host, self.port = self.host.rsplit(b':', 1)
if not self.host:
self.host = None
if (
self.host
- and self.scheme == 'file'
- and self.host not in ('localhost', '127.0.0.1', '[::1]')
+ and self.scheme == b'file'
+ and self.host not in (b'localhost', b'127.0.0.1', b'[::1]')
):
- raise error.Abort(_('file:// URLs can only refer to localhost'))
+ raise error.Abort(
+ _(b'file:// URLs can only refer to localhost')
+ )
self.path = path
# leave the query string escaped
- for a in ('user', 'passwd', 'host', 'port', 'path', 'fragment'):
+ for a in (b'user', b'passwd', b'host', b'port', b'path', b'fragment'):
v = getattr(self, a)
if v is not None:
setattr(self, a, urlreq.unquote(v))
@@ -3104,19 +3116,19 @@
def __repr__(self):
attrs = []
for a in (
- 'scheme',
- 'user',
- 'passwd',
- 'host',
- 'port',
- 'path',
- 'query',
- 'fragment',
+ b'scheme',
+ b'user',
+ b'passwd',
+ b'host',
+ b'port',
+ b'path',
+ b'query',
+ b'fragment',
):
v = getattr(self, a)
if v is not None:
- attrs.append('%s: %r' % (a, pycompat.bytestr(v)))
- return '<url %s>' % ', '.join(attrs)
+ attrs.append(b'%s: %r' % (a, pycompat.bytestr(v)))
+ return b'<url %s>' % b', '.join(attrs)
def __bytes__(self):
r"""Join the URL's components back into a URL string.
@@ -3154,38 +3166,38 @@
"""
if self._localpath:
s = self.path
- if self.scheme == 'bundle':
- s = 'bundle:' + s
+ if self.scheme == b'bundle':
+ s = b'bundle:' + s
if self.fragment:
- s += '#' + self.fragment
+ s += b'#' + self.fragment
return s
- s = self.scheme + ':'
+ s = self.scheme + b':'
if self.user or self.passwd or self.host:
- s += '//'
+ s += b'//'
elif self.scheme and (
not self.path
- or self.path.startswith('/')
+ or self.path.startswith(b'/')
or hasdriveletter(self.path)
):
- s += '//'
+ s += b'//'
if hasdriveletter(self.path):
- s += '/'
+ s += b'/'
if self.user:
s += urlreq.quote(self.user, safe=self._safechars)
if self.passwd:
- s += ':' + urlreq.quote(self.passwd, safe=self._safechars)
+ s += b':' + urlreq.quote(self.passwd, safe=self._safechars)
if self.user or self.passwd:
- s += '@'
+ s += b'@'
if self.host:
- if not (self.host.startswith('[') and self.host.endswith(']')):
+ if not (self.host.startswith(b'[') and self.host.endswith(b']')):
s += urlreq.quote(self.host)
else:
s += self.host
if self.port:
- s += ':' + urlreq.quote(self.port)
+ s += b':' + urlreq.quote(self.port)
if self.host:
- s += '/'
+ s += b'/'
if self.path:
# TODO: similar to the query string, we should not unescape the
# path when we store it, the path might contain '%2f' = '/',
@@ -3193,9 +3205,9 @@
s += urlreq.quote(self.path, safe=self._safepchars)
if self.query:
# we store the query in escaped form.
- s += '?' + self.query
+ s += b'?' + self.query
if self.fragment is not None:
- s += '#' + urlreq.quote(self.fragment, safe=self._safepchars)
+ s += b'#' + urlreq.quote(self.fragment, safe=self._safepchars)
return s
__str__ = encoding.strmethod(__bytes__)
@@ -3213,37 +3225,39 @@
# URIs must not contain credentials. The host is passed in the
# URIs list because Python < 2.4.3 uses only that to search for
# a password.
- return (s, (None, (s, self.host), self.user, self.passwd or ''))
+ return (s, (None, (s, self.host), self.user, self.passwd or b''))
def isabs(self):
- if self.scheme and self.scheme != 'file':
+ if self.scheme and self.scheme != b'file':
return True # remote URL
if hasdriveletter(self.path):
return True # absolute for our purposes - can't be joined()
if self.path.startswith(br'\\'):
return True # Windows UNC path
- if self.path.startswith('/'):
+ if self.path.startswith(b'/'):
return True # POSIX-style
return False
def localpath(self):
- if self.scheme == 'file' or self.scheme == 'bundle':
- path = self.path or '/'
+ if self.scheme == b'file' or self.scheme == b'bundle':
+ path = self.path or b'/'
# For Windows, we need to promote hosts containing drive
# letters to paths with drive letters.
if hasdriveletter(self._hostport):
- path = self._hostport + '/' + self.path
+ path = self._hostport + b'/' + self.path
elif (
self.host is not None and self.path and not hasdriveletter(path)
):
- path = '/' + path
+ path = b'/' + path
return path
return self._origpath
def islocal(self):
'''whether localpath will return something that posixfile can open'''
return (
- not self.scheme or self.scheme == 'file' or self.scheme == 'bundle'
+ not self.scheme
+ or self.scheme == b'file'
+ or self.scheme == b'bundle'
)
@@ -3252,7 +3266,7 @@
def hasdriveletter(path):
- return path and path[1:2] == ':' and path[0:1].isalpha()
+ return path and path[1:2] == b':' and path[0:1].isalpha()
def urllocalpath(path):
@@ -3270,9 +3284,9 @@
Raises an error.Abort when the url is unsafe.
"""
path = urlreq.unquote(path)
- if path.startswith('ssh://-') or path.startswith('svn+ssh://-'):
+ if path.startswith(b'ssh://-') or path.startswith(b'svn+ssh://-'):
raise error.Abort(
- _('potentially unsafe url: %r') % (pycompat.bytestr(path),)
+ _(b'potentially unsafe url: %r') % (pycompat.bytestr(path),)
)
@@ -3280,7 +3294,7 @@
'''hide user credential in a url string'''
u = url(u)
if u.passwd:
- u.passwd = '***'
+ u.passwd = b'***'
return bytes(u)
@@ -3292,19 +3306,19 @@
timecount = unitcountfn(
- (1, 1e3, _('%.0f s')),
- (100, 1, _('%.1f s')),
- (10, 1, _('%.2f s')),
- (1, 1, _('%.3f s')),
- (100, 0.001, _('%.1f ms')),
- (10, 0.001, _('%.2f ms')),
- (1, 0.001, _('%.3f ms')),
- (100, 0.000001, _('%.1f us')),
- (10, 0.000001, _('%.2f us')),
- (1, 0.000001, _('%.3f us')),
- (100, 0.000000001, _('%.1f ns')),
- (10, 0.000000001, _('%.2f ns')),
- (1, 0.000000001, _('%.3f ns')),
+ (1, 1e3, _(b'%.0f s')),
+ (100, 1, _(b'%.1f s')),
+ (10, 1, _(b'%.2f s')),
+ (1, 1, _(b'%.3f s')),
+ (100, 0.001, _(b'%.1f ms')),
+ (10, 0.001, _(b'%.2f ms')),
+ (1, 0.001, _(b'%.3f ms')),
+ (100, 0.000001, _(b'%.1f us')),
+ (10, 0.000001, _(b'%.2f us')),
+ (1, 0.000001, _(b'%.3f us')),
+ (100, 0.000000001, _(b'%.1f ns')),
+ (10, 0.000000001, _(b'%.2f ns')),
+ (1, 0.000000001, _(b'%.3f ns')),
)
@@ -3322,7 +3336,7 @@
level = attr.ib(default=1)
def __bytes__(self):
- return timecount(self.elapsed) if self.elapsed else '<unknown>'
+ return timecount(self.elapsed) if self.elapsed else b'<unknown>'
__str__ = encoding.strmethod(__bytes__)
@@ -3366,9 +3380,9 @@
result = func(*args, **kwargs)
stderr = procutil.stderr
stderr.write(
- '%s%s: %s\n'
+ b'%s%s: %s\n'
% (
- ' ' * time_stats.level * 2,
+ b' ' * time_stats.level * 2,
pycompat.bytestr(func.__name__),
time_stats,
)
@@ -3379,13 +3393,13 @@
_sizeunits = (
- ('m', 2 ** 20),
- ('k', 2 ** 10),
- ('g', 2 ** 30),
- ('kb', 2 ** 10),
- ('mb', 2 ** 20),
- ('gb', 2 ** 30),
- ('b', 1),
+ (b'm', 2 ** 20),
+ (b'k', 2 ** 10),
+ (b'g', 2 ** 30),
+ (b'kb', 2 ** 10),
+ (b'mb', 2 ** 20),
+ (b'gb', 2 ** 30),
+ (b'b', 1),
)
@@ -3406,7 +3420,7 @@
return int(float(t[: -len(k)]) * u)
return int(t)
except ValueError:
- raise error.ParseError(_("couldn't parse size: %s") % s)
+ raise error.ParseError(_(b"couldn't parse size: %s") % s)
class hooks(object):
@@ -3428,7 +3442,7 @@
return results
-def getstackframes(skip=0, line=' %-*s in %s\n', fileline='%s:%d', depth=0):
+def getstackframes(skip=0, line=b' %-*s in %s\n', fileline=b'%s:%d', depth=0):
'''Yields lines for a nicely formatted stacktrace.
Skips the 'skip' last entries, then return the last 'depth' entries.
Each file+linenumber is formatted according to fileline.
@@ -3454,7 +3468,11 @@
def debugstacktrace(
- msg='stacktrace', skip=0, f=procutil.stderr, otherf=procutil.stdout, depth=0
+ msg=b'stacktrace',
+ skip=0,
+ f=procutil.stderr,
+ otherf=procutil.stdout,
+ depth=0,
):
'''Writes a message to f (stderr) with a nicely formatted stacktrace.
Skips the 'skip' entries closest to the call, then show 'depth' entries.
@@ -3464,7 +3482,7 @@
'''
if otherf:
otherf.flush()
- f.write('%s at:\n' % msg.rstrip())
+ f.write(b'%s at:\n' % msg.rstrip())
for line in getstackframes(skip + 1, depth=depth):
f.write(line)
f.flush()
@@ -3482,7 +3500,7 @@
addpath(f)
elif skip is not None:
raise error.ProgrammingError(
- "skip character is only supported " "with a dict source"
+ b"skip character is only supported " b"with a dict source"
)
else:
for f in map:
@@ -3519,11 +3537,11 @@
def finddirs(path):
- pos = path.rfind('/')
+ pos = path.rfind(b'/')
while pos != -1:
yield path[:pos]
- pos = path.rfind('/', 0, pos)
- yield ''
+ pos = path.rfind(b'/', 0, pos)
+ yield b''
# convenient shortcut
@@ -3545,11 +3563,11 @@
if others is None:
others = set()
- fn = '%s~%s' % (f, tag)
+ fn = b'%s~%s' % (f, tag)
if fn not in ctx and fn not in others:
return fn
for n in itertools.count(1):
- fn = '%s~%s~%s' % (f, tag, n)
+ fn = b'%s~%s~%s' % (f, tag, n)
if fn not in ctx and fn not in others:
return fn
@@ -3559,7 +3577,7 @@
s = stream.read(n)
if len(s) < n:
raise error.Abort(
- _("stream ended unexpectedly" " (got %d bytes, expected %d)")
+ _(b"stream ended unexpectedly" b" (got %d bytes, expected %d)")
% (len(s), n)
)
return s
@@ -3589,7 +3607,7 @@
ProgrammingError: negative value for uvarint: -1
"""
if value < 0:
- raise error.ProgrammingError('negative value for uvarint: %d' % value)
+ raise error.ProgrammingError(b'negative value for uvarint: %d' % value)
bits = value & 0x7F
value >>= 7
bytes = []
@@ -3599,7 +3617,7 @@
value >>= 7
bytes.append(pycompat.bytechr(bits))
- return ''.join(bytes)
+ return b''.join(bytes)
def uvarintdecodestream(fh):