mercurial/pycompat.py
author Arseniy Alekseyev <aalekseyev@janestreet.com>
Mon, 26 Jun 2023 11:21:43 +0100
branchstable
changeset 50720 bfbd84c57bda
parent 50219 829aa604d71a
child 50947 9bffc6c4e4c5
permissions -rw-r--r--
dirstate-v2: actually fix the dirstate-v2 upgrade race It looks like the previous fix for the dirstate-v2 upgrade race didn't work. The problem is that it only recovers in case the size of the v1 `dirstate` file is smaller than the `v2` one, whereas in real life it's always larger. This commit changes the test to be more realistic, which reveals the crash, and changes the code to fix the crash.
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
48960
57b58413dad1 pycompat: remove first not ispy3 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48926
diff changeset
    12
import builtins
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
    13
import codecs
48960
57b58413dad1 pycompat: remove first not ispy3 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48926
diff changeset
    14
import concurrent.futures as futures
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
    15
import functools
30583
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30509
diff changeset
    16
import getopt
48960
57b58413dad1 pycompat: remove first not ispy3 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48926
diff changeset
    17
import http.client as httplib
57b58413dad1 pycompat: remove first not ispy3 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48926
diff changeset
    18
import http.cookiejar as cookielib
36216
646002338365 py3: introduce and use pycompat.getargspec
Augie Fackler <augie@google.com>
parents: 36083
diff changeset
    19
import inspect
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
    20
import io
43380
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
    21
import json
30315
3874ddba1ab4 py3: add a bytes version of os.name
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30313
diff changeset
    22
import os
48960
57b58413dad1 pycompat: remove first not ispy3 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48926
diff changeset
    23
import queue
30681
caf7e1c5efe4 py3: have a bytes version of shlex.split()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30671
diff changeset
    24
import shlex
48960
57b58413dad1 pycompat: remove first not ispy3 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48926
diff changeset
    25
import socketserver
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
    26
import struct
29584
06587edd1233 pycompat: make pycompat demandimport friendly
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
    27
import sys
38197
aac4be30e250 py3: wrap tempfile.mkstemp() to use bytes path
Yuya Nishihara <yuya@tcha.org>
parents: 37890
diff changeset
    28
import tempfile
48960
57b58413dad1 pycompat: remove first not ispy3 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48926
diff changeset
    29
import xmlrpc.client as xmlrpclib
29584
06587edd1233 pycompat: make pycompat demandimport friendly
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
    30
49896
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
    31
from typing import (
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
    32
    Any,
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
    33
    AnyStr,
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
    34
    BinaryIO,
50218
0ab92dabea6e typing: add type hints to pycompat.maplist()
Matt Harbison <matt_harbison@yahoo.com>
parents: 50150
diff changeset
    35
    Callable,
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
    36
    Dict,
49898
55d45d0de4e7 typing: add type hints to pycompat.bytestr
Matt Harbison <matt_harbison@yahoo.com>
parents: 49897
diff changeset
    37
    Iterable,
55d45d0de4e7 typing: add type hints to pycompat.bytestr
Matt Harbison <matt_harbison@yahoo.com>
parents: 49897
diff changeset
    38
    Iterator,
49896
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
    39
    List,
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
    40
    Mapping,
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
    41
    NoReturn,
49896
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
    42
    Optional,
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
    43
    Sequence,
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
    44
    Tuple,
49898
55d45d0de4e7 typing: add type hints to pycompat.bytestr
Matt Harbison <matt_harbison@yahoo.com>
parents: 49897
diff changeset
    45
    Type,
55d45d0de4e7 typing: add type hints to pycompat.bytestr
Matt Harbison <matt_harbison@yahoo.com>
parents: 49897
diff changeset
    46
    TypeVar,
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
    47
    cast,
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
    48
    overload,
49896
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
    49
)
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
    50
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
    51
ispy3 = sys.version_info[0] >= 3
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
    52
ispypy = '__pypy__' in sys.builtin_module_names
43793
7b14d649af1b typing: consolidate "if not globals():" trick
Yuya Nishihara <yuya@tcha.org>
parents: 43788
diff changeset
    53
TYPE_CHECKING = False
7b14d649af1b typing: consolidate "if not globals():" trick
Yuya Nishihara <yuya@tcha.org>
parents: 43788
diff changeset
    54
7b14d649af1b typing: consolidate "if not globals():" trick
Yuya Nishihara <yuya@tcha.org>
parents: 43788
diff changeset
    55
if not globals():  # hide this from non-pytype users
7b14d649af1b typing: consolidate "if not globals():" trick
Yuya Nishihara <yuya@tcha.org>
parents: 43788
diff changeset
    56
    import typing
7b14d649af1b typing: consolidate "if not globals():" trick
Yuya Nishihara <yuya@tcha.org>
parents: 43788
diff changeset
    57
7b14d649af1b typing: consolidate "if not globals():" trick
Yuya Nishihara <yuya@tcha.org>
parents: 43788
diff changeset
    58
    TYPE_CHECKING = typing.TYPE_CHECKING
30031
0f6d6fdd3c2a pycompat: provide 'ispy3' constant
Yuya Nishihara <yuya@tcha.org>
parents: 29812
diff changeset
    59
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
    60
_GetOptResult = Tuple[List[Tuple[bytes, bytes]], List[bytes]]
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
    61
_T0 = TypeVar('_T0')
50218
0ab92dabea6e typing: add type hints to pycompat.maplist()
Matt Harbison <matt_harbison@yahoo.com>
parents: 50150
diff changeset
    62
_T1 = TypeVar('_T1')
0ab92dabea6e typing: add type hints to pycompat.maplist()
Matt Harbison <matt_harbison@yahoo.com>
parents: 50150
diff changeset
    63
_S = TypeVar('_S')
49898
55d45d0de4e7 typing: add type hints to pycompat.bytestr
Matt Harbison <matt_harbison@yahoo.com>
parents: 49897
diff changeset
    64
_Tbytestr = TypeVar('_Tbytestr', bound='bytestr')
55d45d0de4e7 typing: add type hints to pycompat.bytestr
Matt Harbison <matt_harbison@yahoo.com>
parents: 49897
diff changeset
    65
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
    66
48960
57b58413dad1 pycompat: remove first not ispy3 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48926
diff changeset
    67
def future_set_exception_info(f, exc_info):
57b58413dad1 pycompat: remove first not ispy3 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48926
diff changeset
    68
    f.set_exception(exc_info[0])
29431
80880ad3fccd py3: conditionalize the urlparse import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29414
diff changeset
    69
37669
1cb54e6193a6 py3: paper over differences in future exception handling
Augie Fackler <augie@google.com>
parents: 37628
diff changeset
    70
48960
57b58413dad1 pycompat: remove first not ispy3 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48926
diff changeset
    71
FileNotFoundError = builtins.FileNotFoundError
47852
2b76255a4f74 template: FileNotFoundError is actually a built in exception
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46380
diff changeset
    72
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
    73
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
    74
def identity(a: _T0) -> _T0:
31777
7d2cbe11ae48 pycompat: introduce identity function as a compat stub
Yuya Nishihara <yuya@tcha.org>
parents: 31579
diff changeset
    75
    return a
7d2cbe11ae48 pycompat: introduce identity function as a compat stub
Yuya Nishihara <yuya@tcha.org>
parents: 31579
diff changeset
    76
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
    77
38576
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    78
def _rapply(f, xs):
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    79
    if xs is None:
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    80
        # assume None means non-value of optional data
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    81
        return xs
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    82
    if isinstance(xs, (list, set, tuple)):
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    83
        return type(xs)(_rapply(f, x) for x in xs)
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    84
    if isinstance(xs, dict):
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    85
        return type(xs)((_rapply(f, k), _rapply(f, v)) for k, v in xs.items())
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    86
    return f(xs)
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    87
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
    88
38576
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    89
def rapply(f, xs):
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    90
    """Apply function recursively to every item preserving the data structure
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    91
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    92
    >>> def f(x):
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    93
    ...     return 'f(%s)' % x
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    94
    >>> rapply(f, None) is None
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    95
    True
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    96
    >>> rapply(f, 'a')
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    97
    'f(a)'
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    98
    >>> rapply(f, {'a'}) == {'f(a)'}
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
    99
    True
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
   100
    >>> rapply(f, ['a', 'b', None, {'c': 'd'}, []])
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
   101
    ['f(a)', 'f(b)', None, {'f(c)': 'f(d)'}, []]
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
   102
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
   103
    >>> xs = [object()]
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
   104
    >>> rapply(identity, xs) is xs
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
   105
    True
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
   106
    """
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
   107
    if f is identity:
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
   108
        # fast path mainly for py2
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
   109
        return xs
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
   110
    return _rapply(f, xs)
152f4822d210 pycompat: move rapply() from util
Yuya Nishihara <yuya@tcha.org>
parents: 38341
diff changeset
   111
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
   112
49050
9ac1a4507bb3 pycompat: remove check for Python >= 3.6
Gregory Szorc <gregory.szorc@gmail.com>
parents: 49037
diff changeset
   113
if os.name == r'nt':
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   114
    # MBCS (or ANSI) filesystem encoding must be used as before.
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   115
    # Otherwise non-ASCII filenames in existing repositories would be
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   116
    # corrupted.
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   117
    # This must be set once prior to any fsencode/fsdecode calls.
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   118
    sys._enablelegacywindowsfsencoding()  # pytype: disable=module-attr
43484
8d5489b048b7 py3: enable legacy fs encoding to fix filename compatibility on Windows
Yuya Nishihara <yuya@tcha.org>
parents: 43117
diff changeset
   119
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   120
fsencode = os.fsencode
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   121
fsdecode = os.fsdecode
49896
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
   122
oscurdir: bytes = os.curdir.encode('ascii')
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
   123
oslinesep: bytes = os.linesep.encode('ascii')
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
   124
osname: bytes = os.name.encode('ascii')
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
   125
ospathsep: bytes = os.pathsep.encode('ascii')
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
   126
ospardir: bytes = os.pardir.encode('ascii')
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
   127
ossep: bytes = os.sep.encode('ascii')
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
   128
osaltsep: Optional[bytes] = os.altsep.encode('ascii') if os.altsep else None
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
   129
osdevnull: bytes = os.devnull.encode('ascii')
39823
24e493ec2229 py3: rename pycompat.getcwd() to encoding.getcwd() (API)
Matt Harbison <matt_harbison@yahoo.com>
parents: 39658
diff changeset
   130
49896
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
   131
sysplatform: bytes = sys.platform.encode('ascii')
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
   132
sysexecutable: bytes = os.fsencode(sys.executable) if sys.executable else b''
36940
dbae581010ea pycompat: name maplist() and ziplist() for better traceback message
Yuya Nishihara <yuya@tcha.org>
parents: 36677
diff changeset
   133
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   134
50218
0ab92dabea6e typing: add type hints to pycompat.maplist()
Matt Harbison <matt_harbison@yahoo.com>
parents: 50150
diff changeset
   135
if TYPE_CHECKING:
0ab92dabea6e typing: add type hints to pycompat.maplist()
Matt Harbison <matt_harbison@yahoo.com>
parents: 50150
diff changeset
   136
0ab92dabea6e typing: add type hints to pycompat.maplist()
Matt Harbison <matt_harbison@yahoo.com>
parents: 50150
diff changeset
   137
    @overload
0ab92dabea6e typing: add type hints to pycompat.maplist()
Matt Harbison <matt_harbison@yahoo.com>
parents: 50150
diff changeset
   138
    def maplist(f: Callable[[_T0], _S], arg: Iterable[_T0]) -> List[_S]:
0ab92dabea6e typing: add type hints to pycompat.maplist()
Matt Harbison <matt_harbison@yahoo.com>
parents: 50150
diff changeset
   139
        ...
0ab92dabea6e typing: add type hints to pycompat.maplist()
Matt Harbison <matt_harbison@yahoo.com>
parents: 50150
diff changeset
   140
0ab92dabea6e typing: add type hints to pycompat.maplist()
Matt Harbison <matt_harbison@yahoo.com>
parents: 50150
diff changeset
   141
    @overload
0ab92dabea6e typing: add type hints to pycompat.maplist()
Matt Harbison <matt_harbison@yahoo.com>
parents: 50150
diff changeset
   142
    def maplist(
0ab92dabea6e typing: add type hints to pycompat.maplist()
Matt Harbison <matt_harbison@yahoo.com>
parents: 50150
diff changeset
   143
        f: Callable[[_T0, _T1], _S], arg1: Iterable[_T0], arg2: Iterable[_T1]
0ab92dabea6e typing: add type hints to pycompat.maplist()
Matt Harbison <matt_harbison@yahoo.com>
parents: 50150
diff changeset
   144
    ) -> List[_S]:
0ab92dabea6e typing: add type hints to pycompat.maplist()
Matt Harbison <matt_harbison@yahoo.com>
parents: 50150
diff changeset
   145
        ...
0ab92dabea6e typing: add type hints to pycompat.maplist()
Matt Harbison <matt_harbison@yahoo.com>
parents: 50150
diff changeset
   146
0ab92dabea6e typing: add type hints to pycompat.maplist()
Matt Harbison <matt_harbison@yahoo.com>
parents: 50150
diff changeset
   147
0ab92dabea6e typing: add type hints to pycompat.maplist()
Matt Harbison <matt_harbison@yahoo.com>
parents: 50150
diff changeset
   148
def maplist(f, *args):
0ab92dabea6e typing: add type hints to pycompat.maplist()
Matt Harbison <matt_harbison@yahoo.com>
parents: 50150
diff changeset
   149
    return list(map(f, *args))
36940
dbae581010ea pycompat: name maplist() and ziplist() for better traceback message
Yuya Nishihara <yuya@tcha.org>
parents: 36677
diff changeset
   150
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   151
50219
829aa604d71a typing: add the return type hint to pycompat.rangelist()
Matt Harbison <matt_harbison@yahoo.com>
parents: 50218
diff changeset
   152
def rangelist(*args) -> List[int]:
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   153
    return list(range(*args))
37067
434e520adb8c annotate: do not construct attr.s object per line while computing history
Yuya Nishihara <yuya@tcha.org>
parents: 36964
diff changeset
   154
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   155
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   156
def ziplist(*args):
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   157
    return list(zip(*args))
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   158
36940
dbae581010ea pycompat: name maplist() and ziplist() for better traceback message
Yuya Nishihara <yuya@tcha.org>
parents: 36677
diff changeset
   159
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   160
rawinput = input
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   161
getargspec = inspect.getfullargspec
30344
19d8e19fde5b py3: document why os.fsencode() can be used to get back bytes argv
Yuya Nishihara <yuya@tcha.org>
parents: 30340
diff changeset
   162
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   163
long = int
39473
8d858fbf2759 cbor: teach the encoder to handle python `long` type for Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39329
diff changeset
   164
49897
f3f33980f19b pycompat: explicitly prefix builtin attr usage with `builtins.`
Matt Harbison <matt_harbison@yahoo.com>
parents: 49896
diff changeset
   165
if builtins.getattr(sys, 'argv', None) is not None:
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   166
    # On POSIX, the char** argv array is converted to Python str using
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   167
    # Py_DecodeLocale(). The inverse of this is Py_EncodeLocale(), which
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   168
    # isn't directly callable from Python code. In practice, os.fsencode()
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   169
    # can be used instead (this is recommended by Python's documentation
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   170
    # for sys.argv).
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   171
    #
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   172
    # On Windows, the wchar_t **argv is passed into the interpreter as-is.
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   173
    # Like POSIX, we need to emulate what Py_EncodeLocale() would do. But
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   174
    # there's an additional wrinkle. What we really want to access is the
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   175
    # ANSI codepage representation of the arguments, as this is what
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   176
    # `int main()` would receive if Python 3 didn't define `int wmain()`
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   177
    # (this is how Python 2 worked). To get that, we encode with the mbcs
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   178
    # encoding, which will pass CP_ACP to the underlying Windows API to
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   179
    # produce bytes.
49896
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
   180
    sysargv: List[bytes] = []
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   181
    if os.name == r'nt':
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   182
        sysargv = [a.encode("mbcs", "ignore") for a in sys.argv]
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   183
    else:
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   184
        sysargv = [fsencode(a) for a in sys.argv]
29808
965c91bad9e3 py3: move xrange alias next to import lines
Yuya Nishihara <yuya@tcha.org>
parents: 29790
diff changeset
   185
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   186
bytechr = struct.Struct('>B').pack
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   187
byterepr = b'%r'.__mod__
31448
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31434
diff changeset
   188
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31434
diff changeset
   189
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   190
class bytestr(bytes):
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   191
    """A bytes which mostly acts as a Python 2 str
32488
548478efc46c pycompat: try __bytes__() to convert object to bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 32232
diff changeset
   192
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   193
    >>> bytestr(), bytestr(bytearray(b'foo')), bytestr(u'ascii'), bytestr(1)
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   194
    ('', 'foo', 'ascii', '1')
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   195
    >>> s = bytestr(b'foo')
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   196
    >>> assert s is bytestr(s)
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   197
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   198
    __bytes__() should be called if provided:
32488
548478efc46c pycompat: try __bytes__() to convert object to bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 32232
diff changeset
   199
49037
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48966
diff changeset
   200
    >>> class bytesable:
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   201
    ...     def __bytes__(self):
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   202
    ...         return b'bytes'
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   203
    >>> bytestr(bytesable())
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   204
    'bytes'
31448
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31434
diff changeset
   205
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   206
    There's no implicit conversion from non-ascii str as its encoding is
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   207
    unknown:
31448
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31434
diff changeset
   208
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   209
    >>> bytestr(chr(0x80)) # doctest: +ELLIPSIS
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   210
    Traceback (most recent call last):
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   211
      ...
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   212
    UnicodeEncodeError: ...
31448
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31434
diff changeset
   213
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   214
    Comparison between bytestr and bytes should work:
31448
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31434
diff changeset
   215
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   216
    >>> assert bytestr(b'foo') == b'foo'
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   217
    >>> assert b'foo' == bytestr(b'foo')
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   218
    >>> assert b'f' in bytestr(b'foo')
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   219
    >>> assert bytestr(b'f') in b'foo'
31448
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31434
diff changeset
   220
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   221
    Sliced elements should be bytes, not integer:
31448
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31434
diff changeset
   222
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   223
    >>> s[1], s[:2]
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   224
    (b'o', b'fo')
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   225
    >>> list(s), list(reversed(s))
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   226
    ([b'f', b'o', b'o'], [b'o', b'o', b'f'])
31448
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31434
diff changeset
   227
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   228
    As bytestr type isn't propagated across operations, you need to cast
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   229
    bytes to bytestr explicitly:
31448
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31434
diff changeset
   230
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   231
    >>> s = bytestr(b'foo').upper()
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   232
    >>> t = bytestr(s)
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   233
    >>> s[0], t[0]
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   234
    (70, b'F')
48029
1fda8c9358ce typing: add a fake `__init__()` to bytestr to distract pytype
Matt Harbison <matt_harbison@yahoo.com>
parents: 47852
diff changeset
   235
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   236
    Be careful to not pass a bytestr object to a function which expects
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   237
    bytearray-like behavior.
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   238
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   239
    >>> t = bytes(t)  # cast to bytes
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   240
    >>> assert type(t) is bytes
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   241
    """
48029
1fda8c9358ce typing: add a fake `__init__()` to bytestr to distract pytype
Matt Harbison <matt_harbison@yahoo.com>
parents: 47852
diff changeset
   242
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   243
    # Trick pytype into not demanding Iterable[int] be passed to __new__(),
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   244
    # since the appropriate bytes format is done internally.
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   245
    #
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   246
    # https://github.com/google/pytype/issues/500
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   247
    if TYPE_CHECKING:
31448
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31434
diff changeset
   248
49898
55d45d0de4e7 typing: add type hints to pycompat.bytestr
Matt Harbison <matt_harbison@yahoo.com>
parents: 49897
diff changeset
   249
        def __init__(self, s: object = b'') -> None:
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   250
            pass
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   251
49898
55d45d0de4e7 typing: add type hints to pycompat.bytestr
Matt Harbison <matt_harbison@yahoo.com>
parents: 49897
diff changeset
   252
    def __new__(cls: Type[_Tbytestr], s: object = b'') -> _Tbytestr:
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   253
        if isinstance(s, bytestr):
31448
b70407bd84d5 pycompat: add bytestr wrapper which mostly acts as a Python 2 str
Yuya Nishihara <yuya@tcha.org>
parents: 31434
diff changeset
   254
            return s
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   255
        if not isinstance(
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   256
            s, (bytes, bytearray)
49897
f3f33980f19b pycompat: explicitly prefix builtin attr usage with `builtins.`
Matt Harbison <matt_harbison@yahoo.com>
parents: 49896
diff changeset
   257
        ) and not builtins.hasattr(  # hasattr-py3-only
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   258
            s, u'__bytes__'
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   259
        ):
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   260
            s = str(s).encode('ascii')
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   261
        return bytes.__new__(cls, s)
35943
1a31111e6239 py3: always drop b'' prefix from repr() of bytestr
Yuya Nishihara <yuya@tcha.org>
parents: 35412
diff changeset
   262
50150
b900f40c343e typing: disable `signature-mismatch` warnings on a few bytestr functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49902
diff changeset
   263
    # The base class uses `int` return in py3, but the point of this class is to
b900f40c343e typing: disable `signature-mismatch` warnings on a few bytestr functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49902
diff changeset
   264
    # behave like py2.
b900f40c343e typing: disable `signature-mismatch` warnings on a few bytestr functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49902
diff changeset
   265
    def __getitem__(self, key) -> bytes:  # pytype: disable=signature-mismatch
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   266
        s = bytes.__getitem__(self, key)
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   267
        if not isinstance(s, bytes):
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   268
            s = bytechr(s)
35944
fc44c2657dc5 py3: drop b'' from repr() of smartset
Yuya Nishihara <yuya@tcha.org>
parents: 35943
diff changeset
   269
        return s
fc44c2657dc5 py3: drop b'' from repr() of smartset
Yuya Nishihara <yuya@tcha.org>
parents: 35943
diff changeset
   270
50150
b900f40c343e typing: disable `signature-mismatch` warnings on a few bytestr functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49902
diff changeset
   271
    # The base class expects `Iterator[int]` return in py3, but the point of
b900f40c343e typing: disable `signature-mismatch` warnings on a few bytestr functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49902
diff changeset
   272
    # this class is to behave like py2.
b900f40c343e typing: disable `signature-mismatch` warnings on a few bytestr functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49902
diff changeset
   273
    def __iter__(self) -> Iterator[bytes]:  # pytype: disable=signature-mismatch
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   274
        return iterbytestr(bytes.__iter__(self))
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   275
49898
55d45d0de4e7 typing: add type hints to pycompat.bytestr
Matt Harbison <matt_harbison@yahoo.com>
parents: 49897
diff changeset
   276
    def __repr__(self) -> str:
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   277
        return bytes.__repr__(self)[1:]  # drop b''
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   278
31820
45761ef1bc93 py3: have registrar process docstrings in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31778
diff changeset
   279
49898
55d45d0de4e7 typing: add type hints to pycompat.bytestr
Matt Harbison <matt_harbison@yahoo.com>
parents: 49897
diff changeset
   280
def iterbytestr(s: Iterable[int]) -> Iterator[bytes]:
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   281
    """Iterate bytes as if it were a str object of Python 2"""
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   282
    return map(bytechr, s)
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   283
31820
45761ef1bc93 py3: have registrar process docstrings in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31778
diff changeset
   284
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   285
if TYPE_CHECKING:
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   286
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   287
    @overload
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   288
    def maybebytestr(s: bytes) -> bytestr:
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   289
        ...
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   290
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   291
    @overload
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   292
    def maybebytestr(s: _T0) -> _T0:
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   293
        ...
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   294
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   295
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   296
def maybebytestr(s):
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   297
    """Promote bytes to bytestr"""
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   298
    if isinstance(s, bytes):
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   299
        return bytestr(s)
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   300
    return s
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   301
30032
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30031
diff changeset
   302
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   303
def sysbytes(s: AnyStr) -> bytes:
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   304
    """Convert an internal str (e.g. keyword, __doc__) back to bytes
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   305
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   306
    This never raises UnicodeEncodeError, but only ASCII characters
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   307
    can be round-trip by sysstr(sysbytes(s)).
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   308
    """
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   309
    if isinstance(s, bytes):
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   310
        return s
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   311
    return s.encode('utf-8')
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   312
30032
2219f4f82ede pycompat: extract function that converts attribute or encoding name to str
Yuya Nishihara <yuya@tcha.org>
parents: 30031
diff changeset
   313
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   314
def sysstr(s: AnyStr) -> str:
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   315
    """Return a keyword str to be passed to Python functions such as
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   316
    getattr() and str.encode()
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   317
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   318
    This never raises UnicodeDecodeError. Non-ascii characters are
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   319
    considered invalid and mapped to arbitrary but unique code points
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   320
    such that 'sysstr(a) != sysstr(b)' for all 'a != b'.
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   321
    """
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   322
    if isinstance(s, builtins.str):
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   323
        return s
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   324
    return s.decode('latin-1')
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   325
32877
a05f3675c46a py3: add a new strurl() which will convert a bytes url to str
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32638
diff changeset
   326
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   327
def strurl(url: AnyStr) -> str:
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   328
    """Converts a bytes url back to str"""
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   329
    if isinstance(url, bytes):
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   330
        return url.decode('ascii')
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   331
    return url
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   332
32878
f22f39d56bb5 py3: add a new bytesurl() to convert a str url into bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32877
diff changeset
   333
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   334
def bytesurl(url: AnyStr) -> bytes:
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   335
    """Converts a str url to bytes by encoding in ascii"""
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   336
    if isinstance(url, str):
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   337
        return url.encode('ascii')
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   338
    return url
32232
76f9a0009b4b pycompat: extract helper to raise exception with traceback
Yuya Nishihara <yuya@tcha.org>
parents: 31942
diff changeset
   339
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   340
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   341
def raisewithtb(exc: BaseException, tb) -> NoReturn:
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   342
    """Raise exception with the given traceback"""
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   343
    raise exc.with_traceback(tb)
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   344
32638
c9318beb7c1a py3: convert __doc__ back to bytes in help.py
Yuya Nishihara <yuya@tcha.org>
parents: 32488
diff changeset
   345
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   346
def getdoc(obj: object) -> Optional[bytes]:
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   347
    """Get docstring as bytes; may be None so gettext() won't confuse it
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   348
    with _('')"""
49897
f3f33980f19b pycompat: explicitly prefix builtin attr usage with `builtins.`
Matt Harbison <matt_harbison@yahoo.com>
parents: 49896
diff changeset
   349
    doc = builtins.getattr(obj, '__doc__', None)
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   350
    if doc is None:
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   351
        return doc
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   352
    return sysbytes(doc)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
   353
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   354
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   355
def _wrapattrfunc(f):
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   356
    @functools.wraps(f)
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   357
    def w(object, name, *args):
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   358
        return f(object, sysstr(name), *args)
29810
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29809
diff changeset
   359
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   360
    return w
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   361
29810
45fa8de47a0f py3: provide (del|get|has|set)attr wrappers that accepts bytes
Yuya Nishihara <yuya@tcha.org>
parents: 29809
diff changeset
   362
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   363
# these wrappers are automagically imported by hgloader
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   364
delattr = _wrapattrfunc(builtins.delattr)
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   365
getattr = _wrapattrfunc(builtins.getattr)
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   366
hasattr = _wrapattrfunc(builtins.hasattr)
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   367
setattr = _wrapattrfunc(builtins.setattr)
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   368
xrange = builtins.range
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   369
unicode = str
31159
76a64c1e5439 py3: add pycompat.open and replace open() calls
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30820
diff changeset
   370
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   371
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   372
def open(
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   373
    name,
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   374
    mode: AnyStr = b'r',
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   375
    buffering: int = -1,
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   376
    encoding: Optional[str] = None,
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   377
) -> Any:
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   378
    # TODO: assert binary mode, and cast result to BinaryIO?
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   379
    return builtins.open(name, sysstr(mode), buffering, encoding)
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   380
37102
6ca5f825a0ca util: make safehasattr() a pycompat function
Yuya Nishihara <yuya@tcha.org>
parents: 37067
diff changeset
   381
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   382
safehasattr = _wrapattrfunc(builtins.hasattr)
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   383
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   384
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   385
def _getoptbwrapper(
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   386
    orig, args: Sequence[bytes], shortlist: bytes, namelist: Sequence[bytes]
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   387
) -> _GetOptResult:
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   388
    """
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   389
    Takes bytes arguments, converts them to unicode, pass them to
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   390
    getopt.getopt(), convert the returned values back to bytes and then
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   391
    return them for Python 3 compatibility as getopt.getopt() don't accepts
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   392
    bytes on Python 3.
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   393
    """
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   394
    args = [a.decode('latin-1') for a in args]
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   395
    shortlist = shortlist.decode('latin-1')
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   396
    namelist = [a.decode('latin-1') for a in namelist]
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   397
    opts, args = orig(args, shortlist, namelist)
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   398
    opts = [(a[0].encode('latin-1'), a[1].encode('latin-1')) for a in opts]
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   399
    args = [a.encode('latin-1') for a in args]
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   400
    return opts, args
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   401
30583
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30509
diff changeset
   402
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   403
def strkwargs(dic: Mapping[bytes, _T0]) -> Dict[str, _T0]:
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   404
    """
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   405
    Converts the keys of a python dictonary to str i.e. unicodes so that
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   406
    they can be passed as keyword arguments as dictionaries with bytes keys
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   407
    can't be passed as keyword arguments to functions on Python 3.
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   408
    """
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   409
    dic = {k.decode('latin-1'): v for k, v in dic.items()}
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   410
    return dic
30584
fbc3f73dc802 py3: utility functions to convert keys of kwargs to bytes/unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30583
diff changeset
   411
fbc3f73dc802 py3: utility functions to convert keys of kwargs to bytes/unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30583
diff changeset
   412
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   413
def byteskwargs(dic: Mapping[str, _T0]) -> Dict[bytes, _T0]:
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   414
    """
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   415
    Converts keys of python dictionaries to bytes as they were converted to
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   416
    str to pass that dictonary as a keyword argument on Python 3.
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   417
    """
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   418
    dic = {k.encode('latin-1'): v for k, v in dic.items()}
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   419
    return dic
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   420
30681
caf7e1c5efe4 py3: have a bytes version of shlex.split()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30671
diff changeset
   421
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   422
# TODO: handle shlex.shlex().
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   423
def shlexsplit(
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   424
    s: bytes, comments: bool = False, posix: bool = True
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   425
) -> List[bytes]:
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   426
    """
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   427
    Takes bytes argument, convert it to str i.e. unicodes, pass that into
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   428
    shlex.split(), convert the returned value to bytes and return that for
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   429
    Python 3 compatibility as shelx.split() don't accept bytes on Python 3.
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   430
    """
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   431
    ret = shlex.split(s.decode('latin-1'), comments, posix)
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   432
    return [a.encode('latin-1') for a in ret]
43021
2cc453284d5c patchbomb: protect email addresses from shell
Floris Bruynooghe <flub@google.com>
parents: 40577
diff changeset
   433
43380
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43117
diff changeset
   434
48962
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   435
iteritems = lambda x: x.items()
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   436
itervalues = lambda x: x.values()
79009cca491e pycompat: remove large Python 2 block
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48960
diff changeset
   437
49051
c3a48dd506da pycompat: remove json.loads polyfill for Python 3.5
Gregory Szorc <gregory.szorc@gmail.com>
parents: 49050
diff changeset
   438
json_loads = json.loads
34639
a568a46751b6 selectors2: do not use platform.system()
Jun Wu <quark@fb.com>
parents: 34468
diff changeset
   439
49896
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
   440
isjython: bool = sysplatform.startswith(b'java')
34644
c0a6c19690ff pycompat: define operating system constants
Jun Wu <quark@fb.com>
parents: 34639
diff changeset
   441
49896
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
   442
isdarwin: bool = sysplatform.startswith(b'darwin')
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
   443
islinux: bool = sysplatform.startswith(b'linux')
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
   444
isposix: bool = osname == b'posix'
9cd327509cd4 typing: add type hints to global variables in mercurial/pycompat.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 49069
diff changeset
   445
iswindows: bool = osname == b'nt'
35235
5b569d512fbd fancyopts: use getopt.gnu_getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 34644
diff changeset
   446
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
   447
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   448
def getoptb(
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   449
    args: Sequence[bytes], shortlist: bytes, namelist: Sequence[bytes]
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   450
) -> _GetOptResult:
35235
5b569d512fbd fancyopts: use getopt.gnu_getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 34644
diff changeset
   451
    return _getoptbwrapper(getopt.getopt, args, shortlist, namelist)
5b569d512fbd fancyopts: use getopt.gnu_getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 34644
diff changeset
   452
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
   453
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   454
def gnugetoptb(
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   455
    args: Sequence[bytes], shortlist: bytes, namelist: Sequence[bytes]
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   456
) -> _GetOptResult:
35235
5b569d512fbd fancyopts: use getopt.gnu_getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 34644
diff changeset
   457
    return _getoptbwrapper(getopt.gnu_getopt, args, shortlist, namelist)
38197
aac4be30e250 py3: wrap tempfile.mkstemp() to use bytes path
Yuya Nishihara <yuya@tcha.org>
parents: 37890
diff changeset
   458
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
   459
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   460
def mkdtemp(
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   461
    suffix: bytes = b'', prefix: bytes = b'tmp', dir: Optional[bytes] = None
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   462
) -> bytes:
38198
2ce60954b1b7 py3: wrap tempfile.mkdtemp() to use bytes path
Yuya Nishihara <yuya@tcha.org>
parents: 38197
diff changeset
   463
    return tempfile.mkdtemp(suffix, prefix, dir)
2ce60954b1b7 py3: wrap tempfile.mkdtemp() to use bytes path
Yuya Nishihara <yuya@tcha.org>
parents: 38197
diff changeset
   464
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
   465
38197
aac4be30e250 py3: wrap tempfile.mkstemp() to use bytes path
Yuya Nishihara <yuya@tcha.org>
parents: 37890
diff changeset
   466
# text=True is not supported; use util.from/tonativeeol() instead
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   467
def mkstemp(
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   468
    suffix: bytes = b'', prefix: bytes = b'tmp', dir: Optional[bytes] = None
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   469
) -> Tuple[int, bytes]:
38197
aac4be30e250 py3: wrap tempfile.mkstemp() to use bytes path
Yuya Nishihara <yuya@tcha.org>
parents: 37890
diff changeset
   470
    return tempfile.mkstemp(suffix, prefix, dir)
38199
cc9aa88792fe py3: wrap tempfile.NamedTemporaryFile() to return bytes fp.name
Yuya Nishihara <yuya@tcha.org>
parents: 38198
diff changeset
   471
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
   472
45727
d4c4391aa7f2 pycompat: add an entry for unnamedtmpfile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45726
diff changeset
   473
# TemporaryFile does not support an "encoding=" argument on python2.
d4c4391aa7f2 pycompat: add an entry for unnamedtmpfile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45726
diff changeset
   474
# This wrapper file are always open in byte mode.
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   475
def unnamedtempfile(mode: Optional[bytes] = None, *args, **kwargs) -> BinaryIO:
45727
d4c4391aa7f2 pycompat: add an entry for unnamedtmpfile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45726
diff changeset
   476
    if mode is None:
46380
7a29d9002250 pycompat: fix a bytes vs str issue in `unnamedtempfile()`
Matt Harbison <matt_harbison@yahoo.com>
parents: 46178
diff changeset
   477
        mode = 'w+b'
45727
d4c4391aa7f2 pycompat: add an entry for unnamedtmpfile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45726
diff changeset
   478
    else:
d4c4391aa7f2 pycompat: add an entry for unnamedtmpfile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45726
diff changeset
   479
        mode = sysstr(mode)
d4c4391aa7f2 pycompat: add an entry for unnamedtmpfile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45726
diff changeset
   480
    assert 'b' in mode
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   481
    return cast(BinaryIO, tempfile.TemporaryFile(mode, *args, **kwargs))
45727
d4c4391aa7f2 pycompat: add an entry for unnamedtmpfile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45726
diff changeset
   482
d4c4391aa7f2 pycompat: add an entry for unnamedtmpfile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45726
diff changeset
   483
45726
d1072cba8aff pycompat: update comment about unnamedtempfile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45057
diff changeset
   484
# NamedTemporaryFile does not support an "encoding=" argument on python2.
d1072cba8aff pycompat: update comment about unnamedtempfile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45057
diff changeset
   485
# This wrapper file are always open in byte mode.
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
   486
def namedtempfile(
49902
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   487
    mode: bytes = b'w+b',
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   488
    bufsize: int = -1,
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   489
    suffix: bytes = b'',
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   490
    prefix: bytes = b'tmp',
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   491
    dir: Optional[bytes] = None,
c5a06cc37401 typing: add type hints to most mercurial/pycompat.py functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 49898
diff changeset
   492
    delete: bool = True,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
   493
):
38199
cc9aa88792fe py3: wrap tempfile.NamedTemporaryFile() to return bytes fp.name
Yuya Nishihara <yuya@tcha.org>
parents: 38198
diff changeset
   494
    mode = sysstr(mode)
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   495
    assert 'b' in mode
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
   496
    return tempfile.NamedTemporaryFile(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
   497
        mode, bufsize, suffix=suffix, prefix=prefix, dir=dir, delete=delete
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43021
diff changeset
   498
    )