mercurial/pycompat.py
author Augie Fackler <augie@google.com>
Tue, 19 Sep 2017 00:06:57 -0400
changeset 34264 8999851a503f
parent 33853 cfcfbe6c96f8
child 34467 192f7b126ed2
permissions -rw-r--r--
tests: fix run-tests default values in Test constructor As far as I can tell, default values are evaluated far earlier on Python 3.6 than 2.7, meaning we've got to be more careful about when we read the defaults dictionary for the kwarg defaults. Sigh. With this change, test-run-tests.t is significantly less of a mess under 3.6.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
30302
3874ddba1ab4 py3: add a bytes version of os.name
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30300
diff changeset
    14
import os
30678
caf7e1c5efe4 py3: have a bytes version of shlex.split()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30668
diff changeset
    15
import shlex
29584
06587edd1233 pycompat: make pycompat demandimport friendly
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
    16
import sys
06587edd1233 pycompat: make pycompat demandimport friendly
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
    17
30030
0f6d6fdd3c2a pycompat: provide 'ispy3' constant
Yuya Nishihara <yuya@tcha.org>
parents: 29801
diff changeset
    18
ispy3 = (sys.version_info[0] >= 3)
33626
524b13fc711f util: fix sortdict.update() to call __setitem__() on PyPy (issue5639)
Yuya Nishihara <yuya@tcha.org>
parents: 32865
diff changeset
    19
ispypy = (r'__pypy__' in sys.builtin_module_names)
30030
0f6d6fdd3c2a pycompat: provide 'ispy3' constant
Yuya Nishihara <yuya@tcha.org>
parents: 29801
diff changeset
    20
0f6d6fdd3c2a pycompat: provide 'ispy3' constant
Yuya Nishihara <yuya@tcha.org>
parents: 29801
diff changeset
    21
if not ispy3:
31934
12aca6770046 util: make cookielib module available
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31843
diff changeset
    22
    import cookielib
29324
b501579147f1 py3: conditionalize cPickle import by adding in util
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28882
diff changeset
    23
    import cPickle as pickle
29455
0c741fd6158a py3: conditionalize httplib import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29433
diff changeset
    24
    import httplib
29584
06587edd1233 pycompat: make pycompat demandimport friendly
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
    25
    import Queue as _queue
29433
33770d2b6cf9 py3: conditionalize SocketServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29432
diff changeset
    26
    import SocketServer as socketserver
29432
34b914ac573e py3: conditionalize xmlrpclib import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29431
diff changeset
    27
    import xmlrpclib
29584
06587edd1233 pycompat: make pycompat demandimport friendly
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
    28
else:
31942
bc0579a25f82 pycompat: import correct cookie module on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31934
diff changeset
    29
    import http.cookiejar as cookielib
29584
06587edd1233 pycompat: make pycompat demandimport friendly
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
    30
    import http.client as httplib
06587edd1233 pycompat: make pycompat demandimport friendly
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
    31
    import pickle
06587edd1233 pycompat: make pycompat demandimport friendly
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
    32
    import queue as _queue
06587edd1233 pycompat: make pycompat demandimport friendly
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
    33
    import socketserver
29432
34b914ac573e py3: conditionalize xmlrpclib import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29431
diff changeset
    34
    import xmlrpc.client as xmlrpclib
29431
80880ad3fccd py3: conditionalize the urlparse import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29414
diff changeset
    35
32865
6e38b4212661 pycompat: move the queue related definitions below queue import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32864
diff changeset
    36
empty = _queue.Empty
6e38b4212661 pycompat: move the queue related definitions below queue import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32864
diff changeset
    37
queue = _queue.Queue
6e38b4212661 pycompat: move the queue related definitions below queue import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32864
diff changeset
    38
31774
7d2cbe11ae48 pycompat: introduce identity function as a compat stub
Yuya Nishihara <yuya@tcha.org>
parents: 31573
diff changeset
    39
def identity(a):
7d2cbe11ae48 pycompat: introduce identity function as a compat stub
Yuya Nishihara <yuya@tcha.org>
parents: 31573
diff changeset
    40
    return a
7d2cbe11ae48 pycompat: introduce identity function as a compat stub
Yuya Nishihara <yuya@tcha.org>
parents: 31573
diff changeset
    41
30030
0f6d6fdd3c2a pycompat: provide 'ispy3' constant
Yuya Nishihara <yuya@tcha.org>
parents: 29801
diff changeset
    42
if ispy3:
29797
965c91bad9e3 py3: move xrange alias next to import lines
Yuya Nishihara <yuya@tcha.org>
parents: 29779
diff changeset
    43
    import builtins
29799
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29798
diff changeset
    44
    import functools
31372
06440ba06bc0 pycompat: move imports of cStringIO/io to where they are used
Yuya Nishihara <yuya@tcha.org>
parents: 31359
diff changeset
    45
    import io
31424
4acc49335a6e py3: optimize py3 compat.bytechr using Struct.pack
Martin von Zweigbergk <martinvonz@google.com>
parents: 31400
diff changeset
    46
    import struct
31372
06440ba06bc0 pycompat: move imports of cStringIO/io to where they are used
Yuya Nishihara <yuya@tcha.org>
parents: 31359
diff changeset
    47
30119
f4a5e0e86a7e py3: add an os.fsencode backport to ease path handling
Martijn Pieters <mjpieters@fb.com>
parents: 30086
diff changeset
    48
    fsencode = os.fsencode
30300
42af0590f4b9 py3: add os.fsdecode() as pycompat.fsdecode()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30133
diff changeset
    49
    fsdecode = os.fsdecode
31775
8181f378b073 pycompat: provide bytes os.linesep
Yuya Nishihara <yuya@tcha.org>
parents: 31774
diff changeset
    50
    oslinesep = os.linesep.encode('ascii')
30302
3874ddba1ab4 py3: add a bytes version of os.name
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30300
diff changeset
    51
    osname = os.name.encode('ascii')
30303
ad40d307a9f0 py3: have pycompat.ospathsep and pycompat.ossep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30302
diff changeset
    52
    ospathsep = os.pathsep.encode('ascii')
ad40d307a9f0 py3: have pycompat.ospathsep and pycompat.ossep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30302
diff changeset
    53
    ossep = os.sep.encode('ascii')
30623
c6026c20a3ce py3: have a bytes version of os.altsep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30579
diff changeset
    54
    osaltsep = os.altsep
c6026c20a3ce py3: have a bytes version of os.altsep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30579
diff changeset
    55
    if osaltsep:
c6026c20a3ce py3: have a bytes version of os.altsep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30579
diff changeset
    56
        osaltsep = osaltsep.encode('ascii')
30500
fc0cfe6c87d7 py3: add os.getcwdb() to have bytes path
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30472
diff changeset
    57
    # os.getcwd() on Python 3 returns string, but it has os.getcwdb() which
fc0cfe6c87d7 py3: add os.getcwdb() to have bytes path
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30472
diff changeset
    58
    # returns bytes.
fc0cfe6c87d7 py3: add os.getcwdb() to have bytes path
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30472
diff changeset
    59
    getcwd = os.getcwdb
30624
a82a6eee2613 py3: have a bytes version of sys.platform
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30623
diff changeset
    60
    sysplatform = sys.platform.encode('ascii')
30668
3fcaf0f660ce py3: have bytes version of sys.executable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30663
diff changeset
    61
    sysexecutable = sys.executable
3fcaf0f660ce py3: have bytes version of sys.executable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30663
diff changeset
    62
    if sysexecutable:
3fcaf0f660ce py3: have bytes version of sys.executable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30663
diff changeset
    63
        sysexecutable = os.fsencode(sysexecutable)
31359
73b3bee8febe pycompat: default to BytesIO instead of StringIO
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31301
diff changeset
    64
    stringio = io.BytesIO
31501
a1e40ceee640 pycompat: add maplist alias for old map behavior
Augie Fackler <augie@google.com>
parents: 31439
diff changeset
    65
    maplist = lambda *args: list(map(*args))
33853
cfcfbe6c96f8 py3: select input or raw_input by pycompat
Yuya Nishihara <yuya@tcha.org>
parents: 33626
diff changeset
    66
    rawinput = input
30334
19d8e19fde5b py3: document why os.fsencode() can be used to get back bytes argv
Yuya Nishihara <yuya@tcha.org>
parents: 30330
diff changeset
    67
30472
277f4fe6d01a py3: provide bytes stdin/out/err through util module
Yuya Nishihara <yuya@tcha.org>
parents: 30334
diff changeset
    68
    # 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
    69
    # 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
    70
    stdin = sys.stdin.buffer
277f4fe6d01a py3: provide bytes stdin/out/err through util module
Yuya Nishihara <yuya@tcha.org>
parents: 30334
diff changeset
    71
    stdout = sys.stdout.buffer
277f4fe6d01a py3: provide bytes stdin/out/err through util module
Yuya Nishihara <yuya@tcha.org>
parents: 30334
diff changeset
    72
    stderr = sys.stderr.buffer
277f4fe6d01a py3: provide bytes stdin/out/err through util module
Yuya Nishihara <yuya@tcha.org>
parents: 30334
diff changeset
    73
30334
19d8e19fde5b py3: document why os.fsencode() can be used to get back bytes argv
Yuya Nishihara <yuya@tcha.org>
parents: 30330
diff changeset
    74
    # 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
    75
    # 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
    76
    #
19d8e19fde5b py3: document why os.fsencode() can be used to get back bytes argv
Yuya Nishihara <yuya@tcha.org>
parents: 30330
diff changeset
    77
    # 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
    78
    #
19d8e19fde5b py3: document why os.fsencode() can be used to get back bytes argv
Yuya Nishihara <yuya@tcha.org>
parents: 30330
diff changeset
    79
    # 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
    80
    # 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
    81
    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
    82
        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
    83
31424
4acc49335a6e py3: optimize py3 compat.bytechr using Struct.pack
Martin von Zweigbergk <martinvonz@google.com>
parents: 31400
diff changeset
    84
    bytechr = struct.Struct('>B').pack
31253
64596338ba10 py3: factor out bytechr() function
Yuya Nishihara <yuya@tcha.org>
parents: 31149
diff changeset
    85
31439
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
    86
    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
    87
        """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
    88
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
    89
        >>> bytestr(), bytestr(bytearray(b'foo')), bytestr(u'ascii'), bytestr(1)
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
    90
        (b'', b'foo', b'ascii', b'1')
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
    91
        >>> 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
    92
        >>> 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
    93
32450
548478efc46c pycompat: try __bytes__() to convert object to bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 32186
diff changeset
    94
        __bytes__() should be called if provided:
548478efc46c pycompat: try __bytes__() to convert object to bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 32186
diff changeset
    95
548478efc46c pycompat: try __bytes__() to convert object to bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 32186
diff changeset
    96
        >>> class bytesable(object):
548478efc46c pycompat: try __bytes__() to convert object to bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 32186
diff changeset
    97
        ...     def __bytes__(self):
548478efc46c pycompat: try __bytes__() to convert object to bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 32186
diff changeset
    98
        ...         return b'bytes'
548478efc46c pycompat: try __bytes__() to convert object to bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 32186
diff changeset
    99
        >>> bytestr(bytesable())
548478efc46c pycompat: try __bytes__() to convert object to bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 32186
diff changeset
   100
        b'bytes'
548478efc46c pycompat: try __bytes__() to convert object to bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 32186
diff changeset
   101
31439
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
   102
        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
   103
        unknown:
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
   104
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
   105
        >>> 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
   106
        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
   107
          ...
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
   108
        UnicodeEncodeError: ...
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
   109
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
   110
        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
   111
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
   112
        >>> 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
   113
        >>> 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
   114
        >>> 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
   115
        >>> 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
   116
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
   117
        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
   118
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
   119
        >>> 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
   120
        (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
   121
        >>> 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
   122
        ([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
   123
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
   124
        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
   125
        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
   126
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
   127
        >>> 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
   128
        >>> 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
   129
        >>> 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
   130
        (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
   131
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
   132
        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
   133
        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
   134
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
   135
        >>> 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
   136
        >>> 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
   137
        """
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
   138
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
   139
        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
   140
            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
   141
                return s
32450
548478efc46c pycompat: try __bytes__() to convert object to bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 32186
diff changeset
   142
            if (not isinstance(s, (bytes, bytearray))
548478efc46c pycompat: try __bytes__() to convert object to bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 32186
diff changeset
   143
                and not hasattr(s, u'__bytes__')):  # hasattr-py3-only
31439
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
   144
                s = str(s).encode(u'ascii')
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
   145
            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
   146
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
   147
        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
   148
            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
   149
            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
   150
                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
   151
            return s
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
        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
   154
            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
   155
31382
c9fd842dc886 pycompat: add helper to iterate each char in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31372
diff changeset
   156
    def iterbytestr(s):
c9fd842dc886 pycompat: add helper to iterate each char in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31372
diff changeset
   157
        """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
   158
        return map(bytechr, s)
31382
c9fd842dc886 pycompat: add helper to iterate each char in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31372
diff changeset
   159
31820
45761ef1bc93 py3: have registrar process docstrings in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31775
diff changeset
   160
    def sysbytes(s):
45761ef1bc93 py3: have registrar process docstrings in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31775
diff changeset
   161
        """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
   162
45761ef1bc93 py3: have registrar process docstrings in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31775
diff changeset
   163
        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
   164
        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
   165
        """
45761ef1bc93 py3: have registrar process docstrings in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31775
diff changeset
   166
        return s.encode(u'utf-8')
45761ef1bc93 py3: have registrar process docstrings in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31775
diff changeset
   167
30032
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
   168
    def sysstr(s):
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
   169
        """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
   170
        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
   171
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
   172
        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
   173
        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
   174
        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
   175
        """
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
   176
        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
   177
            return s
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
   178
        return s.decode(u'latin-1')
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
   179
32859
a05f3675c46a py3: add a new strurl() which will convert a bytes url to str
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32615
diff changeset
   180
    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
   181
        """Converts a bytes url back to str"""
a05f3675c46a py3: add a new strurl() which will convert a bytes url to str
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32615
diff changeset
   182
        return url.decode(u'ascii')
a05f3675c46a py3: add a new strurl() which will convert a bytes url to str
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32615
diff changeset
   183
32860
f22f39d56bb5 py3: add a new bytesurl() to convert a str url into bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32859
diff changeset
   184
    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
   185
        """Converts a str url to bytes by encoding in ascii"""
f22f39d56bb5 py3: add a new bytesurl() to convert a str url into bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32859
diff changeset
   186
        return url.encode(u'ascii')
f22f39d56bb5 py3: add a new bytesurl() to convert a str url into bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32859
diff changeset
   187
32186
76f9a0009b4b pycompat: extract helper to raise exception with traceback
Yuya Nishihara <yuya@tcha.org>
parents: 31942
diff changeset
   188
    def raisewithtb(exc, tb):
76f9a0009b4b pycompat: extract helper to raise exception with traceback
Yuya Nishihara <yuya@tcha.org>
parents: 31942
diff changeset
   189
        """Raise exception with the given traceback"""
76f9a0009b4b pycompat: extract helper to raise exception with traceback
Yuya Nishihara <yuya@tcha.org>
parents: 31942
diff changeset
   190
        raise exc.with_traceback(tb)
76f9a0009b4b pycompat: extract helper to raise exception with traceback
Yuya Nishihara <yuya@tcha.org>
parents: 31942
diff changeset
   191
32615
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
   192
    def getdoc(obj):
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
   193
        """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
   194
        with _('')"""
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
   195
        doc = getattr(obj, u'__doc__', None)
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
   196
        if doc is None:
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
   197
            return doc
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
   198
        return sysbytes(doc)
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
   199
29799
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29798
diff changeset
   200
    def _wrapattrfunc(f):
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29798
diff changeset
   201
        @functools.wraps(f)
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29798
diff changeset
   202
        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
   203
            return f(object, sysstr(name), *args)
29799
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29798
diff changeset
   204
        return w
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29798
diff changeset
   205
29800
178c89e8519a py3: import builtin wrappers automagically by code transformer
Yuya Nishihara <yuya@tcha.org>
parents: 29799
diff changeset
   206
    # 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
   207
    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
   208
    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
   209
    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
   210
    setattr = _wrapattrfunc(builtins.setattr)
29800
178c89e8519a py3: import builtin wrappers automagically by code transformer
Yuya Nishihara <yuya@tcha.org>
parents: 29799
diff changeset
   211
    xrange = builtins.range
31843
526e4597cca5 py3: add pycompat.unicode and add it to importer
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31842
diff changeset
   212
    unicode = str
29799
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29798
diff changeset
   213
31149
76a64c1e5439 py3: add pycompat.open and replace open() calls
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30820
diff changeset
   214
    def open(name, mode='r', buffering=-1):
76a64c1e5439 py3: add pycompat.open and replace open() calls
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30820
diff changeset
   215
        return builtins.open(name, sysstr(mode), buffering)
76a64c1e5439 py3: add pycompat.open and replace open() calls
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30820
diff changeset
   216
30578
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30500
diff changeset
   217
    def getoptb(args, shortlist, namelist):
32864
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
   218
        """
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
   219
        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
   220
        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
   221
        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
   222
        bytes on Python 3.
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
   223
        """
30578
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30500
diff changeset
   224
        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
   225
        shortlist = shortlist.decode('latin-1')
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30500
diff changeset
   226
        namelist = [a.decode('latin-1') for a in namelist]
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30500
diff changeset
   227
        opts, args = getopt.getopt(args, shortlist, namelist)
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30500
diff changeset
   228
        opts = [(a[0].encode('latin-1'), a[1].encode('latin-1'))
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30500
diff changeset
   229
                for a in opts]
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30500
diff changeset
   230
        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
   231
        return opts, args
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30500
diff changeset
   232
30579
fbc3f73dc802 py3: utility functions to convert keys of kwargs to bytes/unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30578
diff changeset
   233
    def strkwargs(dic):
32864
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
   234
        """
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
   235
        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
   236
        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
   237
        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
   238
        """
30579
fbc3f73dc802 py3: utility functions to convert keys of kwargs to bytes/unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30578
diff changeset
   239
        dic = dict((k.decode('latin-1'), v) for k, v in dic.iteritems())
fbc3f73dc802 py3: utility functions to convert keys of kwargs to bytes/unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30578
diff changeset
   240
        return dic
fbc3f73dc802 py3: utility functions to convert keys of kwargs to bytes/unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30578
diff changeset
   241
fbc3f73dc802 py3: utility functions to convert keys of kwargs to bytes/unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30578
diff changeset
   242
    def byteskwargs(dic):
32864
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
   243
        """
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
   244
        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
   245
        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
   246
        """
30579
fbc3f73dc802 py3: utility functions to convert keys of kwargs to bytes/unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30578
diff changeset
   247
        dic = dict((k.encode('latin-1'), v) for k, v in dic.iteritems())
fbc3f73dc802 py3: utility functions to convert keys of kwargs to bytes/unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30578
diff changeset
   248
        return dic
fbc3f73dc802 py3: utility functions to convert keys of kwargs to bytes/unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30578
diff changeset
   249
30678
caf7e1c5efe4 py3: have a bytes version of shlex.split()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30668
diff changeset
   250
    # TODO: handle shlex.shlex().
caf7e1c5efe4 py3: have a bytes version of shlex.split()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30668
diff changeset
   251
    def shlexsplit(s):
32864
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
   252
        """
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
   253
        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
   254
        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
   255
        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
   256
        """
30678
caf7e1c5efe4 py3: have a bytes version of shlex.split()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30668
diff changeset
   257
        ret = shlex.split(s.decode('latin-1'))
caf7e1c5efe4 py3: have a bytes version of shlex.split()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30668
diff changeset
   258
        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
   259
30032
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
   260
else:
31372
06440ba06bc0 pycompat: move imports of cStringIO/io to where they are used
Yuya Nishihara <yuya@tcha.org>
parents: 31359
diff changeset
   261
    import cStringIO
06440ba06bc0 pycompat: move imports of cStringIO/io to where they are used
Yuya Nishihara <yuya@tcha.org>
parents: 31359
diff changeset
   262
31253
64596338ba10 py3: factor out bytechr() function
Yuya Nishihara <yuya@tcha.org>
parents: 31149
diff changeset
   263
    bytechr = chr
31439
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31425
diff changeset
   264
    bytestr = str
31382
c9fd842dc886 pycompat: add helper to iterate each char in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31372
diff changeset
   265
    iterbytestr = iter
31820
45761ef1bc93 py3: have registrar process docstrings in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31775
diff changeset
   266
    sysbytes = identity
31774
7d2cbe11ae48 pycompat: introduce identity function as a compat stub
Yuya Nishihara <yuya@tcha.org>
parents: 31573
diff changeset
   267
    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
   268
    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
   269
    bytesurl = identity
30032
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30030
diff changeset
   270
32186
76f9a0009b4b pycompat: extract helper to raise exception with traceback
Yuya Nishihara <yuya@tcha.org>
parents: 31942
diff changeset
   271
    # this can't be parsed on Python 3
76f9a0009b4b pycompat: extract helper to raise exception with traceback
Yuya Nishihara <yuya@tcha.org>
parents: 31942
diff changeset
   272
    exec('def raisewithtb(exc, tb):\n'
76f9a0009b4b pycompat: extract helper to raise exception with traceback
Yuya Nishihara <yuya@tcha.org>
parents: 31942
diff changeset
   273
         '    raise exc, None, tb\n')
76f9a0009b4b pycompat: extract helper to raise exception with traceback
Yuya Nishihara <yuya@tcha.org>
parents: 31942
diff changeset
   274
30133
f6dcda7505f9 pycompat: only accept a bytestring filepath in Python 2
Martijn Pieters <mjpieters@fb.com>
parents: 30119
diff changeset
   275
    def fsencode(filename):
32864
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
   276
        """
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
   277
        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
   278
        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
   279
        indicates a bug.
f57f1f37290d pycompat: move multiline comments above a function to function doc
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32860
diff changeset
   280
        """
30133
f6dcda7505f9 pycompat: only accept a bytestring filepath in Python 2
Martijn Pieters <mjpieters@fb.com>
parents: 30119
diff changeset
   281
        if isinstance(filename, str):
f6dcda7505f9 pycompat: only accept a bytestring filepath in Python 2
Martijn Pieters <mjpieters@fb.com>
parents: 30119
diff changeset
   282
            return filename
30119
f4a5e0e86a7e py3: add an os.fsencode backport to ease path handling
Martijn Pieters <mjpieters@fb.com>
parents: 30086
diff changeset
   283
        else:
30133
f6dcda7505f9 pycompat: only accept a bytestring filepath in Python 2
Martijn Pieters <mjpieters@fb.com>
parents: 30119
diff changeset
   284
            raise TypeError(
f6dcda7505f9 pycompat: only accept a bytestring filepath in Python 2
Martijn Pieters <mjpieters@fb.com>
parents: 30119
diff changeset
   285
                "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
   286
30300
42af0590f4b9 py3: add os.fsdecode() as pycompat.fsdecode()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30133
diff changeset
   287
    # 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
   288
    # 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
   289
    fsdecode = identity
30300
42af0590f4b9 py3: add os.fsdecode() as pycompat.fsdecode()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30133
diff changeset
   290
32615
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
   291
    def getdoc(obj):
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
   292
        return getattr(obj, '__doc__', None)
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32450
diff changeset
   293
30578
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30500
diff changeset
   294
    def getoptb(args, shortlist, namelist):
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30500
diff changeset
   295
        return getopt.getopt(args, shortlist, namelist)
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30500
diff changeset
   296
31774
7d2cbe11ae48 pycompat: introduce identity function as a compat stub
Yuya Nishihara <yuya@tcha.org>
parents: 31573
diff changeset
   297
    strkwargs = identity
7d2cbe11ae48 pycompat: introduce identity function as a compat stub
Yuya Nishihara <yuya@tcha.org>
parents: 31573
diff changeset
   298
    byteskwargs = identity
30579
fbc3f73dc802 py3: utility functions to convert keys of kwargs to bytes/unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30578
diff changeset
   299
31775
8181f378b073 pycompat: provide bytes os.linesep
Yuya Nishihara <yuya@tcha.org>
parents: 31774
diff changeset
   300
    oslinesep = os.linesep
30302
3874ddba1ab4 py3: add a bytes version of os.name
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30300
diff changeset
   301
    osname = os.name
30303
ad40d307a9f0 py3: have pycompat.ospathsep and pycompat.ossep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30302
diff changeset
   302
    ospathsep = os.pathsep
ad40d307a9f0 py3: have pycompat.ospathsep and pycompat.ossep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30302
diff changeset
   303
    ossep = os.sep
30623
c6026c20a3ce py3: have a bytes version of os.altsep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30579
diff changeset
   304
    osaltsep = os.altsep
30472
277f4fe6d01a py3: provide bytes stdin/out/err through util module
Yuya Nishihara <yuya@tcha.org>
parents: 30334
diff changeset
   305
    stdin = sys.stdin
277f4fe6d01a py3: provide bytes stdin/out/err through util module
Yuya Nishihara <yuya@tcha.org>
parents: 30334
diff changeset
   306
    stdout = sys.stdout
277f4fe6d01a py3: provide bytes stdin/out/err through util module
Yuya Nishihara <yuya@tcha.org>
parents: 30334
diff changeset
   307
    stderr = sys.stderr
31277
86cd1f2cfff5 pycompat: verify sys.argv exists before forwarding it (issue5493)
Augie Fackler <augie@google.com>
parents: 30820
diff changeset
   308
    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
   309
        sysargv = sys.argv
30624
a82a6eee2613 py3: have a bytes version of sys.platform
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30623
diff changeset
   310
    sysplatform = sys.platform
30500
fc0cfe6c87d7 py3: add os.getcwdb() to have bytes path
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30472
diff changeset
   311
    getcwd = os.getcwd
30668
3fcaf0f660ce py3: have bytes version of sys.executable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30663
diff changeset
   312
    sysexecutable = sys.executable
30678
caf7e1c5efe4 py3: have a bytes version of shlex.split()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30668
diff changeset
   313
    shlexsplit = shlex.split
31372
06440ba06bc0 pycompat: move imports of cStringIO/io to where they are used
Yuya Nishihara <yuya@tcha.org>
parents: 31359
diff changeset
   314
    stringio = cStringIO.StringIO
31501
a1e40ceee640 pycompat: add maplist alias for old map behavior
Augie Fackler <augie@google.com>
parents: 31439
diff changeset
   315
    maplist = map
33853
cfcfbe6c96f8 py3: select input or raw_input by pycompat
Yuya Nishihara <yuya@tcha.org>
parents: 33626
diff changeset
   316
    rawinput = raw_input
30302
3874ddba1ab4 py3: add a bytes version of os.name
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30300
diff changeset
   317
28882
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   318
class _pycompatstub(object):
29801
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   319
    def __init__(self):
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   320
        self._aliases = {}
28882
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   321
29801
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   322
    def _registeraliases(self, origin, items):
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   323
        """Add items that will be populated at the first access"""
30086
f3a1089654e3 pycompat: when setting attrs, ensure we use sysstr
Augie Fackler <augie@google.com>
parents: 30032
diff changeset
   324
        items = map(sysstr, items)
f3a1089654e3 pycompat: when setting attrs, ensure we use sysstr
Augie Fackler <augie@google.com>
parents: 30032
diff changeset
   325
        self._aliases.update(
f3a1089654e3 pycompat: when setting attrs, ensure we use sysstr
Augie Fackler <augie@google.com>
parents: 30032
diff changeset
   326
            (item.replace(sysstr('_'), sysstr('')).lower(), (origin, item))
f3a1089654e3 pycompat: when setting attrs, ensure we use sysstr
Augie Fackler <augie@google.com>
parents: 30032
diff changeset
   327
            for item in items)
28882
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   328
31566
c6df6a23dfe5 pycompat: alias urlreq.unquote to unquote_to_bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31501
diff changeset
   329
    def _registeralias(self, origin, attr, name):
c6df6a23dfe5 pycompat: alias urlreq.unquote to unquote_to_bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31501
diff changeset
   330
        """Alias ``origin``.``attr`` as ``name``"""
c6df6a23dfe5 pycompat: alias urlreq.unquote to unquote_to_bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31501
diff changeset
   331
        self._aliases[sysstr(name)] = (origin, sysstr(attr))
c6df6a23dfe5 pycompat: alias urlreq.unquote to unquote_to_bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31501
diff changeset
   332
29801
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   333
    def __getattr__(self, name):
28882
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   334
        try:
29801
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   335
            origin, item = self._aliases[name]
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   336
        except KeyError:
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   337
            raise AttributeError(name)
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   338
        self.__dict__[name] = obj = getattr(origin, item)
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   339
        return obj
28882
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   340
29566
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29455
diff changeset
   341
httpserver = _pycompatstub()
28882
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   342
urlreq = _pycompatstub()
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   343
urlerr = _pycompatstub()
30030
0f6d6fdd3c2a pycompat: provide 'ispy3' constant
Yuya Nishihara <yuya@tcha.org>
parents: 29801
diff changeset
   344
if not ispy3:
29566
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29455
diff changeset
   345
    import BaseHTTPServer
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29455
diff changeset
   346
    import CGIHTTPServer
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29455
diff changeset
   347
    import SimpleHTTPServer
28882
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   348
    import urllib2
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   349
    import urllib
31569
e68932dfbb55 pycompat: define urlreq.urlparse and urlreq.unparse aliases
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31568
diff changeset
   350
    import urlparse
29801
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   351
    urlreq._registeraliases(urllib, (
28882
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   352
        "addclosehook",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   353
        "addinfourl",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   354
        "ftpwrapper",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   355
        "pathname2url",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   356
        "quote",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   357
        "splitattr",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   358
        "splitpasswd",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   359
        "splitport",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   360
        "splituser",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   361
        "unquote",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   362
        "url2pathname",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   363
        "urlencode",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   364
    ))
29801
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   365
    urlreq._registeraliases(urllib2, (
28882
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   366
        "AbstractHTTPHandler",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   367
        "BaseHandler",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   368
        "build_opener",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   369
        "FileHandler",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   370
        "FTPHandler",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   371
        "HTTPBasicAuthHandler",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   372
        "HTTPDigestAuthHandler",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   373
        "HTTPHandler",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   374
        "HTTPPasswordMgrWithDefaultRealm",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   375
        "HTTPSHandler",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   376
        "install_opener",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   377
        "ProxyHandler",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   378
        "Request",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   379
        "urlopen",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   380
    ))
31569
e68932dfbb55 pycompat: define urlreq.urlparse and urlreq.unparse aliases
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31568
diff changeset
   381
    urlreq._registeraliases(urlparse, (
e68932dfbb55 pycompat: define urlreq.urlparse and urlreq.unparse aliases
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31568
diff changeset
   382
        "urlparse",
e68932dfbb55 pycompat: define urlreq.urlparse and urlreq.unparse aliases
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31568
diff changeset
   383
        "urlunparse",
e68932dfbb55 pycompat: define urlreq.urlparse and urlreq.unparse aliases
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31568
diff changeset
   384
    ))
29801
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   385
    urlerr._registeraliases(urllib2, (
28882
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   386
        "HTTPError",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   387
        "URLError",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   388
    ))
29801
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   389
    httpserver._registeraliases(BaseHTTPServer, (
29566
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29455
diff changeset
   390
        "HTTPServer",
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29455
diff changeset
   391
        "BaseHTTPRequestHandler",
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29455
diff changeset
   392
    ))
29801
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   393
    httpserver._registeraliases(SimpleHTTPServer, (
29566
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29455
diff changeset
   394
        "SimpleHTTPRequestHandler",
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29455
diff changeset
   395
    ))
29801
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   396
    httpserver._registeraliases(CGIHTTPServer, (
29566
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29455
diff changeset
   397
        "CGIHTTPRequestHandler",
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29455
diff changeset
   398
    ))
28882
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   399
29801
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   400
else:
31399
1ed169c5e235 pycompat: alias urllib symbols directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31382
diff changeset
   401
    import urllib.parse
1ed169c5e235 pycompat: alias urllib symbols directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31382
diff changeset
   402
    urlreq._registeraliases(urllib.parse, (
1ed169c5e235 pycompat: alias urllib symbols directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31382
diff changeset
   403
        "splitattr",
1ed169c5e235 pycompat: alias urllib symbols directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31382
diff changeset
   404
        "splitpasswd",
1ed169c5e235 pycompat: alias urllib symbols directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31382
diff changeset
   405
        "splitport",
1ed169c5e235 pycompat: alias urllib symbols directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31382
diff changeset
   406
        "splituser",
31569
e68932dfbb55 pycompat: define urlreq.urlparse and urlreq.unparse aliases
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31568
diff changeset
   407
        "urlparse",
e68932dfbb55 pycompat: define urlreq.urlparse and urlreq.unparse aliases
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31568
diff changeset
   408
        "urlunparse",
31399
1ed169c5e235 pycompat: alias urllib symbols directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31382
diff changeset
   409
    ))
31566
c6df6a23dfe5 pycompat: alias urlreq.unquote to unquote_to_bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31501
diff changeset
   410
    urlreq._registeralias(urllib.parse, "unquote_to_bytes", "unquote")
28882
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   411
    import urllib.request
29801
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   412
    urlreq._registeraliases(urllib.request, (
28882
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   413
        "AbstractHTTPHandler",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   414
        "BaseHandler",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   415
        "build_opener",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   416
        "FileHandler",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   417
        "FTPHandler",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   418
        "ftpwrapper",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   419
        "HTTPHandler",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   420
        "HTTPSHandler",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   421
        "install_opener",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   422
        "pathname2url",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   423
        "HTTPBasicAuthHandler",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   424
        "HTTPDigestAuthHandler",
29414
2646fbba4ca7 pycompat: add HTTPPasswordMgrWithDefaultRealm to Python 3 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29405
diff changeset
   425
        "HTTPPasswordMgrWithDefaultRealm",
28882
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   426
        "ProxyHandler",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   427
        "Request",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   428
        "url2pathname",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   429
        "urlopen",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   430
    ))
31399
1ed169c5e235 pycompat: alias urllib symbols directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31382
diff changeset
   431
    import urllib.response
1ed169c5e235 pycompat: alias urllib symbols directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31382
diff changeset
   432
    urlreq._registeraliases(urllib.response, (
1ed169c5e235 pycompat: alias urllib symbols directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31382
diff changeset
   433
        "addclosehook",
1ed169c5e235 pycompat: alias urllib symbols directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31382
diff changeset
   434
        "addinfourl",
1ed169c5e235 pycompat: alias urllib symbols directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31382
diff changeset
   435
    ))
28882
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   436
    import urllib.error
29801
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   437
    urlerr._registeraliases(urllib.error, (
28882
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   438
        "HTTPError",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   439
        "URLError",
800ec7c048b0 pycompat: add util.urlerr util.urlreq classes for py3 compat
timeless <timeless@mozdev.org>
parents: 28835
diff changeset
   440
    ))
29566
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29455
diff changeset
   441
    import http.server
29801
c63ab0524db7 pycompat: delay loading modules registered to stub
Yuya Nishihara <yuya@tcha.org>
parents: 29800
diff changeset
   442
    httpserver._registeraliases(http.server, (
29566
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29455
diff changeset
   443
        "HTTPServer",
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29455
diff changeset
   444
        "BaseHTTPRequestHandler",
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29455
diff changeset
   445
        "SimpleHTTPRequestHandler",
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29455
diff changeset
   446
        "CGIHTTPRequestHandler",
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29455
diff changeset
   447
    ))
31400
fb1f70331ee6 pycompat: custom implementation of urllib.parse.quote()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31399
diff changeset
   448
fb1f70331ee6 pycompat: custom implementation of urllib.parse.quote()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31399
diff changeset
   449
    # urllib.parse.quote() accepts both str and bytes, decodes bytes
fb1f70331ee6 pycompat: custom implementation of urllib.parse.quote()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31399
diff changeset
   450
    # (if necessary), and returns str. This is wonky. We provide a custom
fb1f70331ee6 pycompat: custom implementation of urllib.parse.quote()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31399
diff changeset
   451
    # implementation that only accepts bytes and emits bytes.
fb1f70331ee6 pycompat: custom implementation of urllib.parse.quote()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31399
diff changeset
   452
    def quote(s, safe=r'/'):
fb1f70331ee6 pycompat: custom implementation of urllib.parse.quote()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31399
diff changeset
   453
        s = urllib.parse.quote_from_bytes(s, safe=safe)
fb1f70331ee6 pycompat: custom implementation of urllib.parse.quote()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31399
diff changeset
   454
        return s.encode('ascii', 'strict')
fb1f70331ee6 pycompat: custom implementation of urllib.parse.quote()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31399
diff changeset
   455
31842
c130d092042a py3: add a bytes version of urllib.parse.urlencode() to pycompat.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31820
diff changeset
   456
    # urllib.parse.urlencode() returns str. We use this function to make
c130d092042a py3: add a bytes version of urllib.parse.urlencode() to pycompat.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31820
diff changeset
   457
    # sure we return bytes.
c130d092042a py3: add a bytes version of urllib.parse.urlencode() to pycompat.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31820
diff changeset
   458
    def urlencode(query, doseq=False):
c130d092042a py3: add a bytes version of urllib.parse.urlencode() to pycompat.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31820
diff changeset
   459
            s = urllib.parse.urlencode(query, doseq=doseq)
c130d092042a py3: add a bytes version of urllib.parse.urlencode() to pycompat.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31820
diff changeset
   460
            return s.encode('ascii')
c130d092042a py3: add a bytes version of urllib.parse.urlencode() to pycompat.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31820
diff changeset
   461
31400
fb1f70331ee6 pycompat: custom implementation of urllib.parse.quote()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31399
diff changeset
   462
    urlreq.quote = quote
31842
c130d092042a py3: add a bytes version of urllib.parse.urlencode() to pycompat.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31820
diff changeset
   463
    urlreq.urlencode = urlencode