xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/optparse.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Worker"""A powerful, extensible, and easy-to-use option parser.
2*cda5da8dSAndroid Build Coastguard Worker
3*cda5da8dSAndroid Build Coastguard WorkerBy Greg Ward <[email protected]>
4*cda5da8dSAndroid Build Coastguard Worker
5*cda5da8dSAndroid Build Coastguard WorkerOriginally distributed as Optik.
6*cda5da8dSAndroid Build Coastguard Worker
7*cda5da8dSAndroid Build Coastguard WorkerFor support, use the [email protected] mailing list
8*cda5da8dSAndroid Build Coastguard Worker(http://lists.sourceforge.net/lists/listinfo/optik-users).
9*cda5da8dSAndroid Build Coastguard Worker
10*cda5da8dSAndroid Build Coastguard WorkerSimple usage example:
11*cda5da8dSAndroid Build Coastguard Worker
12*cda5da8dSAndroid Build Coastguard Worker   from optparse import OptionParser
13*cda5da8dSAndroid Build Coastguard Worker
14*cda5da8dSAndroid Build Coastguard Worker   parser = OptionParser()
15*cda5da8dSAndroid Build Coastguard Worker   parser.add_option("-f", "--file", dest="filename",
16*cda5da8dSAndroid Build Coastguard Worker                     help="write report to FILE", metavar="FILE")
17*cda5da8dSAndroid Build Coastguard Worker   parser.add_option("-q", "--quiet",
18*cda5da8dSAndroid Build Coastguard Worker                     action="store_false", dest="verbose", default=True,
19*cda5da8dSAndroid Build Coastguard Worker                     help="don't print status messages to stdout")
20*cda5da8dSAndroid Build Coastguard Worker
21*cda5da8dSAndroid Build Coastguard Worker   (options, args) = parser.parse_args()
22*cda5da8dSAndroid Build Coastguard Worker"""
23*cda5da8dSAndroid Build Coastguard Worker
24*cda5da8dSAndroid Build Coastguard Worker__version__ = "1.5.3"
25*cda5da8dSAndroid Build Coastguard Worker
26*cda5da8dSAndroid Build Coastguard Worker__all__ = ['Option',
27*cda5da8dSAndroid Build Coastguard Worker           'make_option',
28*cda5da8dSAndroid Build Coastguard Worker           'SUPPRESS_HELP',
29*cda5da8dSAndroid Build Coastguard Worker           'SUPPRESS_USAGE',
30*cda5da8dSAndroid Build Coastguard Worker           'Values',
31*cda5da8dSAndroid Build Coastguard Worker           'OptionContainer',
32*cda5da8dSAndroid Build Coastguard Worker           'OptionGroup',
33*cda5da8dSAndroid Build Coastguard Worker           'OptionParser',
34*cda5da8dSAndroid Build Coastguard Worker           'HelpFormatter',
35*cda5da8dSAndroid Build Coastguard Worker           'IndentedHelpFormatter',
36*cda5da8dSAndroid Build Coastguard Worker           'TitledHelpFormatter',
37*cda5da8dSAndroid Build Coastguard Worker           'OptParseError',
38*cda5da8dSAndroid Build Coastguard Worker           'OptionError',
39*cda5da8dSAndroid Build Coastguard Worker           'OptionConflictError',
40*cda5da8dSAndroid Build Coastguard Worker           'OptionValueError',
41*cda5da8dSAndroid Build Coastguard Worker           'BadOptionError',
42*cda5da8dSAndroid Build Coastguard Worker           'check_choice']
43*cda5da8dSAndroid Build Coastguard Worker
44*cda5da8dSAndroid Build Coastguard Worker__copyright__ = """
45*cda5da8dSAndroid Build Coastguard WorkerCopyright (c) 2001-2006 Gregory P. Ward.  All rights reserved.
46*cda5da8dSAndroid Build Coastguard WorkerCopyright (c) 2002-2006 Python Software Foundation.  All rights reserved.
47*cda5da8dSAndroid Build Coastguard Worker
48*cda5da8dSAndroid Build Coastguard WorkerRedistribution and use in source and binary forms, with or without
49*cda5da8dSAndroid Build Coastguard Workermodification, are permitted provided that the following conditions are
50*cda5da8dSAndroid Build Coastguard Workermet:
51*cda5da8dSAndroid Build Coastguard Worker
52*cda5da8dSAndroid Build Coastguard Worker  * Redistributions of source code must retain the above copyright
53*cda5da8dSAndroid Build Coastguard Worker    notice, this list of conditions and the following disclaimer.
54*cda5da8dSAndroid Build Coastguard Worker
55*cda5da8dSAndroid Build Coastguard Worker  * Redistributions in binary form must reproduce the above copyright
56*cda5da8dSAndroid Build Coastguard Worker    notice, this list of conditions and the following disclaimer in the
57*cda5da8dSAndroid Build Coastguard Worker    documentation and/or other materials provided with the distribution.
58*cda5da8dSAndroid Build Coastguard Worker
59*cda5da8dSAndroid Build Coastguard Worker  * Neither the name of the author nor the names of its
60*cda5da8dSAndroid Build Coastguard Worker    contributors may be used to endorse or promote products derived from
61*cda5da8dSAndroid Build Coastguard Worker    this software without specific prior written permission.
62*cda5da8dSAndroid Build Coastguard Worker
63*cda5da8dSAndroid Build Coastguard WorkerTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
64*cda5da8dSAndroid Build Coastguard WorkerIS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
65*cda5da8dSAndroid Build Coastguard WorkerTO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
66*cda5da8dSAndroid Build Coastguard WorkerPARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
67*cda5da8dSAndroid Build Coastguard WorkerCONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
68*cda5da8dSAndroid Build Coastguard WorkerEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
69*cda5da8dSAndroid Build Coastguard WorkerPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
70*cda5da8dSAndroid Build Coastguard WorkerPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
71*cda5da8dSAndroid Build Coastguard WorkerLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
72*cda5da8dSAndroid Build Coastguard WorkerNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73*cda5da8dSAndroid Build Coastguard WorkerSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74*cda5da8dSAndroid Build Coastguard Worker"""
75*cda5da8dSAndroid Build Coastguard Worker
76*cda5da8dSAndroid Build Coastguard Workerimport sys, os
77*cda5da8dSAndroid Build Coastguard Workerimport textwrap
78*cda5da8dSAndroid Build Coastguard Worker
79*cda5da8dSAndroid Build Coastguard Workerdef _repr(self):
80*cda5da8dSAndroid Build Coastguard Worker    return "<%s at 0x%x: %s>" % (self.__class__.__name__, id(self), self)
81*cda5da8dSAndroid Build Coastguard Worker
82*cda5da8dSAndroid Build Coastguard Worker
83*cda5da8dSAndroid Build Coastguard Worker# This file was generated from:
84*cda5da8dSAndroid Build Coastguard Worker#   Id: option_parser.py 527 2006-07-23 15:21:30Z greg
85*cda5da8dSAndroid Build Coastguard Worker#   Id: option.py 522 2006-06-11 16:22:03Z gward
86*cda5da8dSAndroid Build Coastguard Worker#   Id: help.py 527 2006-07-23 15:21:30Z greg
87*cda5da8dSAndroid Build Coastguard Worker#   Id: errors.py 509 2006-04-20 00:58:24Z gward
88*cda5da8dSAndroid Build Coastguard Worker
89*cda5da8dSAndroid Build Coastguard Workertry:
90*cda5da8dSAndroid Build Coastguard Worker    from gettext import gettext, ngettext
91*cda5da8dSAndroid Build Coastguard Workerexcept ImportError:
92*cda5da8dSAndroid Build Coastguard Worker    def gettext(message):
93*cda5da8dSAndroid Build Coastguard Worker        return message
94*cda5da8dSAndroid Build Coastguard Worker
95*cda5da8dSAndroid Build Coastguard Worker    def ngettext(singular, plural, n):
96*cda5da8dSAndroid Build Coastguard Worker        if n == 1:
97*cda5da8dSAndroid Build Coastguard Worker            return singular
98*cda5da8dSAndroid Build Coastguard Worker        return plural
99*cda5da8dSAndroid Build Coastguard Worker
100*cda5da8dSAndroid Build Coastguard Worker_ = gettext
101*cda5da8dSAndroid Build Coastguard Worker
102*cda5da8dSAndroid Build Coastguard Worker
103*cda5da8dSAndroid Build Coastguard Workerclass OptParseError (Exception):
104*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, msg):
105*cda5da8dSAndroid Build Coastguard Worker        self.msg = msg
106*cda5da8dSAndroid Build Coastguard Worker
107*cda5da8dSAndroid Build Coastguard Worker    def __str__(self):
108*cda5da8dSAndroid Build Coastguard Worker        return self.msg
109*cda5da8dSAndroid Build Coastguard Worker
110*cda5da8dSAndroid Build Coastguard Worker
111*cda5da8dSAndroid Build Coastguard Workerclass OptionError (OptParseError):
112*cda5da8dSAndroid Build Coastguard Worker    """
113*cda5da8dSAndroid Build Coastguard Worker    Raised if an Option instance is created with invalid or
114*cda5da8dSAndroid Build Coastguard Worker    inconsistent arguments.
115*cda5da8dSAndroid Build Coastguard Worker    """
116*cda5da8dSAndroid Build Coastguard Worker
117*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, msg, option):
118*cda5da8dSAndroid Build Coastguard Worker        self.msg = msg
119*cda5da8dSAndroid Build Coastguard Worker        self.option_id = str(option)
120*cda5da8dSAndroid Build Coastguard Worker
121*cda5da8dSAndroid Build Coastguard Worker    def __str__(self):
122*cda5da8dSAndroid Build Coastguard Worker        if self.option_id:
123*cda5da8dSAndroid Build Coastguard Worker            return "option %s: %s" % (self.option_id, self.msg)
124*cda5da8dSAndroid Build Coastguard Worker        else:
125*cda5da8dSAndroid Build Coastguard Worker            return self.msg
126*cda5da8dSAndroid Build Coastguard Worker
127*cda5da8dSAndroid Build Coastguard Workerclass OptionConflictError (OptionError):
128*cda5da8dSAndroid Build Coastguard Worker    """
129*cda5da8dSAndroid Build Coastguard Worker    Raised if conflicting options are added to an OptionParser.
130*cda5da8dSAndroid Build Coastguard Worker    """
131*cda5da8dSAndroid Build Coastguard Worker
132*cda5da8dSAndroid Build Coastguard Workerclass OptionValueError (OptParseError):
133*cda5da8dSAndroid Build Coastguard Worker    """
134*cda5da8dSAndroid Build Coastguard Worker    Raised if an invalid option value is encountered on the command
135*cda5da8dSAndroid Build Coastguard Worker    line.
136*cda5da8dSAndroid Build Coastguard Worker    """
137*cda5da8dSAndroid Build Coastguard Worker
138*cda5da8dSAndroid Build Coastguard Workerclass BadOptionError (OptParseError):
139*cda5da8dSAndroid Build Coastguard Worker    """
140*cda5da8dSAndroid Build Coastguard Worker    Raised if an invalid option is seen on the command line.
141*cda5da8dSAndroid Build Coastguard Worker    """
142*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, opt_str):
143*cda5da8dSAndroid Build Coastguard Worker        self.opt_str = opt_str
144*cda5da8dSAndroid Build Coastguard Worker
145*cda5da8dSAndroid Build Coastguard Worker    def __str__(self):
146*cda5da8dSAndroid Build Coastguard Worker        return _("no such option: %s") % self.opt_str
147*cda5da8dSAndroid Build Coastguard Worker
148*cda5da8dSAndroid Build Coastguard Workerclass AmbiguousOptionError (BadOptionError):
149*cda5da8dSAndroid Build Coastguard Worker    """
150*cda5da8dSAndroid Build Coastguard Worker    Raised if an ambiguous option is seen on the command line.
151*cda5da8dSAndroid Build Coastguard Worker    """
152*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, opt_str, possibilities):
153*cda5da8dSAndroid Build Coastguard Worker        BadOptionError.__init__(self, opt_str)
154*cda5da8dSAndroid Build Coastguard Worker        self.possibilities = possibilities
155*cda5da8dSAndroid Build Coastguard Worker
156*cda5da8dSAndroid Build Coastguard Worker    def __str__(self):
157*cda5da8dSAndroid Build Coastguard Worker        return (_("ambiguous option: %s (%s?)")
158*cda5da8dSAndroid Build Coastguard Worker                % (self.opt_str, ", ".join(self.possibilities)))
159*cda5da8dSAndroid Build Coastguard Worker
160*cda5da8dSAndroid Build Coastguard Worker
161*cda5da8dSAndroid Build Coastguard Workerclass HelpFormatter:
162*cda5da8dSAndroid Build Coastguard Worker
163*cda5da8dSAndroid Build Coastguard Worker    """
164*cda5da8dSAndroid Build Coastguard Worker    Abstract base class for formatting option help.  OptionParser
165*cda5da8dSAndroid Build Coastguard Worker    instances should use one of the HelpFormatter subclasses for
166*cda5da8dSAndroid Build Coastguard Worker    formatting help; by default IndentedHelpFormatter is used.
167*cda5da8dSAndroid Build Coastguard Worker
168*cda5da8dSAndroid Build Coastguard Worker    Instance attributes:
169*cda5da8dSAndroid Build Coastguard Worker      parser : OptionParser
170*cda5da8dSAndroid Build Coastguard Worker        the controlling OptionParser instance
171*cda5da8dSAndroid Build Coastguard Worker      indent_increment : int
172*cda5da8dSAndroid Build Coastguard Worker        the number of columns to indent per nesting level
173*cda5da8dSAndroid Build Coastguard Worker      max_help_position : int
174*cda5da8dSAndroid Build Coastguard Worker        the maximum starting column for option help text
175*cda5da8dSAndroid Build Coastguard Worker      help_position : int
176*cda5da8dSAndroid Build Coastguard Worker        the calculated starting column for option help text;
177*cda5da8dSAndroid Build Coastguard Worker        initially the same as the maximum
178*cda5da8dSAndroid Build Coastguard Worker      width : int
179*cda5da8dSAndroid Build Coastguard Worker        total number of columns for output (pass None to constructor for
180*cda5da8dSAndroid Build Coastguard Worker        this value to be taken from the $COLUMNS environment variable)
181*cda5da8dSAndroid Build Coastguard Worker      level : int
182*cda5da8dSAndroid Build Coastguard Worker        current indentation level
183*cda5da8dSAndroid Build Coastguard Worker      current_indent : int
184*cda5da8dSAndroid Build Coastguard Worker        current indentation level (in columns)
185*cda5da8dSAndroid Build Coastguard Worker      help_width : int
186*cda5da8dSAndroid Build Coastguard Worker        number of columns available for option help text (calculated)
187*cda5da8dSAndroid Build Coastguard Worker      default_tag : str
188*cda5da8dSAndroid Build Coastguard Worker        text to replace with each option's default value, "%default"
189*cda5da8dSAndroid Build Coastguard Worker        by default.  Set to false value to disable default value expansion.
190*cda5da8dSAndroid Build Coastguard Worker      option_strings : { Option : str }
191*cda5da8dSAndroid Build Coastguard Worker        maps Option instances to the snippet of help text explaining
192*cda5da8dSAndroid Build Coastguard Worker        the syntax of that option, e.g. "-h, --help" or
193*cda5da8dSAndroid Build Coastguard Worker        "-fFILE, --file=FILE"
194*cda5da8dSAndroid Build Coastguard Worker      _short_opt_fmt : str
195*cda5da8dSAndroid Build Coastguard Worker        format string controlling how short options with values are
196*cda5da8dSAndroid Build Coastguard Worker        printed in help text.  Must be either "%s%s" ("-fFILE") or
197*cda5da8dSAndroid Build Coastguard Worker        "%s %s" ("-f FILE"), because those are the two syntaxes that
198*cda5da8dSAndroid Build Coastguard Worker        Optik supports.
199*cda5da8dSAndroid Build Coastguard Worker      _long_opt_fmt : str
200*cda5da8dSAndroid Build Coastguard Worker        similar but for long options; must be either "%s %s" ("--file FILE")
201*cda5da8dSAndroid Build Coastguard Worker        or "%s=%s" ("--file=FILE").
202*cda5da8dSAndroid Build Coastguard Worker    """
203*cda5da8dSAndroid Build Coastguard Worker
204*cda5da8dSAndroid Build Coastguard Worker    NO_DEFAULT_VALUE = "none"
205*cda5da8dSAndroid Build Coastguard Worker
206*cda5da8dSAndroid Build Coastguard Worker    def __init__(self,
207*cda5da8dSAndroid Build Coastguard Worker                 indent_increment,
208*cda5da8dSAndroid Build Coastguard Worker                 max_help_position,
209*cda5da8dSAndroid Build Coastguard Worker                 width,
210*cda5da8dSAndroid Build Coastguard Worker                 short_first):
211*cda5da8dSAndroid Build Coastguard Worker        self.parser = None
212*cda5da8dSAndroid Build Coastguard Worker        self.indent_increment = indent_increment
213*cda5da8dSAndroid Build Coastguard Worker        if width is None:
214*cda5da8dSAndroid Build Coastguard Worker            try:
215*cda5da8dSAndroid Build Coastguard Worker                width = int(os.environ['COLUMNS'])
216*cda5da8dSAndroid Build Coastguard Worker            except (KeyError, ValueError):
217*cda5da8dSAndroid Build Coastguard Worker                width = 80
218*cda5da8dSAndroid Build Coastguard Worker            width -= 2
219*cda5da8dSAndroid Build Coastguard Worker        self.width = width
220*cda5da8dSAndroid Build Coastguard Worker        self.help_position = self.max_help_position = \
221*cda5da8dSAndroid Build Coastguard Worker                min(max_help_position, max(width - 20, indent_increment * 2))
222*cda5da8dSAndroid Build Coastguard Worker        self.current_indent = 0
223*cda5da8dSAndroid Build Coastguard Worker        self.level = 0
224*cda5da8dSAndroid Build Coastguard Worker        self.help_width = None          # computed later
225*cda5da8dSAndroid Build Coastguard Worker        self.short_first = short_first
226*cda5da8dSAndroid Build Coastguard Worker        self.default_tag = "%default"
227*cda5da8dSAndroid Build Coastguard Worker        self.option_strings = {}
228*cda5da8dSAndroid Build Coastguard Worker        self._short_opt_fmt = "%s %s"
229*cda5da8dSAndroid Build Coastguard Worker        self._long_opt_fmt = "%s=%s"
230*cda5da8dSAndroid Build Coastguard Worker
231*cda5da8dSAndroid Build Coastguard Worker    def set_parser(self, parser):
232*cda5da8dSAndroid Build Coastguard Worker        self.parser = parser
233*cda5da8dSAndroid Build Coastguard Worker
234*cda5da8dSAndroid Build Coastguard Worker    def set_short_opt_delimiter(self, delim):
235*cda5da8dSAndroid Build Coastguard Worker        if delim not in ("", " "):
236*cda5da8dSAndroid Build Coastguard Worker            raise ValueError(
237*cda5da8dSAndroid Build Coastguard Worker                "invalid metavar delimiter for short options: %r" % delim)
238*cda5da8dSAndroid Build Coastguard Worker        self._short_opt_fmt = "%s" + delim + "%s"
239*cda5da8dSAndroid Build Coastguard Worker
240*cda5da8dSAndroid Build Coastguard Worker    def set_long_opt_delimiter(self, delim):
241*cda5da8dSAndroid Build Coastguard Worker        if delim not in ("=", " "):
242*cda5da8dSAndroid Build Coastguard Worker            raise ValueError(
243*cda5da8dSAndroid Build Coastguard Worker                "invalid metavar delimiter for long options: %r" % delim)
244*cda5da8dSAndroid Build Coastguard Worker        self._long_opt_fmt = "%s" + delim + "%s"
245*cda5da8dSAndroid Build Coastguard Worker
246*cda5da8dSAndroid Build Coastguard Worker    def indent(self):
247*cda5da8dSAndroid Build Coastguard Worker        self.current_indent += self.indent_increment
248*cda5da8dSAndroid Build Coastguard Worker        self.level += 1
249*cda5da8dSAndroid Build Coastguard Worker
250*cda5da8dSAndroid Build Coastguard Worker    def dedent(self):
251*cda5da8dSAndroid Build Coastguard Worker        self.current_indent -= self.indent_increment
252*cda5da8dSAndroid Build Coastguard Worker        assert self.current_indent >= 0, "Indent decreased below 0."
253*cda5da8dSAndroid Build Coastguard Worker        self.level -= 1
254*cda5da8dSAndroid Build Coastguard Worker
255*cda5da8dSAndroid Build Coastguard Worker    def format_usage(self, usage):
256*cda5da8dSAndroid Build Coastguard Worker        raise NotImplementedError("subclasses must implement")
257*cda5da8dSAndroid Build Coastguard Worker
258*cda5da8dSAndroid Build Coastguard Worker    def format_heading(self, heading):
259*cda5da8dSAndroid Build Coastguard Worker        raise NotImplementedError("subclasses must implement")
260*cda5da8dSAndroid Build Coastguard Worker
261*cda5da8dSAndroid Build Coastguard Worker    def _format_text(self, text):
262*cda5da8dSAndroid Build Coastguard Worker        """
263*cda5da8dSAndroid Build Coastguard Worker        Format a paragraph of free-form text for inclusion in the
264*cda5da8dSAndroid Build Coastguard Worker        help output at the current indentation level.
265*cda5da8dSAndroid Build Coastguard Worker        """
266*cda5da8dSAndroid Build Coastguard Worker        text_width = max(self.width - self.current_indent, 11)
267*cda5da8dSAndroid Build Coastguard Worker        indent = " "*self.current_indent
268*cda5da8dSAndroid Build Coastguard Worker        return textwrap.fill(text,
269*cda5da8dSAndroid Build Coastguard Worker                             text_width,
270*cda5da8dSAndroid Build Coastguard Worker                             initial_indent=indent,
271*cda5da8dSAndroid Build Coastguard Worker                             subsequent_indent=indent)
272*cda5da8dSAndroid Build Coastguard Worker
273*cda5da8dSAndroid Build Coastguard Worker    def format_description(self, description):
274*cda5da8dSAndroid Build Coastguard Worker        if description:
275*cda5da8dSAndroid Build Coastguard Worker            return self._format_text(description) + "\n"
276*cda5da8dSAndroid Build Coastguard Worker        else:
277*cda5da8dSAndroid Build Coastguard Worker            return ""
278*cda5da8dSAndroid Build Coastguard Worker
279*cda5da8dSAndroid Build Coastguard Worker    def format_epilog(self, epilog):
280*cda5da8dSAndroid Build Coastguard Worker        if epilog:
281*cda5da8dSAndroid Build Coastguard Worker            return "\n" + self._format_text(epilog) + "\n"
282*cda5da8dSAndroid Build Coastguard Worker        else:
283*cda5da8dSAndroid Build Coastguard Worker            return ""
284*cda5da8dSAndroid Build Coastguard Worker
285*cda5da8dSAndroid Build Coastguard Worker
286*cda5da8dSAndroid Build Coastguard Worker    def expand_default(self, option):
287*cda5da8dSAndroid Build Coastguard Worker        if self.parser is None or not self.default_tag:
288*cda5da8dSAndroid Build Coastguard Worker            return option.help
289*cda5da8dSAndroid Build Coastguard Worker
290*cda5da8dSAndroid Build Coastguard Worker        default_value = self.parser.defaults.get(option.dest)
291*cda5da8dSAndroid Build Coastguard Worker        if default_value is NO_DEFAULT or default_value is None:
292*cda5da8dSAndroid Build Coastguard Worker            default_value = self.NO_DEFAULT_VALUE
293*cda5da8dSAndroid Build Coastguard Worker
294*cda5da8dSAndroid Build Coastguard Worker        return option.help.replace(self.default_tag, str(default_value))
295*cda5da8dSAndroid Build Coastguard Worker
296*cda5da8dSAndroid Build Coastguard Worker    def format_option(self, option):
297*cda5da8dSAndroid Build Coastguard Worker        # The help for each option consists of two parts:
298*cda5da8dSAndroid Build Coastguard Worker        #   * the opt strings and metavars
299*cda5da8dSAndroid Build Coastguard Worker        #     eg. ("-x", or "-fFILENAME, --file=FILENAME")
300*cda5da8dSAndroid Build Coastguard Worker        #   * the user-supplied help string
301*cda5da8dSAndroid Build Coastguard Worker        #     eg. ("turn on expert mode", "read data from FILENAME")
302*cda5da8dSAndroid Build Coastguard Worker        #
303*cda5da8dSAndroid Build Coastguard Worker        # If possible, we write both of these on the same line:
304*cda5da8dSAndroid Build Coastguard Worker        #   -x      turn on expert mode
305*cda5da8dSAndroid Build Coastguard Worker        #
306*cda5da8dSAndroid Build Coastguard Worker        # But if the opt string list is too long, we put the help
307*cda5da8dSAndroid Build Coastguard Worker        # string on a second line, indented to the same column it would
308*cda5da8dSAndroid Build Coastguard Worker        # start in if it fit on the first line.
309*cda5da8dSAndroid Build Coastguard Worker        #   -fFILENAME, --file=FILENAME
310*cda5da8dSAndroid Build Coastguard Worker        #           read data from FILENAME
311*cda5da8dSAndroid Build Coastguard Worker        result = []
312*cda5da8dSAndroid Build Coastguard Worker        opts = self.option_strings[option]
313*cda5da8dSAndroid Build Coastguard Worker        opt_width = self.help_position - self.current_indent - 2
314*cda5da8dSAndroid Build Coastguard Worker        if len(opts) > opt_width:
315*cda5da8dSAndroid Build Coastguard Worker            opts = "%*s%s\n" % (self.current_indent, "", opts)
316*cda5da8dSAndroid Build Coastguard Worker            indent_first = self.help_position
317*cda5da8dSAndroid Build Coastguard Worker        else:                       # start help on same line as opts
318*cda5da8dSAndroid Build Coastguard Worker            opts = "%*s%-*s  " % (self.current_indent, "", opt_width, opts)
319*cda5da8dSAndroid Build Coastguard Worker            indent_first = 0
320*cda5da8dSAndroid Build Coastguard Worker        result.append(opts)
321*cda5da8dSAndroid Build Coastguard Worker        if option.help:
322*cda5da8dSAndroid Build Coastguard Worker            help_text = self.expand_default(option)
323*cda5da8dSAndroid Build Coastguard Worker            help_lines = textwrap.wrap(help_text, self.help_width)
324*cda5da8dSAndroid Build Coastguard Worker            result.append("%*s%s\n" % (indent_first, "", help_lines[0]))
325*cda5da8dSAndroid Build Coastguard Worker            result.extend(["%*s%s\n" % (self.help_position, "", line)
326*cda5da8dSAndroid Build Coastguard Worker                           for line in help_lines[1:]])
327*cda5da8dSAndroid Build Coastguard Worker        elif opts[-1] != "\n":
328*cda5da8dSAndroid Build Coastguard Worker            result.append("\n")
329*cda5da8dSAndroid Build Coastguard Worker        return "".join(result)
330*cda5da8dSAndroid Build Coastguard Worker
331*cda5da8dSAndroid Build Coastguard Worker    def store_option_strings(self, parser):
332*cda5da8dSAndroid Build Coastguard Worker        self.indent()
333*cda5da8dSAndroid Build Coastguard Worker        max_len = 0
334*cda5da8dSAndroid Build Coastguard Worker        for opt in parser.option_list:
335*cda5da8dSAndroid Build Coastguard Worker            strings = self.format_option_strings(opt)
336*cda5da8dSAndroid Build Coastguard Worker            self.option_strings[opt] = strings
337*cda5da8dSAndroid Build Coastguard Worker            max_len = max(max_len, len(strings) + self.current_indent)
338*cda5da8dSAndroid Build Coastguard Worker        self.indent()
339*cda5da8dSAndroid Build Coastguard Worker        for group in parser.option_groups:
340*cda5da8dSAndroid Build Coastguard Worker            for opt in group.option_list:
341*cda5da8dSAndroid Build Coastguard Worker                strings = self.format_option_strings(opt)
342*cda5da8dSAndroid Build Coastguard Worker                self.option_strings[opt] = strings
343*cda5da8dSAndroid Build Coastguard Worker                max_len = max(max_len, len(strings) + self.current_indent)
344*cda5da8dSAndroid Build Coastguard Worker        self.dedent()
345*cda5da8dSAndroid Build Coastguard Worker        self.dedent()
346*cda5da8dSAndroid Build Coastguard Worker        self.help_position = min(max_len + 2, self.max_help_position)
347*cda5da8dSAndroid Build Coastguard Worker        self.help_width = max(self.width - self.help_position, 11)
348*cda5da8dSAndroid Build Coastguard Worker
349*cda5da8dSAndroid Build Coastguard Worker    def format_option_strings(self, option):
350*cda5da8dSAndroid Build Coastguard Worker        """Return a comma-separated list of option strings & metavariables."""
351*cda5da8dSAndroid Build Coastguard Worker        if option.takes_value():
352*cda5da8dSAndroid Build Coastguard Worker            metavar = option.metavar or option.dest.upper()
353*cda5da8dSAndroid Build Coastguard Worker            short_opts = [self._short_opt_fmt % (sopt, metavar)
354*cda5da8dSAndroid Build Coastguard Worker                          for sopt in option._short_opts]
355*cda5da8dSAndroid Build Coastguard Worker            long_opts = [self._long_opt_fmt % (lopt, metavar)
356*cda5da8dSAndroid Build Coastguard Worker                         for lopt in option._long_opts]
357*cda5da8dSAndroid Build Coastguard Worker        else:
358*cda5da8dSAndroid Build Coastguard Worker            short_opts = option._short_opts
359*cda5da8dSAndroid Build Coastguard Worker            long_opts = option._long_opts
360*cda5da8dSAndroid Build Coastguard Worker
361*cda5da8dSAndroid Build Coastguard Worker        if self.short_first:
362*cda5da8dSAndroid Build Coastguard Worker            opts = short_opts + long_opts
363*cda5da8dSAndroid Build Coastguard Worker        else:
364*cda5da8dSAndroid Build Coastguard Worker            opts = long_opts + short_opts
365*cda5da8dSAndroid Build Coastguard Worker
366*cda5da8dSAndroid Build Coastguard Worker        return ", ".join(opts)
367*cda5da8dSAndroid Build Coastguard Worker
368*cda5da8dSAndroid Build Coastguard Workerclass IndentedHelpFormatter (HelpFormatter):
369*cda5da8dSAndroid Build Coastguard Worker    """Format help with indented section bodies.
370*cda5da8dSAndroid Build Coastguard Worker    """
371*cda5da8dSAndroid Build Coastguard Worker
372*cda5da8dSAndroid Build Coastguard Worker    def __init__(self,
373*cda5da8dSAndroid Build Coastguard Worker                 indent_increment=2,
374*cda5da8dSAndroid Build Coastguard Worker                 max_help_position=24,
375*cda5da8dSAndroid Build Coastguard Worker                 width=None,
376*cda5da8dSAndroid Build Coastguard Worker                 short_first=1):
377*cda5da8dSAndroid Build Coastguard Worker        HelpFormatter.__init__(
378*cda5da8dSAndroid Build Coastguard Worker            self, indent_increment, max_help_position, width, short_first)
379*cda5da8dSAndroid Build Coastguard Worker
380*cda5da8dSAndroid Build Coastguard Worker    def format_usage(self, usage):
381*cda5da8dSAndroid Build Coastguard Worker        return _("Usage: %s\n") % usage
382*cda5da8dSAndroid Build Coastguard Worker
383*cda5da8dSAndroid Build Coastguard Worker    def format_heading(self, heading):
384*cda5da8dSAndroid Build Coastguard Worker        return "%*s%s:\n" % (self.current_indent, "", heading)
385*cda5da8dSAndroid Build Coastguard Worker
386*cda5da8dSAndroid Build Coastguard Worker
387*cda5da8dSAndroid Build Coastguard Workerclass TitledHelpFormatter (HelpFormatter):
388*cda5da8dSAndroid Build Coastguard Worker    """Format help with underlined section headers.
389*cda5da8dSAndroid Build Coastguard Worker    """
390*cda5da8dSAndroid Build Coastguard Worker
391*cda5da8dSAndroid Build Coastguard Worker    def __init__(self,
392*cda5da8dSAndroid Build Coastguard Worker                 indent_increment=0,
393*cda5da8dSAndroid Build Coastguard Worker                 max_help_position=24,
394*cda5da8dSAndroid Build Coastguard Worker                 width=None,
395*cda5da8dSAndroid Build Coastguard Worker                 short_first=0):
396*cda5da8dSAndroid Build Coastguard Worker        HelpFormatter.__init__ (
397*cda5da8dSAndroid Build Coastguard Worker            self, indent_increment, max_help_position, width, short_first)
398*cda5da8dSAndroid Build Coastguard Worker
399*cda5da8dSAndroid Build Coastguard Worker    def format_usage(self, usage):
400*cda5da8dSAndroid Build Coastguard Worker        return "%s  %s\n" % (self.format_heading(_("Usage")), usage)
401*cda5da8dSAndroid Build Coastguard Worker
402*cda5da8dSAndroid Build Coastguard Worker    def format_heading(self, heading):
403*cda5da8dSAndroid Build Coastguard Worker        return "%s\n%s\n" % (heading, "=-"[self.level] * len(heading))
404*cda5da8dSAndroid Build Coastguard Worker
405*cda5da8dSAndroid Build Coastguard Worker
406*cda5da8dSAndroid Build Coastguard Workerdef _parse_num(val, type):
407*cda5da8dSAndroid Build Coastguard Worker    if val[:2].lower() == "0x":         # hexadecimal
408*cda5da8dSAndroid Build Coastguard Worker        radix = 16
409*cda5da8dSAndroid Build Coastguard Worker    elif val[:2].lower() == "0b":       # binary
410*cda5da8dSAndroid Build Coastguard Worker        radix = 2
411*cda5da8dSAndroid Build Coastguard Worker        val = val[2:] or "0"            # have to remove "0b" prefix
412*cda5da8dSAndroid Build Coastguard Worker    elif val[:1] == "0":                # octal
413*cda5da8dSAndroid Build Coastguard Worker        radix = 8
414*cda5da8dSAndroid Build Coastguard Worker    else:                               # decimal
415*cda5da8dSAndroid Build Coastguard Worker        radix = 10
416*cda5da8dSAndroid Build Coastguard Worker
417*cda5da8dSAndroid Build Coastguard Worker    return type(val, radix)
418*cda5da8dSAndroid Build Coastguard Worker
419*cda5da8dSAndroid Build Coastguard Workerdef _parse_int(val):
420*cda5da8dSAndroid Build Coastguard Worker    return _parse_num(val, int)
421*cda5da8dSAndroid Build Coastguard Worker
422*cda5da8dSAndroid Build Coastguard Worker_builtin_cvt = { "int" : (_parse_int, _("integer")),
423*cda5da8dSAndroid Build Coastguard Worker                 "long" : (_parse_int, _("integer")),
424*cda5da8dSAndroid Build Coastguard Worker                 "float" : (float, _("floating-point")),
425*cda5da8dSAndroid Build Coastguard Worker                 "complex" : (complex, _("complex")) }
426*cda5da8dSAndroid Build Coastguard Worker
427*cda5da8dSAndroid Build Coastguard Workerdef check_builtin(option, opt, value):
428*cda5da8dSAndroid Build Coastguard Worker    (cvt, what) = _builtin_cvt[option.type]
429*cda5da8dSAndroid Build Coastguard Worker    try:
430*cda5da8dSAndroid Build Coastguard Worker        return cvt(value)
431*cda5da8dSAndroid Build Coastguard Worker    except ValueError:
432*cda5da8dSAndroid Build Coastguard Worker        raise OptionValueError(
433*cda5da8dSAndroid Build Coastguard Worker            _("option %s: invalid %s value: %r") % (opt, what, value))
434*cda5da8dSAndroid Build Coastguard Worker
435*cda5da8dSAndroid Build Coastguard Workerdef check_choice(option, opt, value):
436*cda5da8dSAndroid Build Coastguard Worker    if value in option.choices:
437*cda5da8dSAndroid Build Coastguard Worker        return value
438*cda5da8dSAndroid Build Coastguard Worker    else:
439*cda5da8dSAndroid Build Coastguard Worker        choices = ", ".join(map(repr, option.choices))
440*cda5da8dSAndroid Build Coastguard Worker        raise OptionValueError(
441*cda5da8dSAndroid Build Coastguard Worker            _("option %s: invalid choice: %r (choose from %s)")
442*cda5da8dSAndroid Build Coastguard Worker            % (opt, value, choices))
443*cda5da8dSAndroid Build Coastguard Worker
444*cda5da8dSAndroid Build Coastguard Worker# Not supplying a default is different from a default of None,
445*cda5da8dSAndroid Build Coastguard Worker# so we need an explicit "not supplied" value.
446*cda5da8dSAndroid Build Coastguard WorkerNO_DEFAULT = ("NO", "DEFAULT")
447*cda5da8dSAndroid Build Coastguard Worker
448*cda5da8dSAndroid Build Coastguard Worker
449*cda5da8dSAndroid Build Coastguard Workerclass Option:
450*cda5da8dSAndroid Build Coastguard Worker    """
451*cda5da8dSAndroid Build Coastguard Worker    Instance attributes:
452*cda5da8dSAndroid Build Coastguard Worker      _short_opts : [string]
453*cda5da8dSAndroid Build Coastguard Worker      _long_opts : [string]
454*cda5da8dSAndroid Build Coastguard Worker
455*cda5da8dSAndroid Build Coastguard Worker      action : string
456*cda5da8dSAndroid Build Coastguard Worker      type : string
457*cda5da8dSAndroid Build Coastguard Worker      dest : string
458*cda5da8dSAndroid Build Coastguard Worker      default : any
459*cda5da8dSAndroid Build Coastguard Worker      nargs : int
460*cda5da8dSAndroid Build Coastguard Worker      const : any
461*cda5da8dSAndroid Build Coastguard Worker      choices : [string]
462*cda5da8dSAndroid Build Coastguard Worker      callback : function
463*cda5da8dSAndroid Build Coastguard Worker      callback_args : (any*)
464*cda5da8dSAndroid Build Coastguard Worker      callback_kwargs : { string : any }
465*cda5da8dSAndroid Build Coastguard Worker      help : string
466*cda5da8dSAndroid Build Coastguard Worker      metavar : string
467*cda5da8dSAndroid Build Coastguard Worker    """
468*cda5da8dSAndroid Build Coastguard Worker
469*cda5da8dSAndroid Build Coastguard Worker    # The list of instance attributes that may be set through
470*cda5da8dSAndroid Build Coastguard Worker    # keyword args to the constructor.
471*cda5da8dSAndroid Build Coastguard Worker    ATTRS = ['action',
472*cda5da8dSAndroid Build Coastguard Worker             'type',
473*cda5da8dSAndroid Build Coastguard Worker             'dest',
474*cda5da8dSAndroid Build Coastguard Worker             'default',
475*cda5da8dSAndroid Build Coastguard Worker             'nargs',
476*cda5da8dSAndroid Build Coastguard Worker             'const',
477*cda5da8dSAndroid Build Coastguard Worker             'choices',
478*cda5da8dSAndroid Build Coastguard Worker             'callback',
479*cda5da8dSAndroid Build Coastguard Worker             'callback_args',
480*cda5da8dSAndroid Build Coastguard Worker             'callback_kwargs',
481*cda5da8dSAndroid Build Coastguard Worker             'help',
482*cda5da8dSAndroid Build Coastguard Worker             'metavar']
483*cda5da8dSAndroid Build Coastguard Worker
484*cda5da8dSAndroid Build Coastguard Worker    # The set of actions allowed by option parsers.  Explicitly listed
485*cda5da8dSAndroid Build Coastguard Worker    # here so the constructor can validate its arguments.
486*cda5da8dSAndroid Build Coastguard Worker    ACTIONS = ("store",
487*cda5da8dSAndroid Build Coastguard Worker               "store_const",
488*cda5da8dSAndroid Build Coastguard Worker               "store_true",
489*cda5da8dSAndroid Build Coastguard Worker               "store_false",
490*cda5da8dSAndroid Build Coastguard Worker               "append",
491*cda5da8dSAndroid Build Coastguard Worker               "append_const",
492*cda5da8dSAndroid Build Coastguard Worker               "count",
493*cda5da8dSAndroid Build Coastguard Worker               "callback",
494*cda5da8dSAndroid Build Coastguard Worker               "help",
495*cda5da8dSAndroid Build Coastguard Worker               "version")
496*cda5da8dSAndroid Build Coastguard Worker
497*cda5da8dSAndroid Build Coastguard Worker    # The set of actions that involve storing a value somewhere;
498*cda5da8dSAndroid Build Coastguard Worker    # also listed just for constructor argument validation.  (If
499*cda5da8dSAndroid Build Coastguard Worker    # the action is one of these, there must be a destination.)
500*cda5da8dSAndroid Build Coastguard Worker    STORE_ACTIONS = ("store",
501*cda5da8dSAndroid Build Coastguard Worker                     "store_const",
502*cda5da8dSAndroid Build Coastguard Worker                     "store_true",
503*cda5da8dSAndroid Build Coastguard Worker                     "store_false",
504*cda5da8dSAndroid Build Coastguard Worker                     "append",
505*cda5da8dSAndroid Build Coastguard Worker                     "append_const",
506*cda5da8dSAndroid Build Coastguard Worker                     "count")
507*cda5da8dSAndroid Build Coastguard Worker
508*cda5da8dSAndroid Build Coastguard Worker    # The set of actions for which it makes sense to supply a value
509*cda5da8dSAndroid Build Coastguard Worker    # type, ie. which may consume an argument from the command line.
510*cda5da8dSAndroid Build Coastguard Worker    TYPED_ACTIONS = ("store",
511*cda5da8dSAndroid Build Coastguard Worker                     "append",
512*cda5da8dSAndroid Build Coastguard Worker                     "callback")
513*cda5da8dSAndroid Build Coastguard Worker
514*cda5da8dSAndroid Build Coastguard Worker    # The set of actions which *require* a value type, ie. that
515*cda5da8dSAndroid Build Coastguard Worker    # always consume an argument from the command line.
516*cda5da8dSAndroid Build Coastguard Worker    ALWAYS_TYPED_ACTIONS = ("store",
517*cda5da8dSAndroid Build Coastguard Worker                            "append")
518*cda5da8dSAndroid Build Coastguard Worker
519*cda5da8dSAndroid Build Coastguard Worker    # The set of actions which take a 'const' attribute.
520*cda5da8dSAndroid Build Coastguard Worker    CONST_ACTIONS = ("store_const",
521*cda5da8dSAndroid Build Coastguard Worker                     "append_const")
522*cda5da8dSAndroid Build Coastguard Worker
523*cda5da8dSAndroid Build Coastguard Worker    # The set of known types for option parsers.  Again, listed here for
524*cda5da8dSAndroid Build Coastguard Worker    # constructor argument validation.
525*cda5da8dSAndroid Build Coastguard Worker    TYPES = ("string", "int", "long", "float", "complex", "choice")
526*cda5da8dSAndroid Build Coastguard Worker
527*cda5da8dSAndroid Build Coastguard Worker    # Dictionary of argument checking functions, which convert and
528*cda5da8dSAndroid Build Coastguard Worker    # validate option arguments according to the option type.
529*cda5da8dSAndroid Build Coastguard Worker    #
530*cda5da8dSAndroid Build Coastguard Worker    # Signature of checking functions is:
531*cda5da8dSAndroid Build Coastguard Worker    #   check(option : Option, opt : string, value : string) -> any
532*cda5da8dSAndroid Build Coastguard Worker    # where
533*cda5da8dSAndroid Build Coastguard Worker    #   option is the Option instance calling the checker
534*cda5da8dSAndroid Build Coastguard Worker    #   opt is the actual option seen on the command-line
535*cda5da8dSAndroid Build Coastguard Worker    #     (eg. "-a", "--file")
536*cda5da8dSAndroid Build Coastguard Worker    #   value is the option argument seen on the command-line
537*cda5da8dSAndroid Build Coastguard Worker    #
538*cda5da8dSAndroid Build Coastguard Worker    # The return value should be in the appropriate Python type
539*cda5da8dSAndroid Build Coastguard Worker    # for option.type -- eg. an integer if option.type == "int".
540*cda5da8dSAndroid Build Coastguard Worker    #
541*cda5da8dSAndroid Build Coastguard Worker    # If no checker is defined for a type, arguments will be
542*cda5da8dSAndroid Build Coastguard Worker    # unchecked and remain strings.
543*cda5da8dSAndroid Build Coastguard Worker    TYPE_CHECKER = { "int"    : check_builtin,
544*cda5da8dSAndroid Build Coastguard Worker                     "long"   : check_builtin,
545*cda5da8dSAndroid Build Coastguard Worker                     "float"  : check_builtin,
546*cda5da8dSAndroid Build Coastguard Worker                     "complex": check_builtin,
547*cda5da8dSAndroid Build Coastguard Worker                     "choice" : check_choice,
548*cda5da8dSAndroid Build Coastguard Worker                   }
549*cda5da8dSAndroid Build Coastguard Worker
550*cda5da8dSAndroid Build Coastguard Worker
551*cda5da8dSAndroid Build Coastguard Worker    # CHECK_METHODS is a list of unbound method objects; they are called
552*cda5da8dSAndroid Build Coastguard Worker    # by the constructor, in order, after all attributes are
553*cda5da8dSAndroid Build Coastguard Worker    # initialized.  The list is created and filled in later, after all
554*cda5da8dSAndroid Build Coastguard Worker    # the methods are actually defined.  (I just put it here because I
555*cda5da8dSAndroid Build Coastguard Worker    # like to define and document all class attributes in the same
556*cda5da8dSAndroid Build Coastguard Worker    # place.)  Subclasses that add another _check_*() method should
557*cda5da8dSAndroid Build Coastguard Worker    # define their own CHECK_METHODS list that adds their check method
558*cda5da8dSAndroid Build Coastguard Worker    # to those from this class.
559*cda5da8dSAndroid Build Coastguard Worker    CHECK_METHODS = None
560*cda5da8dSAndroid Build Coastguard Worker
561*cda5da8dSAndroid Build Coastguard Worker
562*cda5da8dSAndroid Build Coastguard Worker    # -- Constructor/initialization methods ----------------------------
563*cda5da8dSAndroid Build Coastguard Worker
564*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, *opts, **attrs):
565*cda5da8dSAndroid Build Coastguard Worker        # Set _short_opts, _long_opts attrs from 'opts' tuple.
566*cda5da8dSAndroid Build Coastguard Worker        # Have to be set now, in case no option strings are supplied.
567*cda5da8dSAndroid Build Coastguard Worker        self._short_opts = []
568*cda5da8dSAndroid Build Coastguard Worker        self._long_opts = []
569*cda5da8dSAndroid Build Coastguard Worker        opts = self._check_opt_strings(opts)
570*cda5da8dSAndroid Build Coastguard Worker        self._set_opt_strings(opts)
571*cda5da8dSAndroid Build Coastguard Worker
572*cda5da8dSAndroid Build Coastguard Worker        # Set all other attrs (action, type, etc.) from 'attrs' dict
573*cda5da8dSAndroid Build Coastguard Worker        self._set_attrs(attrs)
574*cda5da8dSAndroid Build Coastguard Worker
575*cda5da8dSAndroid Build Coastguard Worker        # Check all the attributes we just set.  There are lots of
576*cda5da8dSAndroid Build Coastguard Worker        # complicated interdependencies, but luckily they can be farmed
577*cda5da8dSAndroid Build Coastguard Worker        # out to the _check_*() methods listed in CHECK_METHODS -- which
578*cda5da8dSAndroid Build Coastguard Worker        # could be handy for subclasses!  The one thing these all share
579*cda5da8dSAndroid Build Coastguard Worker        # is that they raise OptionError if they discover a problem.
580*cda5da8dSAndroid Build Coastguard Worker        for checker in self.CHECK_METHODS:
581*cda5da8dSAndroid Build Coastguard Worker            checker(self)
582*cda5da8dSAndroid Build Coastguard Worker
583*cda5da8dSAndroid Build Coastguard Worker    def _check_opt_strings(self, opts):
584*cda5da8dSAndroid Build Coastguard Worker        # Filter out None because early versions of Optik had exactly
585*cda5da8dSAndroid Build Coastguard Worker        # one short option and one long option, either of which
586*cda5da8dSAndroid Build Coastguard Worker        # could be None.
587*cda5da8dSAndroid Build Coastguard Worker        opts = [opt for opt in opts if opt]
588*cda5da8dSAndroid Build Coastguard Worker        if not opts:
589*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("at least one option string must be supplied")
590*cda5da8dSAndroid Build Coastguard Worker        return opts
591*cda5da8dSAndroid Build Coastguard Worker
592*cda5da8dSAndroid Build Coastguard Worker    def _set_opt_strings(self, opts):
593*cda5da8dSAndroid Build Coastguard Worker        for opt in opts:
594*cda5da8dSAndroid Build Coastguard Worker            if len(opt) < 2:
595*cda5da8dSAndroid Build Coastguard Worker                raise OptionError(
596*cda5da8dSAndroid Build Coastguard Worker                    "invalid option string %r: "
597*cda5da8dSAndroid Build Coastguard Worker                    "must be at least two characters long" % opt, self)
598*cda5da8dSAndroid Build Coastguard Worker            elif len(opt) == 2:
599*cda5da8dSAndroid Build Coastguard Worker                if not (opt[0] == "-" and opt[1] != "-"):
600*cda5da8dSAndroid Build Coastguard Worker                    raise OptionError(
601*cda5da8dSAndroid Build Coastguard Worker                        "invalid short option string %r: "
602*cda5da8dSAndroid Build Coastguard Worker                        "must be of the form -x, (x any non-dash char)" % opt,
603*cda5da8dSAndroid Build Coastguard Worker                        self)
604*cda5da8dSAndroid Build Coastguard Worker                self._short_opts.append(opt)
605*cda5da8dSAndroid Build Coastguard Worker            else:
606*cda5da8dSAndroid Build Coastguard Worker                if not (opt[0:2] == "--" and opt[2] != "-"):
607*cda5da8dSAndroid Build Coastguard Worker                    raise OptionError(
608*cda5da8dSAndroid Build Coastguard Worker                        "invalid long option string %r: "
609*cda5da8dSAndroid Build Coastguard Worker                        "must start with --, followed by non-dash" % opt,
610*cda5da8dSAndroid Build Coastguard Worker                        self)
611*cda5da8dSAndroid Build Coastguard Worker                self._long_opts.append(opt)
612*cda5da8dSAndroid Build Coastguard Worker
613*cda5da8dSAndroid Build Coastguard Worker    def _set_attrs(self, attrs):
614*cda5da8dSAndroid Build Coastguard Worker        for attr in self.ATTRS:
615*cda5da8dSAndroid Build Coastguard Worker            if attr in attrs:
616*cda5da8dSAndroid Build Coastguard Worker                setattr(self, attr, attrs[attr])
617*cda5da8dSAndroid Build Coastguard Worker                del attrs[attr]
618*cda5da8dSAndroid Build Coastguard Worker            else:
619*cda5da8dSAndroid Build Coastguard Worker                if attr == 'default':
620*cda5da8dSAndroid Build Coastguard Worker                    setattr(self, attr, NO_DEFAULT)
621*cda5da8dSAndroid Build Coastguard Worker                else:
622*cda5da8dSAndroid Build Coastguard Worker                    setattr(self, attr, None)
623*cda5da8dSAndroid Build Coastguard Worker        if attrs:
624*cda5da8dSAndroid Build Coastguard Worker            attrs = sorted(attrs.keys())
625*cda5da8dSAndroid Build Coastguard Worker            raise OptionError(
626*cda5da8dSAndroid Build Coastguard Worker                "invalid keyword arguments: %s" % ", ".join(attrs),
627*cda5da8dSAndroid Build Coastguard Worker                self)
628*cda5da8dSAndroid Build Coastguard Worker
629*cda5da8dSAndroid Build Coastguard Worker
630*cda5da8dSAndroid Build Coastguard Worker    # -- Constructor validation methods --------------------------------
631*cda5da8dSAndroid Build Coastguard Worker
632*cda5da8dSAndroid Build Coastguard Worker    def _check_action(self):
633*cda5da8dSAndroid Build Coastguard Worker        if self.action is None:
634*cda5da8dSAndroid Build Coastguard Worker            self.action = "store"
635*cda5da8dSAndroid Build Coastguard Worker        elif self.action not in self.ACTIONS:
636*cda5da8dSAndroid Build Coastguard Worker            raise OptionError("invalid action: %r" % self.action, self)
637*cda5da8dSAndroid Build Coastguard Worker
638*cda5da8dSAndroid Build Coastguard Worker    def _check_type(self):
639*cda5da8dSAndroid Build Coastguard Worker        if self.type is None:
640*cda5da8dSAndroid Build Coastguard Worker            if self.action in self.ALWAYS_TYPED_ACTIONS:
641*cda5da8dSAndroid Build Coastguard Worker                if self.choices is not None:
642*cda5da8dSAndroid Build Coastguard Worker                    # The "choices" attribute implies "choice" type.
643*cda5da8dSAndroid Build Coastguard Worker                    self.type = "choice"
644*cda5da8dSAndroid Build Coastguard Worker                else:
645*cda5da8dSAndroid Build Coastguard Worker                    # No type given?  "string" is the most sensible default.
646*cda5da8dSAndroid Build Coastguard Worker                    self.type = "string"
647*cda5da8dSAndroid Build Coastguard Worker        else:
648*cda5da8dSAndroid Build Coastguard Worker            # Allow type objects or builtin type conversion functions
649*cda5da8dSAndroid Build Coastguard Worker            # (int, str, etc.) as an alternative to their names.
650*cda5da8dSAndroid Build Coastguard Worker            if isinstance(self.type, type):
651*cda5da8dSAndroid Build Coastguard Worker                self.type = self.type.__name__
652*cda5da8dSAndroid Build Coastguard Worker
653*cda5da8dSAndroid Build Coastguard Worker            if self.type == "str":
654*cda5da8dSAndroid Build Coastguard Worker                self.type = "string"
655*cda5da8dSAndroid Build Coastguard Worker
656*cda5da8dSAndroid Build Coastguard Worker            if self.type not in self.TYPES:
657*cda5da8dSAndroid Build Coastguard Worker                raise OptionError("invalid option type: %r" % self.type, self)
658*cda5da8dSAndroid Build Coastguard Worker            if self.action not in self.TYPED_ACTIONS:
659*cda5da8dSAndroid Build Coastguard Worker                raise OptionError(
660*cda5da8dSAndroid Build Coastguard Worker                    "must not supply a type for action %r" % self.action, self)
661*cda5da8dSAndroid Build Coastguard Worker
662*cda5da8dSAndroid Build Coastguard Worker    def _check_choice(self):
663*cda5da8dSAndroid Build Coastguard Worker        if self.type == "choice":
664*cda5da8dSAndroid Build Coastguard Worker            if self.choices is None:
665*cda5da8dSAndroid Build Coastguard Worker                raise OptionError(
666*cda5da8dSAndroid Build Coastguard Worker                    "must supply a list of choices for type 'choice'", self)
667*cda5da8dSAndroid Build Coastguard Worker            elif not isinstance(self.choices, (tuple, list)):
668*cda5da8dSAndroid Build Coastguard Worker                raise OptionError(
669*cda5da8dSAndroid Build Coastguard Worker                    "choices must be a list of strings ('%s' supplied)"
670*cda5da8dSAndroid Build Coastguard Worker                    % str(type(self.choices)).split("'")[1], self)
671*cda5da8dSAndroid Build Coastguard Worker        elif self.choices is not None:
672*cda5da8dSAndroid Build Coastguard Worker            raise OptionError(
673*cda5da8dSAndroid Build Coastguard Worker                "must not supply choices for type %r" % self.type, self)
674*cda5da8dSAndroid Build Coastguard Worker
675*cda5da8dSAndroid Build Coastguard Worker    def _check_dest(self):
676*cda5da8dSAndroid Build Coastguard Worker        # No destination given, and we need one for this action.  The
677*cda5da8dSAndroid Build Coastguard Worker        # self.type check is for callbacks that take a value.
678*cda5da8dSAndroid Build Coastguard Worker        takes_value = (self.action in self.STORE_ACTIONS or
679*cda5da8dSAndroid Build Coastguard Worker                       self.type is not None)
680*cda5da8dSAndroid Build Coastguard Worker        if self.dest is None and takes_value:
681*cda5da8dSAndroid Build Coastguard Worker
682*cda5da8dSAndroid Build Coastguard Worker            # Glean a destination from the first long option string,
683*cda5da8dSAndroid Build Coastguard Worker            # or from the first short option string if no long options.
684*cda5da8dSAndroid Build Coastguard Worker            if self._long_opts:
685*cda5da8dSAndroid Build Coastguard Worker                # eg. "--foo-bar" -> "foo_bar"
686*cda5da8dSAndroid Build Coastguard Worker                self.dest = self._long_opts[0][2:].replace('-', '_')
687*cda5da8dSAndroid Build Coastguard Worker            else:
688*cda5da8dSAndroid Build Coastguard Worker                self.dest = self._short_opts[0][1]
689*cda5da8dSAndroid Build Coastguard Worker
690*cda5da8dSAndroid Build Coastguard Worker    def _check_const(self):
691*cda5da8dSAndroid Build Coastguard Worker        if self.action not in self.CONST_ACTIONS and self.const is not None:
692*cda5da8dSAndroid Build Coastguard Worker            raise OptionError(
693*cda5da8dSAndroid Build Coastguard Worker                "'const' must not be supplied for action %r" % self.action,
694*cda5da8dSAndroid Build Coastguard Worker                self)
695*cda5da8dSAndroid Build Coastguard Worker
696*cda5da8dSAndroid Build Coastguard Worker    def _check_nargs(self):
697*cda5da8dSAndroid Build Coastguard Worker        if self.action in self.TYPED_ACTIONS:
698*cda5da8dSAndroid Build Coastguard Worker            if self.nargs is None:
699*cda5da8dSAndroid Build Coastguard Worker                self.nargs = 1
700*cda5da8dSAndroid Build Coastguard Worker        elif self.nargs is not None:
701*cda5da8dSAndroid Build Coastguard Worker            raise OptionError(
702*cda5da8dSAndroid Build Coastguard Worker                "'nargs' must not be supplied for action %r" % self.action,
703*cda5da8dSAndroid Build Coastguard Worker                self)
704*cda5da8dSAndroid Build Coastguard Worker
705*cda5da8dSAndroid Build Coastguard Worker    def _check_callback(self):
706*cda5da8dSAndroid Build Coastguard Worker        if self.action == "callback":
707*cda5da8dSAndroid Build Coastguard Worker            if not callable(self.callback):
708*cda5da8dSAndroid Build Coastguard Worker                raise OptionError(
709*cda5da8dSAndroid Build Coastguard Worker                    "callback not callable: %r" % self.callback, self)
710*cda5da8dSAndroid Build Coastguard Worker            if (self.callback_args is not None and
711*cda5da8dSAndroid Build Coastguard Worker                not isinstance(self.callback_args, tuple)):
712*cda5da8dSAndroid Build Coastguard Worker                raise OptionError(
713*cda5da8dSAndroid Build Coastguard Worker                    "callback_args, if supplied, must be a tuple: not %r"
714*cda5da8dSAndroid Build Coastguard Worker                    % self.callback_args, self)
715*cda5da8dSAndroid Build Coastguard Worker            if (self.callback_kwargs is not None and
716*cda5da8dSAndroid Build Coastguard Worker                not isinstance(self.callback_kwargs, dict)):
717*cda5da8dSAndroid Build Coastguard Worker                raise OptionError(
718*cda5da8dSAndroid Build Coastguard Worker                    "callback_kwargs, if supplied, must be a dict: not %r"
719*cda5da8dSAndroid Build Coastguard Worker                    % self.callback_kwargs, self)
720*cda5da8dSAndroid Build Coastguard Worker        else:
721*cda5da8dSAndroid Build Coastguard Worker            if self.callback is not None:
722*cda5da8dSAndroid Build Coastguard Worker                raise OptionError(
723*cda5da8dSAndroid Build Coastguard Worker                    "callback supplied (%r) for non-callback option"
724*cda5da8dSAndroid Build Coastguard Worker                    % self.callback, self)
725*cda5da8dSAndroid Build Coastguard Worker            if self.callback_args is not None:
726*cda5da8dSAndroid Build Coastguard Worker                raise OptionError(
727*cda5da8dSAndroid Build Coastguard Worker                    "callback_args supplied for non-callback option", self)
728*cda5da8dSAndroid Build Coastguard Worker            if self.callback_kwargs is not None:
729*cda5da8dSAndroid Build Coastguard Worker                raise OptionError(
730*cda5da8dSAndroid Build Coastguard Worker                    "callback_kwargs supplied for non-callback option", self)
731*cda5da8dSAndroid Build Coastguard Worker
732*cda5da8dSAndroid Build Coastguard Worker
733*cda5da8dSAndroid Build Coastguard Worker    CHECK_METHODS = [_check_action,
734*cda5da8dSAndroid Build Coastguard Worker                     _check_type,
735*cda5da8dSAndroid Build Coastguard Worker                     _check_choice,
736*cda5da8dSAndroid Build Coastguard Worker                     _check_dest,
737*cda5da8dSAndroid Build Coastguard Worker                     _check_const,
738*cda5da8dSAndroid Build Coastguard Worker                     _check_nargs,
739*cda5da8dSAndroid Build Coastguard Worker                     _check_callback]
740*cda5da8dSAndroid Build Coastguard Worker
741*cda5da8dSAndroid Build Coastguard Worker
742*cda5da8dSAndroid Build Coastguard Worker    # -- Miscellaneous methods -----------------------------------------
743*cda5da8dSAndroid Build Coastguard Worker
744*cda5da8dSAndroid Build Coastguard Worker    def __str__(self):
745*cda5da8dSAndroid Build Coastguard Worker        return "/".join(self._short_opts + self._long_opts)
746*cda5da8dSAndroid Build Coastguard Worker
747*cda5da8dSAndroid Build Coastguard Worker    __repr__ = _repr
748*cda5da8dSAndroid Build Coastguard Worker
749*cda5da8dSAndroid Build Coastguard Worker    def takes_value(self):
750*cda5da8dSAndroid Build Coastguard Worker        return self.type is not None
751*cda5da8dSAndroid Build Coastguard Worker
752*cda5da8dSAndroid Build Coastguard Worker    def get_opt_string(self):
753*cda5da8dSAndroid Build Coastguard Worker        if self._long_opts:
754*cda5da8dSAndroid Build Coastguard Worker            return self._long_opts[0]
755*cda5da8dSAndroid Build Coastguard Worker        else:
756*cda5da8dSAndroid Build Coastguard Worker            return self._short_opts[0]
757*cda5da8dSAndroid Build Coastguard Worker
758*cda5da8dSAndroid Build Coastguard Worker
759*cda5da8dSAndroid Build Coastguard Worker    # -- Processing methods --------------------------------------------
760*cda5da8dSAndroid Build Coastguard Worker
761*cda5da8dSAndroid Build Coastguard Worker    def check_value(self, opt, value):
762*cda5da8dSAndroid Build Coastguard Worker        checker = self.TYPE_CHECKER.get(self.type)
763*cda5da8dSAndroid Build Coastguard Worker        if checker is None:
764*cda5da8dSAndroid Build Coastguard Worker            return value
765*cda5da8dSAndroid Build Coastguard Worker        else:
766*cda5da8dSAndroid Build Coastguard Worker            return checker(self, opt, value)
767*cda5da8dSAndroid Build Coastguard Worker
768*cda5da8dSAndroid Build Coastguard Worker    def convert_value(self, opt, value):
769*cda5da8dSAndroid Build Coastguard Worker        if value is not None:
770*cda5da8dSAndroid Build Coastguard Worker            if self.nargs == 1:
771*cda5da8dSAndroid Build Coastguard Worker                return self.check_value(opt, value)
772*cda5da8dSAndroid Build Coastguard Worker            else:
773*cda5da8dSAndroid Build Coastguard Worker                return tuple([self.check_value(opt, v) for v in value])
774*cda5da8dSAndroid Build Coastguard Worker
775*cda5da8dSAndroid Build Coastguard Worker    def process(self, opt, value, values, parser):
776*cda5da8dSAndroid Build Coastguard Worker
777*cda5da8dSAndroid Build Coastguard Worker        # First, convert the value(s) to the right type.  Howl if any
778*cda5da8dSAndroid Build Coastguard Worker        # value(s) are bogus.
779*cda5da8dSAndroid Build Coastguard Worker        value = self.convert_value(opt, value)
780*cda5da8dSAndroid Build Coastguard Worker
781*cda5da8dSAndroid Build Coastguard Worker        # And then take whatever action is expected of us.
782*cda5da8dSAndroid Build Coastguard Worker        # This is a separate method to make life easier for
783*cda5da8dSAndroid Build Coastguard Worker        # subclasses to add new actions.
784*cda5da8dSAndroid Build Coastguard Worker        return self.take_action(
785*cda5da8dSAndroid Build Coastguard Worker            self.action, self.dest, opt, value, values, parser)
786*cda5da8dSAndroid Build Coastguard Worker
787*cda5da8dSAndroid Build Coastguard Worker    def take_action(self, action, dest, opt, value, values, parser):
788*cda5da8dSAndroid Build Coastguard Worker        if action == "store":
789*cda5da8dSAndroid Build Coastguard Worker            setattr(values, dest, value)
790*cda5da8dSAndroid Build Coastguard Worker        elif action == "store_const":
791*cda5da8dSAndroid Build Coastguard Worker            setattr(values, dest, self.const)
792*cda5da8dSAndroid Build Coastguard Worker        elif action == "store_true":
793*cda5da8dSAndroid Build Coastguard Worker            setattr(values, dest, True)
794*cda5da8dSAndroid Build Coastguard Worker        elif action == "store_false":
795*cda5da8dSAndroid Build Coastguard Worker            setattr(values, dest, False)
796*cda5da8dSAndroid Build Coastguard Worker        elif action == "append":
797*cda5da8dSAndroid Build Coastguard Worker            values.ensure_value(dest, []).append(value)
798*cda5da8dSAndroid Build Coastguard Worker        elif action == "append_const":
799*cda5da8dSAndroid Build Coastguard Worker            values.ensure_value(dest, []).append(self.const)
800*cda5da8dSAndroid Build Coastguard Worker        elif action == "count":
801*cda5da8dSAndroid Build Coastguard Worker            setattr(values, dest, values.ensure_value(dest, 0) + 1)
802*cda5da8dSAndroid Build Coastguard Worker        elif action == "callback":
803*cda5da8dSAndroid Build Coastguard Worker            args = self.callback_args or ()
804*cda5da8dSAndroid Build Coastguard Worker            kwargs = self.callback_kwargs or {}
805*cda5da8dSAndroid Build Coastguard Worker            self.callback(self, opt, value, parser, *args, **kwargs)
806*cda5da8dSAndroid Build Coastguard Worker        elif action == "help":
807*cda5da8dSAndroid Build Coastguard Worker            parser.print_help()
808*cda5da8dSAndroid Build Coastguard Worker            parser.exit()
809*cda5da8dSAndroid Build Coastguard Worker        elif action == "version":
810*cda5da8dSAndroid Build Coastguard Worker            parser.print_version()
811*cda5da8dSAndroid Build Coastguard Worker            parser.exit()
812*cda5da8dSAndroid Build Coastguard Worker        else:
813*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("unknown action %r" % self.action)
814*cda5da8dSAndroid Build Coastguard Worker
815*cda5da8dSAndroid Build Coastguard Worker        return 1
816*cda5da8dSAndroid Build Coastguard Worker
817*cda5da8dSAndroid Build Coastguard Worker# class Option
818*cda5da8dSAndroid Build Coastguard Worker
819*cda5da8dSAndroid Build Coastguard Worker
820*cda5da8dSAndroid Build Coastguard WorkerSUPPRESS_HELP = "SUPPRESS"+"HELP"
821*cda5da8dSAndroid Build Coastguard WorkerSUPPRESS_USAGE = "SUPPRESS"+"USAGE"
822*cda5da8dSAndroid Build Coastguard Worker
823*cda5da8dSAndroid Build Coastguard Workerclass Values:
824*cda5da8dSAndroid Build Coastguard Worker
825*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, defaults=None):
826*cda5da8dSAndroid Build Coastguard Worker        if defaults:
827*cda5da8dSAndroid Build Coastguard Worker            for (attr, val) in defaults.items():
828*cda5da8dSAndroid Build Coastguard Worker                setattr(self, attr, val)
829*cda5da8dSAndroid Build Coastguard Worker
830*cda5da8dSAndroid Build Coastguard Worker    def __str__(self):
831*cda5da8dSAndroid Build Coastguard Worker        return str(self.__dict__)
832*cda5da8dSAndroid Build Coastguard Worker
833*cda5da8dSAndroid Build Coastguard Worker    __repr__ = _repr
834*cda5da8dSAndroid Build Coastguard Worker
835*cda5da8dSAndroid Build Coastguard Worker    def __eq__(self, other):
836*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, Values):
837*cda5da8dSAndroid Build Coastguard Worker            return self.__dict__ == other.__dict__
838*cda5da8dSAndroid Build Coastguard Worker        elif isinstance(other, dict):
839*cda5da8dSAndroid Build Coastguard Worker            return self.__dict__ == other
840*cda5da8dSAndroid Build Coastguard Worker        else:
841*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
842*cda5da8dSAndroid Build Coastguard Worker
843*cda5da8dSAndroid Build Coastguard Worker    def _update_careful(self, dict):
844*cda5da8dSAndroid Build Coastguard Worker        """
845*cda5da8dSAndroid Build Coastguard Worker        Update the option values from an arbitrary dictionary, but only
846*cda5da8dSAndroid Build Coastguard Worker        use keys from dict that already have a corresponding attribute
847*cda5da8dSAndroid Build Coastguard Worker        in self.  Any keys in dict without a corresponding attribute
848*cda5da8dSAndroid Build Coastguard Worker        are silently ignored.
849*cda5da8dSAndroid Build Coastguard Worker        """
850*cda5da8dSAndroid Build Coastguard Worker        for attr in dir(self):
851*cda5da8dSAndroid Build Coastguard Worker            if attr in dict:
852*cda5da8dSAndroid Build Coastguard Worker                dval = dict[attr]
853*cda5da8dSAndroid Build Coastguard Worker                if dval is not None:
854*cda5da8dSAndroid Build Coastguard Worker                    setattr(self, attr, dval)
855*cda5da8dSAndroid Build Coastguard Worker
856*cda5da8dSAndroid Build Coastguard Worker    def _update_loose(self, dict):
857*cda5da8dSAndroid Build Coastguard Worker        """
858*cda5da8dSAndroid Build Coastguard Worker        Update the option values from an arbitrary dictionary,
859*cda5da8dSAndroid Build Coastguard Worker        using all keys from the dictionary regardless of whether
860*cda5da8dSAndroid Build Coastguard Worker        they have a corresponding attribute in self or not.
861*cda5da8dSAndroid Build Coastguard Worker        """
862*cda5da8dSAndroid Build Coastguard Worker        self.__dict__.update(dict)
863*cda5da8dSAndroid Build Coastguard Worker
864*cda5da8dSAndroid Build Coastguard Worker    def _update(self, dict, mode):
865*cda5da8dSAndroid Build Coastguard Worker        if mode == "careful":
866*cda5da8dSAndroid Build Coastguard Worker            self._update_careful(dict)
867*cda5da8dSAndroid Build Coastguard Worker        elif mode == "loose":
868*cda5da8dSAndroid Build Coastguard Worker            self._update_loose(dict)
869*cda5da8dSAndroid Build Coastguard Worker        else:
870*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("invalid update mode: %r" % mode)
871*cda5da8dSAndroid Build Coastguard Worker
872*cda5da8dSAndroid Build Coastguard Worker    def read_module(self, modname, mode="careful"):
873*cda5da8dSAndroid Build Coastguard Worker        __import__(modname)
874*cda5da8dSAndroid Build Coastguard Worker        mod = sys.modules[modname]
875*cda5da8dSAndroid Build Coastguard Worker        self._update(vars(mod), mode)
876*cda5da8dSAndroid Build Coastguard Worker
877*cda5da8dSAndroid Build Coastguard Worker    def read_file(self, filename, mode="careful"):
878*cda5da8dSAndroid Build Coastguard Worker        vars = {}
879*cda5da8dSAndroid Build Coastguard Worker        exec(open(filename).read(), vars)
880*cda5da8dSAndroid Build Coastguard Worker        self._update(vars, mode)
881*cda5da8dSAndroid Build Coastguard Worker
882*cda5da8dSAndroid Build Coastguard Worker    def ensure_value(self, attr, value):
883*cda5da8dSAndroid Build Coastguard Worker        if not hasattr(self, attr) or getattr(self, attr) is None:
884*cda5da8dSAndroid Build Coastguard Worker            setattr(self, attr, value)
885*cda5da8dSAndroid Build Coastguard Worker        return getattr(self, attr)
886*cda5da8dSAndroid Build Coastguard Worker
887*cda5da8dSAndroid Build Coastguard Worker
888*cda5da8dSAndroid Build Coastguard Workerclass OptionContainer:
889*cda5da8dSAndroid Build Coastguard Worker
890*cda5da8dSAndroid Build Coastguard Worker    """
891*cda5da8dSAndroid Build Coastguard Worker    Abstract base class.
892*cda5da8dSAndroid Build Coastguard Worker
893*cda5da8dSAndroid Build Coastguard Worker    Class attributes:
894*cda5da8dSAndroid Build Coastguard Worker      standard_option_list : [Option]
895*cda5da8dSAndroid Build Coastguard Worker        list of standard options that will be accepted by all instances
896*cda5da8dSAndroid Build Coastguard Worker        of this parser class (intended to be overridden by subclasses).
897*cda5da8dSAndroid Build Coastguard Worker
898*cda5da8dSAndroid Build Coastguard Worker    Instance attributes:
899*cda5da8dSAndroid Build Coastguard Worker      option_list : [Option]
900*cda5da8dSAndroid Build Coastguard Worker        the list of Option objects contained by this OptionContainer
901*cda5da8dSAndroid Build Coastguard Worker      _short_opt : { string : Option }
902*cda5da8dSAndroid Build Coastguard Worker        dictionary mapping short option strings, eg. "-f" or "-X",
903*cda5da8dSAndroid Build Coastguard Worker        to the Option instances that implement them.  If an Option
904*cda5da8dSAndroid Build Coastguard Worker        has multiple short option strings, it will appear in this
905*cda5da8dSAndroid Build Coastguard Worker        dictionary multiple times. [1]
906*cda5da8dSAndroid Build Coastguard Worker      _long_opt : { string : Option }
907*cda5da8dSAndroid Build Coastguard Worker        dictionary mapping long option strings, eg. "--file" or
908*cda5da8dSAndroid Build Coastguard Worker        "--exclude", to the Option instances that implement them.
909*cda5da8dSAndroid Build Coastguard Worker        Again, a given Option can occur multiple times in this
910*cda5da8dSAndroid Build Coastguard Worker        dictionary. [1]
911*cda5da8dSAndroid Build Coastguard Worker      defaults : { string : any }
912*cda5da8dSAndroid Build Coastguard Worker        dictionary mapping option destination names to default
913*cda5da8dSAndroid Build Coastguard Worker        values for each destination [1]
914*cda5da8dSAndroid Build Coastguard Worker
915*cda5da8dSAndroid Build Coastguard Worker    [1] These mappings are common to (shared by) all components of the
916*cda5da8dSAndroid Build Coastguard Worker        controlling OptionParser, where they are initially created.
917*cda5da8dSAndroid Build Coastguard Worker
918*cda5da8dSAndroid Build Coastguard Worker    """
919*cda5da8dSAndroid Build Coastguard Worker
920*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, option_class, conflict_handler, description):
921*cda5da8dSAndroid Build Coastguard Worker        # Initialize the option list and related data structures.
922*cda5da8dSAndroid Build Coastguard Worker        # This method must be provided by subclasses, and it must
923*cda5da8dSAndroid Build Coastguard Worker        # initialize at least the following instance attributes:
924*cda5da8dSAndroid Build Coastguard Worker        # option_list, _short_opt, _long_opt, defaults.
925*cda5da8dSAndroid Build Coastguard Worker        self._create_option_list()
926*cda5da8dSAndroid Build Coastguard Worker
927*cda5da8dSAndroid Build Coastguard Worker        self.option_class = option_class
928*cda5da8dSAndroid Build Coastguard Worker        self.set_conflict_handler(conflict_handler)
929*cda5da8dSAndroid Build Coastguard Worker        self.set_description(description)
930*cda5da8dSAndroid Build Coastguard Worker
931*cda5da8dSAndroid Build Coastguard Worker    def _create_option_mappings(self):
932*cda5da8dSAndroid Build Coastguard Worker        # For use by OptionParser constructor -- create the main
933*cda5da8dSAndroid Build Coastguard Worker        # option mappings used by this OptionParser and all
934*cda5da8dSAndroid Build Coastguard Worker        # OptionGroups that it owns.
935*cda5da8dSAndroid Build Coastguard Worker        self._short_opt = {}            # single letter -> Option instance
936*cda5da8dSAndroid Build Coastguard Worker        self._long_opt = {}             # long option -> Option instance
937*cda5da8dSAndroid Build Coastguard Worker        self.defaults = {}              # maps option dest -> default value
938*cda5da8dSAndroid Build Coastguard Worker
939*cda5da8dSAndroid Build Coastguard Worker
940*cda5da8dSAndroid Build Coastguard Worker    def _share_option_mappings(self, parser):
941*cda5da8dSAndroid Build Coastguard Worker        # For use by OptionGroup constructor -- use shared option
942*cda5da8dSAndroid Build Coastguard Worker        # mappings from the OptionParser that owns this OptionGroup.
943*cda5da8dSAndroid Build Coastguard Worker        self._short_opt = parser._short_opt
944*cda5da8dSAndroid Build Coastguard Worker        self._long_opt = parser._long_opt
945*cda5da8dSAndroid Build Coastguard Worker        self.defaults = parser.defaults
946*cda5da8dSAndroid Build Coastguard Worker
947*cda5da8dSAndroid Build Coastguard Worker    def set_conflict_handler(self, handler):
948*cda5da8dSAndroid Build Coastguard Worker        if handler not in ("error", "resolve"):
949*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("invalid conflict_resolution value %r" % handler)
950*cda5da8dSAndroid Build Coastguard Worker        self.conflict_handler = handler
951*cda5da8dSAndroid Build Coastguard Worker
952*cda5da8dSAndroid Build Coastguard Worker    def set_description(self, description):
953*cda5da8dSAndroid Build Coastguard Worker        self.description = description
954*cda5da8dSAndroid Build Coastguard Worker
955*cda5da8dSAndroid Build Coastguard Worker    def get_description(self):
956*cda5da8dSAndroid Build Coastguard Worker        return self.description
957*cda5da8dSAndroid Build Coastguard Worker
958*cda5da8dSAndroid Build Coastguard Worker
959*cda5da8dSAndroid Build Coastguard Worker    def destroy(self):
960*cda5da8dSAndroid Build Coastguard Worker        """see OptionParser.destroy()."""
961*cda5da8dSAndroid Build Coastguard Worker        del self._short_opt
962*cda5da8dSAndroid Build Coastguard Worker        del self._long_opt
963*cda5da8dSAndroid Build Coastguard Worker        del self.defaults
964*cda5da8dSAndroid Build Coastguard Worker
965*cda5da8dSAndroid Build Coastguard Worker
966*cda5da8dSAndroid Build Coastguard Worker    # -- Option-adding methods -----------------------------------------
967*cda5da8dSAndroid Build Coastguard Worker
968*cda5da8dSAndroid Build Coastguard Worker    def _check_conflict(self, option):
969*cda5da8dSAndroid Build Coastguard Worker        conflict_opts = []
970*cda5da8dSAndroid Build Coastguard Worker        for opt in option._short_opts:
971*cda5da8dSAndroid Build Coastguard Worker            if opt in self._short_opt:
972*cda5da8dSAndroid Build Coastguard Worker                conflict_opts.append((opt, self._short_opt[opt]))
973*cda5da8dSAndroid Build Coastguard Worker        for opt in option._long_opts:
974*cda5da8dSAndroid Build Coastguard Worker            if opt in self._long_opt:
975*cda5da8dSAndroid Build Coastguard Worker                conflict_opts.append((opt, self._long_opt[opt]))
976*cda5da8dSAndroid Build Coastguard Worker
977*cda5da8dSAndroid Build Coastguard Worker        if conflict_opts:
978*cda5da8dSAndroid Build Coastguard Worker            handler = self.conflict_handler
979*cda5da8dSAndroid Build Coastguard Worker            if handler == "error":
980*cda5da8dSAndroid Build Coastguard Worker                raise OptionConflictError(
981*cda5da8dSAndroid Build Coastguard Worker                    "conflicting option string(s): %s"
982*cda5da8dSAndroid Build Coastguard Worker                    % ", ".join([co[0] for co in conflict_opts]),
983*cda5da8dSAndroid Build Coastguard Worker                    option)
984*cda5da8dSAndroid Build Coastguard Worker            elif handler == "resolve":
985*cda5da8dSAndroid Build Coastguard Worker                for (opt, c_option) in conflict_opts:
986*cda5da8dSAndroid Build Coastguard Worker                    if opt.startswith("--"):
987*cda5da8dSAndroid Build Coastguard Worker                        c_option._long_opts.remove(opt)
988*cda5da8dSAndroid Build Coastguard Worker                        del self._long_opt[opt]
989*cda5da8dSAndroid Build Coastguard Worker                    else:
990*cda5da8dSAndroid Build Coastguard Worker                        c_option._short_opts.remove(opt)
991*cda5da8dSAndroid Build Coastguard Worker                        del self._short_opt[opt]
992*cda5da8dSAndroid Build Coastguard Worker                    if not (c_option._short_opts or c_option._long_opts):
993*cda5da8dSAndroid Build Coastguard Worker                        c_option.container.option_list.remove(c_option)
994*cda5da8dSAndroid Build Coastguard Worker
995*cda5da8dSAndroid Build Coastguard Worker    def add_option(self, *args, **kwargs):
996*cda5da8dSAndroid Build Coastguard Worker        """add_option(Option)
997*cda5da8dSAndroid Build Coastguard Worker           add_option(opt_str, ..., kwarg=val, ...)
998*cda5da8dSAndroid Build Coastguard Worker        """
999*cda5da8dSAndroid Build Coastguard Worker        if isinstance(args[0], str):
1000*cda5da8dSAndroid Build Coastguard Worker            option = self.option_class(*args, **kwargs)
1001*cda5da8dSAndroid Build Coastguard Worker        elif len(args) == 1 and not kwargs:
1002*cda5da8dSAndroid Build Coastguard Worker            option = args[0]
1003*cda5da8dSAndroid Build Coastguard Worker            if not isinstance(option, Option):
1004*cda5da8dSAndroid Build Coastguard Worker                raise TypeError("not an Option instance: %r" % option)
1005*cda5da8dSAndroid Build Coastguard Worker        else:
1006*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("invalid arguments")
1007*cda5da8dSAndroid Build Coastguard Worker
1008*cda5da8dSAndroid Build Coastguard Worker        self._check_conflict(option)
1009*cda5da8dSAndroid Build Coastguard Worker
1010*cda5da8dSAndroid Build Coastguard Worker        self.option_list.append(option)
1011*cda5da8dSAndroid Build Coastguard Worker        option.container = self
1012*cda5da8dSAndroid Build Coastguard Worker        for opt in option._short_opts:
1013*cda5da8dSAndroid Build Coastguard Worker            self._short_opt[opt] = option
1014*cda5da8dSAndroid Build Coastguard Worker        for opt in option._long_opts:
1015*cda5da8dSAndroid Build Coastguard Worker            self._long_opt[opt] = option
1016*cda5da8dSAndroid Build Coastguard Worker
1017*cda5da8dSAndroid Build Coastguard Worker        if option.dest is not None:     # option has a dest, we need a default
1018*cda5da8dSAndroid Build Coastguard Worker            if option.default is not NO_DEFAULT:
1019*cda5da8dSAndroid Build Coastguard Worker                self.defaults[option.dest] = option.default
1020*cda5da8dSAndroid Build Coastguard Worker            elif option.dest not in self.defaults:
1021*cda5da8dSAndroid Build Coastguard Worker                self.defaults[option.dest] = None
1022*cda5da8dSAndroid Build Coastguard Worker
1023*cda5da8dSAndroid Build Coastguard Worker        return option
1024*cda5da8dSAndroid Build Coastguard Worker
1025*cda5da8dSAndroid Build Coastguard Worker    def add_options(self, option_list):
1026*cda5da8dSAndroid Build Coastguard Worker        for option in option_list:
1027*cda5da8dSAndroid Build Coastguard Worker            self.add_option(option)
1028*cda5da8dSAndroid Build Coastguard Worker
1029*cda5da8dSAndroid Build Coastguard Worker    # -- Option query/removal methods ----------------------------------
1030*cda5da8dSAndroid Build Coastguard Worker
1031*cda5da8dSAndroid Build Coastguard Worker    def get_option(self, opt_str):
1032*cda5da8dSAndroid Build Coastguard Worker        return (self._short_opt.get(opt_str) or
1033*cda5da8dSAndroid Build Coastguard Worker                self._long_opt.get(opt_str))
1034*cda5da8dSAndroid Build Coastguard Worker
1035*cda5da8dSAndroid Build Coastguard Worker    def has_option(self, opt_str):
1036*cda5da8dSAndroid Build Coastguard Worker        return (opt_str in self._short_opt or
1037*cda5da8dSAndroid Build Coastguard Worker                opt_str in self._long_opt)
1038*cda5da8dSAndroid Build Coastguard Worker
1039*cda5da8dSAndroid Build Coastguard Worker    def remove_option(self, opt_str):
1040*cda5da8dSAndroid Build Coastguard Worker        option = self._short_opt.get(opt_str)
1041*cda5da8dSAndroid Build Coastguard Worker        if option is None:
1042*cda5da8dSAndroid Build Coastguard Worker            option = self._long_opt.get(opt_str)
1043*cda5da8dSAndroid Build Coastguard Worker        if option is None:
1044*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("no such option %r" % opt_str)
1045*cda5da8dSAndroid Build Coastguard Worker
1046*cda5da8dSAndroid Build Coastguard Worker        for opt in option._short_opts:
1047*cda5da8dSAndroid Build Coastguard Worker            del self._short_opt[opt]
1048*cda5da8dSAndroid Build Coastguard Worker        for opt in option._long_opts:
1049*cda5da8dSAndroid Build Coastguard Worker            del self._long_opt[opt]
1050*cda5da8dSAndroid Build Coastguard Worker        option.container.option_list.remove(option)
1051*cda5da8dSAndroid Build Coastguard Worker
1052*cda5da8dSAndroid Build Coastguard Worker
1053*cda5da8dSAndroid Build Coastguard Worker    # -- Help-formatting methods ---------------------------------------
1054*cda5da8dSAndroid Build Coastguard Worker
1055*cda5da8dSAndroid Build Coastguard Worker    def format_option_help(self, formatter):
1056*cda5da8dSAndroid Build Coastguard Worker        if not self.option_list:
1057*cda5da8dSAndroid Build Coastguard Worker            return ""
1058*cda5da8dSAndroid Build Coastguard Worker        result = []
1059*cda5da8dSAndroid Build Coastguard Worker        for option in self.option_list:
1060*cda5da8dSAndroid Build Coastguard Worker            if not option.help is SUPPRESS_HELP:
1061*cda5da8dSAndroid Build Coastguard Worker                result.append(formatter.format_option(option))
1062*cda5da8dSAndroid Build Coastguard Worker        return "".join(result)
1063*cda5da8dSAndroid Build Coastguard Worker
1064*cda5da8dSAndroid Build Coastguard Worker    def format_description(self, formatter):
1065*cda5da8dSAndroid Build Coastguard Worker        return formatter.format_description(self.get_description())
1066*cda5da8dSAndroid Build Coastguard Worker
1067*cda5da8dSAndroid Build Coastguard Worker    def format_help(self, formatter):
1068*cda5da8dSAndroid Build Coastguard Worker        result = []
1069*cda5da8dSAndroid Build Coastguard Worker        if self.description:
1070*cda5da8dSAndroid Build Coastguard Worker            result.append(self.format_description(formatter))
1071*cda5da8dSAndroid Build Coastguard Worker        if self.option_list:
1072*cda5da8dSAndroid Build Coastguard Worker            result.append(self.format_option_help(formatter))
1073*cda5da8dSAndroid Build Coastguard Worker        return "\n".join(result)
1074*cda5da8dSAndroid Build Coastguard Worker
1075*cda5da8dSAndroid Build Coastguard Worker
1076*cda5da8dSAndroid Build Coastguard Workerclass OptionGroup (OptionContainer):
1077*cda5da8dSAndroid Build Coastguard Worker
1078*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, parser, title, description=None):
1079*cda5da8dSAndroid Build Coastguard Worker        self.parser = parser
1080*cda5da8dSAndroid Build Coastguard Worker        OptionContainer.__init__(
1081*cda5da8dSAndroid Build Coastguard Worker            self, parser.option_class, parser.conflict_handler, description)
1082*cda5da8dSAndroid Build Coastguard Worker        self.title = title
1083*cda5da8dSAndroid Build Coastguard Worker
1084*cda5da8dSAndroid Build Coastguard Worker    def _create_option_list(self):
1085*cda5da8dSAndroid Build Coastguard Worker        self.option_list = []
1086*cda5da8dSAndroid Build Coastguard Worker        self._share_option_mappings(self.parser)
1087*cda5da8dSAndroid Build Coastguard Worker
1088*cda5da8dSAndroid Build Coastguard Worker    def set_title(self, title):
1089*cda5da8dSAndroid Build Coastguard Worker        self.title = title
1090*cda5da8dSAndroid Build Coastguard Worker
1091*cda5da8dSAndroid Build Coastguard Worker    def destroy(self):
1092*cda5da8dSAndroid Build Coastguard Worker        """see OptionParser.destroy()."""
1093*cda5da8dSAndroid Build Coastguard Worker        OptionContainer.destroy(self)
1094*cda5da8dSAndroid Build Coastguard Worker        del self.option_list
1095*cda5da8dSAndroid Build Coastguard Worker
1096*cda5da8dSAndroid Build Coastguard Worker    # -- Help-formatting methods ---------------------------------------
1097*cda5da8dSAndroid Build Coastguard Worker
1098*cda5da8dSAndroid Build Coastguard Worker    def format_help(self, formatter):
1099*cda5da8dSAndroid Build Coastguard Worker        result = formatter.format_heading(self.title)
1100*cda5da8dSAndroid Build Coastguard Worker        formatter.indent()
1101*cda5da8dSAndroid Build Coastguard Worker        result += OptionContainer.format_help(self, formatter)
1102*cda5da8dSAndroid Build Coastguard Worker        formatter.dedent()
1103*cda5da8dSAndroid Build Coastguard Worker        return result
1104*cda5da8dSAndroid Build Coastguard Worker
1105*cda5da8dSAndroid Build Coastguard Worker
1106*cda5da8dSAndroid Build Coastguard Workerclass OptionParser (OptionContainer):
1107*cda5da8dSAndroid Build Coastguard Worker
1108*cda5da8dSAndroid Build Coastguard Worker    """
1109*cda5da8dSAndroid Build Coastguard Worker    Class attributes:
1110*cda5da8dSAndroid Build Coastguard Worker      standard_option_list : [Option]
1111*cda5da8dSAndroid Build Coastguard Worker        list of standard options that will be accepted by all instances
1112*cda5da8dSAndroid Build Coastguard Worker        of this parser class (intended to be overridden by subclasses).
1113*cda5da8dSAndroid Build Coastguard Worker
1114*cda5da8dSAndroid Build Coastguard Worker    Instance attributes:
1115*cda5da8dSAndroid Build Coastguard Worker      usage : string
1116*cda5da8dSAndroid Build Coastguard Worker        a usage string for your program.  Before it is displayed
1117*cda5da8dSAndroid Build Coastguard Worker        to the user, "%prog" will be expanded to the name of
1118*cda5da8dSAndroid Build Coastguard Worker        your program (self.prog or os.path.basename(sys.argv[0])).
1119*cda5da8dSAndroid Build Coastguard Worker      prog : string
1120*cda5da8dSAndroid Build Coastguard Worker        the name of the current program (to override
1121*cda5da8dSAndroid Build Coastguard Worker        os.path.basename(sys.argv[0])).
1122*cda5da8dSAndroid Build Coastguard Worker      description : string
1123*cda5da8dSAndroid Build Coastguard Worker        A paragraph of text giving a brief overview of your program.
1124*cda5da8dSAndroid Build Coastguard Worker        optparse reformats this paragraph to fit the current terminal
1125*cda5da8dSAndroid Build Coastguard Worker        width and prints it when the user requests help (after usage,
1126*cda5da8dSAndroid Build Coastguard Worker        but before the list of options).
1127*cda5da8dSAndroid Build Coastguard Worker      epilog : string
1128*cda5da8dSAndroid Build Coastguard Worker        paragraph of help text to print after option help
1129*cda5da8dSAndroid Build Coastguard Worker
1130*cda5da8dSAndroid Build Coastguard Worker      option_groups : [OptionGroup]
1131*cda5da8dSAndroid Build Coastguard Worker        list of option groups in this parser (option groups are
1132*cda5da8dSAndroid Build Coastguard Worker        irrelevant for parsing the command-line, but very useful
1133*cda5da8dSAndroid Build Coastguard Worker        for generating help)
1134*cda5da8dSAndroid Build Coastguard Worker
1135*cda5da8dSAndroid Build Coastguard Worker      allow_interspersed_args : bool = true
1136*cda5da8dSAndroid Build Coastguard Worker        if true, positional arguments may be interspersed with options.
1137*cda5da8dSAndroid Build Coastguard Worker        Assuming -a and -b each take a single argument, the command-line
1138*cda5da8dSAndroid Build Coastguard Worker          -ablah foo bar -bboo baz
1139*cda5da8dSAndroid Build Coastguard Worker        will be interpreted the same as
1140*cda5da8dSAndroid Build Coastguard Worker          -ablah -bboo -- foo bar baz
1141*cda5da8dSAndroid Build Coastguard Worker        If this flag were false, that command line would be interpreted as
1142*cda5da8dSAndroid Build Coastguard Worker          -ablah -- foo bar -bboo baz
1143*cda5da8dSAndroid Build Coastguard Worker        -- ie. we stop processing options as soon as we see the first
1144*cda5da8dSAndroid Build Coastguard Worker        non-option argument.  (This is the tradition followed by
1145*cda5da8dSAndroid Build Coastguard Worker        Python's getopt module, Perl's Getopt::Std, and other argument-
1146*cda5da8dSAndroid Build Coastguard Worker        parsing libraries, but it is generally annoying to users.)
1147*cda5da8dSAndroid Build Coastguard Worker
1148*cda5da8dSAndroid Build Coastguard Worker      process_default_values : bool = true
1149*cda5da8dSAndroid Build Coastguard Worker        if true, option default values are processed similarly to option
1150*cda5da8dSAndroid Build Coastguard Worker        values from the command line: that is, they are passed to the
1151*cda5da8dSAndroid Build Coastguard Worker        type-checking function for the option's type (as long as the
1152*cda5da8dSAndroid Build Coastguard Worker        default value is a string).  (This really only matters if you
1153*cda5da8dSAndroid Build Coastguard Worker        have defined custom types; see SF bug #955889.)  Set it to false
1154*cda5da8dSAndroid Build Coastguard Worker        to restore the behaviour of Optik 1.4.1 and earlier.
1155*cda5da8dSAndroid Build Coastguard Worker
1156*cda5da8dSAndroid Build Coastguard Worker      rargs : [string]
1157*cda5da8dSAndroid Build Coastguard Worker        the argument list currently being parsed.  Only set when
1158*cda5da8dSAndroid Build Coastguard Worker        parse_args() is active, and continually trimmed down as
1159*cda5da8dSAndroid Build Coastguard Worker        we consume arguments.  Mainly there for the benefit of
1160*cda5da8dSAndroid Build Coastguard Worker        callback options.
1161*cda5da8dSAndroid Build Coastguard Worker      largs : [string]
1162*cda5da8dSAndroid Build Coastguard Worker        the list of leftover arguments that we have skipped while
1163*cda5da8dSAndroid Build Coastguard Worker        parsing options.  If allow_interspersed_args is false, this
1164*cda5da8dSAndroid Build Coastguard Worker        list is always empty.
1165*cda5da8dSAndroid Build Coastguard Worker      values : Values
1166*cda5da8dSAndroid Build Coastguard Worker        the set of option values currently being accumulated.  Only
1167*cda5da8dSAndroid Build Coastguard Worker        set when parse_args() is active.  Also mainly for callbacks.
1168*cda5da8dSAndroid Build Coastguard Worker
1169*cda5da8dSAndroid Build Coastguard Worker    Because of the 'rargs', 'largs', and 'values' attributes,
1170*cda5da8dSAndroid Build Coastguard Worker    OptionParser is not thread-safe.  If, for some perverse reason, you
1171*cda5da8dSAndroid Build Coastguard Worker    need to parse command-line arguments simultaneously in different
1172*cda5da8dSAndroid Build Coastguard Worker    threads, use different OptionParser instances.
1173*cda5da8dSAndroid Build Coastguard Worker
1174*cda5da8dSAndroid Build Coastguard Worker    """
1175*cda5da8dSAndroid Build Coastguard Worker
1176*cda5da8dSAndroid Build Coastguard Worker    standard_option_list = []
1177*cda5da8dSAndroid Build Coastguard Worker
1178*cda5da8dSAndroid Build Coastguard Worker    def __init__(self,
1179*cda5da8dSAndroid Build Coastguard Worker                 usage=None,
1180*cda5da8dSAndroid Build Coastguard Worker                 option_list=None,
1181*cda5da8dSAndroid Build Coastguard Worker                 option_class=Option,
1182*cda5da8dSAndroid Build Coastguard Worker                 version=None,
1183*cda5da8dSAndroid Build Coastguard Worker                 conflict_handler="error",
1184*cda5da8dSAndroid Build Coastguard Worker                 description=None,
1185*cda5da8dSAndroid Build Coastguard Worker                 formatter=None,
1186*cda5da8dSAndroid Build Coastguard Worker                 add_help_option=True,
1187*cda5da8dSAndroid Build Coastguard Worker                 prog=None,
1188*cda5da8dSAndroid Build Coastguard Worker                 epilog=None):
1189*cda5da8dSAndroid Build Coastguard Worker        OptionContainer.__init__(
1190*cda5da8dSAndroid Build Coastguard Worker            self, option_class, conflict_handler, description)
1191*cda5da8dSAndroid Build Coastguard Worker        self.set_usage(usage)
1192*cda5da8dSAndroid Build Coastguard Worker        self.prog = prog
1193*cda5da8dSAndroid Build Coastguard Worker        self.version = version
1194*cda5da8dSAndroid Build Coastguard Worker        self.allow_interspersed_args = True
1195*cda5da8dSAndroid Build Coastguard Worker        self.process_default_values = True
1196*cda5da8dSAndroid Build Coastguard Worker        if formatter is None:
1197*cda5da8dSAndroid Build Coastguard Worker            formatter = IndentedHelpFormatter()
1198*cda5da8dSAndroid Build Coastguard Worker        self.formatter = formatter
1199*cda5da8dSAndroid Build Coastguard Worker        self.formatter.set_parser(self)
1200*cda5da8dSAndroid Build Coastguard Worker        self.epilog = epilog
1201*cda5da8dSAndroid Build Coastguard Worker
1202*cda5da8dSAndroid Build Coastguard Worker        # Populate the option list; initial sources are the
1203*cda5da8dSAndroid Build Coastguard Worker        # standard_option_list class attribute, the 'option_list'
1204*cda5da8dSAndroid Build Coastguard Worker        # argument, and (if applicable) the _add_version_option() and
1205*cda5da8dSAndroid Build Coastguard Worker        # _add_help_option() methods.
1206*cda5da8dSAndroid Build Coastguard Worker        self._populate_option_list(option_list,
1207*cda5da8dSAndroid Build Coastguard Worker                                   add_help=add_help_option)
1208*cda5da8dSAndroid Build Coastguard Worker
1209*cda5da8dSAndroid Build Coastguard Worker        self._init_parsing_state()
1210*cda5da8dSAndroid Build Coastguard Worker
1211*cda5da8dSAndroid Build Coastguard Worker
1212*cda5da8dSAndroid Build Coastguard Worker    def destroy(self):
1213*cda5da8dSAndroid Build Coastguard Worker        """
1214*cda5da8dSAndroid Build Coastguard Worker        Declare that you are done with this OptionParser.  This cleans up
1215*cda5da8dSAndroid Build Coastguard Worker        reference cycles so the OptionParser (and all objects referenced by
1216*cda5da8dSAndroid Build Coastguard Worker        it) can be garbage-collected promptly.  After calling destroy(), the
1217*cda5da8dSAndroid Build Coastguard Worker        OptionParser is unusable.
1218*cda5da8dSAndroid Build Coastguard Worker        """
1219*cda5da8dSAndroid Build Coastguard Worker        OptionContainer.destroy(self)
1220*cda5da8dSAndroid Build Coastguard Worker        for group in self.option_groups:
1221*cda5da8dSAndroid Build Coastguard Worker            group.destroy()
1222*cda5da8dSAndroid Build Coastguard Worker        del self.option_list
1223*cda5da8dSAndroid Build Coastguard Worker        del self.option_groups
1224*cda5da8dSAndroid Build Coastguard Worker        del self.formatter
1225*cda5da8dSAndroid Build Coastguard Worker
1226*cda5da8dSAndroid Build Coastguard Worker
1227*cda5da8dSAndroid Build Coastguard Worker    # -- Private methods -----------------------------------------------
1228*cda5da8dSAndroid Build Coastguard Worker    # (used by our or OptionContainer's constructor)
1229*cda5da8dSAndroid Build Coastguard Worker
1230*cda5da8dSAndroid Build Coastguard Worker    def _create_option_list(self):
1231*cda5da8dSAndroid Build Coastguard Worker        self.option_list = []
1232*cda5da8dSAndroid Build Coastguard Worker        self.option_groups = []
1233*cda5da8dSAndroid Build Coastguard Worker        self._create_option_mappings()
1234*cda5da8dSAndroid Build Coastguard Worker
1235*cda5da8dSAndroid Build Coastguard Worker    def _add_help_option(self):
1236*cda5da8dSAndroid Build Coastguard Worker        self.add_option("-h", "--help",
1237*cda5da8dSAndroid Build Coastguard Worker                        action="help",
1238*cda5da8dSAndroid Build Coastguard Worker                        help=_("show this help message and exit"))
1239*cda5da8dSAndroid Build Coastguard Worker
1240*cda5da8dSAndroid Build Coastguard Worker    def _add_version_option(self):
1241*cda5da8dSAndroid Build Coastguard Worker        self.add_option("--version",
1242*cda5da8dSAndroid Build Coastguard Worker                        action="version",
1243*cda5da8dSAndroid Build Coastguard Worker                        help=_("show program's version number and exit"))
1244*cda5da8dSAndroid Build Coastguard Worker
1245*cda5da8dSAndroid Build Coastguard Worker    def _populate_option_list(self, option_list, add_help=True):
1246*cda5da8dSAndroid Build Coastguard Worker        if self.standard_option_list:
1247*cda5da8dSAndroid Build Coastguard Worker            self.add_options(self.standard_option_list)
1248*cda5da8dSAndroid Build Coastguard Worker        if option_list:
1249*cda5da8dSAndroid Build Coastguard Worker            self.add_options(option_list)
1250*cda5da8dSAndroid Build Coastguard Worker        if self.version:
1251*cda5da8dSAndroid Build Coastguard Worker            self._add_version_option()
1252*cda5da8dSAndroid Build Coastguard Worker        if add_help:
1253*cda5da8dSAndroid Build Coastguard Worker            self._add_help_option()
1254*cda5da8dSAndroid Build Coastguard Worker
1255*cda5da8dSAndroid Build Coastguard Worker    def _init_parsing_state(self):
1256*cda5da8dSAndroid Build Coastguard Worker        # These are set in parse_args() for the convenience of callbacks.
1257*cda5da8dSAndroid Build Coastguard Worker        self.rargs = None
1258*cda5da8dSAndroid Build Coastguard Worker        self.largs = None
1259*cda5da8dSAndroid Build Coastguard Worker        self.values = None
1260*cda5da8dSAndroid Build Coastguard Worker
1261*cda5da8dSAndroid Build Coastguard Worker
1262*cda5da8dSAndroid Build Coastguard Worker    # -- Simple modifier methods ---------------------------------------
1263*cda5da8dSAndroid Build Coastguard Worker
1264*cda5da8dSAndroid Build Coastguard Worker    def set_usage(self, usage):
1265*cda5da8dSAndroid Build Coastguard Worker        if usage is None:
1266*cda5da8dSAndroid Build Coastguard Worker            self.usage = _("%prog [options]")
1267*cda5da8dSAndroid Build Coastguard Worker        elif usage is SUPPRESS_USAGE:
1268*cda5da8dSAndroid Build Coastguard Worker            self.usage = None
1269*cda5da8dSAndroid Build Coastguard Worker        # For backwards compatibility with Optik 1.3 and earlier.
1270*cda5da8dSAndroid Build Coastguard Worker        elif usage.lower().startswith("usage: "):
1271*cda5da8dSAndroid Build Coastguard Worker            self.usage = usage[7:]
1272*cda5da8dSAndroid Build Coastguard Worker        else:
1273*cda5da8dSAndroid Build Coastguard Worker            self.usage = usage
1274*cda5da8dSAndroid Build Coastguard Worker
1275*cda5da8dSAndroid Build Coastguard Worker    def enable_interspersed_args(self):
1276*cda5da8dSAndroid Build Coastguard Worker        """Set parsing to not stop on the first non-option, allowing
1277*cda5da8dSAndroid Build Coastguard Worker        interspersing switches with command arguments. This is the
1278*cda5da8dSAndroid Build Coastguard Worker        default behavior. See also disable_interspersed_args() and the
1279*cda5da8dSAndroid Build Coastguard Worker        class documentation description of the attribute
1280*cda5da8dSAndroid Build Coastguard Worker        allow_interspersed_args."""
1281*cda5da8dSAndroid Build Coastguard Worker        self.allow_interspersed_args = True
1282*cda5da8dSAndroid Build Coastguard Worker
1283*cda5da8dSAndroid Build Coastguard Worker    def disable_interspersed_args(self):
1284*cda5da8dSAndroid Build Coastguard Worker        """Set parsing to stop on the first non-option. Use this if
1285*cda5da8dSAndroid Build Coastguard Worker        you have a command processor which runs another command that
1286*cda5da8dSAndroid Build Coastguard Worker        has options of its own and you want to make sure these options
1287*cda5da8dSAndroid Build Coastguard Worker        don't get confused.
1288*cda5da8dSAndroid Build Coastguard Worker        """
1289*cda5da8dSAndroid Build Coastguard Worker        self.allow_interspersed_args = False
1290*cda5da8dSAndroid Build Coastguard Worker
1291*cda5da8dSAndroid Build Coastguard Worker    def set_process_default_values(self, process):
1292*cda5da8dSAndroid Build Coastguard Worker        self.process_default_values = process
1293*cda5da8dSAndroid Build Coastguard Worker
1294*cda5da8dSAndroid Build Coastguard Worker    def set_default(self, dest, value):
1295*cda5da8dSAndroid Build Coastguard Worker        self.defaults[dest] = value
1296*cda5da8dSAndroid Build Coastguard Worker
1297*cda5da8dSAndroid Build Coastguard Worker    def set_defaults(self, **kwargs):
1298*cda5da8dSAndroid Build Coastguard Worker        self.defaults.update(kwargs)
1299*cda5da8dSAndroid Build Coastguard Worker
1300*cda5da8dSAndroid Build Coastguard Worker    def _get_all_options(self):
1301*cda5da8dSAndroid Build Coastguard Worker        options = self.option_list[:]
1302*cda5da8dSAndroid Build Coastguard Worker        for group in self.option_groups:
1303*cda5da8dSAndroid Build Coastguard Worker            options.extend(group.option_list)
1304*cda5da8dSAndroid Build Coastguard Worker        return options
1305*cda5da8dSAndroid Build Coastguard Worker
1306*cda5da8dSAndroid Build Coastguard Worker    def get_default_values(self):
1307*cda5da8dSAndroid Build Coastguard Worker        if not self.process_default_values:
1308*cda5da8dSAndroid Build Coastguard Worker            # Old, pre-Optik 1.5 behaviour.
1309*cda5da8dSAndroid Build Coastguard Worker            return Values(self.defaults)
1310*cda5da8dSAndroid Build Coastguard Worker
1311*cda5da8dSAndroid Build Coastguard Worker        defaults = self.defaults.copy()
1312*cda5da8dSAndroid Build Coastguard Worker        for option in self._get_all_options():
1313*cda5da8dSAndroid Build Coastguard Worker            default = defaults.get(option.dest)
1314*cda5da8dSAndroid Build Coastguard Worker            if isinstance(default, str):
1315*cda5da8dSAndroid Build Coastguard Worker                opt_str = option.get_opt_string()
1316*cda5da8dSAndroid Build Coastguard Worker                defaults[option.dest] = option.check_value(opt_str, default)
1317*cda5da8dSAndroid Build Coastguard Worker
1318*cda5da8dSAndroid Build Coastguard Worker        return Values(defaults)
1319*cda5da8dSAndroid Build Coastguard Worker
1320*cda5da8dSAndroid Build Coastguard Worker
1321*cda5da8dSAndroid Build Coastguard Worker    # -- OptionGroup methods -------------------------------------------
1322*cda5da8dSAndroid Build Coastguard Worker
1323*cda5da8dSAndroid Build Coastguard Worker    def add_option_group(self, *args, **kwargs):
1324*cda5da8dSAndroid Build Coastguard Worker        # XXX lots of overlap with OptionContainer.add_option()
1325*cda5da8dSAndroid Build Coastguard Worker        if isinstance(args[0], str):
1326*cda5da8dSAndroid Build Coastguard Worker            group = OptionGroup(self, *args, **kwargs)
1327*cda5da8dSAndroid Build Coastguard Worker        elif len(args) == 1 and not kwargs:
1328*cda5da8dSAndroid Build Coastguard Worker            group = args[0]
1329*cda5da8dSAndroid Build Coastguard Worker            if not isinstance(group, OptionGroup):
1330*cda5da8dSAndroid Build Coastguard Worker                raise TypeError("not an OptionGroup instance: %r" % group)
1331*cda5da8dSAndroid Build Coastguard Worker            if group.parser is not self:
1332*cda5da8dSAndroid Build Coastguard Worker                raise ValueError("invalid OptionGroup (wrong parser)")
1333*cda5da8dSAndroid Build Coastguard Worker        else:
1334*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("invalid arguments")
1335*cda5da8dSAndroid Build Coastguard Worker
1336*cda5da8dSAndroid Build Coastguard Worker        self.option_groups.append(group)
1337*cda5da8dSAndroid Build Coastguard Worker        return group
1338*cda5da8dSAndroid Build Coastguard Worker
1339*cda5da8dSAndroid Build Coastguard Worker    def get_option_group(self, opt_str):
1340*cda5da8dSAndroid Build Coastguard Worker        option = (self._short_opt.get(opt_str) or
1341*cda5da8dSAndroid Build Coastguard Worker                  self._long_opt.get(opt_str))
1342*cda5da8dSAndroid Build Coastguard Worker        if option and option.container is not self:
1343*cda5da8dSAndroid Build Coastguard Worker            return option.container
1344*cda5da8dSAndroid Build Coastguard Worker        return None
1345*cda5da8dSAndroid Build Coastguard Worker
1346*cda5da8dSAndroid Build Coastguard Worker
1347*cda5da8dSAndroid Build Coastguard Worker    # -- Option-parsing methods ----------------------------------------
1348*cda5da8dSAndroid Build Coastguard Worker
1349*cda5da8dSAndroid Build Coastguard Worker    def _get_args(self, args):
1350*cda5da8dSAndroid Build Coastguard Worker        if args is None:
1351*cda5da8dSAndroid Build Coastguard Worker            return sys.argv[1:]
1352*cda5da8dSAndroid Build Coastguard Worker        else:
1353*cda5da8dSAndroid Build Coastguard Worker            return args[:]              # don't modify caller's list
1354*cda5da8dSAndroid Build Coastguard Worker
1355*cda5da8dSAndroid Build Coastguard Worker    def parse_args(self, args=None, values=None):
1356*cda5da8dSAndroid Build Coastguard Worker        """
1357*cda5da8dSAndroid Build Coastguard Worker        parse_args(args : [string] = sys.argv[1:],
1358*cda5da8dSAndroid Build Coastguard Worker                   values : Values = None)
1359*cda5da8dSAndroid Build Coastguard Worker        -> (values : Values, args : [string])
1360*cda5da8dSAndroid Build Coastguard Worker
1361*cda5da8dSAndroid Build Coastguard Worker        Parse the command-line options found in 'args' (default:
1362*cda5da8dSAndroid Build Coastguard Worker        sys.argv[1:]).  Any errors result in a call to 'error()', which
1363*cda5da8dSAndroid Build Coastguard Worker        by default prints the usage message to stderr and calls
1364*cda5da8dSAndroid Build Coastguard Worker        sys.exit() with an error message.  On success returns a pair
1365*cda5da8dSAndroid Build Coastguard Worker        (values, args) where 'values' is a Values instance (with all
1366*cda5da8dSAndroid Build Coastguard Worker        your option values) and 'args' is the list of arguments left
1367*cda5da8dSAndroid Build Coastguard Worker        over after parsing options.
1368*cda5da8dSAndroid Build Coastguard Worker        """
1369*cda5da8dSAndroid Build Coastguard Worker        rargs = self._get_args(args)
1370*cda5da8dSAndroid Build Coastguard Worker        if values is None:
1371*cda5da8dSAndroid Build Coastguard Worker            values = self.get_default_values()
1372*cda5da8dSAndroid Build Coastguard Worker
1373*cda5da8dSAndroid Build Coastguard Worker        # Store the halves of the argument list as attributes for the
1374*cda5da8dSAndroid Build Coastguard Worker        # convenience of callbacks:
1375*cda5da8dSAndroid Build Coastguard Worker        #   rargs
1376*cda5da8dSAndroid Build Coastguard Worker        #     the rest of the command-line (the "r" stands for
1377*cda5da8dSAndroid Build Coastguard Worker        #     "remaining" or "right-hand")
1378*cda5da8dSAndroid Build Coastguard Worker        #   largs
1379*cda5da8dSAndroid Build Coastguard Worker        #     the leftover arguments -- ie. what's left after removing
1380*cda5da8dSAndroid Build Coastguard Worker        #     options and their arguments (the "l" stands for "leftover"
1381*cda5da8dSAndroid Build Coastguard Worker        #     or "left-hand")
1382*cda5da8dSAndroid Build Coastguard Worker        self.rargs = rargs
1383*cda5da8dSAndroid Build Coastguard Worker        self.largs = largs = []
1384*cda5da8dSAndroid Build Coastguard Worker        self.values = values
1385*cda5da8dSAndroid Build Coastguard Worker
1386*cda5da8dSAndroid Build Coastguard Worker        try:
1387*cda5da8dSAndroid Build Coastguard Worker            stop = self._process_args(largs, rargs, values)
1388*cda5da8dSAndroid Build Coastguard Worker        except (BadOptionError, OptionValueError) as err:
1389*cda5da8dSAndroid Build Coastguard Worker            self.error(str(err))
1390*cda5da8dSAndroid Build Coastguard Worker
1391*cda5da8dSAndroid Build Coastguard Worker        args = largs + rargs
1392*cda5da8dSAndroid Build Coastguard Worker        return self.check_values(values, args)
1393*cda5da8dSAndroid Build Coastguard Worker
1394*cda5da8dSAndroid Build Coastguard Worker    def check_values(self, values, args):
1395*cda5da8dSAndroid Build Coastguard Worker        """
1396*cda5da8dSAndroid Build Coastguard Worker        check_values(values : Values, args : [string])
1397*cda5da8dSAndroid Build Coastguard Worker        -> (values : Values, args : [string])
1398*cda5da8dSAndroid Build Coastguard Worker
1399*cda5da8dSAndroid Build Coastguard Worker        Check that the supplied option values and leftover arguments are
1400*cda5da8dSAndroid Build Coastguard Worker        valid.  Returns the option values and leftover arguments
1401*cda5da8dSAndroid Build Coastguard Worker        (possibly adjusted, possibly completely new -- whatever you
1402*cda5da8dSAndroid Build Coastguard Worker        like).  Default implementation just returns the passed-in
1403*cda5da8dSAndroid Build Coastguard Worker        values; subclasses may override as desired.
1404*cda5da8dSAndroid Build Coastguard Worker        """
1405*cda5da8dSAndroid Build Coastguard Worker        return (values, args)
1406*cda5da8dSAndroid Build Coastguard Worker
1407*cda5da8dSAndroid Build Coastguard Worker    def _process_args(self, largs, rargs, values):
1408*cda5da8dSAndroid Build Coastguard Worker        """_process_args(largs : [string],
1409*cda5da8dSAndroid Build Coastguard Worker                         rargs : [string],
1410*cda5da8dSAndroid Build Coastguard Worker                         values : Values)
1411*cda5da8dSAndroid Build Coastguard Worker
1412*cda5da8dSAndroid Build Coastguard Worker        Process command-line arguments and populate 'values', consuming
1413*cda5da8dSAndroid Build Coastguard Worker        options and arguments from 'rargs'.  If 'allow_interspersed_args' is
1414*cda5da8dSAndroid Build Coastguard Worker        false, stop at the first non-option argument.  If true, accumulate any
1415*cda5da8dSAndroid Build Coastguard Worker        interspersed non-option arguments in 'largs'.
1416*cda5da8dSAndroid Build Coastguard Worker        """
1417*cda5da8dSAndroid Build Coastguard Worker        while rargs:
1418*cda5da8dSAndroid Build Coastguard Worker            arg = rargs[0]
1419*cda5da8dSAndroid Build Coastguard Worker            # We handle bare "--" explicitly, and bare "-" is handled by the
1420*cda5da8dSAndroid Build Coastguard Worker            # standard arg handler since the short arg case ensures that the
1421*cda5da8dSAndroid Build Coastguard Worker            # len of the opt string is greater than 1.
1422*cda5da8dSAndroid Build Coastguard Worker            if arg == "--":
1423*cda5da8dSAndroid Build Coastguard Worker                del rargs[0]
1424*cda5da8dSAndroid Build Coastguard Worker                return
1425*cda5da8dSAndroid Build Coastguard Worker            elif arg[0:2] == "--":
1426*cda5da8dSAndroid Build Coastguard Worker                # process a single long option (possibly with value(s))
1427*cda5da8dSAndroid Build Coastguard Worker                self._process_long_opt(rargs, values)
1428*cda5da8dSAndroid Build Coastguard Worker            elif arg[:1] == "-" and len(arg) > 1:
1429*cda5da8dSAndroid Build Coastguard Worker                # process a cluster of short options (possibly with
1430*cda5da8dSAndroid Build Coastguard Worker                # value(s) for the last one only)
1431*cda5da8dSAndroid Build Coastguard Worker                self._process_short_opts(rargs, values)
1432*cda5da8dSAndroid Build Coastguard Worker            elif self.allow_interspersed_args:
1433*cda5da8dSAndroid Build Coastguard Worker                largs.append(arg)
1434*cda5da8dSAndroid Build Coastguard Worker                del rargs[0]
1435*cda5da8dSAndroid Build Coastguard Worker            else:
1436*cda5da8dSAndroid Build Coastguard Worker                return                  # stop now, leave this arg in rargs
1437*cda5da8dSAndroid Build Coastguard Worker
1438*cda5da8dSAndroid Build Coastguard Worker        # Say this is the original argument list:
1439*cda5da8dSAndroid Build Coastguard Worker        # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)]
1440*cda5da8dSAndroid Build Coastguard Worker        #                            ^
1441*cda5da8dSAndroid Build Coastguard Worker        # (we are about to process arg(i)).
1442*cda5da8dSAndroid Build Coastguard Worker        #
1443*cda5da8dSAndroid Build Coastguard Worker        # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of
1444*cda5da8dSAndroid Build Coastguard Worker        # [arg0, ..., arg(i-1)] (any options and their arguments will have
1445*cda5da8dSAndroid Build Coastguard Worker        # been removed from largs).
1446*cda5da8dSAndroid Build Coastguard Worker        #
1447*cda5da8dSAndroid Build Coastguard Worker        # The while loop will usually consume 1 or more arguments per pass.
1448*cda5da8dSAndroid Build Coastguard Worker        # If it consumes 1 (eg. arg is an option that takes no arguments),
1449*cda5da8dSAndroid Build Coastguard Worker        # then after _process_arg() is done the situation is:
1450*cda5da8dSAndroid Build Coastguard Worker        #
1451*cda5da8dSAndroid Build Coastguard Worker        #   largs = subset of [arg0, ..., arg(i)]
1452*cda5da8dSAndroid Build Coastguard Worker        #   rargs = [arg(i+1), ..., arg(N-1)]
1453*cda5da8dSAndroid Build Coastguard Worker        #
1454*cda5da8dSAndroid Build Coastguard Worker        # If allow_interspersed_args is false, largs will always be
1455*cda5da8dSAndroid Build Coastguard Worker        # *empty* -- still a subset of [arg0, ..., arg(i-1)], but
1456*cda5da8dSAndroid Build Coastguard Worker        # not a very interesting subset!
1457*cda5da8dSAndroid Build Coastguard Worker
1458*cda5da8dSAndroid Build Coastguard Worker    def _match_long_opt(self, opt):
1459*cda5da8dSAndroid Build Coastguard Worker        """_match_long_opt(opt : string) -> string
1460*cda5da8dSAndroid Build Coastguard Worker
1461*cda5da8dSAndroid Build Coastguard Worker        Determine which long option string 'opt' matches, ie. which one
1462*cda5da8dSAndroid Build Coastguard Worker        it is an unambiguous abbreviation for.  Raises BadOptionError if
1463*cda5da8dSAndroid Build Coastguard Worker        'opt' doesn't unambiguously match any long option string.
1464*cda5da8dSAndroid Build Coastguard Worker        """
1465*cda5da8dSAndroid Build Coastguard Worker        return _match_abbrev(opt, self._long_opt)
1466*cda5da8dSAndroid Build Coastguard Worker
1467*cda5da8dSAndroid Build Coastguard Worker    def _process_long_opt(self, rargs, values):
1468*cda5da8dSAndroid Build Coastguard Worker        arg = rargs.pop(0)
1469*cda5da8dSAndroid Build Coastguard Worker
1470*cda5da8dSAndroid Build Coastguard Worker        # Value explicitly attached to arg?  Pretend it's the next
1471*cda5da8dSAndroid Build Coastguard Worker        # argument.
1472*cda5da8dSAndroid Build Coastguard Worker        if "=" in arg:
1473*cda5da8dSAndroid Build Coastguard Worker            (opt, next_arg) = arg.split("=", 1)
1474*cda5da8dSAndroid Build Coastguard Worker            rargs.insert(0, next_arg)
1475*cda5da8dSAndroid Build Coastguard Worker            had_explicit_value = True
1476*cda5da8dSAndroid Build Coastguard Worker        else:
1477*cda5da8dSAndroid Build Coastguard Worker            opt = arg
1478*cda5da8dSAndroid Build Coastguard Worker            had_explicit_value = False
1479*cda5da8dSAndroid Build Coastguard Worker
1480*cda5da8dSAndroid Build Coastguard Worker        opt = self._match_long_opt(opt)
1481*cda5da8dSAndroid Build Coastguard Worker        option = self._long_opt[opt]
1482*cda5da8dSAndroid Build Coastguard Worker        if option.takes_value():
1483*cda5da8dSAndroid Build Coastguard Worker            nargs = option.nargs
1484*cda5da8dSAndroid Build Coastguard Worker            if len(rargs) < nargs:
1485*cda5da8dSAndroid Build Coastguard Worker                self.error(ngettext(
1486*cda5da8dSAndroid Build Coastguard Worker                    "%(option)s option requires %(number)d argument",
1487*cda5da8dSAndroid Build Coastguard Worker                    "%(option)s option requires %(number)d arguments",
1488*cda5da8dSAndroid Build Coastguard Worker                    nargs) % {"option": opt, "number": nargs})
1489*cda5da8dSAndroid Build Coastguard Worker            elif nargs == 1:
1490*cda5da8dSAndroid Build Coastguard Worker                value = rargs.pop(0)
1491*cda5da8dSAndroid Build Coastguard Worker            else:
1492*cda5da8dSAndroid Build Coastguard Worker                value = tuple(rargs[0:nargs])
1493*cda5da8dSAndroid Build Coastguard Worker                del rargs[0:nargs]
1494*cda5da8dSAndroid Build Coastguard Worker
1495*cda5da8dSAndroid Build Coastguard Worker        elif had_explicit_value:
1496*cda5da8dSAndroid Build Coastguard Worker            self.error(_("%s option does not take a value") % opt)
1497*cda5da8dSAndroid Build Coastguard Worker
1498*cda5da8dSAndroid Build Coastguard Worker        else:
1499*cda5da8dSAndroid Build Coastguard Worker            value = None
1500*cda5da8dSAndroid Build Coastguard Worker
1501*cda5da8dSAndroid Build Coastguard Worker        option.process(opt, value, values, self)
1502*cda5da8dSAndroid Build Coastguard Worker
1503*cda5da8dSAndroid Build Coastguard Worker    def _process_short_opts(self, rargs, values):
1504*cda5da8dSAndroid Build Coastguard Worker        arg = rargs.pop(0)
1505*cda5da8dSAndroid Build Coastguard Worker        stop = False
1506*cda5da8dSAndroid Build Coastguard Worker        i = 1
1507*cda5da8dSAndroid Build Coastguard Worker        for ch in arg[1:]:
1508*cda5da8dSAndroid Build Coastguard Worker            opt = "-" + ch
1509*cda5da8dSAndroid Build Coastguard Worker            option = self._short_opt.get(opt)
1510*cda5da8dSAndroid Build Coastguard Worker            i += 1                      # we have consumed a character
1511*cda5da8dSAndroid Build Coastguard Worker
1512*cda5da8dSAndroid Build Coastguard Worker            if not option:
1513*cda5da8dSAndroid Build Coastguard Worker                raise BadOptionError(opt)
1514*cda5da8dSAndroid Build Coastguard Worker            if option.takes_value():
1515*cda5da8dSAndroid Build Coastguard Worker                # Any characters left in arg?  Pretend they're the
1516*cda5da8dSAndroid Build Coastguard Worker                # next arg, and stop consuming characters of arg.
1517*cda5da8dSAndroid Build Coastguard Worker                if i < len(arg):
1518*cda5da8dSAndroid Build Coastguard Worker                    rargs.insert(0, arg[i:])
1519*cda5da8dSAndroid Build Coastguard Worker                    stop = True
1520*cda5da8dSAndroid Build Coastguard Worker
1521*cda5da8dSAndroid Build Coastguard Worker                nargs = option.nargs
1522*cda5da8dSAndroid Build Coastguard Worker                if len(rargs) < nargs:
1523*cda5da8dSAndroid Build Coastguard Worker                    self.error(ngettext(
1524*cda5da8dSAndroid Build Coastguard Worker                        "%(option)s option requires %(number)d argument",
1525*cda5da8dSAndroid Build Coastguard Worker                        "%(option)s option requires %(number)d arguments",
1526*cda5da8dSAndroid Build Coastguard Worker                        nargs) % {"option": opt, "number": nargs})
1527*cda5da8dSAndroid Build Coastguard Worker                elif nargs == 1:
1528*cda5da8dSAndroid Build Coastguard Worker                    value = rargs.pop(0)
1529*cda5da8dSAndroid Build Coastguard Worker                else:
1530*cda5da8dSAndroid Build Coastguard Worker                    value = tuple(rargs[0:nargs])
1531*cda5da8dSAndroid Build Coastguard Worker                    del rargs[0:nargs]
1532*cda5da8dSAndroid Build Coastguard Worker
1533*cda5da8dSAndroid Build Coastguard Worker            else:                       # option doesn't take a value
1534*cda5da8dSAndroid Build Coastguard Worker                value = None
1535*cda5da8dSAndroid Build Coastguard Worker
1536*cda5da8dSAndroid Build Coastguard Worker            option.process(opt, value, values, self)
1537*cda5da8dSAndroid Build Coastguard Worker
1538*cda5da8dSAndroid Build Coastguard Worker            if stop:
1539*cda5da8dSAndroid Build Coastguard Worker                break
1540*cda5da8dSAndroid Build Coastguard Worker
1541*cda5da8dSAndroid Build Coastguard Worker
1542*cda5da8dSAndroid Build Coastguard Worker    # -- Feedback methods ----------------------------------------------
1543*cda5da8dSAndroid Build Coastguard Worker
1544*cda5da8dSAndroid Build Coastguard Worker    def get_prog_name(self):
1545*cda5da8dSAndroid Build Coastguard Worker        if self.prog is None:
1546*cda5da8dSAndroid Build Coastguard Worker            return os.path.basename(sys.argv[0])
1547*cda5da8dSAndroid Build Coastguard Worker        else:
1548*cda5da8dSAndroid Build Coastguard Worker            return self.prog
1549*cda5da8dSAndroid Build Coastguard Worker
1550*cda5da8dSAndroid Build Coastguard Worker    def expand_prog_name(self, s):
1551*cda5da8dSAndroid Build Coastguard Worker        return s.replace("%prog", self.get_prog_name())
1552*cda5da8dSAndroid Build Coastguard Worker
1553*cda5da8dSAndroid Build Coastguard Worker    def get_description(self):
1554*cda5da8dSAndroid Build Coastguard Worker        return self.expand_prog_name(self.description)
1555*cda5da8dSAndroid Build Coastguard Worker
1556*cda5da8dSAndroid Build Coastguard Worker    def exit(self, status=0, msg=None):
1557*cda5da8dSAndroid Build Coastguard Worker        if msg:
1558*cda5da8dSAndroid Build Coastguard Worker            sys.stderr.write(msg)
1559*cda5da8dSAndroid Build Coastguard Worker        sys.exit(status)
1560*cda5da8dSAndroid Build Coastguard Worker
1561*cda5da8dSAndroid Build Coastguard Worker    def error(self, msg):
1562*cda5da8dSAndroid Build Coastguard Worker        """error(msg : string)
1563*cda5da8dSAndroid Build Coastguard Worker
1564*cda5da8dSAndroid Build Coastguard Worker        Print a usage message incorporating 'msg' to stderr and exit.
1565*cda5da8dSAndroid Build Coastguard Worker        If you override this in a subclass, it should not return -- it
1566*cda5da8dSAndroid Build Coastguard Worker        should either exit or raise an exception.
1567*cda5da8dSAndroid Build Coastguard Worker        """
1568*cda5da8dSAndroid Build Coastguard Worker        self.print_usage(sys.stderr)
1569*cda5da8dSAndroid Build Coastguard Worker        self.exit(2, "%s: error: %s\n" % (self.get_prog_name(), msg))
1570*cda5da8dSAndroid Build Coastguard Worker
1571*cda5da8dSAndroid Build Coastguard Worker    def get_usage(self):
1572*cda5da8dSAndroid Build Coastguard Worker        if self.usage:
1573*cda5da8dSAndroid Build Coastguard Worker            return self.formatter.format_usage(
1574*cda5da8dSAndroid Build Coastguard Worker                self.expand_prog_name(self.usage))
1575*cda5da8dSAndroid Build Coastguard Worker        else:
1576*cda5da8dSAndroid Build Coastguard Worker            return ""
1577*cda5da8dSAndroid Build Coastguard Worker
1578*cda5da8dSAndroid Build Coastguard Worker    def print_usage(self, file=None):
1579*cda5da8dSAndroid Build Coastguard Worker        """print_usage(file : file = stdout)
1580*cda5da8dSAndroid Build Coastguard Worker
1581*cda5da8dSAndroid Build Coastguard Worker        Print the usage message for the current program (self.usage) to
1582*cda5da8dSAndroid Build Coastguard Worker        'file' (default stdout).  Any occurrence of the string "%prog" in
1583*cda5da8dSAndroid Build Coastguard Worker        self.usage is replaced with the name of the current program
1584*cda5da8dSAndroid Build Coastguard Worker        (basename of sys.argv[0]).  Does nothing if self.usage is empty
1585*cda5da8dSAndroid Build Coastguard Worker        or not defined.
1586*cda5da8dSAndroid Build Coastguard Worker        """
1587*cda5da8dSAndroid Build Coastguard Worker        if self.usage:
1588*cda5da8dSAndroid Build Coastguard Worker            print(self.get_usage(), file=file)
1589*cda5da8dSAndroid Build Coastguard Worker
1590*cda5da8dSAndroid Build Coastguard Worker    def get_version(self):
1591*cda5da8dSAndroid Build Coastguard Worker        if self.version:
1592*cda5da8dSAndroid Build Coastguard Worker            return self.expand_prog_name(self.version)
1593*cda5da8dSAndroid Build Coastguard Worker        else:
1594*cda5da8dSAndroid Build Coastguard Worker            return ""
1595*cda5da8dSAndroid Build Coastguard Worker
1596*cda5da8dSAndroid Build Coastguard Worker    def print_version(self, file=None):
1597*cda5da8dSAndroid Build Coastguard Worker        """print_version(file : file = stdout)
1598*cda5da8dSAndroid Build Coastguard Worker
1599*cda5da8dSAndroid Build Coastguard Worker        Print the version message for this program (self.version) to
1600*cda5da8dSAndroid Build Coastguard Worker        'file' (default stdout).  As with print_usage(), any occurrence
1601*cda5da8dSAndroid Build Coastguard Worker        of "%prog" in self.version is replaced by the current program's
1602*cda5da8dSAndroid Build Coastguard Worker        name.  Does nothing if self.version is empty or undefined.
1603*cda5da8dSAndroid Build Coastguard Worker        """
1604*cda5da8dSAndroid Build Coastguard Worker        if self.version:
1605*cda5da8dSAndroid Build Coastguard Worker            print(self.get_version(), file=file)
1606*cda5da8dSAndroid Build Coastguard Worker
1607*cda5da8dSAndroid Build Coastguard Worker    def format_option_help(self, formatter=None):
1608*cda5da8dSAndroid Build Coastguard Worker        if formatter is None:
1609*cda5da8dSAndroid Build Coastguard Worker            formatter = self.formatter
1610*cda5da8dSAndroid Build Coastguard Worker        formatter.store_option_strings(self)
1611*cda5da8dSAndroid Build Coastguard Worker        result = []
1612*cda5da8dSAndroid Build Coastguard Worker        result.append(formatter.format_heading(_("Options")))
1613*cda5da8dSAndroid Build Coastguard Worker        formatter.indent()
1614*cda5da8dSAndroid Build Coastguard Worker        if self.option_list:
1615*cda5da8dSAndroid Build Coastguard Worker            result.append(OptionContainer.format_option_help(self, formatter))
1616*cda5da8dSAndroid Build Coastguard Worker            result.append("\n")
1617*cda5da8dSAndroid Build Coastguard Worker        for group in self.option_groups:
1618*cda5da8dSAndroid Build Coastguard Worker            result.append(group.format_help(formatter))
1619*cda5da8dSAndroid Build Coastguard Worker            result.append("\n")
1620*cda5da8dSAndroid Build Coastguard Worker        formatter.dedent()
1621*cda5da8dSAndroid Build Coastguard Worker        # Drop the last "\n", or the header if no options or option groups:
1622*cda5da8dSAndroid Build Coastguard Worker        return "".join(result[:-1])
1623*cda5da8dSAndroid Build Coastguard Worker
1624*cda5da8dSAndroid Build Coastguard Worker    def format_epilog(self, formatter):
1625*cda5da8dSAndroid Build Coastguard Worker        return formatter.format_epilog(self.epilog)
1626*cda5da8dSAndroid Build Coastguard Worker
1627*cda5da8dSAndroid Build Coastguard Worker    def format_help(self, formatter=None):
1628*cda5da8dSAndroid Build Coastguard Worker        if formatter is None:
1629*cda5da8dSAndroid Build Coastguard Worker            formatter = self.formatter
1630*cda5da8dSAndroid Build Coastguard Worker        result = []
1631*cda5da8dSAndroid Build Coastguard Worker        if self.usage:
1632*cda5da8dSAndroid Build Coastguard Worker            result.append(self.get_usage() + "\n")
1633*cda5da8dSAndroid Build Coastguard Worker        if self.description:
1634*cda5da8dSAndroid Build Coastguard Worker            result.append(self.format_description(formatter) + "\n")
1635*cda5da8dSAndroid Build Coastguard Worker        result.append(self.format_option_help(formatter))
1636*cda5da8dSAndroid Build Coastguard Worker        result.append(self.format_epilog(formatter))
1637*cda5da8dSAndroid Build Coastguard Worker        return "".join(result)
1638*cda5da8dSAndroid Build Coastguard Worker
1639*cda5da8dSAndroid Build Coastguard Worker    def print_help(self, file=None):
1640*cda5da8dSAndroid Build Coastguard Worker        """print_help(file : file = stdout)
1641*cda5da8dSAndroid Build Coastguard Worker
1642*cda5da8dSAndroid Build Coastguard Worker        Print an extended help message, listing all options and any
1643*cda5da8dSAndroid Build Coastguard Worker        help text provided with them, to 'file' (default stdout).
1644*cda5da8dSAndroid Build Coastguard Worker        """
1645*cda5da8dSAndroid Build Coastguard Worker        if file is None:
1646*cda5da8dSAndroid Build Coastguard Worker            file = sys.stdout
1647*cda5da8dSAndroid Build Coastguard Worker        file.write(self.format_help())
1648*cda5da8dSAndroid Build Coastguard Worker
1649*cda5da8dSAndroid Build Coastguard Worker# class OptionParser
1650*cda5da8dSAndroid Build Coastguard Worker
1651*cda5da8dSAndroid Build Coastguard Worker
1652*cda5da8dSAndroid Build Coastguard Workerdef _match_abbrev(s, wordmap):
1653*cda5da8dSAndroid Build Coastguard Worker    """_match_abbrev(s : string, wordmap : {string : Option}) -> string
1654*cda5da8dSAndroid Build Coastguard Worker
1655*cda5da8dSAndroid Build Coastguard Worker    Return the string key in 'wordmap' for which 's' is an unambiguous
1656*cda5da8dSAndroid Build Coastguard Worker    abbreviation.  If 's' is found to be ambiguous or doesn't match any of
1657*cda5da8dSAndroid Build Coastguard Worker    'words', raise BadOptionError.
1658*cda5da8dSAndroid Build Coastguard Worker    """
1659*cda5da8dSAndroid Build Coastguard Worker    # Is there an exact match?
1660*cda5da8dSAndroid Build Coastguard Worker    if s in wordmap:
1661*cda5da8dSAndroid Build Coastguard Worker        return s
1662*cda5da8dSAndroid Build Coastguard Worker    else:
1663*cda5da8dSAndroid Build Coastguard Worker        # Isolate all words with s as a prefix.
1664*cda5da8dSAndroid Build Coastguard Worker        possibilities = [word for word in wordmap.keys()
1665*cda5da8dSAndroid Build Coastguard Worker                         if word.startswith(s)]
1666*cda5da8dSAndroid Build Coastguard Worker        # No exact match, so there had better be just one possibility.
1667*cda5da8dSAndroid Build Coastguard Worker        if len(possibilities) == 1:
1668*cda5da8dSAndroid Build Coastguard Worker            return possibilities[0]
1669*cda5da8dSAndroid Build Coastguard Worker        elif not possibilities:
1670*cda5da8dSAndroid Build Coastguard Worker            raise BadOptionError(s)
1671*cda5da8dSAndroid Build Coastguard Worker        else:
1672*cda5da8dSAndroid Build Coastguard Worker            # More than one possible completion: ambiguous prefix.
1673*cda5da8dSAndroid Build Coastguard Worker            possibilities.sort()
1674*cda5da8dSAndroid Build Coastguard Worker            raise AmbiguousOptionError(s, possibilities)
1675*cda5da8dSAndroid Build Coastguard Worker
1676*cda5da8dSAndroid Build Coastguard Worker
1677*cda5da8dSAndroid Build Coastguard Worker# Some day, there might be many Option classes.  As of Optik 1.3, the
1678*cda5da8dSAndroid Build Coastguard Worker# preferred way to instantiate Options is indirectly, via make_option(),
1679*cda5da8dSAndroid Build Coastguard Worker# which will become a factory function when there are many Option
1680*cda5da8dSAndroid Build Coastguard Worker# classes.
1681*cda5da8dSAndroid Build Coastguard Workermake_option = Option
1682