diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py --- a/mercurial/pycompat.py +++ b/mercurial/pycompat.py @@ -154,7 +154,7 @@ bytechr = struct.Struct(r'>B').pack byterepr = b'%r'.__mod__ - class bytestr(bytes): + class _bytestr(bytes): """A bytes which mostly acts as a Python 2 str >>> bytestr(), bytestr(bytearray(b'foo')), bytestr(u'ascii'), bytestr(1) @@ -208,7 +208,7 @@ """ def __new__(cls, s=b''): - if isinstance(s, bytestr): + if isinstance(s, _bytestr): return s if not isinstance( s, (bytes, bytearray) @@ -398,7 +398,7 @@ unicode = unicode bytechr = chr byterepr = repr - bytestr = str + _bytestr = str iterbytestr = iter maybebytestr = identity sysbytes = identity @@ -504,3 +504,8 @@ return tempfile.NamedTemporaryFile( mode, bufsize, suffix=suffix, prefix=prefix, dir=dir, delete=delete ) + + +def bytestr(s=b''): + # type: (Union[bytes,str]) -> _bytestr + return _bytestr(s) diff --git a/mercurial/urllibcompat.py b/mercurial/urllibcompat.py --- a/mercurial/urllibcompat.py +++ b/mercurial/urllibcompat.py @@ -105,7 +105,7 @@ def quote(s, safe=r'/'): # bytestr has an __iter__ that emits characters. quote_from_bytes() # does an iteration and expects ints. We coerce to bytes to appease it. - if isinstance(s, pycompat.bytestr): + if isinstance(s, pycompat._bytestr): s = bytes(s) s = urllib.parse.quote_from_bytes(s, safe=safe) return s.encode('ascii', 'strict')