mercurial/fancyopts.py
author Gregory Szorc <gregory.szorc@gmail.com>
Mon, 20 Jan 2020 23:51:25 -0800
changeset 44118 f81c17ec303c
parent 43474 70d42e2ad9b4
child 44452 9d2b2df2c2ba
permissions -rw-r--r--
hgdemandimport: apply lazy module loading to sys.meta_path finders Python's `sys.meta_path` finders are the primary objects whose job it is to find a module at import time. When `import` is called, Python iterates objects in this list and calls `o.find_spec(...)` to find a `ModuleSpec` (or None if the module couldn't be found by that finder). If no meta path finder can find a module, import fails. One of the default meta path finders is `PathFinder`. Its job is to import modules from the filesystem and is probably the most important importer. This finder looks at `sys.path` and `sys.path_hooks` to do its job. The `ModuleSpec` returned by `MetaPathImporter.find_spec()` has a `loader` attribute, which defines the concrete module loader to use. `sys.path_hooks` is a hook point for teaching `PathFinder` to instantiate custom loader types. Previously, we injected a custom `sys.path_hook` that told `PathFinder` to wrap the default loaders with a loader that creates a module object that is lazy. This approach worked. But its main limitation was that it only applied to the `PathFinder` meta path importer. There are other meta path importers that are registered. And in the case of PyOxidizer loading modules from memory, `PathFinder` doesn't come into play since PyOxidizer's own meta path importer was handling all imports. This commit changes our approach to lazy module loading by proxying all meta path importers. Specifically, we overload the `find_spec()` method to swap in a wrapped loader on the `ModuleSpec` before it is returned. The end result of this is all meta path importers should be lazy. As much as I would have loved to utilize .__class__ manipulation to achieve this, some meta path importers are implemented in C/Rust in such a way that they cannot be monkeypatched. This is why we use __getattribute__ to define a proxy. Also, this change could theoretically open us up to regressions in meta path importers whose loader is creating module objects which can't be monkeypatched. But I'm not aware of any of these in the wild. So I think we'll be safe. According to hyperfine, this change yields a decent startup time win of 5-6ms: ``` Benchmark #1: ~/.pyenv/versions/3.6.10/bin/python ./hg version Time (mean ± σ): 86.8 ms ± 0.5 ms [User: 78.0 ms, System: 8.7 ms] Range (min … max): 86.0 ms … 89.1 ms 50 runs Time (mean ± σ): 81.1 ms ± 2.7 ms [User: 74.5 ms, System: 6.5 ms] Range (min … max): 77.8 ms … 90.5 ms 50 runs Benchmark #2: ~/.pyenv/versions/3.7.6/bin/python ./hg version Time (mean ± σ): 78.9 ms ± 0.6 ms [User: 70.2 ms, System: 8.7 ms] Range (min … max): 78.1 ms … 81.2 ms 50 runs Time (mean ± σ): 73.4 ms ± 0.6 ms [User: 65.3 ms, System: 8.0 ms] Range (min … max): 72.4 ms … 75.7 ms 50 runs Benchmark #3: ~/.pyenv/versions/3.8.1/bin/python ./hg version Time (mean ± σ): 78.1 ms ± 0.6 ms [User: 70.2 ms, System: 7.9 ms] Range (min … max): 77.4 ms … 80.9 ms 50 runs Time (mean ± σ): 72.1 ms ± 0.4 ms [User: 64.4 ms, System: 7.6 ms] Range (min … max): 71.4 ms … 74.1 ms 50 runs ``` Differential Revision: https://phab.mercurial-scm.org/D7954
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8230
ec98f35e3e16 fancyopts: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 7772
diff changeset
     1
# fancyopts.py - better command line parsing
ec98f35e3e16 fancyopts: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 7772
diff changeset
     2
#
ec98f35e3e16 fancyopts: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 7772
diff changeset
     3
#  Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
ec98f35e3e16 fancyopts: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 7772
diff changeset
     4
#
ec98f35e3e16 fancyopts: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 7772
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 8366
diff changeset
     6
# GNU General Public License version 2 or any later version.
8230
ec98f35e3e16 fancyopts: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 7772
diff changeset
     7
25947
6002e2d95e54 fancyopts: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25563
diff changeset
     8
from __future__ import absolute_import
6002e2d95e54 fancyopts: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25563
diff changeset
     9
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
    10
import abc
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    11
import functools
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    12
25947
6002e2d95e54 fancyopts: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25563
diff changeset
    13
from .i18n import _
30578
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29947
diff changeset
    14
from . import (
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29947
diff changeset
    15
    error,
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29947
diff changeset
    16
    pycompat,
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29947
diff changeset
    17
)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    18
29947
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
    19
# Set of flags to not apply boolean negation logic on
32291
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 30578
diff changeset
    20
nevernegate = {
29947
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
    21
    # avoid --no-noninteractive
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    22
    b'noninteractive',
29947
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
    23
    # These two flags are special because they cause hg to do one
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
    24
    # thing and then exit, and so aren't suitable for use in things
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
    25
    # like aliases anyway.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    26
    b'help',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    27
    b'version',
32291
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 30578
diff changeset
    28
}
29947
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
    29
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
    30
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    31
def _earlyoptarg(arg, shortlist, namelist):
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    32
    """Check if the given arg is a valid unabbreviated option
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    33
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    34
    Returns (flag_str, has_embedded_value?, embedded_value, takes_value?)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    35
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    36
    >>> def opt(arg):
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    37
    ...     return _earlyoptarg(arg, b'R:q', [b'cwd=', b'debugger'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    38
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    39
    long form:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    40
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    41
    >>> opt(b'--cwd')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    42
    ('--cwd', False, '', True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    43
    >>> opt(b'--cwd=')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    44
    ('--cwd', True, '', True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    45
    >>> opt(b'--cwd=foo')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    46
    ('--cwd', True, 'foo', True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    47
    >>> opt(b'--debugger')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    48
    ('--debugger', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    49
    >>> opt(b'--debugger=')  # invalid but parsable
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    50
    ('--debugger', True, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    51
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    52
    short form:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    53
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    54
    >>> opt(b'-R')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    55
    ('-R', False, '', True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    56
    >>> opt(b'-Rfoo')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    57
    ('-R', True, 'foo', True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    58
    >>> opt(b'-q')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    59
    ('-q', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    60
    >>> opt(b'-qfoo')  # invalid but parsable
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    61
    ('-q', True, 'foo', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    62
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    63
    unknown or invalid:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    64
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    65
    >>> opt(b'--unknown')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    66
    ('', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    67
    >>> opt(b'-u')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    68
    ('', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    69
    >>> opt(b'-ufoo')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    70
    ('', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    71
    >>> opt(b'--')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    72
    ('', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    73
    >>> opt(b'-')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    74
    ('', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    75
    >>> opt(b'-:')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    76
    ('', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    77
    >>> opt(b'-:foo')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    78
    ('', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    79
    """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    80
    if arg.startswith(b'--'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    81
        flag, eq, val = arg.partition(b'=')
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    82
        if flag[2:] in namelist:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    83
            return flag, bool(eq), val, False
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    84
        if flag[2:] + b'=' in namelist:
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    85
            return flag, bool(eq), val, True
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    86
    elif arg.startswith(b'-') and arg != b'-' and not arg.startswith(b'-:'):
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    87
        flag, val = arg[:2], arg[2:]
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    88
        i = shortlist.find(flag[1:])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    89
        if i >= 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    90
            return flag, bool(val), val, shortlist.startswith(b':', i + 1)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    91
    return b'', False, b'', False
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    92
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
    93
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    94
def earlygetopt(args, shortlist, namelist, gnu=False, keepsep=False):
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    95
    """Parse options like getopt, but ignores unknown options and abbreviated
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    96
    forms
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    97
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    98
    If gnu=False, this stops processing options as soon as a non/unknown-option
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    99
    argument is encountered. Otherwise, option and non-option arguments may be
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   100
    intermixed, and unknown-option arguments are taken as non-option.
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   101
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   102
    If keepsep=True, '--' won't be removed from the list of arguments left.
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   103
    This is useful for stripping early options from a full command arguments.
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   104
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   105
    >>> def get(args, gnu=False, keepsep=False):
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   106
    ...     return earlygetopt(args, b'R:q', [b'cwd=', b'debugger'],
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   107
    ...                        gnu=gnu, keepsep=keepsep)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   108
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   109
    default parsing rules for early options:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   110
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   111
    >>> get([b'x', b'--cwd', b'foo', b'-Rbar', b'-q', b'y'], gnu=True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   112
    ([('--cwd', 'foo'), ('-R', 'bar'), ('-q', '')], ['x', 'y'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   113
    >>> get([b'x', b'--cwd=foo', b'y', b'-R', b'bar', b'--debugger'], gnu=True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   114
    ([('--cwd', 'foo'), ('-R', 'bar'), ('--debugger', '')], ['x', 'y'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   115
    >>> get([b'--unknown', b'--cwd=foo', b'--', '--debugger'], gnu=True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   116
    ([('--cwd', 'foo')], ['--unknown', '--debugger'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   117
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   118
    restricted parsing rules (early options must come first):
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   119
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   120
    >>> get([b'--cwd', b'foo', b'-Rbar', b'x', b'-q', b'y'], gnu=False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   121
    ([('--cwd', 'foo'), ('-R', 'bar')], ['x', '-q', 'y'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   122
    >>> get([b'--cwd=foo', b'x', b'y', b'-R', b'bar', b'--debugger'], gnu=False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   123
    ([('--cwd', 'foo')], ['x', 'y', '-R', 'bar', '--debugger'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   124
    >>> get([b'--unknown', b'--cwd=foo', b'--', '--debugger'], gnu=False)
35227
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   125
    ([], ['--unknown', '--cwd=foo', '--', '--debugger'])
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   126
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   127
    stripping early options (without loosing '--'):
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   128
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   129
    >>> get([b'x', b'-Rbar', b'--', '--debugger'], gnu=True, keepsep=True)[1]
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   130
    ['x', '--', '--debugger']
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   131
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   132
    last argument:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   133
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   134
    >>> get([b'--cwd'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   135
    ([], ['--cwd'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   136
    >>> get([b'--cwd=foo'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   137
    ([('--cwd', 'foo')], [])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   138
    >>> get([b'-R'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   139
    ([], ['-R'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   140
    >>> get([b'-Rbar'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   141
    ([('-R', 'bar')], [])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   142
    >>> get([b'-q'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   143
    ([('-q', '')], [])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   144
    >>> get([b'-q', b'--'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   145
    ([('-q', '')], [])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   146
35227
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   147
    '--' may be a value:
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   148
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   149
    >>> get([b'-R', b'--', b'x'])
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   150
    ([('-R', '--')], ['x'])
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   151
    >>> get([b'--cwd', b'--', b'x'])
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   152
    ([('--cwd', '--')], ['x'])
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   153
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   154
    value passed to bool options:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   155
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   156
    >>> get([b'--debugger=foo', b'x'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   157
    ([], ['--debugger=foo', 'x'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   158
    >>> get([b'-qfoo', b'x'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   159
    ([], ['-qfoo', 'x'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   160
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   161
    short option isn't separated with '=':
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   162
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   163
    >>> get([b'-R=bar'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   164
    ([('-R', '=bar')], [])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   165
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   166
    ':' may be in shortlist, but shouldn't be taken as an option letter:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   167
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   168
    >>> get([b'-:', b'y'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   169
    ([], ['-:', 'y'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   170
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   171
    '-' is a valid non-option argument:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   172
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   173
    >>> get([b'-', b'y'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   174
    ([], ['-', 'y'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   175
    """
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   176
    parsedopts = []
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   177
    parsedargs = []
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   178
    pos = 0
35227
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   179
    while pos < len(args):
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   180
        arg = args[pos]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   181
        if arg == b'--':
35227
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   182
            pos += not keepsep
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   183
            break
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   184
        flag, hasval, val, takeval = _earlyoptarg(arg, shortlist, namelist)
35227
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   185
        if not hasval and takeval and pos + 1 >= len(args):
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   186
            # missing last argument
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   187
            break
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   188
        if not flag or hasval and not takeval:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   189
            # non-option argument or -b/--bool=INVALID_VALUE
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   190
            if gnu:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   191
                parsedargs.append(arg)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   192
                pos += 1
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   193
            else:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   194
                break
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   195
        elif hasval == takeval:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   196
            # -b/--bool or -s/--str=VALUE
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   197
            parsedopts.append((flag, val))
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   198
            pos += 1
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   199
        else:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   200
            # -s/--str VALUE
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   201
            parsedopts.append((flag, args[pos + 1]))
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   202
            pos += 2
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   203
35227
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   204
    parsedargs.extend(args[pos:])
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   205
    return parsedopts, parsedargs
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   206
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
   207
43474
70d42e2ad9b4 pytype: don't warn us about ignored-on-py3 metaclasses
Augie Fackler <augie@google.com>
parents: 43077
diff changeset
   208
class customopt(object):  # pytype: disable=ignored-metaclass
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   209
    """Manage defaults and mutations for any type of opt."""
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   210
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   211
    __metaclass__ = abc.ABCMeta
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   212
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   213
    def __init__(self, defaultvalue):
37092
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
   214
        self._defaultvalue = defaultvalue
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   215
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   216
    def _isboolopt(self):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   217
        return False
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   218
37092
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
   219
    def getdefaultvalue(self):
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
   220
        """Returns the default value for this opt.
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
   221
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
   222
        Subclasses should override this to return a new value if the value type
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
   223
        is mutable."""
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
   224
        return self._defaultvalue
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
   225
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   226
    @abc.abstractmethod
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   227
    def newstate(self, oldstate, newparam, abort):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   228
        """Adds newparam to oldstate and returns the new state.
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   229
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   230
        On failure, abort can be called with a string error message."""
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   231
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
   232
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   233
class _simpleopt(customopt):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   234
    def _isboolopt(self):
37092
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
   235
        return isinstance(self._defaultvalue, (bool, type(None)))
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   236
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   237
    def newstate(self, oldstate, newparam, abort):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   238
        return newparam
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   239
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
   240
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   241
class _callableopt(customopt):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   242
    def __init__(self, callablefn):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   243
        self.callablefn = callablefn
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   244
        super(_callableopt, self).__init__(None)
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   245
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   246
    def newstate(self, oldstate, newparam, abort):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   247
        return self.callablefn(newparam)
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   248
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
   249
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   250
class _listopt(customopt):
37092
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
   251
    def getdefaultvalue(self):
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
   252
        return self._defaultvalue[:]
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
   253
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   254
    def newstate(self, oldstate, newparam, abort):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   255
        oldstate.append(newparam)
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   256
        return oldstate
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   257
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
   258
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   259
class _intopt(customopt):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   260
    def newstate(self, oldstate, newparam, abort):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   261
        try:
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   262
            return int(newparam)
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   263
        except ValueError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   264
            abort(_(b'expected int'))
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   265
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
   266
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   267
def _defaultopt(default):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   268
    """Returns a default opt implementation, given a default value."""
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   269
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   270
    if isinstance(default, customopt):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   271
        return default
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   272
    elif callable(default):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   273
        return _callableopt(default)
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   274
    elif isinstance(default, list):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   275
        return _listopt(default[:])
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   276
    elif type(default) is type(1):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   277
        return _intopt(default)
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   278
    else:
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   279
        return _simpleopt(default)
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   280
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
   281
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   282
def fancyopts(args, options, state, gnu=False, early=False, optaliases=None):
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   283
    """
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   284
    read args, parse options, and store options in state
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   285
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   286
    each option is a tuple of:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   287
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   288
      short option or ''
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   289
      long option
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   290
      default value
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   291
      description
11321
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10282
diff changeset
   292
      option value label(optional)
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   293
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   294
    option types include:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   295
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   296
      boolean or none - option sets variable in state to true
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   297
      string - parameter string is stored in state
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   298
      list - parameter string is added to a list
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   299
      integer - parameter strings is stored as int
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   300
      function - call function with parameter
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   301
      customopt - subclass of 'customopt'
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   302
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   303
    optaliases is a mapping from a canonical option name to a list of
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   304
    additional long options. This exists for preserving backward compatibility
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   305
    of early options. If we want to use it extensively, please consider moving
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   306
    the functionality to the options table (e.g separate long options by '|'.)
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   307
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   308
    non-option args are returned
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   309
    """
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   310
    if optaliases is None:
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   311
        optaliases = {}
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   312
    namelist = []
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   313
    shortlist = b''
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   314
    argmap = {}
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   315
    defmap = {}
29947
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
   316
    negations = {}
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
   317
    alllong = set(o[1] for o in options)
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   318
11321
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10282
diff changeset
   319
    for option in options:
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10282
diff changeset
   320
        if len(option) == 5:
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10282
diff changeset
   321
            short, name, default, comment, dummy = option
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10282
diff changeset
   322
        else:
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10282
diff changeset
   323
            short, name, default, comment = option
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   324
        # convert opts to getopt format
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   325
        onames = [name]
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   326
        onames.extend(optaliases.get(name, []))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   327
        name = name.replace(b'-', b'_')
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   328
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   329
        argmap[b'-' + short] = name
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   330
        for n in onames:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   331
            argmap[b'--' + n] = name
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   332
        defmap[name] = _defaultopt(default)
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   333
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   334
        # copy defaults to state
37092
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
   335
        state[name] = defmap[name].getdefaultvalue()
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   336
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   337
        # does it take a parameter?
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   338
        if not defmap[name]._isboolopt():
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   339
            if short:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   340
                short += b':'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   341
            onames = [n + b'=' for n in onames]
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   342
        elif name not in nevernegate:
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   343
            for n in onames:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   344
                if n.startswith(b'no-'):
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   345
                    insert = n[3:]
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   346
                else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   347
                    insert = b'no-' + n
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   348
                # backout (as a practical example) has both --commit and
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   349
                # --no-commit options, so we don't want to allow the
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   350
                # negations of those flags.
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   351
                if insert not in alllong:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   352
                    assert (b'--' + n) not in negations
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   353
                    negations[b'--' + insert] = b'--' + n
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   354
                    namelist.append(insert)
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   355
        if short:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   356
            shortlist += short
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   357
        if name:
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   358
            namelist.extend(onames)
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   359
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   360
    # parse arguments
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   361
    if early:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   362
        parse = functools.partial(earlygetopt, gnu=gnu)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   363
    elif gnu:
35226
5b569d512fbd fancyopts: use getopt.gnu_getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35223
diff changeset
   364
        parse = pycompat.gnugetoptb
7772
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
   365
    else:
30578
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29947
diff changeset
   366
        parse = pycompat.getoptb
7772
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
   367
    opts, args = parse(args, shortlist, namelist)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   368
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   369
    # transfer result to state
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   370
    for opt, val in opts:
29947
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
   371
        boolval = True
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
   372
        negation = negations.get(opt, False)
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
   373
        if negation:
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
   374
            opt = negation
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
   375
            boolval = False
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   376
        name = argmap[opt]
25563
69e8384a436c fancyopts: allow all callable as default parameter value
introom <i@introo.me>
parents: 21794
diff changeset
   377
        obj = defmap[name]
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   378
        if obj._isboolopt():
29947
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
   379
            state[name] = boolval
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   380
        else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
   381
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   382
            def abort(s):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
   383
                raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   384
                    _(b'invalid value %r for option %s, %s')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
   385
                    % (pycompat.maybebytestr(val), opt, s)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
   386
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
   387
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
   388
            state[name] = defmap[name].newstate(state[name], val, abort)
209
63af1db35611 Beginning of new command parsing interface
mpm@selenic.com
parents: 164
diff changeset
   389
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   390
    # return unparsed args
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   391
    return args