1ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# Author: Steven J. Bethard <steven.bethard@gmail.com>.
2ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
3ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot"""Command-line parsing library
4ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
5ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotThis module is an optparse-inspired command-line parsing library that:
6ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
7ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    - handles both optional and positional arguments
8ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    - produces highly informative usage messages
9ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    - supports parsers that dispatch to sub-parsers
10ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
11ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotThe following is a simple usage example that sums integers from the
12ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotcommand-line and writes the result to a file::
13ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
14ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    parser = argparse.ArgumentParser(
15ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        description='sum the integers at the command line')
16ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    parser.add_argument(
17ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        'integers', metavar='int', nargs='+', type=int,
18ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        help='an integer to be summed')
19ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    parser.add_argument(
20ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        '--log', default=sys.stdout, type=argparse.FileType('w'),
21ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        help='the file where the sum should be written')
22ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    args = parser.parse_args()
23ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    args.log.write('%s' % sum(args.integers))
24ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    args.log.close()
25ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
26ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotThe module contains the following public classes:
27ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
28ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    - ArgumentParser -- The main entry point for command-line parsing. As the
29ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        example above shows, the add_argument() method is used to populate
30ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        the parser with actions for optional and positional arguments. Then
31ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        the parse_args() method is invoked to convert the args at the
32ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        command-line into an object with attributes.
33ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
34ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    - ArgumentError -- The exception raised by ArgumentParser objects when
35ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        there are errors with the parser's actions. Errors raised while
36ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        parsing the command-line are caught by ArgumentParser and emitted
37ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        as command-line messages.
38ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
39ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    - FileType -- A factory for defining types of files to be created. As the
40ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        example above shows, instances of FileType are typically passed as
41ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        the type= argument of add_argument() calls.
42ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
43ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    - Action -- The base class for parser actions. Typically actions are
44ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        selected by passing strings like 'store_true' or 'append_const' to
45ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        the action= argument of add_argument(). However, for greater
46ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        customization of ArgumentParser actions, subclasses of Action may
47ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        be defined and passed as the action= argument.
48ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
49ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter,
50ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        ArgumentDefaultsHelpFormatter -- Formatter classes which
51ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        may be passed as the formatter_class= argument to the
52ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        ArgumentParser constructor. HelpFormatter is the default,
53ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser
54ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        not to change the formatting for help text, and
55ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        ArgumentDefaultsHelpFormatter adds information about argument defaults
56ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        to the help.
57ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
58ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotAll other classes in this module are considered implementation details.
59ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot(Also note that HelpFormatter and RawDescriptionHelpFormatter are only
60ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotconsidered public as object names -- the API of the formatter objects is
61ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotstill considered an implementation detail.)
62ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot"""
63ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
64ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot__version__ = '1.1'
65ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot__all__ = [
66ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    'ArgumentParser',
67ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    'ArgumentError',
68ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    'ArgumentTypeError',
69ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    'FileType',
70ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    'HelpFormatter',
71ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    'ArgumentDefaultsHelpFormatter',
72ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    'RawDescriptionHelpFormatter',
73ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    'RawTextHelpFormatter',
74ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    'Namespace',
75ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    'Action',
76ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    'ONE_OR_MORE',
77ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    'OPTIONAL',
78ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    'PARSER',
79ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    'REMAINDER',
80ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    'SUPPRESS',
81ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    'ZERO_OR_MORE',
82ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot]
83ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
84ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
85ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotimport collections as _collections
86ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotimport copy as _copy
87ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotimport os as _os
88ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotimport re as _re
89ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotimport sys as _sys
90ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotimport textwrap as _textwrap
91ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
92ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotfrom gettext import gettext as _
93ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
94ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
95ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotdef _callable(obj):
96ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    return hasattr(obj, '__call__') or hasattr(obj, '__bases__')
97ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
98ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
99ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotSUPPRESS = '==SUPPRESS=='
100ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
101ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotOPTIONAL = '?'
102ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotZERO_OR_MORE = '*'
103ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotONE_OR_MORE = '+'
104ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotPARSER = 'A...'
105ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotREMAINDER = '...'
106ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot_UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args'
107ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
108ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# =============================
109ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# Utility functions and classes
110ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# =============================
111ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
112ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass _AttributeHolder(object):
113ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """Abstract base class that provides __repr__.
114ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
115ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    The __repr__ method returns a string in the format::
116ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        ClassName(attr=name, attr=name, ...)
117ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    The attributes are determined either by a class-level attribute,
118ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    '_kwarg_names', or by inspecting the instance __dict__.
119ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """
120ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
121ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __repr__(self):
122ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        type_name = type(self).__name__
123ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        arg_strings = []
124ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for arg in self._get_args():
125ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            arg_strings.append(repr(arg))
126ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for name, value in self._get_kwargs():
127ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            arg_strings.append('%s=%r' % (name, value))
128ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return '%s(%s)' % (type_name, ', '.join(arg_strings))
129ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
130ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _get_kwargs(self):
131ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return sorted(self.__dict__.items())
132ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
133ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _get_args(self):
134ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return []
135ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
136ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
137ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotdef _ensure_value(namespace, name, value):
138ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    if getattr(namespace, name, None) is None:
139ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        setattr(namespace, name, value)
140ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    return getattr(namespace, name)
141ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
142ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
143ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# ===============
144ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# Formatting Help
145ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# ===============
146ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
147ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass HelpFormatter(object):
148ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """Formatter for generating usage messages and argument help strings.
149ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
150ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    Only the name of this class is considered a public API. All the methods
151ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    provided by the class are considered an implementation detail.
152ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """
153ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
154ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self,
155ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 prog,
156ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 indent_increment=2,
157ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 max_help_position=24,
158ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 width=None):
159ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
160ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # default setting for width
161ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if width is None:
162ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            try:
163ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                width = int(_os.environ['COLUMNS'])
164ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            except (KeyError, ValueError):
165ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                width = 80
166ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            width -= 2
167ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
168ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._prog = prog
169ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._indent_increment = indent_increment
170ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._max_help_position = max_help_position
171ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._width = width
172ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
173ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._current_indent = 0
174ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._level = 0
175ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._action_max_length = 0
176ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
177ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._root_section = self._Section(self, None)
178ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._current_section = self._root_section
179ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
180ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._whitespace_matcher = _re.compile(r'\s+')
181ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._long_break_matcher = _re.compile(r'\n\n\n+')
182ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
183ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # ===============================
184ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # Section and indentation methods
185ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # ===============================
186ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _indent(self):
187ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._current_indent += self._indent_increment
188ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._level += 1
189ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
190ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _dedent(self):
191ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._current_indent -= self._indent_increment
192ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        assert self._current_indent >= 0, 'Indent decreased below 0.'
193ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._level -= 1
194ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
195ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    class _Section(object):
196ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
197ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        def __init__(self, formatter, parent, heading=None):
198ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self.formatter = formatter
199ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self.parent = parent
200ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self.heading = heading
201ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self.items = []
202ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
203ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        def format_help(self):
204ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # format the indented section
205ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if self.parent is not None:
206ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                self.formatter._indent()
207ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            join = self.formatter._join_parts
208ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            for func, args in self.items:
209ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                func(*args)
210ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            item_help = join([func(*args) for func, args in self.items])
211ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if self.parent is not None:
212ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                self.formatter._dedent()
213ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
214ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # return nothing if the section was empty
215ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if not item_help:
216ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                return ''
217ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
218ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # add the heading if the section was non-empty
219ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if self.heading is not SUPPRESS and self.heading is not None:
220ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                current_indent = self.formatter._current_indent
221ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                heading = '%*s%s:\n' % (current_indent, '', self.heading)
222ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            else:
223ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                heading = ''
224ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
225ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # join the section-initial newline, the heading and the help
226ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            return join(['\n', heading, item_help, '\n'])
227ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
228ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _add_item(self, func, args):
229ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._current_section.items.append((func, args))
230ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
231ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # ========================
232ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # Message building methods
233ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # ========================
234ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def start_section(self, heading):
235ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._indent()
236ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        section = self._Section(self, self._current_section, heading)
237ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._add_item(section.format_help, [])
238ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._current_section = section
239ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
240ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def end_section(self):
241ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._current_section = self._current_section.parent
242ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._dedent()
243ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
244ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def add_text(self, text):
245ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if text is not SUPPRESS and text is not None:
246ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self._add_item(self._format_text, [text])
247ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
248ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def add_usage(self, usage, actions, groups, prefix=None):
249ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if usage is not SUPPRESS:
250ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            args = usage, actions, groups, prefix
251ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self._add_item(self._format_usage, args)
252ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
253ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def add_argument(self, action):
254ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if action.help is not SUPPRESS:
255ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
256ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # find all invocations
257ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            get_invocation = self._format_action_invocation
258ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            invocations = [get_invocation(action)]
259ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            for subaction in self._iter_indented_subactions(action):
260ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                invocations.append(get_invocation(subaction))
261ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
262ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # update the maximum item length
263ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            invocation_length = max([len(s) for s in invocations])
264ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            action_length = invocation_length + self._current_indent
265ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self._action_max_length = max(self._action_max_length,
266ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                                          action_length)
267ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
268ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # add the item to the list
269ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self._add_item(self._format_action, [action])
270ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
271ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def add_arguments(self, actions):
272ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for action in actions:
273ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self.add_argument(action)
274ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
275ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # =======================
276ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # Help-formatting methods
277ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # =======================
278ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def format_help(self):
279ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        help = self._root_section.format_help()
280ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if help:
281ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            help = self._long_break_matcher.sub('\n\n', help)
282ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            help = help.strip('\n') + '\n'
283ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return help
284ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
285ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _join_parts(self, part_strings):
286ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return ''.join([part
287ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        for part in part_strings
288ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        if part and part is not SUPPRESS])
289ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
290ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _format_usage(self, usage, actions, groups, prefix):
291ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if prefix is None:
292ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            prefix = _('usage: ')
293ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
294ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if usage is specified, use that
295ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if usage is not None:
296ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            usage = usage % dict(prog=self._prog)
297ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
298ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if no optionals or positionals are available, usage is just prog
299ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif usage is None and not actions:
300ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            usage = '%(prog)s' % dict(prog=self._prog)
301ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
302ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if optionals and positionals are available, calculate usage
303ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif usage is None:
304ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            prog = '%(prog)s' % dict(prog=self._prog)
305ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
306ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # split optionals from positionals
307ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            optionals = []
308ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            positionals = []
309ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            for action in actions:
310ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if action.option_strings:
311ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    optionals.append(action)
312ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                else:
313ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    positionals.append(action)
314ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
315ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # build full usage string
316ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            format = self._format_actions_usage
317ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            action_usage = format(optionals + positionals, groups)
318ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            usage = ' '.join([s for s in [prog, action_usage] if s])
319ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
320ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # wrap the usage parts if it's too long
321ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            text_width = self._width - self._current_indent
322ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if len(prefix) + len(usage) > text_width:
323ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
324ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # break usage into wrappable parts
325ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                part_regexp = r'\(.*?\)+|\[.*?\]+|\S+'
326ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                opt_usage = format(optionals, groups)
327ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                pos_usage = format(positionals, groups)
328ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                opt_parts = _re.findall(part_regexp, opt_usage)
329ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                pos_parts = _re.findall(part_regexp, pos_usage)
330ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                assert ' '.join(opt_parts) == opt_usage
331ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                assert ' '.join(pos_parts) == pos_usage
332ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
333ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # helper for wrapping lines
334ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                def get_lines(parts, indent, prefix=None):
335ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    lines = []
336ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    line = []
337ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    if prefix is not None:
338ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        line_len = len(prefix) - 1
339ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    else:
340ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        line_len = len(indent) - 1
341ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    for part in parts:
342ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        if line_len + 1 + len(part) > text_width:
343ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                            lines.append(indent + ' '.join(line))
344ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                            line = []
345ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                            line_len = len(indent) - 1
346ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        line.append(part)
347ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        line_len += len(part) + 1
348ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    if line:
349ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        lines.append(indent + ' '.join(line))
350ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    if prefix is not None:
351ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        lines[0] = lines[0][len(indent):]
352ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    return lines
353ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
354ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # if prog is short, follow it with optionals or positionals
355ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if len(prefix) + len(prog) <= 0.75 * text_width:
356ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    indent = ' ' * (len(prefix) + len(prog) + 1)
357ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    if opt_parts:
358ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        lines = get_lines([prog] + opt_parts, indent, prefix)
359ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        lines.extend(get_lines(pos_parts, indent))
360ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    elif pos_parts:
361ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        lines = get_lines([prog] + pos_parts, indent, prefix)
362ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    else:
363ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        lines = [prog]
364ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
365ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # if prog is long, put it on its own line
366ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                else:
367ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    indent = ' ' * len(prefix)
368ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    parts = opt_parts + pos_parts
369ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    lines = get_lines(parts, indent)
370ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    if len(lines) > 1:
371ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        lines = []
372ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        lines.extend(get_lines(opt_parts, indent))
373ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        lines.extend(get_lines(pos_parts, indent))
374ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    lines = [prog] + lines
375ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
376ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # join lines into usage
377ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                usage = '\n'.join(lines)
378ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
379ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # prefix with 'usage:'
380ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return '%s%s\n\n' % (prefix, usage)
381ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
382ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _format_actions_usage(self, actions, groups):
383ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # find group indices and identify actions in groups
384ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        group_actions = set()
385ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        inserts = {}
386ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for group in groups:
387ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            try:
388ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                start = actions.index(group._group_actions[0])
389ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            except ValueError:
390ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                continue
391ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            else:
392ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                end = start + len(group._group_actions)
393ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if actions[start:end] == group._group_actions:
394ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    for action in group._group_actions:
395ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        group_actions.add(action)
396ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    if not group.required:
397ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        if start in inserts:
398ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                            inserts[start] += ' ['
399ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        else:
400ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                            inserts[start] = '['
401ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        inserts[end] = ']'
402ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    else:
403ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        if start in inserts:
404ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                            inserts[start] += ' ('
405ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        else:
406ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                            inserts[start] = '('
407ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        inserts[end] = ')'
408ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    for i in range(start + 1, end):
409ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        inserts[i] = '|'
410ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
411ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # collect all actions format strings
412ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        parts = []
413ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for i, action in enumerate(actions):
414ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
415ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # suppressed arguments are marked with None
416ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # remove | separators for suppressed arguments
417ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if action.help is SUPPRESS:
418ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                parts.append(None)
419ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if inserts.get(i) == '|':
420ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    inserts.pop(i)
421ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                elif inserts.get(i + 1) == '|':
422ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    inserts.pop(i + 1)
423ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
424ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # produce all arg strings
425ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            elif not action.option_strings:
426ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                part = self._format_args(action, action.dest)
427ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
428ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # if it's in a group, strip the outer []
429ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if action in group_actions:
430ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    if part[0] == '[' and part[-1] == ']':
431ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        part = part[1:-1]
432ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
433ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # add the action string to the list
434ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                parts.append(part)
435ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
436ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # produce the first way to invoke the option in brackets
437ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            else:
438ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                option_string = action.option_strings[0]
439ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
440ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # if the Optional doesn't take a value, format is:
441ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                #    -s or --long
442ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if action.nargs == 0:
443ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    part = '%s' % option_string
444ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
445ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # if the Optional takes a value, format is:
446ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                #    -s ARGS or --long ARGS
447ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                else:
448ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    default = action.dest.upper()
449ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    args_string = self._format_args(action, default)
450ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    part = '%s %s' % (option_string, args_string)
451ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
452ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # make it look optional if it's not required or in a group
453ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if not action.required and action not in group_actions:
454ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    part = '[%s]' % part
455ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
456ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # add the action string to the list
457ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                parts.append(part)
458ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
459ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # insert things at the necessary indices
460ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for i in sorted(inserts, reverse=True):
461ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            parts[i:i] = [inserts[i]]
462ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
463ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # join all the action items with spaces
464ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        text = ' '.join([item for item in parts if item is not None])
465ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
466ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # clean up separators for mutually exclusive groups
467ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        open = r'[\[(]'
468ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        close = r'[\])]'
469ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        text = _re.sub(r'(%s) ' % open, r'\1', text)
470ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        text = _re.sub(r' (%s)' % close, r'\1', text)
471ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        text = _re.sub(r'%s *%s' % (open, close), r'', text)
472ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        text = _re.sub(r'\(([^|]*)\)', r'\1', text)
473ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        text = text.strip()
474ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
475ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # return the text
476ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return text
477ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
478ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _format_text(self, text):
479ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if '%(prog)' in text:
480ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            text = text % dict(prog=self._prog)
481ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        text_width = self._width - self._current_indent
482ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        indent = ' ' * self._current_indent
483ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return self._fill_text(text, text_width, indent) + '\n\n'
484ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
485ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _format_action(self, action):
486ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # determine the required width and the entry label
487ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        help_position = min(self._action_max_length + 2,
488ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                            self._max_help_position)
489ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        help_width = self._width - help_position
490ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        action_width = help_position - self._current_indent - 2
491ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        action_header = self._format_action_invocation(action)
492ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
493ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # ho nelp; start on same line and add a final newline
494ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if not action.help:
495ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            tup = self._current_indent, '', action_header
496ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            action_header = '%*s%s\n' % tup
497ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
498ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # short action name; start on the same line and pad two spaces
499ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif len(action_header) <= action_width:
500ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            tup = self._current_indent, '', action_width, action_header
501ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            action_header = '%*s%-*s  ' % tup
502ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            indent_first = 0
503ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
504ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # long action name; start on the next line
505ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        else:
506ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            tup = self._current_indent, '', action_header
507ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            action_header = '%*s%s\n' % tup
508ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            indent_first = help_position
509ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
510ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # collect the pieces of the action help
511ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        parts = [action_header]
512ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
513ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if there was help for the action, add lines of help text
514ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if action.help:
515ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            help_text = self._expand_help(action)
516ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            help_lines = self._split_lines(help_text, help_width)
517ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            parts.append('%*s%s\n' % (indent_first, '', help_lines[0]))
518ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            for line in help_lines[1:]:
519ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                parts.append('%*s%s\n' % (help_position, '', line))
520ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
521ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # or add a newline if the description doesn't end with one
522ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif not action_header.endswith('\n'):
523ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            parts.append('\n')
524ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
525ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if there are any sub-actions, add their help as well
526ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for subaction in self._iter_indented_subactions(action):
527ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            parts.append(self._format_action(subaction))
528ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
529ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # return a single string
530ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return self._join_parts(parts)
531ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
532ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _format_action_invocation(self, action):
533ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if not action.option_strings:
534ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            metavar, = self._metavar_formatter(action, action.dest)(1)
535ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            return metavar
536ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
537ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        else:
538ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            parts = []
539ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
540ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # if the Optional doesn't take a value, format is:
541ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            #    -s, --long
542ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if action.nargs == 0:
543ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                parts.extend(action.option_strings)
544ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
545ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # if the Optional takes a value, format is:
546ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            #    -s ARGS, --long ARGS
547ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            else:
548ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                default = action.dest.upper()
549ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                args_string = self._format_args(action, default)
550ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                for option_string in action.option_strings:
551ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    parts.append('%s %s' % (option_string, args_string))
552ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
553ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            return ', '.join(parts)
554ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
555ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _metavar_formatter(self, action, default_metavar):
556ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if action.metavar is not None:
557ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            result = action.metavar
558ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif action.choices is not None:
559ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            choice_strs = [str(choice) for choice in action.choices]
560ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            result = '{%s}' % ','.join(choice_strs)
561ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        else:
562ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            result = default_metavar
563ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
564ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        def format(tuple_size):
565ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if isinstance(result, tuple):
566ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                return result
567ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            else:
568ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                return (result, ) * tuple_size
569ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return format
570ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
571ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _format_args(self, action, default_metavar):
572ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        get_metavar = self._metavar_formatter(action, default_metavar)
573ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if action.nargs is None:
574ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            result = '%s' % get_metavar(1)
575ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif action.nargs == OPTIONAL:
576ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            result = '[%s]' % get_metavar(1)
577ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif action.nargs == ZERO_OR_MORE:
578ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            result = '[%s [%s ...]]' % get_metavar(2)
579ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif action.nargs == ONE_OR_MORE:
580ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            result = '%s [%s ...]' % get_metavar(2)
581ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif action.nargs == REMAINDER:
582ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            result = '...'
583ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif action.nargs == PARSER:
584ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            result = '%s ...' % get_metavar(1)
585ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        else:
586ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            formats = ['%s' for _ in range(action.nargs)]
587ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            result = ' '.join(formats) % get_metavar(action.nargs)
588ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return result
589ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
590ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _expand_help(self, action):
591ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        params = dict(vars(action), prog=self._prog)
592ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for name in list(params):
593ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if params[name] is SUPPRESS:
594ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                del params[name]
595ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for name in list(params):
596ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if hasattr(params[name], '__name__'):
597ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                params[name] = params[name].__name__
598ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if params.get('choices') is not None:
599ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            choices_str = ', '.join([str(c) for c in params['choices']])
600ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            params['choices'] = choices_str
601ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return self._get_help_string(action) % params
602ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
603ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _iter_indented_subactions(self, action):
604ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        try:
605ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            get_subactions = action._get_subactions
606ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        except AttributeError:
607ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            pass
608ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        else:
609ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self._indent()
610ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            for subaction in get_subactions():
611ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                yield subaction
612ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self._dedent()
613ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
614ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _split_lines(self, text, width):
615ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        text = self._whitespace_matcher.sub(' ', text).strip()
616ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return _textwrap.wrap(text, width)
617ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
618ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _fill_text(self, text, width, indent):
619ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        text = self._whitespace_matcher.sub(' ', text).strip()
620ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return _textwrap.fill(text, width, initial_indent=indent,
621ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                                           subsequent_indent=indent)
622ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
623ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _get_help_string(self, action):
624ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return action.help
625ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
626ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
627ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass RawDescriptionHelpFormatter(HelpFormatter):
628ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """Help message formatter which retains any formatting in descriptions.
629ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
630ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    Only the name of this class is considered a public API. All the methods
631ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    provided by the class are considered an implementation detail.
632ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """
633ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
634ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _fill_text(self, text, width, indent):
635ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return ''.join([indent + line for line in text.splitlines(True)])
636ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
637ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
638ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass RawTextHelpFormatter(RawDescriptionHelpFormatter):
639ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """Help message formatter which retains formatting of all help text.
640ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
641ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    Only the name of this class is considered a public API. All the methods
642ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    provided by the class are considered an implementation detail.
643ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """
644ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
645ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _split_lines(self, text, width):
646ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return text.splitlines()
647ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
648ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
649ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass ArgumentDefaultsHelpFormatter(HelpFormatter):
650ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """Help message formatter which adds default values to argument help.
651ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
652ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    Only the name of this class is considered a public API. All the methods
653ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    provided by the class are considered an implementation detail.
654ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """
655ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
656ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _get_help_string(self, action):
657ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        help = action.help
658ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if '%(default)' not in action.help:
659ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if action.default is not SUPPRESS:
660ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
661ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if action.option_strings or action.nargs in defaulting_nargs:
662ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    help += ' (default: %(default)s)'
663ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return help
664ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
665ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
666ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# =====================
667ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# Options and Arguments
668ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# =====================
669ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
670ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotdef _get_action_name(argument):
671ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    if argument is None:
672ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return None
673ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    elif argument.option_strings:
674ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return  '/'.join(argument.option_strings)
675ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    elif argument.metavar not in (None, SUPPRESS):
676ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return argument.metavar
677ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    elif argument.dest not in (None, SUPPRESS):
678ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return argument.dest
679ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    else:
680ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return None
681ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
682ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
683ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass ArgumentError(Exception):
684ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """An error from creating or using an argument (optional or positional).
685ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
686ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    The string value of this exception is the message, augmented with
687ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    information about the argument that caused it.
688ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """
689ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
690ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self, argument, message):
691ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.argument_name = _get_action_name(argument)
692ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.message = message
693ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
694ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __str__(self):
695ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if self.argument_name is None:
696ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            format = '%(message)s'
697ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        else:
698ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            format = 'argument %(argument_name)s: %(message)s'
699ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return format % dict(message=self.message,
700ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                             argument_name=self.argument_name)
701ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
702ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
703ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass ArgumentTypeError(Exception):
704ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """An error from trying to convert a command line string to a type."""
705ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    pass
706ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
707ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
708ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# ==============
709ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# Action classes
710ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# ==============
711ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
712ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass Action(_AttributeHolder):
713ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """Information about how to convert command line strings to Python objects.
714ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
715ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    Action objects are used by an ArgumentParser to represent the information
716ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    needed to parse a single argument from one or more strings from the
717ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    command line. The keyword arguments to the Action constructor are also
718ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    all attributes of Action instances.
719ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
720ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    Keyword Arguments:
721ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
722ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - option_strings -- A list of command-line option strings which
723ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            should be associated with this action.
724ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
725ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - dest -- The name of the attribute to hold the created object(s)
726ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
727ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - nargs -- The number of command-line arguments that should be
728ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            consumed. By default, one argument will be consumed and a single
729ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            value will be produced.  Other values include:
730ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                - N (an integer) consumes N arguments (and produces a list)
731ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                - '?' consumes zero or one arguments
732ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                - '*' consumes zero or more arguments (and produces a list)
733ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                - '+' consumes one or more arguments (and produces a list)
734ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            Note that the difference between the default and nargs=1 is that
735ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            with the default, a single value will be produced, while with
736ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            nargs=1, a list containing a single value will be produced.
737ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
738ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - const -- The value to be produced if the option is specified and the
739ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            option uses an action that takes no values.
740ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
741ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - default -- The value to be produced if the option is not specified.
742ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
743ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - type -- A callable that accepts a single string argument, and
744ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            returns the converted value.  The standard Python types str, int,
745ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            float, and complex are useful examples of such callables.  If None,
746ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            str is used.
747ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
748ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - choices -- A container of values that should be allowed. If not None,
749ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            after a command-line argument has been converted to the appropriate
750ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            type, an exception will be raised if it is not a member of this
751ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            collection.
752ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
753ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - required -- True if the action must always be specified at the
754ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            command line. This is only meaningful for optional command-line
755ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            arguments.
756ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
757ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - help -- The help string describing the argument.
758ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
759ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - metavar -- The name to be used for the option's argument with the
760ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            help string. If None, the 'dest' value will be used as the name.
761ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """
762ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
763ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self,
764ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 option_strings,
765ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 dest,
766ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 nargs=None,
767ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 const=None,
768ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 default=None,
769ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 type=None,
770ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 choices=None,
771ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 required=False,
772ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 help=None,
773ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 metavar=None):
774ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.option_strings = option_strings
775ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.dest = dest
776ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.nargs = nargs
777ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.const = const
778ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.default = default
779ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.type = type
780ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.choices = choices
781ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.required = required
782ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.help = help
783ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.metavar = metavar
784ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
785ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _get_kwargs(self):
786ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        names = [
787ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'option_strings',
788ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'dest',
789ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'nargs',
790ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'const',
791ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'default',
792ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'type',
793ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'choices',
794ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'help',
795ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'metavar',
796ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        ]
797ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return [(name, getattr(self, name)) for name in names]
798ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
799ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __call__(self, parser, namespace, values, option_string=None):
800ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        raise NotImplementedError(_('.__call__() not defined'))
801ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
802ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
803ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass _StoreAction(Action):
804ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
805ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self,
806ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 option_strings,
807ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 dest,
808ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 nargs=None,
809ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 const=None,
810ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 default=None,
811ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 type=None,
812ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 choices=None,
813ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 required=False,
814ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 help=None,
815ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 metavar=None):
816ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if nargs == 0:
817ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            raise ValueError('nargs for store actions must be > 0; if you '
818ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                             'have nothing to store, actions such as store '
819ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                             'true or store const may be more appropriate')
820ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if const is not None and nargs != OPTIONAL:
821ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            raise ValueError('nargs must be %r to supply const' % OPTIONAL)
822ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        super(_StoreAction, self).__init__(
823ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            option_strings=option_strings,
824ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            dest=dest,
825ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            nargs=nargs,
826ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            const=const,
827ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            default=default,
828ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            type=type,
829ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            choices=choices,
830ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            required=required,
831ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            help=help,
832ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            metavar=metavar)
833ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
834ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __call__(self, parser, namespace, values, option_string=None):
835ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        setattr(namespace, self.dest, values)
836ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
837ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
838ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass _StoreConstAction(Action):
839ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
840ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self,
841ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 option_strings,
842ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 dest,
843ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 const,
844ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 default=None,
845ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 required=False,
846ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 help=None,
847ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 metavar=None):
848ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        super(_StoreConstAction, self).__init__(
849ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            option_strings=option_strings,
850ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            dest=dest,
851ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            nargs=0,
852ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            const=const,
853ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            default=default,
854ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            required=required,
855ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            help=help)
856ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
857ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __call__(self, parser, namespace, values, option_string=None):
858ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        setattr(namespace, self.dest, self.const)
859ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
860ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
861ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass _StoreTrueAction(_StoreConstAction):
862ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
863ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self,
864ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 option_strings,
865ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 dest,
866ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 default=False,
867ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 required=False,
868ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 help=None):
869ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        super(_StoreTrueAction, self).__init__(
870ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            option_strings=option_strings,
871ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            dest=dest,
872ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            const=True,
873ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            default=default,
874ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            required=required,
875ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            help=help)
876ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
877ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
878ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass _StoreFalseAction(_StoreConstAction):
879ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
880ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self,
881ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 option_strings,
882ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 dest,
883ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 default=True,
884ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 required=False,
885ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 help=None):
886ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        super(_StoreFalseAction, self).__init__(
887ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            option_strings=option_strings,
888ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            dest=dest,
889ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            const=False,
890ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            default=default,
891ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            required=required,
892ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            help=help)
893ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
894ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
895ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass _AppendAction(Action):
896ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
897ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self,
898ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 option_strings,
899ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 dest,
900ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 nargs=None,
901ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 const=None,
902ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 default=None,
903ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 type=None,
904ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 choices=None,
905ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 required=False,
906ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 help=None,
907ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 metavar=None):
908ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if nargs == 0:
909ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            raise ValueError('nargs for append actions must be > 0; if arg '
910ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                             'strings are not supplying the value to append, '
911ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                             'the append const action may be more appropriate')
912ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if const is not None and nargs != OPTIONAL:
913ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            raise ValueError('nargs must be %r to supply const' % OPTIONAL)
914ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        super(_AppendAction, self).__init__(
915ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            option_strings=option_strings,
916ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            dest=dest,
917ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            nargs=nargs,
918ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            const=const,
919ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            default=default,
920ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            type=type,
921ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            choices=choices,
922ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            required=required,
923ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            help=help,
924ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            metavar=metavar)
925ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
926ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __call__(self, parser, namespace, values, option_string=None):
927ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        items = _copy.copy(_ensure_value(namespace, self.dest, []))
928ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        items.append(values)
929ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        setattr(namespace, self.dest, items)
930ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
931ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
932ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass _AppendConstAction(Action):
933ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
934ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self,
935ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 option_strings,
936ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 dest,
937ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 const,
938ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 default=None,
939ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 required=False,
940ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 help=None,
941ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 metavar=None):
942ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        super(_AppendConstAction, self).__init__(
943ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            option_strings=option_strings,
944ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            dest=dest,
945ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            nargs=0,
946ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            const=const,
947ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            default=default,
948ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            required=required,
949ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            help=help,
950ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            metavar=metavar)
951ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
952ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __call__(self, parser, namespace, values, option_string=None):
953ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        items = _copy.copy(_ensure_value(namespace, self.dest, []))
954ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        items.append(self.const)
955ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        setattr(namespace, self.dest, items)
956ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
957ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
958ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass _CountAction(Action):
959ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
960ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self,
961ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 option_strings,
962ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 dest,
963ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 default=None,
964ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 required=False,
965ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 help=None):
966ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        super(_CountAction, self).__init__(
967ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            option_strings=option_strings,
968ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            dest=dest,
969ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            nargs=0,
970ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            default=default,
971ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            required=required,
972ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            help=help)
973ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
974ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __call__(self, parser, namespace, values, option_string=None):
975ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        new_count = _ensure_value(namespace, self.dest, 0) + 1
976ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        setattr(namespace, self.dest, new_count)
977ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
978ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
979ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass _HelpAction(Action):
980ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
981ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self,
982ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 option_strings,
983ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 dest=SUPPRESS,
984ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 default=SUPPRESS,
985ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 help=None):
986ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        super(_HelpAction, self).__init__(
987ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            option_strings=option_strings,
988ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            dest=dest,
989ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            default=default,
990ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            nargs=0,
991ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            help=help)
992ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
993ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __call__(self, parser, namespace, values, option_string=None):
994ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        parser.print_help()
995ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        parser.exit()
996ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
997ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
998ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass _VersionAction(Action):
999ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1000ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self,
1001ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 option_strings,
1002ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 version=None,
1003ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 dest=SUPPRESS,
1004ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 default=SUPPRESS,
1005ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 help="show program's version number and exit"):
1006ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        super(_VersionAction, self).__init__(
1007ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            option_strings=option_strings,
1008ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            dest=dest,
1009ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            default=default,
1010ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            nargs=0,
1011ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            help=help)
1012ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.version = version
1013ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1014ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __call__(self, parser, namespace, values, option_string=None):
1015ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        version = self.version
1016ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if version is None:
1017ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            version = parser.version
1018ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        formatter = parser._get_formatter()
1019ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        formatter.add_text(version)
1020ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        parser.exit(message=formatter.format_help())
1021ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1022ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1023ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass _SubParsersAction(Action):
1024ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1025ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    class _ChoicesPseudoAction(Action):
1026ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1027ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        def __init__(self, name, help):
1028ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            sup = super(_SubParsersAction._ChoicesPseudoAction, self)
1029ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            sup.__init__(option_strings=[], dest=name, help=help)
1030ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1031ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self,
1032ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 option_strings,
1033ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 prog,
1034ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 parser_class,
1035ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 dest=SUPPRESS,
1036ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 help=None,
1037ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 metavar=None):
1038ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1039ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._prog_prefix = prog
1040ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._parser_class = parser_class
1041ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._name_parser_map = _collections.OrderedDict()
1042ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._choices_actions = []
1043ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1044ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        super(_SubParsersAction, self).__init__(
1045ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            option_strings=option_strings,
1046ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            dest=dest,
1047ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            nargs=PARSER,
1048ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            choices=self._name_parser_map,
1049ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            help=help,
1050ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            metavar=metavar)
1051ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1052ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def add_parser(self, name, **kwargs):
1053ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # set prog from the existing prefix
1054ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if kwargs.get('prog') is None:
1055ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            kwargs['prog'] = '%s %s' % (self._prog_prefix, name)
1056ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1057ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # create a pseudo-action to hold the choice help
1058ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if 'help' in kwargs:
1059ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            help = kwargs.pop('help')
1060ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            choice_action = self._ChoicesPseudoAction(name, help)
1061ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self._choices_actions.append(choice_action)
1062ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1063ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # create the parser and add it to the map
1064ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        parser = self._parser_class(**kwargs)
1065ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._name_parser_map[name] = parser
1066ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return parser
1067ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1068ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _get_subactions(self):
1069ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return self._choices_actions
1070ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1071ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __call__(self, parser, namespace, values, option_string=None):
1072ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        parser_name = values[0]
1073ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        arg_strings = values[1:]
1074ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1075ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # set the parser name if requested
1076ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if self.dest is not SUPPRESS:
1077ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            setattr(namespace, self.dest, parser_name)
1078ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1079ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # select the parser
1080ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        try:
1081ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            parser = self._name_parser_map[parser_name]
1082ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        except KeyError:
1083ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            tup = parser_name, ', '.join(self._name_parser_map)
1084ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            msg = _('unknown parser %r (choices: %s)') % tup
1085ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            raise ArgumentError(self, msg)
1086ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1087ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # parse all the remaining options into the namespace
1088ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # store any unrecognized options on the object, so that the top
1089ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # level parser can decide what to do with them
1090ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        namespace, arg_strings = parser.parse_known_args(arg_strings, namespace)
1091ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if arg_strings:
1092ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, [])
1093ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings)
1094ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1095ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1096ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# ==============
1097ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# Type classes
1098ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# ==============
1099ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1100ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass FileType(object):
1101ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """Factory for creating file object types
1102ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1103ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    Instances of FileType are typically passed as type= arguments to the
1104ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    ArgumentParser add_argument() method.
1105ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1106ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    Keyword Arguments:
1107ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - mode -- A string indicating how the file is to be opened. Accepts the
1108ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            same values as the builtin open() function.
1109ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - bufsize -- The file's desired buffer size. Accepts the same values as
1110ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            the builtin open() function.
1111ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """
1112ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1113ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self, mode='r', bufsize=-1):
1114ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._mode = mode
1115ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._bufsize = bufsize
1116ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1117ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __call__(self, string):
1118ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # the special argument "-" means sys.std{in,out}
1119ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if string == '-':
1120ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if 'r' in self._mode:
1121ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                return _sys.stdin
1122ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            elif 'w' in self._mode:
1123ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                return _sys.stdout
1124ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            else:
1125ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                msg = _('argument "-" with mode %r') % self._mode
1126ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                raise ValueError(msg)
1127ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1128ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # all other arguments are used as file names
1129ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        try:
1130ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            return open(string, self._mode, self._bufsize)
1131ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        except IOError as e:
1132ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            message = _("can't open '%s': %s")
1133ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            raise ArgumentTypeError(message % (string, e))
1134ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1135ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __repr__(self):
1136ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        args = self._mode, self._bufsize
1137ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        args_str = ', '.join(repr(arg) for arg in args if arg != -1)
1138ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return '%s(%s)' % (type(self).__name__, args_str)
1139ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1140ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# ===========================
1141ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# Optional and Positional Parsing
1142ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# ===========================
1143ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1144ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass Namespace(_AttributeHolder):
1145ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """Simple object for storing attributes.
1146ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1147ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    Implements equality by attribute names and values, and provides a simple
1148ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    string representation.
1149ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """
1150ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1151ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self, **kwargs):
1152ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for name in kwargs:
1153ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            setattr(self, name, kwargs[name])
1154ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1155ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    __hash__ = None
1156ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1157ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __eq__(self, other):
1158ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return vars(self) == vars(other)
1159ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1160ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __ne__(self, other):
1161ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return not (self == other)
1162ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1163ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __contains__(self, key):
1164ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return key in self.__dict__
1165ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1166ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1167ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass _ActionsContainer(object):
1168ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1169ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self,
1170ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 description,
1171ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 prefix_chars,
1172ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 argument_default,
1173ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 conflict_handler):
1174ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        super(_ActionsContainer, self).__init__()
1175ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1176ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.description = description
1177ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.argument_default = argument_default
1178ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.prefix_chars = prefix_chars
1179ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.conflict_handler = conflict_handler
1180ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1181ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # set up registries
1182ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._registries = {}
1183ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1184ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # register actions
1185ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.register('action', None, _StoreAction)
1186ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.register('action', 'store', _StoreAction)
1187ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.register('action', 'store_const', _StoreConstAction)
1188ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.register('action', 'store_true', _StoreTrueAction)
1189ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.register('action', 'store_false', _StoreFalseAction)
1190ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.register('action', 'append', _AppendAction)
1191ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.register('action', 'append_const', _AppendConstAction)
1192ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.register('action', 'count', _CountAction)
1193ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.register('action', 'help', _HelpAction)
1194ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.register('action', 'version', _VersionAction)
1195ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.register('action', 'parsers', _SubParsersAction)
1196ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1197ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # raise an exception if the conflict handler is invalid
1198ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._get_handler()
1199ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1200ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # action storage
1201ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._actions = []
1202ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._option_string_actions = {}
1203ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1204ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # groups
1205ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._action_groups = []
1206ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._mutually_exclusive_groups = []
1207ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1208ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # defaults storage
1209ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._defaults = {}
1210ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1211ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # determines whether an "option" looks like a negative number
1212ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._negative_number_matcher = _re.compile(r'^-\d+$|^-\d*\.\d+$')
1213ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1214ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # whether or not there are any optionals that look like negative
1215ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # numbers -- uses a list so it can be shared and edited
1216ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._has_negative_number_optionals = []
1217ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1218ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # ====================
1219ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # Registration methods
1220ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # ====================
1221ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def register(self, registry_name, value, object):
1222ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        registry = self._registries.setdefault(registry_name, {})
1223ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        registry[value] = object
1224ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1225ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _registry_get(self, registry_name, value, default=None):
1226ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return self._registries[registry_name].get(value, default)
1227ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1228ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # ==================================
1229ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # Namespace default accessor methods
1230ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # ==================================
1231ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def set_defaults(self, **kwargs):
1232ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._defaults.update(kwargs)
1233ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1234ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if these defaults match any existing arguments, replace
1235ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # the previous default on the object with the new one
1236ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for action in self._actions:
1237ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if action.dest in kwargs:
1238ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                action.default = kwargs[action.dest]
1239ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1240ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def get_default(self, dest):
1241ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for action in self._actions:
1242ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if action.dest == dest and action.default is not None:
1243ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                return action.default
1244ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return self._defaults.get(dest, None)
1245ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1246ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1247ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # =======================
1248ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # Adding argument actions
1249ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # =======================
1250ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def add_argument(self, *args, **kwargs):
1251ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        """
1252ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        add_argument(dest, ..., name=value, ...)
1253ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        add_argument(option_string, option_string, ..., name=value, ...)
1254ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        """
1255ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1256ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if no positional args are supplied or only one is supplied and
1257ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # it doesn't look like an option string, parse a positional
1258ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # argument
1259ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        chars = self.prefix_chars
1260ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if not args or len(args) == 1 and args[0][0] not in chars:
1261ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if args and 'dest' in kwargs:
1262ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                raise ValueError('dest supplied twice for positional argument')
1263ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            kwargs = self._get_positional_kwargs(*args, **kwargs)
1264ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1265ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # otherwise, we're adding an optional argument
1266ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        else:
1267ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            kwargs = self._get_optional_kwargs(*args, **kwargs)
1268ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1269ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if no default was supplied, use the parser-level default
1270ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if 'default' not in kwargs:
1271ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            dest = kwargs['dest']
1272ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if dest in self._defaults:
1273ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                kwargs['default'] = self._defaults[dest]
1274ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            elif self.argument_default is not None:
1275ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                kwargs['default'] = self.argument_default
1276ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1277ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # create the action object, and add it to the parser
1278ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        action_class = self._pop_action_class(kwargs)
1279ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if not _callable(action_class):
1280ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            raise ValueError('unknown action "%s"' % (action_class,))
1281ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        action = action_class(**kwargs)
1282ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1283ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # raise an error if the action type is not callable
1284ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        type_func = self._registry_get('type', action.type, action.type)
1285ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if not _callable(type_func):
1286ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            raise ValueError('%r is not callable' % (type_func,))
1287ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1288ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # raise an error if the metavar does not match the type
1289ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if hasattr(self, "_get_formatter"):
1290ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            try:
1291ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                self._get_formatter()._format_args(action, None)
1292ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            except TypeError:
1293ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                raise ValueError("length of metavar tuple does not match nargs")
1294ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1295ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return self._add_action(action)
1296ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1297ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def add_argument_group(self, *args, **kwargs):
1298ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        group = _ArgumentGroup(self, *args, **kwargs)
1299ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._action_groups.append(group)
1300ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return group
1301ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1302ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def add_mutually_exclusive_group(self, **kwargs):
1303ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        group = _MutuallyExclusiveGroup(self, **kwargs)
1304ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._mutually_exclusive_groups.append(group)
1305ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return group
1306ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1307ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _add_action(self, action):
1308ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # resolve any conflicts
1309ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._check_conflict(action)
1310ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1311ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # add to actions list
1312ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._actions.append(action)
1313ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        action.container = self
1314ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1315ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # index the action by any option strings it has
1316ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for option_string in action.option_strings:
1317ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self._option_string_actions[option_string] = action
1318ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1319ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # set the flag if any option strings look like negative numbers
1320ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for option_string in action.option_strings:
1321ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if self._negative_number_matcher.match(option_string):
1322ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if not self._has_negative_number_optionals:
1323ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    self._has_negative_number_optionals.append(True)
1324ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1325ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # return the created action
1326ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return action
1327ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1328ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _remove_action(self, action):
1329ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._actions.remove(action)
1330ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1331ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _add_container_actions(self, container):
1332ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # collect groups by titles
1333ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        title_group_map = {}
1334ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for group in self._action_groups:
1335ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if group.title in title_group_map:
1336ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                msg = _('cannot merge actions - two groups are named %r')
1337ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                raise ValueError(msg % (group.title))
1338ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            title_group_map[group.title] = group
1339ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1340ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # map each action to its group
1341ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        group_map = {}
1342ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for group in container._action_groups:
1343ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1344ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # if a group with the title exists, use that, otherwise
1345ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # create a new group matching the container's group
1346ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if group.title not in title_group_map:
1347ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                title_group_map[group.title] = self.add_argument_group(
1348ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    title=group.title,
1349ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    description=group.description,
1350ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    conflict_handler=group.conflict_handler)
1351ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1352ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # map the actions to their new group
1353ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            for action in group._group_actions:
1354ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                group_map[action] = title_group_map[group.title]
1355ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1356ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # add container's mutually exclusive groups
1357ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # NOTE: if add_mutually_exclusive_group ever gains title= and
1358ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # description= then this code will need to be expanded as above
1359ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for group in container._mutually_exclusive_groups:
1360ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            mutex_group = self.add_mutually_exclusive_group(
1361ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                required=group.required)
1362ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1363ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # map the actions to their new mutex group
1364ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            for action in group._group_actions:
1365ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                group_map[action] = mutex_group
1366ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1367ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # add all actions to this container or their group
1368ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for action in container._actions:
1369ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            group_map.get(action, self)._add_action(action)
1370ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1371ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _get_positional_kwargs(self, dest, **kwargs):
1372ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # make sure required is not specified
1373ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if 'required' in kwargs:
1374ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            msg = _("'required' is an invalid argument for positionals")
1375ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            raise TypeError(msg)
1376ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1377ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # mark positional arguments as required if at least one is
1378ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # always required
1379ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]:
1380ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            kwargs['required'] = True
1381ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs:
1382ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            kwargs['required'] = True
1383ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1384ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # return the keyword arguments with no option strings
1385ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return dict(kwargs, dest=dest, option_strings=[])
1386ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1387ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _get_optional_kwargs(self, *args, **kwargs):
1388ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # determine short and long option strings
1389ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        option_strings = []
1390ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        long_option_strings = []
1391ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for option_string in args:
1392ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # error on strings that don't start with an appropriate prefix
1393ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if not option_string[0] in self.prefix_chars:
1394ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                msg = _('invalid option string %r: '
1395ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        'must start with a character %r')
1396ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                tup = option_string, self.prefix_chars
1397ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                raise ValueError(msg % tup)
1398ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1399ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # strings starting with two prefix characters are long options
1400ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            option_strings.append(option_string)
1401ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if option_string[0] in self.prefix_chars:
1402ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if len(option_string) > 1:
1403ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    if option_string[1] in self.prefix_chars:
1404ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        long_option_strings.append(option_string)
1405ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1406ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x'
1407ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        dest = kwargs.pop('dest', None)
1408ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if dest is None:
1409ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if long_option_strings:
1410ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                dest_option_string = long_option_strings[0]
1411ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            else:
1412ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                dest_option_string = option_strings[0]
1413ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            dest = dest_option_string.lstrip(self.prefix_chars)
1414ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if not dest:
1415ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                msg = _('dest= is required for options like %r')
1416ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                raise ValueError(msg % option_string)
1417ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            dest = dest.replace('-', '_')
1418ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1419ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # return the updated keyword arguments
1420ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return dict(kwargs, dest=dest, option_strings=option_strings)
1421ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1422ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _pop_action_class(self, kwargs, default=None):
1423ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        action = kwargs.pop('action', default)
1424ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return self._registry_get('action', action, action)
1425ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1426ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _get_handler(self):
1427ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # determine function from conflict handler string
1428ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        handler_func_name = '_handle_conflict_%s' % self.conflict_handler
1429ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        try:
1430ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            return getattr(self, handler_func_name)
1431ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        except AttributeError:
1432ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            msg = _('invalid conflict_resolution value: %r')
1433ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            raise ValueError(msg % self.conflict_handler)
1434ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1435ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _check_conflict(self, action):
1436ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1437ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # find all options that conflict with this option
1438ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        confl_optionals = []
1439ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for option_string in action.option_strings:
1440ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if option_string in self._option_string_actions:
1441ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                confl_optional = self._option_string_actions[option_string]
1442ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                confl_optionals.append((option_string, confl_optional))
1443ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1444ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # resolve any conflicts
1445ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if confl_optionals:
1446ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            conflict_handler = self._get_handler()
1447ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            conflict_handler(action, confl_optionals)
1448ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1449ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _handle_conflict_error(self, action, conflicting_actions):
1450ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        message = _('conflicting option string(s): %s')
1451ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        conflict_string = ', '.join([option_string
1452ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                                     for option_string, action
1453ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                                     in conflicting_actions])
1454ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        raise ArgumentError(action, message % conflict_string)
1455ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1456ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _handle_conflict_resolve(self, action, conflicting_actions):
1457ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1458ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # remove all conflicting options
1459ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for option_string, action in conflicting_actions:
1460ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1461ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # remove the conflicting option
1462ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            action.option_strings.remove(option_string)
1463ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self._option_string_actions.pop(option_string, None)
1464ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1465ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # if the option now has no option string, remove it from the
1466ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # container holding it
1467ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if not action.option_strings:
1468ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                action.container._remove_action(action)
1469ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1470ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1471ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass _ArgumentGroup(_ActionsContainer):
1472ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1473ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self, container, title=None, description=None, **kwargs):
1474ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # add any missing keyword arguments by checking the container
1475ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        update = kwargs.setdefault
1476ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        update('conflict_handler', container.conflict_handler)
1477ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        update('prefix_chars', container.prefix_chars)
1478ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        update('argument_default', container.argument_default)
1479ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        super_init = super(_ArgumentGroup, self).__init__
1480ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        super_init(description=description, **kwargs)
1481ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1482ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # group attributes
1483ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.title = title
1484ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._group_actions = []
1485ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1486ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # share most attributes with the container
1487ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._registries = container._registries
1488ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._actions = container._actions
1489ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._option_string_actions = container._option_string_actions
1490ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._defaults = container._defaults
1491ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._has_negative_number_optionals = \
1492ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            container._has_negative_number_optionals
1493ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._mutually_exclusive_groups = container._mutually_exclusive_groups
1494ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1495ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _add_action(self, action):
1496ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        action = super(_ArgumentGroup, self)._add_action(action)
1497ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._group_actions.append(action)
1498ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return action
1499ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1500ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _remove_action(self, action):
1501ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        super(_ArgumentGroup, self)._remove_action(action)
1502ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._group_actions.remove(action)
1503ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1504ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1505ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass _MutuallyExclusiveGroup(_ArgumentGroup):
1506ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1507ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self, container, required=False):
1508ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        super(_MutuallyExclusiveGroup, self).__init__(container)
1509ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.required = required
1510ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._container = container
1511ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1512ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _add_action(self, action):
1513ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if action.required:
1514ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            msg = _('mutually exclusive arguments must be optional')
1515ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            raise ValueError(msg)
1516ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        action = self._container._add_action(action)
1517ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._group_actions.append(action)
1518ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return action
1519ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1520ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _remove_action(self, action):
1521ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._container._remove_action(action)
1522ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._group_actions.remove(action)
1523ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1524ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1525ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass ArgumentParser(_AttributeHolder, _ActionsContainer):
1526ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """Object for parsing command line strings into Python objects.
1527ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1528ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    Keyword Arguments:
1529ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - prog -- The name of the program (default: sys.argv[0])
1530ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - usage -- A usage message (default: auto-generated from arguments)
1531ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - description -- A description of what the program does
1532ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - epilog -- Text following the argument descriptions
1533ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - parents -- Parsers whose arguments should be copied into this one
1534ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - formatter_class -- HelpFormatter class for printing help messages
1535ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - prefix_chars -- Characters that prefix optional arguments
1536ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - fromfile_prefix_chars -- Characters that prefix files containing
1537ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            additional arguments
1538ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - argument_default -- The default value for all arguments
1539ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - conflict_handler -- String indicating how to handle conflicts
1540ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        - add_help -- Add a -h/-help option
1541ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """
1542ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1543ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self,
1544ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 prog=None,
1545ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 usage=None,
1546ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 description=None,
1547ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 epilog=None,
1548ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 version=None,
1549ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 parents=[],
1550ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 formatter_class=HelpFormatter,
1551ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 prefix_chars='-',
1552ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 fromfile_prefix_chars=None,
1553ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 argument_default=None,
1554ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 conflict_handler='error',
1555ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                 add_help=True):
1556ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1557ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if version is not None:
1558ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            import warnings
1559ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            warnings.warn(
1560ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                """The "version" argument to ArgumentParser is deprecated. """
1561ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                """Please use """
1562ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                """"add_argument(..., action='version', version="N", ...)" """
1563ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                """instead""", DeprecationWarning)
1564ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1565ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        superinit = super(ArgumentParser, self).__init__
1566ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        superinit(description=description,
1567ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                  prefix_chars=prefix_chars,
1568ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                  argument_default=argument_default,
1569ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                  conflict_handler=conflict_handler)
1570ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1571ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # default setting for prog
1572ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if prog is None:
1573ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            prog = _os.path.basename(_sys.argv[0])
1574ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1575ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.prog = prog
1576ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.usage = usage
1577ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.epilog = epilog
1578ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.version = version
1579ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.formatter_class = formatter_class
1580ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.fromfile_prefix_chars = fromfile_prefix_chars
1581ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.add_help = add_help
1582ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1583ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        add_group = self.add_argument_group
1584ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._positionals = add_group(_('positional arguments'))
1585ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._optionals = add_group(_('optional arguments'))
1586ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._subparsers = None
1587ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1588ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # register types
1589ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        def identity(string):
1590ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            return string
1591ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.register('type', None, identity)
1592ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1593ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # add help and version arguments if necessary
1594ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # (using explicit default to override global argument_default)
1595ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        default_prefix = '-' if '-' in prefix_chars else prefix_chars[0]
1596ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if self.add_help:
1597ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self.add_argument(
1598ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                default_prefix+'h', default_prefix*2+'help',
1599ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                action='help', default=SUPPRESS,
1600ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                help=_('show this help message and exit'))
1601ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if self.version:
1602ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self.add_argument(
1603ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                default_prefix+'v', default_prefix*2+'version',
1604ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                action='version', default=SUPPRESS,
1605ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                version=self.version,
1606ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                help=_("show program's version number and exit"))
1607ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1608ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # add parent arguments and defaults
1609ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for parent in parents:
1610ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self._add_container_actions(parent)
1611ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            try:
1612ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                defaults = parent._defaults
1613ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            except AttributeError:
1614ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                pass
1615ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            else:
1616ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                self._defaults.update(defaults)
1617ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1618ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # =======================
1619ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # Pretty __repr__ methods
1620ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # =======================
1621ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _get_kwargs(self):
1622ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        names = [
1623ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'prog',
1624ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'usage',
1625ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'description',
1626ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'version',
1627ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'formatter_class',
1628ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'conflict_handler',
1629ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'add_help',
1630ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        ]
1631ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return [(name, getattr(self, name)) for name in names]
1632ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1633ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # ==================================
1634ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # Optional/Positional adding methods
1635ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # ==================================
1636ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def add_subparsers(self, **kwargs):
1637ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if self._subparsers is not None:
1638ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self.error(_('cannot have multiple subparser arguments'))
1639ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1640ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # add the parser class to the arguments if it's not present
1641ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        kwargs.setdefault('parser_class', type(self))
1642ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1643ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if 'title' in kwargs or 'description' in kwargs:
1644ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            title = _(kwargs.pop('title', 'subcommands'))
1645ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            description = _(kwargs.pop('description', None))
1646ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self._subparsers = self.add_argument_group(title, description)
1647ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        else:
1648ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self._subparsers = self._positionals
1649ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1650ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # prog defaults to the usage message of this parser, skipping
1651ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # optional arguments and with no "usage:" prefix
1652ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if kwargs.get('prog') is None:
1653ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            formatter = self._get_formatter()
1654ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            positionals = self._get_positional_actions()
1655ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            groups = self._mutually_exclusive_groups
1656ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            formatter.add_usage(self.usage, positionals, groups, '')
1657ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            kwargs['prog'] = formatter.format_help().strip()
1658ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1659ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # create the parsers action and add it to the positionals list
1660ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        parsers_class = self._pop_action_class(kwargs, 'parsers')
1661ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        action = parsers_class(option_strings=[], **kwargs)
1662ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._subparsers._add_action(action)
1663ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1664ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # return the created parsers action
1665ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return action
1666ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1667ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _add_action(self, action):
1668ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if action.option_strings:
1669ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self._optionals._add_action(action)
1670ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        else:
1671ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self._positionals._add_action(action)
1672ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return action
1673ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1674ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _get_optional_actions(self):
1675ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return [action
1676ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                for action in self._actions
1677ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if action.option_strings]
1678ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1679ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _get_positional_actions(self):
1680ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return [action
1681ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                for action in self._actions
1682ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if not action.option_strings]
1683ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1684ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # =====================================
1685ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # Command line argument parsing methods
1686ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # =====================================
1687ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def parse_args(self, args=None, namespace=None):
1688ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        args, argv = self.parse_known_args(args, namespace)
1689ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if argv:
1690ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            msg = _('unrecognized arguments: %s')
1691ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self.error(msg % ' '.join(argv))
1692ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return args
1693ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1694ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def parse_known_args(self, args=None, namespace=None):
1695ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if args is None:
1696ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # args default to the system args
1697ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            args = _sys.argv[1:]
1698ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        else:
1699ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # make sure that args are mutable
1700ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            args = list(args)
1701ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1702ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # default Namespace built from parser defaults
1703ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if namespace is None:
1704ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            namespace = Namespace()
1705ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1706ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # add any action defaults that aren't present
1707ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for action in self._actions:
1708ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if action.dest is not SUPPRESS:
1709ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if not hasattr(namespace, action.dest):
1710ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    if action.default is not SUPPRESS:
1711ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        setattr(namespace, action.dest, action.default)
1712ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1713ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # add any parser defaults that aren't present
1714ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for dest in self._defaults:
1715ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if not hasattr(namespace, dest):
1716ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                setattr(namespace, dest, self._defaults[dest])
1717ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1718ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # parse the arguments and exit if there are any errors
1719ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        try:
1720ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            namespace, args = self._parse_known_args(args, namespace)
1721ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR):
1722ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                args.extend(getattr(namespace, _UNRECOGNIZED_ARGS_ATTR))
1723ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                delattr(namespace, _UNRECOGNIZED_ARGS_ATTR)
1724ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            return namespace, args
1725ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        except ArgumentError:
1726ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            err = _sys.exc_info()[1]
1727ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self.error(str(err))
1728ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1729ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _parse_known_args(self, arg_strings, namespace):
1730ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # replace arg strings that are file references
1731ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if self.fromfile_prefix_chars is not None:
1732ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            arg_strings = self._read_args_from_files(arg_strings)
1733ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1734ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # map all mutually exclusive arguments to the other arguments
1735ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # they can't occur with
1736ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        action_conflicts = {}
1737ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for mutex_group in self._mutually_exclusive_groups:
1738ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            group_actions = mutex_group._group_actions
1739ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            for i, mutex_action in enumerate(mutex_group._group_actions):
1740ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                conflicts = action_conflicts.setdefault(mutex_action, [])
1741ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                conflicts.extend(group_actions[:i])
1742ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                conflicts.extend(group_actions[i + 1:])
1743ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1744ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # find all option indices, and determine the arg_string_pattern
1745ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # which has an 'O' if there is an option at an index,
1746ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # an 'A' if there is an argument, or a '-' if there is a '--'
1747ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        option_string_indices = {}
1748ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        arg_string_pattern_parts = []
1749ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        arg_strings_iter = iter(arg_strings)
1750ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for i, arg_string in enumerate(arg_strings_iter):
1751ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1752ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # all args after -- are non-options
1753ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if arg_string == '--':
1754ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                arg_string_pattern_parts.append('-')
1755ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                for arg_string in arg_strings_iter:
1756ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    arg_string_pattern_parts.append('A')
1757ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1758ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # otherwise, add the arg to the arg strings
1759ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # and note the index if it was an option
1760ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            else:
1761ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                option_tuple = self._parse_optional(arg_string)
1762ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if option_tuple is None:
1763ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    pattern = 'A'
1764ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                else:
1765ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    option_string_indices[i] = option_tuple
1766ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    pattern = 'O'
1767ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                arg_string_pattern_parts.append(pattern)
1768ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1769ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # join the pieces together to form the pattern
1770ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        arg_strings_pattern = ''.join(arg_string_pattern_parts)
1771ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1772ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # converts arg strings to the appropriate and then takes the action
1773ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        seen_actions = set()
1774ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        seen_non_default_actions = set()
1775ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1776ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        def take_action(action, argument_strings, option_string=None):
1777ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            seen_actions.add(action)
1778ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            argument_values = self._get_values(action, argument_strings)
1779ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1780ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # error if this argument is not allowed with other previously
1781ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # seen arguments, assuming that actions that use the default
1782ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # value don't really count as "present"
1783ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if argument_values is not action.default:
1784ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                seen_non_default_actions.add(action)
1785ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                for conflict_action in action_conflicts.get(action, []):
1786ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    if conflict_action in seen_non_default_actions:
1787ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        msg = _('not allowed with argument %s')
1788ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        action_name = _get_action_name(conflict_action)
1789ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        raise ArgumentError(action, msg % action_name)
1790ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1791ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # take the action if we didn't receive a SUPPRESS value
1792ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # (e.g. from a default)
1793ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if argument_values is not SUPPRESS:
1794ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                action(self, namespace, argument_values, option_string)
1795ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1796ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # function to convert arg_strings into an optional action
1797ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        def consume_optional(start_index):
1798ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1799ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # get the optional identified at this index
1800ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            option_tuple = option_string_indices[start_index]
1801ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            action, option_string, explicit_arg = option_tuple
1802ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1803ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # identify additional optionals in the same arg string
1804ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # (e.g. -xyz is the same as -x -y -z if no args are required)
1805ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            match_argument = self._match_argument
1806ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            action_tuples = []
1807ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            while True:
1808ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1809ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # if we found no optional action, skip it
1810ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if action is None:
1811ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    extras.append(arg_strings[start_index])
1812ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    return start_index + 1
1813ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1814ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # if there is an explicit argument, try to match the
1815ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # optional's string arguments to only this
1816ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if explicit_arg is not None:
1817ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    arg_count = match_argument(action, 'A')
1818ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1819ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    # if the action is a single-dash option and takes no
1820ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    # arguments, try to parse more single-dash options out
1821ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    # of the tail of the option string
1822ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    chars = self.prefix_chars
1823ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    if arg_count == 0 and option_string[1] not in chars:
1824ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        action_tuples.append((action, [], option_string))
1825ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        char = option_string[0]
1826ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        option_string = char + explicit_arg[0]
1827ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        new_explicit_arg = explicit_arg[1:] or None
1828ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        optionals_map = self._option_string_actions
1829ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        if option_string in optionals_map:
1830ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                            action = optionals_map[option_string]
1831ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                            explicit_arg = new_explicit_arg
1832ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        else:
1833ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                            msg = _('ignored explicit argument %r')
1834ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                            raise ArgumentError(action, msg % explicit_arg)
1835ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1836ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    # if the action expect exactly one argument, we've
1837ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    # successfully matched the option; exit the loop
1838ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    elif arg_count == 1:
1839ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        stop = start_index + 1
1840ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        args = [explicit_arg]
1841ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        action_tuples.append((action, args, option_string))
1842ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        break
1843ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1844ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    # error if a double-dash option did not use the
1845ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    # explicit argument
1846ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    else:
1847ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        msg = _('ignored explicit argument %r')
1848ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        raise ArgumentError(action, msg % explicit_arg)
1849ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1850ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # if there is no explicit argument, try to match the
1851ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # optional's string arguments with the following strings
1852ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # if successful, exit the loop
1853ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                else:
1854ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    start = start_index + 1
1855ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    selected_patterns = arg_strings_pattern[start:]
1856ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    arg_count = match_argument(action, selected_patterns)
1857ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    stop = start + arg_count
1858ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    args = arg_strings[start:stop]
1859ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    action_tuples.append((action, args, option_string))
1860ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    break
1861ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1862ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # add the Optional to the list and return the index at which
1863ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # the Optional's string args stopped
1864ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            assert action_tuples
1865ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            for action, args, option_string in action_tuples:
1866ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                take_action(action, args, option_string)
1867ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            return stop
1868ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1869ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # the list of Positionals left to be parsed; this is modified
1870ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # by consume_positionals()
1871ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        positionals = self._get_positional_actions()
1872ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1873ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # function to convert arg_strings into positional actions
1874ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        def consume_positionals(start_index):
1875ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # match as many Positionals as possible
1876ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            match_partial = self._match_arguments_partial
1877ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            selected_pattern = arg_strings_pattern[start_index:]
1878ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            arg_counts = match_partial(positionals, selected_pattern)
1879ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1880ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # slice off the appropriate arg strings for each Positional
1881ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # and add the Positional and its args to the list
1882ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            for action, arg_count in zip(positionals, arg_counts):
1883ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                args = arg_strings[start_index: start_index + arg_count]
1884ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                start_index += arg_count
1885ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                take_action(action, args)
1886ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1887ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # slice off the Positionals that we just parsed and return the
1888ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # index at which the Positionals' string args stopped
1889ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            positionals[:] = positionals[len(arg_counts):]
1890ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            return start_index
1891ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1892ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # consume Positionals and Optionals alternately, until we have
1893ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # passed the last option string
1894ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        extras = []
1895ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        start_index = 0
1896ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if option_string_indices:
1897ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            max_option_string_index = max(option_string_indices)
1898ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        else:
1899ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            max_option_string_index = -1
1900ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        while start_index <= max_option_string_index:
1901ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1902ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # consume any Positionals preceding the next option
1903ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            next_option_string_index = min([
1904ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                index
1905ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                for index in option_string_indices
1906ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if index >= start_index])
1907ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if start_index != next_option_string_index:
1908ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                positionals_end_index = consume_positionals(start_index)
1909ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1910ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # only try to parse the next optional if we didn't consume
1911ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # the option string during the positionals parsing
1912ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if positionals_end_index > start_index:
1913ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    start_index = positionals_end_index
1914ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    continue
1915ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                else:
1916ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    start_index = positionals_end_index
1917ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1918ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # if we consumed all the positionals we could and we're not
1919ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # at the index of an option string, there were extra arguments
1920ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if start_index not in option_string_indices:
1921ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                strings = arg_strings[start_index:next_option_string_index]
1922ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                extras.extend(strings)
1923ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                start_index = next_option_string_index
1924ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1925ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # consume the next optional and any arguments for it
1926ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            start_index = consume_optional(start_index)
1927ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1928ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # consume any positionals following the last Optional
1929ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        stop_index = consume_positionals(start_index)
1930ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1931ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if we didn't consume all the argument strings, there were extras
1932ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        extras.extend(arg_strings[stop_index:])
1933ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1934ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if we didn't use all the Positional objects, there were too few
1935ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # arg strings supplied.
1936ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if positionals:
1937ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self.error(_('too few arguments'))
1938ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1939ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # make sure all required actions were present, and convert defaults.
1940ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for action in self._actions:
1941ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if action not in seen_actions:
1942ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if action.required:
1943ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    name = _get_action_name(action)
1944ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    self.error(_('argument %s is required') % name)
1945ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                else:
1946ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    # Convert action default now instead of doing it before
1947ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    # parsing arguments to avoid calling convert functions
1948ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    # twice (which may fail) if the argument was given, but
1949ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    # only if it was defined already in the namespace
1950ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    if (action.default is not None and
1951ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                            isinstance(action.default, basestring) and
1952ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                            hasattr(namespace, action.dest) and
1953ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                            action.default is getattr(namespace, action.dest)):
1954ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        setattr(namespace, action.dest,
1955ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                                self._get_value(action, action.default))
1956ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1957ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # make sure all required groups had one option present
1958ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for group in self._mutually_exclusive_groups:
1959ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if group.required:
1960ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                for action in group._group_actions:
1961ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    if action in seen_non_default_actions:
1962ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        break
1963ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1964ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # if no actions were used, report the error
1965ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                else:
1966ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    names = [_get_action_name(action)
1967ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                             for action in group._group_actions
1968ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                             if action.help is not SUPPRESS]
1969ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    msg = _('one of the arguments %s is required')
1970ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    self.error(msg % ' '.join(names))
1971ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1972ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # return the updated namespace and the extra arguments
1973ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return namespace, extras
1974ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1975ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _read_args_from_files(self, arg_strings):
1976ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # expand arguments referencing files
1977ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        new_arg_strings = []
1978ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for arg_string in arg_strings:
1979ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1980ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # for regular arguments, just add them back into the list
1981ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if not arg_string or arg_string[0] not in self.fromfile_prefix_chars:
1982ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                new_arg_strings.append(arg_string)
1983ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
1984ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            # replace arguments referencing files with the file content
1985ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            else:
1986ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                try:
1987ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    args_file = open(arg_string[1:])
1988ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    try:
1989ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        arg_strings = []
1990ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        for arg_line in args_file.read().splitlines():
1991ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                            for arg in self.convert_arg_line_to_args(arg_line):
1992ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                                arg_strings.append(arg)
1993ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        arg_strings = self._read_args_from_files(arg_strings)
1994ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        new_arg_strings.extend(arg_strings)
1995ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    finally:
1996ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        args_file.close()
1997ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                except IOError:
1998ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    err = _sys.exc_info()[1]
1999ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    self.error(str(err))
2000ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2001ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # return the modified argument list
2002ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return new_arg_strings
2003ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2004ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def convert_arg_line_to_args(self, arg_line):
2005ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return [arg_line]
2006ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2007ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _match_argument(self, action, arg_strings_pattern):
2008ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # match the pattern for this action to the arg strings
2009ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        nargs_pattern = self._get_nargs_pattern(action)
2010ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        match = _re.match(nargs_pattern, arg_strings_pattern)
2011ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2012ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # raise an exception if we weren't able to find a match
2013ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if match is None:
2014ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            nargs_errors = {
2015ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                None: _('expected one argument'),
2016ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                OPTIONAL: _('expected at most one argument'),
2017ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                ONE_OR_MORE: _('expected at least one argument'),
2018ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            }
2019ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            default = _('expected %s argument(s)') % action.nargs
2020ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            msg = nargs_errors.get(action.nargs, default)
2021ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            raise ArgumentError(action, msg)
2022ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2023ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # return the number of arguments matched
2024ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return len(match.group(1))
2025ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2026ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _match_arguments_partial(self, actions, arg_strings_pattern):
2027ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # progressively shorten the actions list by slicing off the
2028ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # final actions until we find a match
2029ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        result = []
2030ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for i in range(len(actions), 0, -1):
2031ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            actions_slice = actions[:i]
2032ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            pattern = ''.join([self._get_nargs_pattern(action)
2033ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                               for action in actions_slice])
2034ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            match = _re.match(pattern, arg_strings_pattern)
2035ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if match is not None:
2036ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                result.extend([len(string) for string in match.groups()])
2037ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                break
2038ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2039ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # return the list of arg string counts
2040ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return result
2041ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2042ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _parse_optional(self, arg_string):
2043ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if it's an empty string, it was meant to be a positional
2044ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if not arg_string:
2045ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            return None
2046ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2047ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if it doesn't start with a prefix, it was meant to be positional
2048ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if not arg_string[0] in self.prefix_chars:
2049ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            return None
2050ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2051ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if the option string is present in the parser, return the action
2052ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if arg_string in self._option_string_actions:
2053ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            action = self._option_string_actions[arg_string]
2054ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            return action, arg_string, None
2055ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2056ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if it's just a single character, it was meant to be positional
2057ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if len(arg_string) == 1:
2058ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            return None
2059ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2060ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if the option string before the "=" is present, return the action
2061ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if '=' in arg_string:
2062ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            option_string, explicit_arg = arg_string.split('=', 1)
2063ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if option_string in self._option_string_actions:
2064ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                action = self._option_string_actions[option_string]
2065ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                return action, option_string, explicit_arg
2066ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2067ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # search through all possible prefixes of the option string
2068ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # and all actions in the parser for possible interpretations
2069ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        option_tuples = self._get_option_tuples(arg_string)
2070ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2071ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if multiple actions match, the option string was ambiguous
2072ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if len(option_tuples) > 1:
2073ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            options = ', '.join([option_string
2074ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                for action, option_string, explicit_arg in option_tuples])
2075ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            tup = arg_string, options
2076ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self.error(_('ambiguous option: %s could match %s') % tup)
2077ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2078ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if exactly one action matched, this segmentation is good,
2079ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # so return the parsed action
2080ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif len(option_tuples) == 1:
2081ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            option_tuple, = option_tuples
2082ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            return option_tuple
2083ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2084ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if it was not found as an option, but it looks like a negative
2085ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # number, it was meant to be positional
2086ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # unless there are negative-number-like options
2087ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if self._negative_number_matcher.match(arg_string):
2088ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if not self._has_negative_number_optionals:
2089ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                return None
2090ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2091ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if it contains a space, it was meant to be a positional
2092ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if ' ' in arg_string:
2093ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            return None
2094ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2095ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # it was meant to be an optional but there is no such option
2096ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # in this parser (though it might be a valid option in a subparser)
2097ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return None, arg_string, None
2098ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2099ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _get_option_tuples(self, option_string):
2100ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        result = []
2101ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2102ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # option strings starting with two prefix characters are only
2103ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # split at the '='
2104ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        chars = self.prefix_chars
2105ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if option_string[0] in chars and option_string[1] in chars:
2106ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if '=' in option_string:
2107ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                option_prefix, explicit_arg = option_string.split('=', 1)
2108ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            else:
2109ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                option_prefix = option_string
2110ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                explicit_arg = None
2111ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            for option_string in self._option_string_actions:
2112ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if option_string.startswith(option_prefix):
2113ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    action = self._option_string_actions[option_string]
2114ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    tup = action, option_string, explicit_arg
2115ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    result.append(tup)
2116ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2117ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # single character options can be concatenated with their arguments
2118ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # but multiple character options always have to have their argument
2119ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # separate
2120ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif option_string[0] in chars and option_string[1] not in chars:
2121ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            option_prefix = option_string
2122ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            explicit_arg = None
2123ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            short_option_prefix = option_string[:2]
2124ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            short_explicit_arg = option_string[2:]
2125ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2126ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            for option_string in self._option_string_actions:
2127ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                if option_string == short_option_prefix:
2128ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    action = self._option_string_actions[option_string]
2129ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    tup = action, option_string, short_explicit_arg
2130ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    result.append(tup)
2131ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                elif option_string.startswith(option_prefix):
2132ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    action = self._option_string_actions[option_string]
2133ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    tup = action, option_string, explicit_arg
2134ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                    result.append(tup)
2135ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2136ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # shouldn't ever get here
2137ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        else:
2138ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self.error(_('unexpected option string: %s') % option_string)
2139ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2140ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # return the collected option tuples
2141ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return result
2142ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2143ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _get_nargs_pattern(self, action):
2144ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # in all examples below, we have to allow for '--' args
2145ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # which are represented as '-' in the pattern
2146ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        nargs = action.nargs
2147ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2148ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # the default (None) is assumed to be a single argument
2149ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if nargs is None:
2150ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            nargs_pattern = '(-*A-*)'
2151ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2152ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # allow zero or one arguments
2153ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif nargs == OPTIONAL:
2154ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            nargs_pattern = '(-*A?-*)'
2155ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2156ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # allow zero or more arguments
2157ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif nargs == ZERO_OR_MORE:
2158ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            nargs_pattern = '(-*[A-]*)'
2159ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2160ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # allow one or more arguments
2161ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif nargs == ONE_OR_MORE:
2162ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            nargs_pattern = '(-*A[A-]*)'
2163ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2164ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # allow any number of options or arguments
2165ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif nargs == REMAINDER:
2166ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            nargs_pattern = '([-AO]*)'
2167ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2168ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # allow one argument followed by any number of options or arguments
2169ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif nargs == PARSER:
2170ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            nargs_pattern = '(-*A[-AO]*)'
2171ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2172ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # all others should be integers
2173ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        else:
2174ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)
2175ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2176ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # if this is an optional action, -- is not allowed
2177ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if action.option_strings:
2178ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            nargs_pattern = nargs_pattern.replace('-*', '')
2179ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            nargs_pattern = nargs_pattern.replace('-', '')
2180ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2181ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # return the pattern
2182ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return nargs_pattern
2183ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2184ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # ========================
2185ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # Value conversion methods
2186ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # ========================
2187ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _get_values(self, action, arg_strings):
2188ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # for everything but PARSER, REMAINDER args, strip out first '--'
2189ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if action.nargs not in [PARSER, REMAINDER]:
2190ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            try:
2191ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                arg_strings.remove('--')
2192ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            except ValueError:
2193ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                pass
2194ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2195ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # optional argument produces a default when not present
2196ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if not arg_strings and action.nargs == OPTIONAL:
2197ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if action.option_strings:
2198ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                value = action.const
2199ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            else:
2200ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                value = action.default
2201ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if isinstance(value, basestring):
2202ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                value = self._get_value(action, value)
2203ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                self._check_value(action, value)
2204ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2205ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # when nargs='*' on a positional, if there were no command-line
2206ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # args, use the default if it is anything other than None
2207ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif (not arg_strings and action.nargs == ZERO_OR_MORE and
2208ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot              not action.option_strings):
2209ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if action.default is not None:
2210ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                value = action.default
2211ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            else:
2212ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                value = arg_strings
2213ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self._check_value(action, value)
2214ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2215ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # single argument or optional argument produces a single value
2216ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]:
2217ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            arg_string, = arg_strings
2218ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            value = self._get_value(action, arg_string)
2219ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self._check_value(action, value)
2220ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2221ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # REMAINDER arguments convert all values, checking none
2222ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif action.nargs == REMAINDER:
2223ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            value = [self._get_value(action, v) for v in arg_strings]
2224ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2225ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # PARSER arguments convert all values, but check only the first
2226ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        elif action.nargs == PARSER:
2227ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            value = [self._get_value(action, v) for v in arg_strings]
2228ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self._check_value(action, value[0])
2229ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2230ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # all other types of nargs produce a list
2231ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        else:
2232ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            value = [self._get_value(action, v) for v in arg_strings]
2233ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            for v in value:
2234ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                self._check_value(action, v)
2235ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2236ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # return the converted value
2237ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return value
2238ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2239ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _get_value(self, action, arg_string):
2240ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        type_func = self._registry_get('type', action.type, action.type)
2241ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if not _callable(type_func):
2242ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            msg = _('%r is not callable')
2243ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            raise ArgumentError(action, msg % type_func)
2244ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2245ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # convert the value to the appropriate type
2246ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        try:
2247ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            result = type_func(arg_string)
2248ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2249ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # ArgumentTypeErrors indicate errors
2250ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        except ArgumentTypeError:
2251ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            name = getattr(action.type, '__name__', repr(action.type))
2252ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            msg = str(_sys.exc_info()[1])
2253ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            raise ArgumentError(action, msg)
2254ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2255ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # TypeErrors or ValueErrors also indicate errors
2256ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        except (TypeError, ValueError):
2257ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            name = getattr(action.type, '__name__', repr(action.type))
2258ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            msg = _('invalid %s value: %r')
2259ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            raise ArgumentError(action, msg % (name, arg_string))
2260ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2261ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # return the converted value
2262ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return result
2263ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2264ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _check_value(self, action, value):
2265ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # converted value must be one of the choices (if specified)
2266ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if action.choices is not None and value not in action.choices:
2267ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            tup = value, ', '.join(map(repr, action.choices))
2268ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            msg = _('invalid choice: %r (choose from %s)') % tup
2269ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            raise ArgumentError(action, msg)
2270ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2271ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # =======================
2272ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # Help-formatting methods
2273ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # =======================
2274ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def format_usage(self):
2275ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        formatter = self._get_formatter()
2276ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        formatter.add_usage(self.usage, self._actions,
2277ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                            self._mutually_exclusive_groups)
2278ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return formatter.format_help()
2279ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2280ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def format_help(self):
2281ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        formatter = self._get_formatter()
2282ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2283ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # usage
2284ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        formatter.add_usage(self.usage, self._actions,
2285ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                            self._mutually_exclusive_groups)
2286ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2287ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # description
2288ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        formatter.add_text(self.description)
2289ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2290ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # positionals, optionals and user-defined groups
2291ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for action_group in self._action_groups:
2292ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            formatter.start_section(action_group.title)
2293ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            formatter.add_text(action_group.description)
2294ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            formatter.add_arguments(action_group._group_actions)
2295ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            formatter.end_section()
2296ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2297ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # epilog
2298ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        formatter.add_text(self.epilog)
2299ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2300ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        # determine help from format above
2301ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return formatter.format_help()
2302ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2303ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def format_version(self):
2304ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        import warnings
2305ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        warnings.warn(
2306ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'The format_version method is deprecated -- the "version" '
2307ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'argument to ArgumentParser is no longer supported.',
2308ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            DeprecationWarning)
2309ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        formatter = self._get_formatter()
2310ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        formatter.add_text(self.version)
2311ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return formatter.format_help()
2312ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2313ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _get_formatter(self):
2314ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return self.formatter_class(prog=self.prog)
2315ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2316ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # =====================
2317ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # Help-printing methods
2318ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # =====================
2319ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def print_usage(self, file=None):
2320ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if file is None:
2321ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            file = _sys.stdout
2322ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._print_message(self.format_usage(), file)
2323ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2324ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def print_help(self, file=None):
2325ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if file is None:
2326ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            file = _sys.stdout
2327ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._print_message(self.format_help(), file)
2328ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2329ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def print_version(self, file=None):
2330ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        import warnings
2331ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        warnings.warn(
2332ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'The print_version method is deprecated -- the "version" '
2333ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            'argument to ArgumentParser is no longer supported.',
2334ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            DeprecationWarning)
2335ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self._print_message(self.format_version(), file)
2336ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2337ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def _print_message(self, message, file=None):
2338ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if message:
2339ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if file is None:
2340ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                file = _sys.stderr
2341ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            file.write(message)
2342ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2343ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # ===============
2344ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # Exiting methods
2345ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    # ===============
2346ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def exit(self, status=0, message=None):
2347ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if message:
2348ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self._print_message(message, _sys.stderr)
2349ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        _sys.exit(status)
2350ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2351ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def error(self, message):
2352ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        """error(message: string)
2353ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2354ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        Prints a usage message incorporating the message to stderr and
2355ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        exits.
2356ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
2357ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        If you override this in a subclass, it should not return -- it
2358ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        should either exit or raise an exception.
2359ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        """
2360ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.print_usage(_sys.stderr)
2361ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.exit(2, _('%s: error: %s\n') % (self.prog, message))
2362