+++ /dev/null
-"""A powerful, extensible, and easy-to-use option parser.\r
-\r
-By Greg Ward <gward@python.net>\r
-\r
-Originally distributed as Optik.\r
-\r
-For support, use the optik-users@lists.sourceforge.net mailing list\r
-(http://lists.sourceforge.net/lists/listinfo/optik-users).\r
-\r
-Simple usage example:\r
-\r
- from optparse import OptionParser\r
-\r
- parser = OptionParser()\r
- parser.add_option("-f", "--file", dest="filename",\r
- help="write report to FILE", metavar="FILE")\r
- parser.add_option("-q", "--quiet",\r
- action="store_false", dest="verbose", default=True,\r
- help="don't print status messages to stdout")\r
-\r
- (options, args) = parser.parse_args()\r
-"""\r
-\r
-__version__ = "1.5.3"\r
-\r
-__all__ = ['Option',\r
- 'make_option',\r
- 'SUPPRESS_HELP',\r
- 'SUPPRESS_USAGE',\r
- 'Values',\r
- 'OptionContainer',\r
- 'OptionGroup',\r
- 'OptionParser',\r
- 'HelpFormatter',\r
- 'IndentedHelpFormatter',\r
- 'TitledHelpFormatter',\r
- 'OptParseError',\r
- 'OptionError',\r
- 'OptionConflictError',\r
- 'OptionValueError',\r
- 'BadOptionError']\r
-\r
-__copyright__ = """\r
-Copyright (c) 2001-2006 Gregory P. Ward. All rights reserved.\r
-Copyright (c) 2002-2006 Python Software Foundation. All rights reserved.\r
-\r
-Redistribution and use in source and binary forms, with or without\r
-modification, are permitted provided that the following conditions are\r
-met:\r
-\r
- * Redistributions of source code must retain the above copyright\r
- notice, this list of conditions and the following disclaimer.\r
-\r
- * Redistributions in binary form must reproduce the above copyright\r
- notice, this list of conditions and the following disclaimer in the\r
- documentation and/or other materials provided with the distribution.\r
-\r
- * Neither the name of the author nor the names of its\r
- contributors may be used to endorse or promote products derived from\r
- this software without specific prior written permission.\r
-\r
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS\r
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\r
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\r
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR\r
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-"""\r
-\r
-import sys, os\r
-import types\r
-import textwrap\r
-\r
-def _repr(self):\r
- return "<%s at 0x%x: %s>" % (self.__class__.__name__, id(self), self)\r
-\r
-\r
-# This file was generated from:\r
-# Id: option_parser.py 527 2006-07-23 15:21:30Z greg\r
-# Id: option.py 522 2006-06-11 16:22:03Z gward\r
-# Id: help.py 527 2006-07-23 15:21:30Z greg\r
-# Id: errors.py 509 2006-04-20 00:58:24Z gward\r
-\r
-try:\r
- from gettext import gettext\r
-except ImportError:\r
- def gettext(message):\r
- return message\r
-_ = gettext\r
-\r
-\r
-class OptParseError (Exception):\r
- def __init__(self, msg):\r
- self.msg = msg\r
-\r
- def __str__(self):\r
- return self.msg\r
-\r
-\r
-class OptionError (OptParseError):\r
- """\r
- Raised if an Option instance is created with invalid or\r
- inconsistent arguments.\r
- """\r
-\r
- def __init__(self, msg, option):\r
- self.msg = msg\r
- self.option_id = str(option)\r
-\r
- def __str__(self):\r
- if self.option_id:\r
- return "option %s: %s" % (self.option_id, self.msg)\r
- else:\r
- return self.msg\r
-\r
-class OptionConflictError (OptionError):\r
- """\r
- Raised if conflicting options are added to an OptionParser.\r
- """\r
-\r
-class OptionValueError (OptParseError):\r
- """\r
- Raised if an invalid option value is encountered on the command\r
- line.\r
- """\r
-\r
-class BadOptionError (OptParseError):\r
- """\r
- Raised if an invalid option is seen on the command line.\r
- """\r
- def __init__(self, opt_str):\r
- self.opt_str = opt_str\r
-\r
- def __str__(self):\r
- return _("no such option: %s") % self.opt_str\r
-\r
-class AmbiguousOptionError (BadOptionError):\r
- """\r
- Raised if an ambiguous option is seen on the command line.\r
- """\r
- def __init__(self, opt_str, possibilities):\r
- BadOptionError.__init__(self, opt_str)\r
- self.possibilities = possibilities\r
-\r
- def __str__(self):\r
- return (_("ambiguous option: %s (%s?)")\r
- % (self.opt_str, ", ".join(self.possibilities)))\r
-\r
-\r
-class HelpFormatter:\r
-\r
- """\r
- Abstract base class for formatting option help. OptionParser\r
- instances should use one of the HelpFormatter subclasses for\r
- formatting help; by default IndentedHelpFormatter is used.\r
-\r
- Instance attributes:\r
- parser : OptionParser\r
- the controlling OptionParser instance\r
- indent_increment : int\r
- the number of columns to indent per nesting level\r
- max_help_position : int\r
- the maximum starting column for option help text\r
- help_position : int\r
- the calculated starting column for option help text;\r
- initially the same as the maximum\r
- width : int\r
- total number of columns for output (pass None to constructor for\r
- this value to be taken from the $COLUMNS environment variable)\r
- level : int\r
- current indentation level\r
- current_indent : int\r
- current indentation level (in columns)\r
- help_width : int\r
- number of columns available for option help text (calculated)\r
- default_tag : str\r
- text to replace with each option's default value, "%default"\r
- by default. Set to false value to disable default value expansion.\r
- option_strings : { Option : str }\r
- maps Option instances to the snippet of help text explaining\r
- the syntax of that option, e.g. "-h, --help" or\r
- "-fFILE, --file=FILE"\r
- _short_opt_fmt : str\r
- format string controlling how short options with values are\r
- printed in help text. Must be either "%s%s" ("-fFILE") or\r
- "%s %s" ("-f FILE"), because those are the two syntaxes that\r
- Optik supports.\r
- _long_opt_fmt : str\r
- similar but for long options; must be either "%s %s" ("--file FILE")\r
- or "%s=%s" ("--file=FILE").\r
- """\r
-\r
- NO_DEFAULT_VALUE = "none"\r
-\r
- def __init__(self,\r
- indent_increment,\r
- max_help_position,\r
- width,\r
- short_first):\r
- self.parser = None\r
- self.indent_increment = indent_increment\r
- self.help_position = self.max_help_position = max_help_position\r
- if width is None:\r
- try:\r
- width = int(os.environ['COLUMNS'])\r
- except (KeyError, ValueError):\r
- width = 80\r
- width -= 2\r
- self.width = width\r
- self.current_indent = 0\r
- self.level = 0\r
- self.help_width = None # computed later\r
- self.short_first = short_first\r
- self.default_tag = "%default"\r
- self.option_strings = {}\r
- self._short_opt_fmt = "%s %s"\r
- self._long_opt_fmt = "%s=%s"\r
-\r
- def set_parser(self, parser):\r
- self.parser = parser\r
-\r
- def set_short_opt_delimiter(self, delim):\r
- if delim not in ("", " "):\r
- raise ValueError(\r
- "invalid metavar delimiter for short options: %r" % delim)\r
- self._short_opt_fmt = "%s" + delim + "%s"\r
-\r
- def set_long_opt_delimiter(self, delim):\r
- if delim not in ("=", " "):\r
- raise ValueError(\r
- "invalid metavar delimiter for long options: %r" % delim)\r
- self._long_opt_fmt = "%s" + delim + "%s"\r
-\r
- def indent(self):\r
- self.current_indent += self.indent_increment\r
- self.level += 1\r
-\r
- def dedent(self):\r
- self.current_indent -= self.indent_increment\r
- assert self.current_indent >= 0, "Indent decreased below 0."\r
- self.level -= 1\r
-\r
- def format_usage(self, usage):\r
- raise NotImplementedError, "subclasses must implement"\r
-\r
- def format_heading(self, heading):\r
- raise NotImplementedError, "subclasses must implement"\r
-\r
- def _format_text(self, text):\r
- """\r
- Format a paragraph of free-form text for inclusion in the\r
- help output at the current indentation level.\r
- """\r
- text_width = self.width - self.current_indent\r
- indent = " "*self.current_indent\r
- return textwrap.fill(text,\r
- text_width,\r
- initial_indent=indent,\r
- subsequent_indent=indent)\r
-\r
- def format_description(self, description):\r
- if description:\r
- return self._format_text(description) + "\n"\r
- else:\r
- return ""\r
-\r
- def format_epilog(self, epilog):\r
- if epilog:\r
- return "\n" + self._format_text(epilog) + "\n"\r
- else:\r
- return ""\r
-\r
-\r
- def expand_default(self, option):\r
- if self.parser is None or not self.default_tag:\r
- return option.help\r
-\r
- default_value = self.parser.defaults.get(option.dest)\r
- if default_value is NO_DEFAULT or default_value is None:\r
- default_value = self.NO_DEFAULT_VALUE\r
-\r
- return option.help.replace(self.default_tag, str(default_value))\r
-\r
- def format_option(self, option):\r
- # The help for each option consists of two parts:\r
- # * the opt strings and metavars\r
- # eg. ("-x", or "-fFILENAME, --file=FILENAME")\r
- # * the user-supplied help string\r
- # eg. ("turn on expert mode", "read data from FILENAME")\r
- #\r
- # If possible, we write both of these on the same line:\r
- # -x turn on expert mode\r
- #\r
- # But if the opt string list is too long, we put the help\r
- # string on a second line, indented to the same column it would\r
- # start in if it fit on the first line.\r
- # -fFILENAME, --file=FILENAME\r
- # read data from FILENAME\r
- result = []\r
- opts = self.option_strings[option]\r
- opt_width = self.help_position - self.current_indent - 2\r
- if len(opts) > opt_width:\r
- opts = "%*s%s\n" % (self.current_indent, "", opts)\r
- indent_first = self.help_position\r
- else: # start help on same line as opts\r
- opts = "%*s%-*s " % (self.current_indent, "", opt_width, opts)\r
- indent_first = 0\r
- result.append(opts)\r
- if option.help:\r
- help_text = self.expand_default(option)\r
- help_lines = textwrap.wrap(help_text, self.help_width)\r
- result.append("%*s%s\n" % (indent_first, "", help_lines[0]))\r
- result.extend(["%*s%s\n" % (self.help_position, "", line)\r
- for line in help_lines[1:]])\r
- elif opts[-1] != "\n":\r
- result.append("\n")\r
- return "".join(result)\r
-\r
- def store_option_strings(self, parser):\r
- self.indent()\r
- max_len = 0\r
- for opt in parser.option_list:\r
- strings = self.format_option_strings(opt)\r
- self.option_strings[opt] = strings\r
- max_len = max(max_len, len(strings) + self.current_indent)\r
- self.indent()\r
- for group in parser.option_groups:\r
- for opt in group.option_list:\r
- strings = self.format_option_strings(opt)\r
- self.option_strings[opt] = strings\r
- max_len = max(max_len, len(strings) + self.current_indent)\r
- self.dedent()\r
- self.dedent()\r
- self.help_position = min(max_len + 2, self.max_help_position)\r
- self.help_width = self.width - self.help_position\r
-\r
- def format_option_strings(self, option):\r
- """Return a comma-separated list of option strings & metavariables."""\r
- if option.takes_value():\r
- metavar = option.metavar or option.dest.upper()\r
- short_opts = [self._short_opt_fmt % (sopt, metavar)\r
- for sopt in option._short_opts]\r
- long_opts = [self._long_opt_fmt % (lopt, metavar)\r
- for lopt in option._long_opts]\r
- else:\r
- short_opts = option._short_opts\r
- long_opts = option._long_opts\r
-\r
- if self.short_first:\r
- opts = short_opts + long_opts\r
- else:\r
- opts = long_opts + short_opts\r
-\r
- return ", ".join(opts)\r
-\r
-class IndentedHelpFormatter (HelpFormatter):\r
- """Format help with indented section bodies.\r
- """\r
-\r
- def __init__(self,\r
- indent_increment=2,\r
- max_help_position=24,\r
- width=None,\r
- short_first=1):\r
- HelpFormatter.__init__(\r
- self, indent_increment, max_help_position, width, short_first)\r
-\r
- def format_usage(self, usage):\r
- return _("Usage: %s\n") % usage\r
-\r
- def format_heading(self, heading):\r
- return "%*s%s:\n" % (self.current_indent, "", heading)\r
-\r
-\r
-class TitledHelpFormatter (HelpFormatter):\r
- """Format help with underlined section headers.\r
- """\r
-\r
- def __init__(self,\r
- indent_increment=0,\r
- max_help_position=24,\r
- width=None,\r
- short_first=0):\r
- HelpFormatter.__init__ (\r
- self, indent_increment, max_help_position, width, short_first)\r
-\r
- def format_usage(self, usage):\r
- return "%s %s\n" % (self.format_heading(_("Usage")), usage)\r
-\r
- def format_heading(self, heading):\r
- return "%s\n%s\n" % (heading, "=-"[self.level] * len(heading))\r
-\r
-\r
-def _parse_num(val, type):\r
- if val[:2].lower() == "0x": # hexadecimal\r
- radix = 16\r
- elif val[:2].lower() == "0b": # binary\r
- radix = 2\r
- val = val[2:] or "0" # have to remove "0b" prefix\r
- elif val[:1] == "0": # octal\r
- radix = 8\r
- else: # decimal\r
- radix = 10\r
-\r
- return type(val, radix)\r
-\r
-def _parse_int(val):\r
- return _parse_num(val, int)\r
-\r
-def _parse_long(val):\r
- return _parse_num(val, long)\r
-\r
-_builtin_cvt = { "int" : (_parse_int, _("integer")),\r
- "long" : (_parse_long, _("long integer")),\r
- "float" : (float, _("floating-point")),\r
- "complex" : (complex, _("complex")) }\r
-\r
-def check_builtin(option, opt, value):\r
- (cvt, what) = _builtin_cvt[option.type]\r
- try:\r
- return cvt(value)\r
- except ValueError:\r
- raise OptionValueError(\r
- _("option %s: invalid %s value: %r") % (opt, what, value))\r
-\r
-def check_choice(option, opt, value):\r
- if value in option.choices:\r
- return value\r
- else:\r
- choices = ", ".join(map(repr, option.choices))\r
- raise OptionValueError(\r
- _("option %s: invalid choice: %r (choose from %s)")\r
- % (opt, value, choices))\r
-\r
-# Not supplying a default is different from a default of None,\r
-# so we need an explicit "not supplied" value.\r
-NO_DEFAULT = ("NO", "DEFAULT")\r
-\r
-\r
-class Option:\r
- """\r
- Instance attributes:\r
- _short_opts : [string]\r
- _long_opts : [string]\r
-\r
- action : string\r
- type : string\r
- dest : string\r
- default : any\r
- nargs : int\r
- const : any\r
- choices : [string]\r
- callback : function\r
- callback_args : (any*)\r
- callback_kwargs : { string : any }\r
- help : string\r
- metavar : string\r
- """\r
-\r
- # The list of instance attributes that may be set through\r
- # keyword args to the constructor.\r
- ATTRS = ['action',\r
- 'type',\r
- 'dest',\r
- 'default',\r
- 'nargs',\r
- 'const',\r
- 'choices',\r
- 'callback',\r
- 'callback_args',\r
- 'callback_kwargs',\r
- 'help',\r
- 'metavar']\r
-\r
- # The set of actions allowed by option parsers. Explicitly listed\r
- # here so the constructor can validate its arguments.\r
- ACTIONS = ("store",\r
- "store_const",\r
- "store_true",\r
- "store_false",\r
- "append",\r
- "append_const",\r
- "count",\r
- "callback",\r
- "help",\r
- "version")\r
-\r
- # The set of actions that involve storing a value somewhere;\r
- # also listed just for constructor argument validation. (If\r
- # the action is one of these, there must be a destination.)\r
- STORE_ACTIONS = ("store",\r
- "store_const",\r
- "store_true",\r
- "store_false",\r
- "append",\r
- "append_const",\r
- "count")\r
-\r
- # The set of actions for which it makes sense to supply a value\r
- # type, ie. which may consume an argument from the command line.\r
- TYPED_ACTIONS = ("store",\r
- "append",\r
- "callback")\r
-\r
- # The set of actions which *require* a value type, ie. that\r
- # always consume an argument from the command line.\r
- ALWAYS_TYPED_ACTIONS = ("store",\r
- "append")\r
-\r
- # The set of actions which take a 'const' attribute.\r
- CONST_ACTIONS = ("store_const",\r
- "append_const")\r
-\r
- # The set of known types for option parsers. Again, listed here for\r
- # constructor argument validation.\r
- TYPES = ("string", "int", "long", "float", "complex", "choice")\r
-\r
- # Dictionary of argument checking functions, which convert and\r
- # validate option arguments according to the option type.\r
- #\r
- # Signature of checking functions is:\r
- # check(option : Option, opt : string, value : string) -> any\r
- # where\r
- # option is the Option instance calling the checker\r
- # opt is the actual option seen on the command-line\r
- # (eg. "-a", "--file")\r
- # value is the option argument seen on the command-line\r
- #\r
- # The return value should be in the appropriate Python type\r
- # for option.type -- eg. an integer if option.type == "int".\r
- #\r
- # If no checker is defined for a type, arguments will be\r
- # unchecked and remain strings.\r
- TYPE_CHECKER = { "int" : check_builtin,\r
- "long" : check_builtin,\r
- "float" : check_builtin,\r
- "complex": check_builtin,\r
- "choice" : check_choice,\r
- }\r
-\r
-\r
- # CHECK_METHODS is a list of unbound method objects; they are called\r
- # by the constructor, in order, after all attributes are\r
- # initialized. The list is created and filled in later, after all\r
- # the methods are actually defined. (I just put it here because I\r
- # like to define and document all class attributes in the same\r
- # place.) Subclasses that add another _check_*() method should\r
- # define their own CHECK_METHODS list that adds their check method\r
- # to those from this class.\r
- CHECK_METHODS = None\r
-\r
-\r
- # -- Constructor/initialization methods ----------------------------\r
-\r
- def __init__(self, *opts, **attrs):\r
- # Set _short_opts, _long_opts attrs from 'opts' tuple.\r
- # Have to be set now, in case no option strings are supplied.\r
- self._short_opts = []\r
- self._long_opts = []\r
- opts = self._check_opt_strings(opts)\r
- self._set_opt_strings(opts)\r
-\r
- # Set all other attrs (action, type, etc.) from 'attrs' dict\r
- self._set_attrs(attrs)\r
-\r
- # Check all the attributes we just set. There are lots of\r
- # complicated interdependencies, but luckily they can be farmed\r
- # out to the _check_*() methods listed in CHECK_METHODS -- which\r
- # could be handy for subclasses! The one thing these all share\r
- # is that they raise OptionError if they discover a problem.\r
- for checker in self.CHECK_METHODS:\r
- checker(self)\r
-\r
- def _check_opt_strings(self, opts):\r
- # Filter out None because early versions of Optik had exactly\r
- # one short option and one long option, either of which\r
- # could be None.\r
- opts = filter(None, opts)\r
- if not opts:\r
- raise TypeError("at least one option string must be supplied")\r
- return opts\r
-\r
- def _set_opt_strings(self, opts):\r
- for opt in opts:\r
- if len(opt) < 2:\r
- raise OptionError(\r
- "invalid option string %r: "\r
- "must be at least two characters long" % opt, self)\r
- elif len(opt) == 2:\r
- if not (opt[0] == "-" and opt[1] != "-"):\r
- raise OptionError(\r
- "invalid short option string %r: "\r
- "must be of the form -x, (x any non-dash char)" % opt,\r
- self)\r
- self._short_opts.append(opt)\r
- else:\r
- if not (opt[0:2] == "--" and opt[2] != "-"):\r
- raise OptionError(\r
- "invalid long option string %r: "\r
- "must start with --, followed by non-dash" % opt,\r
- self)\r
- self._long_opts.append(opt)\r
-\r
- def _set_attrs(self, attrs):\r
- for attr in self.ATTRS:\r
- if attr in attrs:\r
- setattr(self, attr, attrs[attr])\r
- del attrs[attr]\r
- else:\r
- if attr == 'default':\r
- setattr(self, attr, NO_DEFAULT)\r
- else:\r
- setattr(self, attr, None)\r
- if attrs:\r
- attrs = attrs.keys()\r
- attrs.sort()\r
- raise OptionError(\r
- "invalid keyword arguments: %s" % ", ".join(attrs),\r
- self)\r
-\r
-\r
- # -- Constructor validation methods --------------------------------\r
-\r
- def _check_action(self):\r
- if self.action is None:\r
- self.action = "store"\r
- elif self.action not in self.ACTIONS:\r
- raise OptionError("invalid action: %r" % self.action, self)\r
-\r
- def _check_type(self):\r
- if self.type is None:\r
- if self.action in self.ALWAYS_TYPED_ACTIONS:\r
- if self.choices is not None:\r
- # The "choices" attribute implies "choice" type.\r
- self.type = "choice"\r
- else:\r
- # No type given? "string" is the most sensible default.\r
- self.type = "string"\r
- else:\r
- # Allow type objects or builtin type conversion functions\r
- # (int, str, etc.) as an alternative to their names. (The\r
- # complicated check of __builtin__ is only necessary for\r
- # Python 2.1 and earlier, and is short-circuited by the\r
- # first check on modern Pythons.)\r
- import __builtin__\r
- if ( type(self.type) is types.TypeType or\r
- (hasattr(self.type, "__name__") and\r
- getattr(__builtin__, self.type.__name__, None) is self.type) ):\r
- self.type = self.type.__name__\r
-\r
- if self.type == "str":\r
- self.type = "string"\r
-\r
- if self.type not in self.TYPES:\r
- raise OptionError("invalid option type: %r" % self.type, self)\r
- if self.action not in self.TYPED_ACTIONS:\r
- raise OptionError(\r
- "must not supply a type for action %r" % self.action, self)\r
-\r
- def _check_choice(self):\r
- if self.type == "choice":\r
- if self.choices is None:\r
- raise OptionError(\r
- "must supply a list of choices for type 'choice'", self)\r
- elif type(self.choices) not in (types.TupleType, types.ListType):\r
- raise OptionError(\r
- "choices must be a list of strings ('%s' supplied)"\r
- % str(type(self.choices)).split("'")[1], self)\r
- elif self.choices is not None:\r
- raise OptionError(\r
- "must not supply choices for type %r" % self.type, self)\r
-\r
- def _check_dest(self):\r
- # No destination given, and we need one for this action. The\r
- # self.type check is for callbacks that take a value.\r
- takes_value = (self.action in self.STORE_ACTIONS or\r
- self.type is not None)\r
- if self.dest is None and takes_value:\r
-\r
- # Glean a destination from the first long option string,\r
- # or from the first short option string if no long options.\r
- if self._long_opts:\r
- # eg. "--foo-bar" -> "foo_bar"\r
- self.dest = self._long_opts[0][2:].replace('-', '_')\r
- else:\r
- self.dest = self._short_opts[0][1]\r
-\r
- def _check_const(self):\r
- if self.action not in self.CONST_ACTIONS and self.const is not None:\r
- raise OptionError(\r
- "'const' must not be supplied for action %r" % self.action,\r
- self)\r
-\r
- def _check_nargs(self):\r
- if self.action in self.TYPED_ACTIONS:\r
- if self.nargs is None:\r
- self.nargs = 1\r
- elif self.nargs is not None:\r
- raise OptionError(\r
- "'nargs' must not be supplied for action %r" % self.action,\r
- self)\r
-\r
- def _check_callback(self):\r
- if self.action == "callback":\r
- if not hasattr(self.callback, '__call__'):\r
- raise OptionError(\r
- "callback not callable: %r" % self.callback, self)\r
- if (self.callback_args is not None and\r
- type(self.callback_args) is not types.TupleType):\r
- raise OptionError(\r
- "callback_args, if supplied, must be a tuple: not %r"\r
- % self.callback_args, self)\r
- if (self.callback_kwargs is not None and\r
- type(self.callback_kwargs) is not types.DictType):\r
- raise OptionError(\r
- "callback_kwargs, if supplied, must be a dict: not %r"\r
- % self.callback_kwargs, self)\r
- else:\r
- if self.callback is not None:\r
- raise OptionError(\r
- "callback supplied (%r) for non-callback option"\r
- % self.callback, self)\r
- if self.callback_args is not None:\r
- raise OptionError(\r
- "callback_args supplied for non-callback option", self)\r
- if self.callback_kwargs is not None:\r
- raise OptionError(\r
- "callback_kwargs supplied for non-callback option", self)\r
-\r
-\r
- CHECK_METHODS = [_check_action,\r
- _check_type,\r
- _check_choice,\r
- _check_dest,\r
- _check_const,\r
- _check_nargs,\r
- _check_callback]\r
-\r
-\r
- # -- Miscellaneous methods -----------------------------------------\r
-\r
- def __str__(self):\r
- return "/".join(self._short_opts + self._long_opts)\r
-\r
- __repr__ = _repr\r
-\r
- def takes_value(self):\r
- return self.type is not None\r
-\r
- def get_opt_string(self):\r
- if self._long_opts:\r
- return self._long_opts[0]\r
- else:\r
- return self._short_opts[0]\r
-\r
-\r
- # -- Processing methods --------------------------------------------\r
-\r
- def check_value(self, opt, value):\r
- checker = self.TYPE_CHECKER.get(self.type)\r
- if checker is None:\r
- return value\r
- else:\r
- return checker(self, opt, value)\r
-\r
- def convert_value(self, opt, value):\r
- if value is not None:\r
- if self.nargs == 1:\r
- return self.check_value(opt, value)\r
- else:\r
- return tuple([self.check_value(opt, v) for v in value])\r
-\r
- def process(self, opt, value, values, parser):\r
-\r
- # First, convert the value(s) to the right type. Howl if any\r
- # value(s) are bogus.\r
- value = self.convert_value(opt, value)\r
-\r
- # And then take whatever action is expected of us.\r
- # This is a separate method to make life easier for\r
- # subclasses to add new actions.\r
- return self.take_action(\r
- self.action, self.dest, opt, value, values, parser)\r
-\r
- def take_action(self, action, dest, opt, value, values, parser):\r
- if action == "store":\r
- setattr(values, dest, value)\r
- elif action == "store_const":\r
- setattr(values, dest, self.const)\r
- elif action == "store_true":\r
- setattr(values, dest, True)\r
- elif action == "store_false":\r
- setattr(values, dest, False)\r
- elif action == "append":\r
- values.ensure_value(dest, []).append(value)\r
- elif action == "append_const":\r
- values.ensure_value(dest, []).append(self.const)\r
- elif action == "count":\r
- setattr(values, dest, values.ensure_value(dest, 0) + 1)\r
- elif action == "callback":\r
- args = self.callback_args or ()\r
- kwargs = self.callback_kwargs or {}\r
- self.callback(self, opt, value, parser, *args, **kwargs)\r
- elif action == "help":\r
- parser.print_help()\r
- parser.exit()\r
- elif action == "version":\r
- parser.print_version()\r
- parser.exit()\r
- else:\r
- raise ValueError("unknown action %r" % self.action)\r
-\r
- return 1\r
-\r
-# class Option\r
-\r
-\r
-SUPPRESS_HELP = "SUPPRESS"+"HELP"\r
-SUPPRESS_USAGE = "SUPPRESS"+"USAGE"\r
-\r
-try:\r
- basestring\r
-except NameError:\r
- def isbasestring(x):\r
- return isinstance(x, (types.StringType, types.UnicodeType))\r
-else:\r
- def isbasestring(x):\r
- return isinstance(x, basestring)\r
-\r
-class Values:\r
-\r
- def __init__(self, defaults=None):\r
- if defaults:\r
- for (attr, val) in defaults.items():\r
- setattr(self, attr, val)\r
-\r
- def __str__(self):\r
- return str(self.__dict__)\r
-\r
- __repr__ = _repr\r
-\r
- def __cmp__(self, other):\r
- if isinstance(other, Values):\r
- return cmp(self.__dict__, other.__dict__)\r
- elif isinstance(other, types.DictType):\r
- return cmp(self.__dict__, other)\r
- else:\r
- return -1\r
-\r
- def _update_careful(self, dict):\r
- """\r
- Update the option values from an arbitrary dictionary, but only\r
- use keys from dict that already have a corresponding attribute\r
- in self. Any keys in dict without a corresponding attribute\r
- are silently ignored.\r
- """\r
- for attr in dir(self):\r
- if attr in dict:\r
- dval = dict[attr]\r
- if dval is not None:\r
- setattr(self, attr, dval)\r
-\r
- def _update_loose(self, dict):\r
- """\r
- Update the option values from an arbitrary dictionary,\r
- using all keys from the dictionary regardless of whether\r
- they have a corresponding attribute in self or not.\r
- """\r
- self.__dict__.update(dict)\r
-\r
- def _update(self, dict, mode):\r
- if mode == "careful":\r
- self._update_careful(dict)\r
- elif mode == "loose":\r
- self._update_loose(dict)\r
- else:\r
- raise ValueError, "invalid update mode: %r" % mode\r
-\r
- def read_module(self, modname, mode="careful"):\r
- __import__(modname)\r
- mod = sys.modules[modname]\r
- self._update(vars(mod), mode)\r
-\r
- def read_file(self, filename, mode="careful"):\r
- vars = {}\r
- execfile(filename, vars)\r
- self._update(vars, mode)\r
-\r
- def ensure_value(self, attr, value):\r
- if not hasattr(self, attr) or getattr(self, attr) is None:\r
- setattr(self, attr, value)\r
- return getattr(self, attr)\r
-\r
-\r
-class OptionContainer:\r
-\r
- """\r
- Abstract base class.\r
-\r
- Class attributes:\r
- standard_option_list : [Option]\r
- list of standard options that will be accepted by all instances\r
- of this parser class (intended to be overridden by subclasses).\r
-\r
- Instance attributes:\r
- option_list : [Option]\r
- the list of Option objects contained by this OptionContainer\r
- _short_opt : { string : Option }\r
- dictionary mapping short option strings, eg. "-f" or "-X",\r
- to the Option instances that implement them. If an Option\r
- has multiple short option strings, it will appears in this\r
- dictionary multiple times. [1]\r
- _long_opt : { string : Option }\r
- dictionary mapping long option strings, eg. "--file" or\r
- "--exclude", to the Option instances that implement them.\r
- Again, a given Option can occur multiple times in this\r
- dictionary. [1]\r
- defaults : { string : any }\r
- dictionary mapping option destination names to default\r
- values for each destination [1]\r
-\r
- [1] These mappings are common to (shared by) all components of the\r
- controlling OptionParser, where they are initially created.\r
-\r
- """\r
-\r
- def __init__(self, option_class, conflict_handler, description):\r
- # Initialize the option list and related data structures.\r
- # This method must be provided by subclasses, and it must\r
- # initialize at least the following instance attributes:\r
- # option_list, _short_opt, _long_opt, defaults.\r
- self._create_option_list()\r
-\r
- self.option_class = option_class\r
- self.set_conflict_handler(conflict_handler)\r
- self.set_description(description)\r
-\r
- def _create_option_mappings(self):\r
- # For use by OptionParser constructor -- create the master\r
- # option mappings used by this OptionParser and all\r
- # OptionGroups that it owns.\r
- self._short_opt = {} # single letter -> Option instance\r
- self._long_opt = {} # long option -> Option instance\r
- self.defaults = {} # maps option dest -> default value\r
-\r
-\r
- def _share_option_mappings(self, parser):\r
- # For use by OptionGroup constructor -- use shared option\r
- # mappings from the OptionParser that owns this OptionGroup.\r
- self._short_opt = parser._short_opt\r
- self._long_opt = parser._long_opt\r
- self.defaults = parser.defaults\r
-\r
- def set_conflict_handler(self, handler):\r
- if handler not in ("error", "resolve"):\r
- raise ValueError, "invalid conflict_resolution value %r" % handler\r
- self.conflict_handler = handler\r
-\r
- def set_description(self, description):\r
- self.description = description\r
-\r
- def get_description(self):\r
- return self.description\r
-\r
-\r
- def destroy(self):\r
- """see OptionParser.destroy()."""\r
- del self._short_opt\r
- del self._long_opt\r
- del self.defaults\r
-\r
-\r
- # -- Option-adding methods -----------------------------------------\r
-\r
- def _check_conflict(self, option):\r
- conflict_opts = []\r
- for opt in option._short_opts:\r
- if opt in self._short_opt:\r
- conflict_opts.append((opt, self._short_opt[opt]))\r
- for opt in option._long_opts:\r
- if opt in self._long_opt:\r
- conflict_opts.append((opt, self._long_opt[opt]))\r
-\r
- if conflict_opts:\r
- handler = self.conflict_handler\r
- if handler == "error":\r
- raise OptionConflictError(\r
- "conflicting option string(s): %s"\r
- % ", ".join([co[0] for co in conflict_opts]),\r
- option)\r
- elif handler == "resolve":\r
- for (opt, c_option) in conflict_opts:\r
- if opt.startswith("--"):\r
- c_option._long_opts.remove(opt)\r
- del self._long_opt[opt]\r
- else:\r
- c_option._short_opts.remove(opt)\r
- del self._short_opt[opt]\r
- if not (c_option._short_opts or c_option._long_opts):\r
- c_option.container.option_list.remove(c_option)\r
-\r
- def add_option(self, *args, **kwargs):\r
- """add_option(Option)\r
- add_option(opt_str, ..., kwarg=val, ...)\r
- """\r
- if type(args[0]) in types.StringTypes:\r
- option = self.option_class(*args, **kwargs)\r
- elif len(args) == 1 and not kwargs:\r
- option = args[0]\r
- if not isinstance(option, Option):\r
- raise TypeError, "not an Option instance: %r" % option\r
- else:\r
- raise TypeError, "invalid arguments"\r
-\r
- self._check_conflict(option)\r
-\r
- self.option_list.append(option)\r
- option.container = self\r
- for opt in option._short_opts:\r
- self._short_opt[opt] = option\r
- for opt in option._long_opts:\r
- self._long_opt[opt] = option\r
-\r
- if option.dest is not None: # option has a dest, we need a default\r
- if option.default is not NO_DEFAULT:\r
- self.defaults[option.dest] = option.default\r
- elif option.dest not in self.defaults:\r
- self.defaults[option.dest] = None\r
-\r
- return option\r
-\r
- def add_options(self, option_list):\r
- for option in option_list:\r
- self.add_option(option)\r
-\r
- # -- Option query/removal methods ----------------------------------\r
-\r
- def get_option(self, opt_str):\r
- return (self._short_opt.get(opt_str) or\r
- self._long_opt.get(opt_str))\r
-\r
- def has_option(self, opt_str):\r
- return (opt_str in self._short_opt or\r
- opt_str in self._long_opt)\r
-\r
- def remove_option(self, opt_str):\r
- option = self._short_opt.get(opt_str)\r
- if option is None:\r
- option = self._long_opt.get(opt_str)\r
- if option is None:\r
- raise ValueError("no such option %r" % opt_str)\r
-\r
- for opt in option._short_opts:\r
- del self._short_opt[opt]\r
- for opt in option._long_opts:\r
- del self._long_opt[opt]\r
- option.container.option_list.remove(option)\r
-\r
-\r
- # -- Help-formatting methods ---------------------------------------\r
-\r
- def format_option_help(self, formatter):\r
- if not self.option_list:\r
- return ""\r
- result = []\r
- for option in self.option_list:\r
- if not option.help is SUPPRESS_HELP:\r
- result.append(formatter.format_option(option))\r
- return "".join(result)\r
-\r
- def format_description(self, formatter):\r
- return formatter.format_description(self.get_description())\r
-\r
- def format_help(self, formatter):\r
- result = []\r
- if self.description:\r
- result.append(self.format_description(formatter))\r
- if self.option_list:\r
- result.append(self.format_option_help(formatter))\r
- return "\n".join(result)\r
-\r
-\r
-class OptionGroup (OptionContainer):\r
-\r
- def __init__(self, parser, title, description=None):\r
- self.parser = parser\r
- OptionContainer.__init__(\r
- self, parser.option_class, parser.conflict_handler, description)\r
- self.title = title\r
-\r
- def _create_option_list(self):\r
- self.option_list = []\r
- self._share_option_mappings(self.parser)\r
-\r
- def set_title(self, title):\r
- self.title = title\r
-\r
- def destroy(self):\r
- """see OptionParser.destroy()."""\r
- OptionContainer.destroy(self)\r
- del self.option_list\r
-\r
- # -- Help-formatting methods ---------------------------------------\r
-\r
- def format_help(self, formatter):\r
- result = formatter.format_heading(self.title)\r
- formatter.indent()\r
- result += OptionContainer.format_help(self, formatter)\r
- formatter.dedent()\r
- return result\r
-\r
-\r
-class OptionParser (OptionContainer):\r
-\r
- """\r
- Class attributes:\r
- standard_option_list : [Option]\r
- list of standard options that will be accepted by all instances\r
- of this parser class (intended to be overridden by subclasses).\r
-\r
- Instance attributes:\r
- usage : string\r
- a usage string for your program. Before it is displayed\r
- to the user, "%prog" will be expanded to the name of\r
- your program (self.prog or os.path.basename(sys.argv[0])).\r
- prog : string\r
- the name of the current program (to override\r
- os.path.basename(sys.argv[0])).\r
- description : string\r
- A paragraph of text giving a brief overview of your program.\r
- optparse reformats this paragraph to fit the current terminal\r
- width and prints it when the user requests help (after usage,\r
- but before the list of options).\r
- epilog : string\r
- paragraph of help text to print after option help\r
-\r
- option_groups : [OptionGroup]\r
- list of option groups in this parser (option groups are\r
- irrelevant for parsing the command-line, but very useful\r
- for generating help)\r
-\r
- allow_interspersed_args : bool = true\r
- if true, positional arguments may be interspersed with options.\r
- Assuming -a and -b each take a single argument, the command-line\r
- -ablah foo bar -bboo baz\r
- will be interpreted the same as\r
- -ablah -bboo -- foo bar baz\r
- If this flag were false, that command line would be interpreted as\r
- -ablah -- foo bar -bboo baz\r
- -- ie. we stop processing options as soon as we see the first\r
- non-option argument. (This is the tradition followed by\r
- Python's getopt module, Perl's Getopt::Std, and other argument-\r
- parsing libraries, but it is generally annoying to users.)\r
-\r
- process_default_values : bool = true\r
- if true, option default values are processed similarly to option\r
- values from the command line: that is, they are passed to the\r
- type-checking function for the option's type (as long as the\r
- default value is a string). (This really only matters if you\r
- have defined custom types; see SF bug #955889.) Set it to false\r
- to restore the behaviour of Optik 1.4.1 and earlier.\r
-\r
- rargs : [string]\r
- the argument list currently being parsed. Only set when\r
- parse_args() is active, and continually trimmed down as\r
- we consume arguments. Mainly there for the benefit of\r
- callback options.\r
- largs : [string]\r
- the list of leftover arguments that we have skipped while\r
- parsing options. If allow_interspersed_args is false, this\r
- list is always empty.\r
- values : Values\r
- the set of option values currently being accumulated. Only\r
- set when parse_args() is active. Also mainly for callbacks.\r
-\r
- Because of the 'rargs', 'largs', and 'values' attributes,\r
- OptionParser is not thread-safe. If, for some perverse reason, you\r
- need to parse command-line arguments simultaneously in different\r
- threads, use different OptionParser instances.\r
-\r
- """\r
-\r
- standard_option_list = []\r
-\r
- def __init__(self,\r
- usage=None,\r
- option_list=None,\r
- option_class=Option,\r
- version=None,\r
- conflict_handler="error",\r
- description=None,\r
- formatter=None,\r
- add_help_option=True,\r
- prog=None,\r
- epilog=None):\r
- OptionContainer.__init__(\r
- self, option_class, conflict_handler, description)\r
- self.set_usage(usage)\r
- self.prog = prog\r
- self.version = version\r
- self.allow_interspersed_args = True\r
- self.process_default_values = True\r
- if formatter is None:\r
- formatter = IndentedHelpFormatter()\r
- self.formatter = formatter\r
- self.formatter.set_parser(self)\r
- self.epilog = epilog\r
-\r
- # Populate the option list; initial sources are the\r
- # standard_option_list class attribute, the 'option_list'\r
- # argument, and (if applicable) the _add_version_option() and\r
- # _add_help_option() methods.\r
- self._populate_option_list(option_list,\r
- add_help=add_help_option)\r
-\r
- self._init_parsing_state()\r
-\r
-\r
- def destroy(self):\r
- """\r
- Declare that you are done with this OptionParser. This cleans up\r
- reference cycles so the OptionParser (and all objects referenced by\r
- it) can be garbage-collected promptly. After calling destroy(), the\r
- OptionParser is unusable.\r
- """\r
- OptionContainer.destroy(self)\r
- for group in self.option_groups:\r
- group.destroy()\r
- del self.option_list\r
- del self.option_groups\r
- del self.formatter\r
-\r
-\r
- # -- Private methods -----------------------------------------------\r
- # (used by our or OptionContainer's constructor)\r
-\r
- def _create_option_list(self):\r
- self.option_list = []\r
- self.option_groups = []\r
- self._create_option_mappings()\r
-\r
- def _add_help_option(self):\r
- self.add_option("-h", "--help",\r
- action="help",\r
- help=_("show this help message and exit"))\r
-\r
- def _add_version_option(self):\r
- self.add_option("--version",\r
- action="version",\r
- help=_("show program's version number and exit"))\r
-\r
- def _populate_option_list(self, option_list, add_help=True):\r
- if self.standard_option_list:\r
- self.add_options(self.standard_option_list)\r
- if option_list:\r
- self.add_options(option_list)\r
- if self.version:\r
- self._add_version_option()\r
- if add_help:\r
- self._add_help_option()\r
-\r
- def _init_parsing_state(self):\r
- # These are set in parse_args() for the convenience of callbacks.\r
- self.rargs = None\r
- self.largs = None\r
- self.values = None\r
-\r
-\r
- # -- Simple modifier methods ---------------------------------------\r
-\r
- def set_usage(self, usage):\r
- if usage is None:\r
- self.usage = _("%prog [options]")\r
- elif usage is SUPPRESS_USAGE:\r
- self.usage = None\r
- # For backwards compatibility with Optik 1.3 and earlier.\r
- elif usage.lower().startswith("usage: "):\r
- self.usage = usage[7:]\r
- else:\r
- self.usage = usage\r
-\r
- def enable_interspersed_args(self):\r
- """Set parsing to not stop on the first non-option, allowing\r
- interspersing switches with command arguments. This is the\r
- default behavior. See also disable_interspersed_args() and the\r
- class documentation description of the attribute\r
- allow_interspersed_args."""\r
- self.allow_interspersed_args = True\r
-\r
- def disable_interspersed_args(self):\r
- """Set parsing to stop on the first non-option. Use this if\r
- you have a command processor which runs another command that\r
- has options of its own and you want to make sure these options\r
- don't get confused.\r
- """\r
- self.allow_interspersed_args = False\r
-\r
- def set_process_default_values(self, process):\r
- self.process_default_values = process\r
-\r
- def set_default(self, dest, value):\r
- self.defaults[dest] = value\r
-\r
- def set_defaults(self, **kwargs):\r
- self.defaults.update(kwargs)\r
-\r
- def _get_all_options(self):\r
- options = self.option_list[:]\r
- for group in self.option_groups:\r
- options.extend(group.option_list)\r
- return options\r
-\r
- def get_default_values(self):\r
- if not self.process_default_values:\r
- # Old, pre-Optik 1.5 behaviour.\r
- return Values(self.defaults)\r
-\r
- defaults = self.defaults.copy()\r
- for option in self._get_all_options():\r
- default = defaults.get(option.dest)\r
- if isbasestring(default):\r
- opt_str = option.get_opt_string()\r
- defaults[option.dest] = option.check_value(opt_str, default)\r
-\r
- return Values(defaults)\r
-\r
-\r
- # -- OptionGroup methods -------------------------------------------\r
-\r
- def add_option_group(self, *args, **kwargs):\r
- # XXX lots of overlap with OptionContainer.add_option()\r
- if type(args[0]) is types.StringType:\r
- group = OptionGroup(self, *args, **kwargs)\r
- elif len(args) == 1 and not kwargs:\r
- group = args[0]\r
- if not isinstance(group, OptionGroup):\r
- raise TypeError, "not an OptionGroup instance: %r" % group\r
- if group.parser is not self:\r
- raise ValueError, "invalid OptionGroup (wrong parser)"\r
- else:\r
- raise TypeError, "invalid arguments"\r
-\r
- self.option_groups.append(group)\r
- return group\r
-\r
- def get_option_group(self, opt_str):\r
- option = (self._short_opt.get(opt_str) or\r
- self._long_opt.get(opt_str))\r
- if option and option.container is not self:\r
- return option.container\r
- return None\r
-\r
-\r
- # -- Option-parsing methods ----------------------------------------\r
-\r
- def _get_args(self, args):\r
- if args is None:\r
- return sys.argv[1:]\r
- else:\r
- return args[:] # don't modify caller's list\r
-\r
- def parse_args(self, args=None, values=None):\r
- """\r
- parse_args(args : [string] = sys.argv[1:],\r
- values : Values = None)\r
- -> (values : Values, args : [string])\r
-\r
- Parse the command-line options found in 'args' (default:\r
- sys.argv[1:]). Any errors result in a call to 'error()', which\r
- by default prints the usage message to stderr and calls\r
- sys.exit() with an error message. On success returns a pair\r
- (values, args) where 'values' is an Values instance (with all\r
- your option values) and 'args' is the list of arguments left\r
- over after parsing options.\r
- """\r
- rargs = self._get_args(args)\r
- if values is None:\r
- values = self.get_default_values()\r
-\r
- # Store the halves of the argument list as attributes for the\r
- # convenience of callbacks:\r
- # rargs\r
- # the rest of the command-line (the "r" stands for\r
- # "remaining" or "right-hand")\r
- # largs\r
- # the leftover arguments -- ie. what's left after removing\r
- # options and their arguments (the "l" stands for "leftover"\r
- # or "left-hand")\r
- self.rargs = rargs\r
- self.largs = largs = []\r
- self.values = values\r
-\r
- try:\r
- stop = self._process_args(largs, rargs, values)\r
- except (BadOptionError, OptionValueError), err:\r
- self.error(str(err))\r
-\r
- args = largs + rargs\r
- return self.check_values(values, args)\r
-\r
- def check_values(self, values, args):\r
- """\r
- check_values(values : Values, args : [string])\r
- -> (values : Values, args : [string])\r
-\r
- Check that the supplied option values and leftover arguments are\r
- valid. Returns the option values and leftover arguments\r
- (possibly adjusted, possibly completely new -- whatever you\r
- like). Default implementation just returns the passed-in\r
- values; subclasses may override as desired.\r
- """\r
- return (values, args)\r
-\r
- def _process_args(self, largs, rargs, values):\r
- """_process_args(largs : [string],\r
- rargs : [string],\r
- values : Values)\r
-\r
- Process command-line arguments and populate 'values', consuming\r
- options and arguments from 'rargs'. If 'allow_interspersed_args' is\r
- false, stop at the first non-option argument. If true, accumulate any\r
- interspersed non-option arguments in 'largs'.\r
- """\r
- while rargs:\r
- arg = rargs[0]\r
- # We handle bare "--" explicitly, and bare "-" is handled by the\r
- # standard arg handler since the short arg case ensures that the\r
- # len of the opt string is greater than 1.\r
- if arg == "--":\r
- del rargs[0]\r
- return\r
- elif arg[0:2] == "--":\r
- # process a single long option (possibly with value(s))\r
- self._process_long_opt(rargs, values)\r
- elif arg[:1] == "-" and len(arg) > 1:\r
- # process a cluster of short options (possibly with\r
- # value(s) for the last one only)\r
- self._process_short_opts(rargs, values)\r
- elif self.allow_interspersed_args:\r
- largs.append(arg)\r
- del rargs[0]\r
- else:\r
- return # stop now, leave this arg in rargs\r
-\r
- # Say this is the original argument list:\r
- # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)]\r
- # ^\r
- # (we are about to process arg(i)).\r
- #\r
- # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of\r
- # [arg0, ..., arg(i-1)] (any options and their arguments will have\r
- # been removed from largs).\r
- #\r
- # The while loop will usually consume 1 or more arguments per pass.\r
- # If it consumes 1 (eg. arg is an option that takes no arguments),\r
- # then after _process_arg() is done the situation is:\r
- #\r
- # largs = subset of [arg0, ..., arg(i)]\r
- # rargs = [arg(i+1), ..., arg(N-1)]\r
- #\r
- # If allow_interspersed_args is false, largs will always be\r
- # *empty* -- still a subset of [arg0, ..., arg(i-1)], but\r
- # not a very interesting subset!\r
-\r
- def _match_long_opt(self, opt):\r
- """_match_long_opt(opt : string) -> string\r
-\r
- Determine which long option string 'opt' matches, ie. which one\r
- it is an unambiguous abbrevation for. Raises BadOptionError if\r
- 'opt' doesn't unambiguously match any long option string.\r
- """\r
- return _match_abbrev(opt, self._long_opt)\r
-\r
- def _process_long_opt(self, rargs, values):\r
- arg = rargs.pop(0)\r
-\r
- # Value explicitly attached to arg? Pretend it's the next\r
- # argument.\r
- if "=" in arg:\r
- (opt, next_arg) = arg.split("=", 1)\r
- rargs.insert(0, next_arg)\r
- had_explicit_value = True\r
- else:\r
- opt = arg\r
- had_explicit_value = False\r
-\r
- opt = self._match_long_opt(opt)\r
- option = self._long_opt[opt]\r
- if option.takes_value():\r
- nargs = option.nargs\r
- if len(rargs) < nargs:\r
- if nargs == 1:\r
- self.error(_("%s option requires an argument") % opt)\r
- else:\r
- self.error(_("%s option requires %d arguments")\r
- % (opt, nargs))\r
- elif nargs == 1:\r
- value = rargs.pop(0)\r
- else:\r
- value = tuple(rargs[0:nargs])\r
- del rargs[0:nargs]\r
-\r
- elif had_explicit_value:\r
- self.error(_("%s option does not take a value") % opt)\r
-\r
- else:\r
- value = None\r
-\r
- option.process(opt, value, values, self)\r
-\r
- def _process_short_opts(self, rargs, values):\r
- arg = rargs.pop(0)\r
- stop = False\r
- i = 1\r
- for ch in arg[1:]:\r
- opt = "-" + ch\r
- option = self._short_opt.get(opt)\r
- i += 1 # we have consumed a character\r
-\r
- if not option:\r
- raise BadOptionError(opt)\r
- if option.takes_value():\r
- # Any characters left in arg? Pretend they're the\r
- # next arg, and stop consuming characters of arg.\r
- if i < len(arg):\r
- rargs.insert(0, arg[i:])\r
- stop = True\r
-\r
- nargs = option.nargs\r
- if len(rargs) < nargs:\r
- if nargs == 1:\r
- self.error(_("%s option requires an argument") % opt)\r
- else:\r
- self.error(_("%s option requires %d arguments")\r
- % (opt, nargs))\r
- elif nargs == 1:\r
- value = rargs.pop(0)\r
- else:\r
- value = tuple(rargs[0:nargs])\r
- del rargs[0:nargs]\r
-\r
- else: # option doesn't take a value\r
- value = None\r
-\r
- option.process(opt, value, values, self)\r
-\r
- if stop:\r
- break\r
-\r
-\r
- # -- Feedback methods ----------------------------------------------\r
-\r
- def get_prog_name(self):\r
- if self.prog is None:\r
- return os.path.basename(sys.argv[0])\r
- else:\r
- return self.prog\r
-\r
- def expand_prog_name(self, s):\r
- return s.replace("%prog", self.get_prog_name())\r
-\r
- def get_description(self):\r
- return self.expand_prog_name(self.description)\r
-\r
- def exit(self, status=0, msg=None):\r
- if msg:\r
- sys.stderr.write(msg)\r
- sys.exit(status)\r
-\r
- def error(self, msg):\r
- """error(msg : string)\r
-\r
- Print a usage message incorporating 'msg' to stderr and exit.\r
- If you override this in a subclass, it should not return -- it\r
- should either exit or raise an exception.\r
- """\r
- self.print_usage(sys.stderr)\r
- self.exit(2, "%s: error: %s\n" % (self.get_prog_name(), msg))\r
-\r
- def get_usage(self):\r
- if self.usage:\r
- return self.formatter.format_usage(\r
- self.expand_prog_name(self.usage))\r
- else:\r
- return ""\r
-\r
- def print_usage(self, file=None):\r
- """print_usage(file : file = stdout)\r
-\r
- Print the usage message for the current program (self.usage) to\r
- 'file' (default stdout). Any occurrence of the string "%prog" in\r
- self.usage is replaced with the name of the current program\r
- (basename of sys.argv[0]). Does nothing if self.usage is empty\r
- or not defined.\r
- """\r
- if self.usage:\r
- print >>file, self.get_usage()\r
-\r
- def get_version(self):\r
- if self.version:\r
- return self.expand_prog_name(self.version)\r
- else:\r
- return ""\r
-\r
- def print_version(self, file=None):\r
- """print_version(file : file = stdout)\r
-\r
- Print the version message for this program (self.version) to\r
- 'file' (default stdout). As with print_usage(), any occurrence\r
- of "%prog" in self.version is replaced by the current program's\r
- name. Does nothing if self.version is empty or undefined.\r
- """\r
- if self.version:\r
- print >>file, self.get_version()\r
-\r
- def format_option_help(self, formatter=None):\r
- if formatter is None:\r
- formatter = self.formatter\r
- formatter.store_option_strings(self)\r
- result = []\r
- result.append(formatter.format_heading(_("Options")))\r
- formatter.indent()\r
- if self.option_list:\r
- result.append(OptionContainer.format_option_help(self, formatter))\r
- result.append("\n")\r
- for group in self.option_groups:\r
- result.append(group.format_help(formatter))\r
- result.append("\n")\r
- formatter.dedent()\r
- # Drop the last "\n", or the header if no options or option groups:\r
- return "".join(result[:-1])\r
-\r
- def format_epilog(self, formatter):\r
- return formatter.format_epilog(self.epilog)\r
-\r
- def format_help(self, formatter=None):\r
- if formatter is None:\r
- formatter = self.formatter\r
- result = []\r
- if self.usage:\r
- result.append(self.get_usage() + "\n")\r
- if self.description:\r
- result.append(self.format_description(formatter) + "\n")\r
- result.append(self.format_option_help(formatter))\r
- result.append(self.format_epilog(formatter))\r
- return "".join(result)\r
-\r
- # used by test suite\r
- def _get_encoding(self, file):\r
- encoding = getattr(file, "encoding", None)\r
- if not encoding:\r
- encoding = sys.getdefaultencoding()\r
- return encoding\r
-\r
- def print_help(self, file=None):\r
- """print_help(file : file = stdout)\r
-\r
- Print an extended help message, listing all options and any\r
- help text provided with them, to 'file' (default stdout).\r
- """\r
- if file is None:\r
- file = sys.stdout\r
- encoding = self._get_encoding(file)\r
- file.write(self.format_help().encode(encoding, "replace"))\r
-\r
-# class OptionParser\r
-\r
-\r
-def _match_abbrev(s, wordmap):\r
- """_match_abbrev(s : string, wordmap : {string : Option}) -> string\r
-\r
- Return the string key in 'wordmap' for which 's' is an unambiguous\r
- abbreviation. If 's' is found to be ambiguous or doesn't match any of\r
- 'words', raise BadOptionError.\r
- """\r
- # Is there an exact match?\r
- if s in wordmap:\r
- return s\r
- else:\r
- # Isolate all words with s as a prefix.\r
- possibilities = [word for word in wordmap.keys()\r
- if word.startswith(s)]\r
- # No exact match, so there had better be just one possibility.\r
- if len(possibilities) == 1:\r
- return possibilities[0]\r
- elif not possibilities:\r
- raise BadOptionError(s)\r
- else:\r
- # More than one possible completion: ambiguous prefix.\r
- possibilities.sort()\r
- raise AmbiguousOptionError(s, possibilities)\r
-\r
-\r
-# Some day, there might be many Option classes. As of Optik 1.3, the\r
-# preferred way to instantiate Options is indirectly, via make_option(),\r
-# which will become a factory function when there are many Option\r
-# classes.\r
-make_option = Option\r