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