We no longer support Python 2. So we can delete its compatibility
code and remove the conditional and dedent the Python 3 code.
In order to make the linter happy, we had to inline imports in the
stanza at the top of the file.
( )
| Alphare |
| hg-reviewers |
We no longer support Python 2. So we can delete its compatibility
code and remove the conditional and dedent the Python 3 code.
In order to make the linter happy, we had to inline imports in the
stanza at the top of the file.
| No Linters Available |
| No Unit Test Coverage |
| Path | Packages | |||
|---|---|---|---|---|
| M | mercurial/pycompat.py (629 lines) |
| Commit | Parents | Author | Summary | Date |
|---|---|---|---|---|
| 4abe41a5f474 | c45ca45b04c9 | Gregory Szorc | Feb 20 2022, 4:48 PM |
| # pycompat.py - portability shim for python 3 | # pycompat.py - portability shim for python 3 | ||||
| # | # | ||||
| # This software may be used and distributed according to the terms of the | # This software may be used and distributed according to the terms of the | ||||
| # GNU General Public License version 2 or any later version. | # GNU General Public License version 2 or any later version. | ||||
| """Mercurial portability shim for python 3. | """Mercurial portability shim for python 3. | ||||
| This contains aliases to hide python version-specific details from the core. | This contains aliases to hide python version-specific details from the core. | ||||
| """ | """ | ||||
| from __future__ import absolute_import | from __future__ import absolute_import | ||||
| import builtins | import builtins | ||||
| import codecs | |||||
| import concurrent.futures as futures | import concurrent.futures as futures | ||||
| import functools | |||||
| import getopt | import getopt | ||||
| import http.client as httplib | import http.client as httplib | ||||
| import http.cookiejar as cookielib | import http.cookiejar as cookielib | ||||
| import inspect | import inspect | ||||
| import io | |||||
| import json | import json | ||||
| import os | import os | ||||
| import queue | import queue | ||||
| import shlex | import shlex | ||||
| import socketserver | import socketserver | ||||
| import struct | |||||
| import sys | import sys | ||||
| import tempfile | import tempfile | ||||
| import xmlrpc.client as xmlrpclib | import xmlrpc.client as xmlrpclib | ||||
| ispy3 = sys.version_info[0] >= 3 | ispy3 = sys.version_info[0] >= 3 | ||||
| ispypy = '__pypy__' in sys.builtin_module_names | ispypy = '__pypy__' in sys.builtin_module_names | ||||
| TYPE_CHECKING = False | TYPE_CHECKING = False | ||||
| if not globals(): # hide this from non-pytype users | if not globals(): # hide this from non-pytype users | ||||
| import typing | import typing | ||||
| TYPE_CHECKING = typing.TYPE_CHECKING | TYPE_CHECKING = typing.TYPE_CHECKING | ||||
| True | True | ||||
| """ | """ | ||||
| if f is identity: | if f is identity: | ||||
| # fast path mainly for py2 | # fast path mainly for py2 | ||||
| return xs | return xs | ||||
| return _rapply(f, xs) | return _rapply(f, xs) | ||||
| if ispy3: | |||||
| import builtins | |||||
| import codecs | |||||
| import functools | |||||
| import io | |||||
| import struct | |||||
| if os.name == r'nt' and sys.version_info >= (3, 6): | if os.name == r'nt' and sys.version_info >= (3, 6): | ||||
| # MBCS (or ANSI) filesystem encoding must be used as before. | # MBCS (or ANSI) filesystem encoding must be used as before. | ||||
| # Otherwise non-ASCII filenames in existing repositories would be | # Otherwise non-ASCII filenames in existing repositories would be | ||||
| # corrupted. | # corrupted. | ||||
| # This must be set once prior to any fsencode/fsdecode calls. | # This must be set once prior to any fsencode/fsdecode calls. | ||||
| sys._enablelegacywindowsfsencoding() # pytype: disable=module-attr | sys._enablelegacywindowsfsencoding() # pytype: disable=module-attr | ||||
| fsencode = os.fsencode | fsencode = os.fsencode | ||||
| fsdecode = os.fsdecode | fsdecode = os.fsdecode | ||||
| oscurdir = os.curdir.encode('ascii') | oscurdir = os.curdir.encode('ascii') | ||||
| oslinesep = os.linesep.encode('ascii') | oslinesep = os.linesep.encode('ascii') | ||||
| osname = os.name.encode('ascii') | osname = os.name.encode('ascii') | ||||
| ospathsep = os.pathsep.encode('ascii') | ospathsep = os.pathsep.encode('ascii') | ||||
| ospardir = os.pardir.encode('ascii') | ospardir = os.pardir.encode('ascii') | ||||
| ossep = os.sep.encode('ascii') | ossep = os.sep.encode('ascii') | ||||
| osaltsep = os.altsep | osaltsep = os.altsep | ||||
| if osaltsep: | if osaltsep: | ||||
| osaltsep = osaltsep.encode('ascii') | osaltsep = osaltsep.encode('ascii') | ||||
| osdevnull = os.devnull.encode('ascii') | osdevnull = os.devnull.encode('ascii') | ||||
| sysplatform = sys.platform.encode('ascii') | sysplatform = sys.platform.encode('ascii') | ||||
| sysexecutable = sys.executable | sysexecutable = sys.executable | ||||
| if sysexecutable: | if sysexecutable: | ||||
| sysexecutable = os.fsencode(sysexecutable) | sysexecutable = os.fsencode(sysexecutable) | ||||
| bytesio = io.BytesIO | bytesio = io.BytesIO | ||||
| # TODO deprecate stringio name, as it is a lie on Python 3. | # TODO deprecate stringio name, as it is a lie on Python 3. | ||||
| stringio = bytesio | stringio = bytesio | ||||
| def maplist(*args): | def maplist(*args): | ||||
| return list(map(*args)) | return list(map(*args)) | ||||
| def rangelist(*args): | def rangelist(*args): | ||||
| return list(range(*args)) | return list(range(*args)) | ||||
| def ziplist(*args): | def ziplist(*args): | ||||
| return list(zip(*args)) | return list(zip(*args)) | ||||
| rawinput = input | rawinput = input | ||||
| getargspec = inspect.getfullargspec | getargspec = inspect.getfullargspec | ||||
| long = int | long = int | ||||
| if getattr(sys, 'argv', None) is not None: | if getattr(sys, 'argv', None) is not None: | ||||
| # On POSIX, the char** argv array is converted to Python str using | # On POSIX, the char** argv array is converted to Python str using | ||||
| # Py_DecodeLocale(). The inverse of this is Py_EncodeLocale(), which | # Py_DecodeLocale(). The inverse of this is Py_EncodeLocale(), which | ||||
| # isn't directly callable from Python code. In practice, os.fsencode() | # isn't directly callable from Python code. In practice, os.fsencode() | ||||
| # can be used instead (this is recommended by Python's documentation | # can be used instead (this is recommended by Python's documentation | ||||
| # for sys.argv). | # for sys.argv). | ||||
| # | # | ||||
| # On Windows, the wchar_t **argv is passed into the interpreter as-is. | # On Windows, the wchar_t **argv is passed into the interpreter as-is. | ||||
| # Like POSIX, we need to emulate what Py_EncodeLocale() would do. But | # Like POSIX, we need to emulate what Py_EncodeLocale() would do. But | ||||
| # there's an additional wrinkle. What we really want to access is the | # there's an additional wrinkle. What we really want to access is the | ||||
| # ANSI codepage representation of the arguments, as this is what | # ANSI codepage representation of the arguments, as this is what | ||||
| # `int main()` would receive if Python 3 didn't define `int wmain()` | # `int main()` would receive if Python 3 didn't define `int wmain()` | ||||
| # (this is how Python 2 worked). To get that, we encode with the mbcs | # (this is how Python 2 worked). To get that, we encode with the mbcs | ||||
| # encoding, which will pass CP_ACP to the underlying Windows API to | # encoding, which will pass CP_ACP to the underlying Windows API to | ||||
| # produce bytes. | # produce bytes. | ||||
| if os.name == r'nt': | if os.name == r'nt': | ||||
| sysargv = [a.encode("mbcs", "ignore") for a in sys.argv] | sysargv = [a.encode("mbcs", "ignore") for a in sys.argv] | ||||
| else: | else: | ||||
| sysargv = [fsencode(a) for a in sys.argv] | sysargv = [fsencode(a) for a in sys.argv] | ||||
| bytechr = struct.Struct('>B').pack | bytechr = struct.Struct('>B').pack | ||||
| byterepr = b'%r'.__mod__ | byterepr = b'%r'.__mod__ | ||||
| class bytestr(bytes): | class bytestr(bytes): | ||||
| """A bytes which mostly acts as a Python 2 str | """A bytes which mostly acts as a Python 2 str | ||||
| >>> bytestr(), bytestr(bytearray(b'foo')), bytestr(u'ascii'), bytestr(1) | >>> bytestr(), bytestr(bytearray(b'foo')), bytestr(u'ascii'), bytestr(1) | ||||
| ('', 'foo', 'ascii', '1') | ('', 'foo', 'ascii', '1') | ||||
| >>> s = bytestr(b'foo') | >>> s = bytestr(b'foo') | ||||
| >>> assert s is bytestr(s) | >>> assert s is bytestr(s) | ||||
| __bytes__() should be called if provided: | __bytes__() should be called if provided: | ||||
| >>> class bytesable(object): | >>> class bytesable(object): | ||||
| ... def __bytes__(self): | ... def __bytes__(self): | ||||
| ... return b'bytes' | ... return b'bytes' | ||||
| >>> bytestr(bytesable()) | >>> bytestr(bytesable()) | ||||
| 'bytes' | 'bytes' | ||||
| There's no implicit conversion from non-ascii str as its encoding is | There's no implicit conversion from non-ascii str as its encoding is | ||||
| unknown: | unknown: | ||||
| >>> bytestr(chr(0x80)) # doctest: +ELLIPSIS | >>> bytestr(chr(0x80)) # doctest: +ELLIPSIS | ||||
| Traceback (most recent call last): | Traceback (most recent call last): | ||||
| ... | ... | ||||
| UnicodeEncodeError: ... | UnicodeEncodeError: ... | ||||
| Comparison between bytestr and bytes should work: | Comparison between bytestr and bytes should work: | ||||
| >>> assert bytestr(b'foo') == b'foo' | >>> assert bytestr(b'foo') == b'foo' | ||||
| >>> assert b'foo' == bytestr(b'foo') | >>> assert b'foo' == bytestr(b'foo') | ||||
| >>> assert b'f' in bytestr(b'foo') | >>> assert b'f' in bytestr(b'foo') | ||||
| >>> assert bytestr(b'f') in b'foo' | >>> assert bytestr(b'f') in b'foo' | ||||
| Sliced elements should be bytes, not integer: | Sliced elements should be bytes, not integer: | ||||
| >>> s[1], s[:2] | >>> s[1], s[:2] | ||||
| (b'o', b'fo') | (b'o', b'fo') | ||||
| >>> list(s), list(reversed(s)) | >>> list(s), list(reversed(s)) | ||||
| ([b'f', b'o', b'o'], [b'o', b'o', b'f']) | ([b'f', b'o', b'o'], [b'o', b'o', b'f']) | ||||
| As bytestr type isn't propagated across operations, you need to cast | As bytestr type isn't propagated across operations, you need to cast | ||||
| bytes to bytestr explicitly: | bytes to bytestr explicitly: | ||||
| >>> s = bytestr(b'foo').upper() | >>> s = bytestr(b'foo').upper() | ||||
| >>> t = bytestr(s) | >>> t = bytestr(s) | ||||
| >>> s[0], t[0] | >>> s[0], t[0] | ||||
| (70, b'F') | (70, b'F') | ||||
| Be careful to not pass a bytestr object to a function which expects | Be careful to not pass a bytestr object to a function which expects | ||||
| bytearray-like behavior. | bytearray-like behavior. | ||||
| >>> t = bytes(t) # cast to bytes | >>> t = bytes(t) # cast to bytes | ||||
| >>> assert type(t) is bytes | >>> assert type(t) is bytes | ||||
| """ | """ | ||||
| # Trick pytype into not demanding Iterable[int] be passed to __new__(), | # Trick pytype into not demanding Iterable[int] be passed to __new__(), | ||||
| # since the appropriate bytes format is done internally. | # since the appropriate bytes format is done internally. | ||||
| # | # | ||||
| # https://github.com/google/pytype/issues/500 | # https://github.com/google/pytype/issues/500 | ||||
| if TYPE_CHECKING: | if TYPE_CHECKING: | ||||
| def __init__(self, s=b''): | def __init__(self, s=b''): | ||||
| pass | pass | ||||
| def __new__(cls, s=b''): | def __new__(cls, s=b''): | ||||
| if isinstance(s, bytestr): | if isinstance(s, bytestr): | ||||
| return s | return s | ||||
| if not isinstance( | if not isinstance( | ||||
| s, (bytes, bytearray) | s, (bytes, bytearray) | ||||
| ) and not hasattr( # hasattr-py3-only | ) and not hasattr( # hasattr-py3-only | ||||
| s, u'__bytes__' | s, u'__bytes__' | ||||
| ): | ): | ||||
| s = str(s).encode('ascii') | s = str(s).encode('ascii') | ||||
| return bytes.__new__(cls, s) | return bytes.__new__(cls, s) | ||||
| def __getitem__(self, key): | def __getitem__(self, key): | ||||
| s = bytes.__getitem__(self, key) | s = bytes.__getitem__(self, key) | ||||
| if not isinstance(s, bytes): | if not isinstance(s, bytes): | ||||
| s = bytechr(s) | s = bytechr(s) | ||||
| return s | return s | ||||
| def __iter__(self): | def __iter__(self): | ||||
| return iterbytestr(bytes.__iter__(self)) | return iterbytestr(bytes.__iter__(self)) | ||||
| def __repr__(self): | def __repr__(self): | ||||
| return bytes.__repr__(self)[1:] # drop b'' | return bytes.__repr__(self)[1:] # drop b'' | ||||
| def iterbytestr(s): | def iterbytestr(s): | ||||
| """Iterate bytes as if it were a str object of Python 2""" | """Iterate bytes as if it were a str object of Python 2""" | ||||
| return map(bytechr, s) | return map(bytechr, s) | ||||
| def maybebytestr(s): | def maybebytestr(s): | ||||
| """Promote bytes to bytestr""" | """Promote bytes to bytestr""" | ||||
| if isinstance(s, bytes): | if isinstance(s, bytes): | ||||
| return bytestr(s) | return bytestr(s) | ||||
| return s | return s | ||||
| def sysbytes(s): | def sysbytes(s): | ||||
| """Convert an internal str (e.g. keyword, __doc__) back to bytes | """Convert an internal str (e.g. keyword, __doc__) back to bytes | ||||
| This never raises UnicodeEncodeError, but only ASCII characters | This never raises UnicodeEncodeError, but only ASCII characters | ||||
| can be round-trip by sysstr(sysbytes(s)). | can be round-trip by sysstr(sysbytes(s)). | ||||
| """ | """ | ||||
| if isinstance(s, bytes): | if isinstance(s, bytes): | ||||
| return s | return s | ||||
| return s.encode('utf-8') | return s.encode('utf-8') | ||||
| def sysstr(s): | def sysstr(s): | ||||
| """Return a keyword str to be passed to Python functions such as | """Return a keyword str to be passed to Python functions such as | ||||
| getattr() and str.encode() | getattr() and str.encode() | ||||
| This never raises UnicodeDecodeError. Non-ascii characters are | This never raises UnicodeDecodeError. Non-ascii characters are | ||||
| considered invalid and mapped to arbitrary but unique code points | considered invalid and mapped to arbitrary but unique code points | ||||
| such that 'sysstr(a) != sysstr(b)' for all 'a != b'. | such that 'sysstr(a) != sysstr(b)' for all 'a != b'. | ||||
| """ | """ | ||||
| if isinstance(s, builtins.str): | if isinstance(s, builtins.str): | ||||
| return s | return s | ||||
| return s.decode('latin-1') | return s.decode('latin-1') | ||||
| def strurl(url): | def strurl(url): | ||||
| """Converts a bytes url back to str""" | """Converts a bytes url back to str""" | ||||
| if isinstance(url, bytes): | if isinstance(url, bytes): | ||||
| return url.decode('ascii') | return url.decode('ascii') | ||||
| return url | return url | ||||
| def bytesurl(url): | def bytesurl(url): | ||||
| """Converts a str url to bytes by encoding in ascii""" | """Converts a str url to bytes by encoding in ascii""" | ||||
| if isinstance(url, str): | if isinstance(url, str): | ||||
| return url.encode('ascii') | return url.encode('ascii') | ||||
| return url | return url | ||||
| def raisewithtb(exc, tb): | def raisewithtb(exc, tb): | ||||
| """Raise exception with the given traceback""" | """Raise exception with the given traceback""" | ||||
| raise exc.with_traceback(tb) | raise exc.with_traceback(tb) | ||||
| def getdoc(obj): | def getdoc(obj): | ||||
| """Get docstring as bytes; may be None so gettext() won't confuse it | """Get docstring as bytes; may be None so gettext() won't confuse it | ||||
| with _('')""" | with _('')""" | ||||
| doc = getattr(obj, '__doc__', None) | doc = getattr(obj, '__doc__', None) | ||||
| if doc is None: | if doc is None: | ||||
| return doc | return doc | ||||
| return sysbytes(doc) | return sysbytes(doc) | ||||
| def _wrapattrfunc(f): | def _wrapattrfunc(f): | ||||
| @functools.wraps(f) | @functools.wraps(f) | ||||
| def w(object, name, *args): | def w(object, name, *args): | ||||
| return f(object, sysstr(name), *args) | return f(object, sysstr(name), *args) | ||||
| return w | return w | ||||
| # these wrappers are automagically imported by hgloader | # these wrappers are automagically imported by hgloader | ||||
| delattr = _wrapattrfunc(builtins.delattr) | delattr = _wrapattrfunc(builtins.delattr) | ||||
| getattr = _wrapattrfunc(builtins.getattr) | getattr = _wrapattrfunc(builtins.getattr) | ||||
| hasattr = _wrapattrfunc(builtins.hasattr) | hasattr = _wrapattrfunc(builtins.hasattr) | ||||
| setattr = _wrapattrfunc(builtins.setattr) | setattr = _wrapattrfunc(builtins.setattr) | ||||
| xrange = builtins.range | xrange = builtins.range | ||||
| unicode = str | unicode = str | ||||
| def open(name, mode=b'r', buffering=-1, encoding=None): | def open(name, mode=b'r', buffering=-1, encoding=None): | ||||
| return builtins.open(name, sysstr(mode), buffering, encoding) | return builtins.open(name, sysstr(mode), buffering, encoding) | ||||
| safehasattr = _wrapattrfunc(builtins.hasattr) | safehasattr = _wrapattrfunc(builtins.hasattr) | ||||
| def _getoptbwrapper(orig, args, shortlist, namelist): | def _getoptbwrapper(orig, args, shortlist, namelist): | ||||
| """ | """ | ||||
| Takes bytes arguments, converts them to unicode, pass them to | Takes bytes arguments, converts them to unicode, pass them to | ||||
| getopt.getopt(), convert the returned values back to bytes and then | getopt.getopt(), convert the returned values back to bytes and then | ||||
| return them for Python 3 compatibility as getopt.getopt() don't accepts | return them for Python 3 compatibility as getopt.getopt() don't accepts | ||||
| bytes on Python 3. | bytes on Python 3. | ||||
| """ | """ | ||||
| args = [a.decode('latin-1') for a in args] | args = [a.decode('latin-1') for a in args] | ||||
| shortlist = shortlist.decode('latin-1') | shortlist = shortlist.decode('latin-1') | ||||
| namelist = [a.decode('latin-1') for a in namelist] | namelist = [a.decode('latin-1') for a in namelist] | ||||
| opts, args = orig(args, shortlist, namelist) | opts, args = orig(args, shortlist, namelist) | ||||
| opts = [(a[0].encode('latin-1'), a[1].encode('latin-1')) for a in opts] | opts = [(a[0].encode('latin-1'), a[1].encode('latin-1')) for a in opts] | ||||
| args = [a.encode('latin-1') for a in args] | args = [a.encode('latin-1') for a in args] | ||||
| return opts, args | return opts, args | ||||
| def strkwargs(dic): | def strkwargs(dic): | ||||
| """ | """ | ||||
| Converts the keys of a python dictonary to str i.e. unicodes so that | Converts the keys of a python dictonary to str i.e. unicodes so that | ||||
| they can be passed as keyword arguments as dictionaries with bytes keys | they can be passed as keyword arguments as dictionaries with bytes keys | ||||
| can't be passed as keyword arguments to functions on Python 3. | can't be passed as keyword arguments to functions on Python 3. | ||||
| """ | """ | ||||
| dic = {k.decode('latin-1'): v for k, v in dic.items()} | dic = {k.decode('latin-1'): v for k, v in dic.items()} | ||||
| return dic | return dic | ||||
| def byteskwargs(dic): | def byteskwargs(dic): | ||||
| """ | """ | ||||
| Converts keys of python dictionaries to bytes as they were converted to | Converts keys of python dictionaries to bytes as they were converted to | ||||
| str to pass that dictonary as a keyword argument on Python 3. | str to pass that dictonary as a keyword argument on Python 3. | ||||
| """ | """ | ||||
| dic = {k.encode('latin-1'): v for k, v in dic.items()} | dic = {k.encode('latin-1'): v for k, v in dic.items()} | ||||
| return dic | return dic | ||||
| # TODO: handle shlex.shlex(). | # TODO: handle shlex.shlex(). | ||||
| def shlexsplit(s, comments=False, posix=True): | def shlexsplit(s, comments=False, posix=True): | ||||
| """ | """ | ||||
| Takes bytes argument, convert it to str i.e. unicodes, pass that into | Takes bytes argument, convert it to str i.e. unicodes, pass that into | ||||
| shlex.split(), convert the returned value to bytes and return that for | shlex.split(), convert the returned value to bytes and return that for | ||||
| Python 3 compatibility as shelx.split() don't accept bytes on Python 3. | Python 3 compatibility as shelx.split() don't accept bytes on Python 3. | ||||
| """ | """ | ||||
| ret = shlex.split(s.decode('latin-1'), comments, posix) | ret = shlex.split(s.decode('latin-1'), comments, posix) | ||||
| return [a.encode('latin-1') for a in ret] | return [a.encode('latin-1') for a in ret] | ||||
| iteritems = lambda x: x.items() | iteritems = lambda x: x.items() | ||||
| itervalues = lambda x: x.values() | itervalues = lambda x: x.values() | ||||
| # Python 3.5's json.load and json.loads require str. We polyfill its | # Python 3.5's json.load and json.loads require str. We polyfill its | ||||
| # code for detecting encoding from bytes. | # code for detecting encoding from bytes. | ||||
| if sys.version_info[0:2] < (3, 6): | if sys.version_info[0:2] < (3, 6): | ||||
| def _detect_encoding(b): | def _detect_encoding(b): | ||||
| bstartswith = b.startswith | bstartswith = b.startswith | ||||
| if bstartswith((codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE)): | if bstartswith((codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE)): | ||||
| return 'utf-32' | return 'utf-32' | ||||
| if bstartswith((codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE)): | if bstartswith((codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE)): | ||||
| return 'utf-16' | return 'utf-16' | ||||
| if bstartswith(codecs.BOM_UTF8): | if bstartswith(codecs.BOM_UTF8): | ||||
| return 'utf-8-sig' | return 'utf-8-sig' | ||||
| if len(b) >= 4: | if len(b) >= 4: | ||||
| if not b[0]: | if not b[0]: | ||||
| # 00 00 -- -- - utf-32-be | # 00 00 -- -- - utf-32-be | ||||
| # 00 XX -- -- - utf-16-be | # 00 XX -- -- - utf-16-be | ||||
| return 'utf-16-be' if b[1] else 'utf-32-be' | return 'utf-16-be' if b[1] else 'utf-32-be' | ||||
| if not b[1]: | if not b[1]: | ||||
| # XX 00 00 00 - utf-32-le | # XX 00 00 00 - utf-32-le | ||||
| # XX 00 00 XX - utf-16-le | # XX 00 00 XX - utf-16-le | ||||
| # XX 00 XX -- - utf-16-le | # XX 00 XX -- - utf-16-le | ||||
| return 'utf-16-le' if b[2] or b[3] else 'utf-32-le' | return 'utf-16-le' if b[2] or b[3] else 'utf-32-le' | ||||
| elif len(b) == 2: | elif len(b) == 2: | ||||
| if not b[0]: | if not b[0]: | ||||
| # 00 XX - utf-16-be | # 00 XX - utf-16-be | ||||
| return 'utf-16-be' | return 'utf-16-be' | ||||
| if not b[1]: | if not b[1]: | ||||
| # XX 00 - utf-16-le | # XX 00 - utf-16-le | ||||
| return 'utf-16-le' | return 'utf-16-le' | ||||
| # default | # default | ||||
| return 'utf-8' | return 'utf-8' | ||||
| def json_loads(s, *args, **kwargs): | def json_loads(s, *args, **kwargs): | ||||
| if isinstance(s, (bytes, bytearray)): | if isinstance(s, (bytes, bytearray)): | ||||
| s = s.decode(_detect_encoding(s), 'surrogatepass') | s = s.decode(_detect_encoding(s), 'surrogatepass') | ||||
| return json.loads(s, *args, **kwargs) | return json.loads(s, *args, **kwargs) | ||||
| else: | else: | ||||
| json_loads = json.loads | json_loads = json.loads | ||||
| else: | |||||
| import cStringIO | |||||
| xrange = xrange | |||||
| unicode = unicode | |||||
| bytechr = chr | |||||
| byterepr = repr | |||||
| bytestr = str | |||||
| iterbytestr = iter | |||||
| maybebytestr = identity | |||||
| sysbytes = identity | |||||
| sysstr = identity | |||||
| strurl = identity | |||||
| bytesurl = identity | |||||
| open = open | |||||
| delattr = delattr | |||||
| getattr = getattr | |||||
| hasattr = hasattr | |||||
| setattr = setattr | |||||
| # this can't be parsed on Python 3 | |||||
| exec(b'def raisewithtb(exc, tb):\n raise exc, None, tb\n') | |||||
| def fsencode(filename): | |||||
| """ | |||||
| Partial backport from os.py in Python 3, which only accepts bytes. | |||||
| In Python 2, our paths should only ever be bytes, a unicode path | |||||
| indicates a bug. | |||||
| """ | |||||
| if isinstance(filename, str): | |||||
| return filename | |||||
| else: | |||||
| raise TypeError("expect str, not %s" % type(filename).__name__) | |||||
| # In Python 2, fsdecode() has a very chance to receive bytes. So it's | |||||
| # better not to touch Python 2 part as it's already working fine. | |||||
| fsdecode = identity | |||||
| def getdoc(obj): | |||||
| return getattr(obj, '__doc__', None) | |||||
| _notset = object() | |||||
| def safehasattr(thing, attr): | |||||
| return getattr(thing, attr, _notset) is not _notset | |||||
| def _getoptbwrapper(orig, args, shortlist, namelist): | |||||
| return orig(args, shortlist, namelist) | |||||
| strkwargs = identity | |||||
| byteskwargs = identity | |||||
| oscurdir = os.curdir | |||||
| oslinesep = os.linesep | |||||
| osname = os.name | |||||
| ospathsep = os.pathsep | |||||
| ospardir = os.pardir | |||||
| ossep = os.sep | |||||
| osaltsep = os.altsep | |||||
| osdevnull = os.devnull | |||||
| long = long | |||||
| if getattr(sys, 'argv', None) is not None: | |||||
| sysargv = sys.argv | |||||
| sysplatform = sys.platform | |||||
| sysexecutable = sys.executable | |||||
| shlexsplit = shlex.split | |||||
| bytesio = cStringIO.StringIO | |||||
| stringio = bytesio | |||||
| maplist = map | |||||
| rangelist = range | |||||
| ziplist = zip | |||||
| rawinput = raw_input | |||||
| getargspec = inspect.getargspec | |||||
| iteritems = lambda x: x.iteritems() | |||||
| itervalues = lambda x: x.itervalues() | |||||
| json_loads = json.loads | |||||
| isjython = sysplatform.startswith(b'java') | isjython = sysplatform.startswith(b'java') | ||||
| isdarwin = sysplatform.startswith(b'darwin') | isdarwin = sysplatform.startswith(b'darwin') | ||||
| islinux = sysplatform.startswith(b'linux') | islinux = sysplatform.startswith(b'linux') | ||||
| isposix = osname == b'posix' | isposix = osname == b'posix' | ||||
| iswindows = osname == b'nt' | iswindows = osname == b'nt' | ||||