+++ /dev/null
-# Author: Steven J. Bethard <steven.bethard@gmail.com>.\r
-\r
-"""Command-line parsing library\r
-\r
-This module is an optparse-inspired command-line parsing library that:\r
-\r
- - handles both optional and positional arguments\r
- - produces highly informative usage messages\r
- - supports parsers that dispatch to sub-parsers\r
-\r
-The following is a simple usage example that sums integers from the\r
-command-line and writes the result to a file::\r
-\r
- parser = argparse.ArgumentParser(\r
- description='sum the integers at the command line')\r
- parser.add_argument(\r
- 'integers', metavar='int', nargs='+', type=int,\r
- help='an integer to be summed')\r
- parser.add_argument(\r
- '--log', default=sys.stdout, type=argparse.FileType('w'),\r
- help='the file where the sum should be written')\r
- args = parser.parse_args()\r
- args.log.write('%s' % sum(args.integers))\r
- args.log.close()\r
-\r
-The module contains the following public classes:\r
-\r
- - ArgumentParser -- The main entry point for command-line parsing. As the\r
- example above shows, the add_argument() method is used to populate\r
- the parser with actions for optional and positional arguments. Then\r
- the parse_args() method is invoked to convert the args at the\r
- command-line into an object with attributes.\r
-\r
- - ArgumentError -- The exception raised by ArgumentParser objects when\r
- there are errors with the parser's actions. Errors raised while\r
- parsing the command-line are caught by ArgumentParser and emitted\r
- as command-line messages.\r
-\r
- - FileType -- A factory for defining types of files to be created. As the\r
- example above shows, instances of FileType are typically passed as\r
- the type= argument of add_argument() calls.\r
-\r
- - Action -- The base class for parser actions. Typically actions are\r
- selected by passing strings like 'store_true' or 'append_const' to\r
- the action= argument of add_argument(). However, for greater\r
- customization of ArgumentParser actions, subclasses of Action may\r
- be defined and passed as the action= argument.\r
-\r
- - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter,\r
- ArgumentDefaultsHelpFormatter -- Formatter classes which\r
- may be passed as the formatter_class= argument to the\r
- ArgumentParser constructor. HelpFormatter is the default,\r
- RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser\r
- not to change the formatting for help text, and\r
- ArgumentDefaultsHelpFormatter adds information about argument defaults\r
- to the help.\r
-\r
-All other classes in this module are considered implementation details.\r
-(Also note that HelpFormatter and RawDescriptionHelpFormatter are only\r
-considered public as object names -- the API of the formatter objects is\r
-still considered an implementation detail.)\r
-"""\r
-\r
-__version__ = '1.1'\r
-__all__ = [\r
- 'ArgumentParser',\r
- 'ArgumentError',\r
- 'ArgumentTypeError',\r
- 'FileType',\r
- 'HelpFormatter',\r
- 'ArgumentDefaultsHelpFormatter',\r
- 'RawDescriptionHelpFormatter',\r
- 'RawTextHelpFormatter',\r
- 'Namespace',\r
- 'Action',\r
- 'ONE_OR_MORE',\r
- 'OPTIONAL',\r
- 'PARSER',\r
- 'REMAINDER',\r
- 'SUPPRESS',\r
- 'ZERO_OR_MORE',\r
-]\r
-\r
-\r
-import collections as _collections\r
-import copy as _copy\r
-import os as _os\r
-import re as _re\r
-import sys as _sys\r
-import textwrap as _textwrap\r
-\r
-from gettext import gettext as _\r
-\r
-\r
-def _callable(obj):\r
- return hasattr(obj, '__call__') or hasattr(obj, '__bases__')\r
-\r
-\r
-SUPPRESS = '==SUPPRESS=='\r
-\r
-OPTIONAL = '?'\r
-ZERO_OR_MORE = '*'\r
-ONE_OR_MORE = '+'\r
-PARSER = 'A...'\r
-REMAINDER = '...'\r
-_UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args'\r
-\r
-# =============================\r
-# Utility functions and classes\r
-# =============================\r
-\r
-class _AttributeHolder(object):\r
- """Abstract base class that provides __repr__.\r
-\r
- The __repr__ method returns a string in the format::\r
- ClassName(attr=name, attr=name, ...)\r
- The attributes are determined either by a class-level attribute,\r
- '_kwarg_names', or by inspecting the instance __dict__.\r
- """\r
-\r
- def __repr__(self):\r
- type_name = type(self).__name__\r
- arg_strings = []\r
- for arg in self._get_args():\r
- arg_strings.append(repr(arg))\r
- for name, value in self._get_kwargs():\r
- arg_strings.append('%s=%r' % (name, value))\r
- return '%s(%s)' % (type_name, ', '.join(arg_strings))\r
-\r
- def _get_kwargs(self):\r
- return sorted(self.__dict__.items())\r
-\r
- def _get_args(self):\r
- return []\r
-\r
-\r
-def _ensure_value(namespace, name, value):\r
- if getattr(namespace, name, None) is None:\r
- setattr(namespace, name, value)\r
- return getattr(namespace, name)\r
-\r
-\r
-# ===============\r
-# Formatting Help\r
-# ===============\r
-\r
-class HelpFormatter(object):\r
- """Formatter for generating usage messages and argument help strings.\r
-\r
- Only the name of this class is considered a public API. All the methods\r
- provided by the class are considered an implementation detail.\r
- """\r
-\r
- def __init__(self,\r
- prog,\r
- indent_increment=2,\r
- max_help_position=24,\r
- width=None):\r
-\r
- # default setting for width\r
- if width is None:\r
- try:\r
- width = int(_os.environ['COLUMNS'])\r
- except (KeyError, ValueError):\r
- width = 80\r
- width -= 2\r
-\r
- self._prog = prog\r
- self._indent_increment = indent_increment\r
- self._max_help_position = max_help_position\r
- self._max_help_position = min(max_help_position,\r
- max(width - 20, indent_increment * 2))\r
- self._width = width\r
-\r
- self._current_indent = 0\r
- self._level = 0\r
- self._action_max_length = 0\r
-\r
- self._root_section = self._Section(self, None)\r
- self._current_section = self._root_section\r
-\r
- self._whitespace_matcher = _re.compile(r'\s+')\r
- self._long_break_matcher = _re.compile(r'\n\n\n+')\r
-\r
- # ===============================\r
- # Section and indentation methods\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
- class _Section(object):\r
-\r
- def __init__(self, formatter, parent, heading=None):\r
- self.formatter = formatter\r
- self.parent = parent\r
- self.heading = heading\r
- self.items = []\r
-\r
- def format_help(self):\r
- # format the indented section\r
- if self.parent is not None:\r
- self.formatter._indent()\r
- join = self.formatter._join_parts\r
- for func, args in self.items:\r
- func(*args)\r
- item_help = join([func(*args) for func, args in self.items])\r
- if self.parent is not None:\r
- self.formatter._dedent()\r
-\r
- # return nothing if the section was empty\r
- if not item_help:\r
- return ''\r
-\r
- # add the heading if the section was non-empty\r
- if self.heading is not SUPPRESS and self.heading is not None:\r
- current_indent = self.formatter._current_indent\r
- heading = '%*s%s:\n' % (current_indent, '', self.heading)\r
- else:\r
- heading = ''\r
-\r
- # join the section-initial newline, the heading and the help\r
- return join(['\n', heading, item_help, '\n'])\r
-\r
- def _add_item(self, func, args):\r
- self._current_section.items.append((func, args))\r
-\r
- # ========================\r
- # Message building methods\r
- # ========================\r
- def start_section(self, heading):\r
- self._indent()\r
- section = self._Section(self, self._current_section, heading)\r
- self._add_item(section.format_help, [])\r
- self._current_section = section\r
-\r
- def end_section(self):\r
- self._current_section = self._current_section.parent\r
- self._dedent()\r
-\r
- def add_text(self, text):\r
- if text is not SUPPRESS and text is not None:\r
- self._add_item(self._format_text, [text])\r
-\r
- def add_usage(self, usage, actions, groups, prefix=None):\r
- if usage is not SUPPRESS:\r
- args = usage, actions, groups, prefix\r
- self._add_item(self._format_usage, args)\r
-\r
- def add_argument(self, action):\r
- if action.help is not SUPPRESS:\r
-\r
- # find all invocations\r
- get_invocation = self._format_action_invocation\r
- invocations = [get_invocation(action)]\r
- for subaction in self._iter_indented_subactions(action):\r
- invocations.append(get_invocation(subaction))\r
-\r
- # update the maximum item length\r
- invocation_length = max([len(s) for s in invocations])\r
- action_length = invocation_length + self._current_indent\r
- self._action_max_length = max(self._action_max_length,\r
- action_length)\r
-\r
- # add the item to the list\r
- self._add_item(self._format_action, [action])\r
-\r
- def add_arguments(self, actions):\r
- for action in actions:\r
- self.add_argument(action)\r
-\r
- # =======================\r
- # Help-formatting methods\r
- # =======================\r
- def format_help(self):\r
- help = self._root_section.format_help()\r
- if help:\r
- help = self._long_break_matcher.sub('\n\n', help)\r
- help = help.strip('\n') + '\n'\r
- return help\r
-\r
- def _join_parts(self, part_strings):\r
- return ''.join([part\r
- for part in part_strings\r
- if part and part is not SUPPRESS])\r
-\r
- def _format_usage(self, usage, actions, groups, prefix):\r
- if prefix is None:\r
- prefix = _('usage: ')\r
-\r
- # if usage is specified, use that\r
- if usage is not None:\r
- usage = usage % dict(prog=self._prog)\r
-\r
- # if no optionals or positionals are available, usage is just prog\r
- elif usage is None and not actions:\r
- usage = '%(prog)s' % dict(prog=self._prog)\r
-\r
- # if optionals and positionals are available, calculate usage\r
- elif usage is None:\r
- prog = '%(prog)s' % dict(prog=self._prog)\r
-\r
- # split optionals from positionals\r
- optionals = []\r
- positionals = []\r
- for action in actions:\r
- if action.option_strings:\r
- optionals.append(action)\r
- else:\r
- positionals.append(action)\r
-\r
- # build full usage string\r
- format = self._format_actions_usage\r
- action_usage = format(optionals + positionals, groups)\r
- usage = ' '.join([s for s in [prog, action_usage] if s])\r
-\r
- # wrap the usage parts if it's too long\r
- text_width = self._width - self._current_indent\r
- if len(prefix) + len(usage) > text_width:\r
-\r
- # break usage into wrappable parts\r
- part_regexp = r'\(.*?\)+|\[.*?\]+|\S+'\r
- opt_usage = format(optionals, groups)\r
- pos_usage = format(positionals, groups)\r
- opt_parts = _re.findall(part_regexp, opt_usage)\r
- pos_parts = _re.findall(part_regexp, pos_usage)\r
- assert ' '.join(opt_parts) == opt_usage\r
- assert ' '.join(pos_parts) == pos_usage\r
-\r
- # helper for wrapping lines\r
- def get_lines(parts, indent, prefix=None):\r
- lines = []\r
- line = []\r
- if prefix is not None:\r
- line_len = len(prefix) - 1\r
- else:\r
- line_len = len(indent) - 1\r
- for part in parts:\r
- if line_len + 1 + len(part) > text_width and line:\r
- lines.append(indent + ' '.join(line))\r
- line = []\r
- line_len = len(indent) - 1\r
- line.append(part)\r
- line_len += len(part) + 1\r
- if line:\r
- lines.append(indent + ' '.join(line))\r
- if prefix is not None:\r
- lines[0] = lines[0][len(indent):]\r
- return lines\r
-\r
- # if prog is short, follow it with optionals or positionals\r
- if len(prefix) + len(prog) <= 0.75 * text_width:\r
- indent = ' ' * (len(prefix) + len(prog) + 1)\r
- if opt_parts:\r
- lines = get_lines([prog] + opt_parts, indent, prefix)\r
- lines.extend(get_lines(pos_parts, indent))\r
- elif pos_parts:\r
- lines = get_lines([prog] + pos_parts, indent, prefix)\r
- else:\r
- lines = [prog]\r
-\r
- # if prog is long, put it on its own line\r
- else:\r
- indent = ' ' * len(prefix)\r
- parts = opt_parts + pos_parts\r
- lines = get_lines(parts, indent)\r
- if len(lines) > 1:\r
- lines = []\r
- lines.extend(get_lines(opt_parts, indent))\r
- lines.extend(get_lines(pos_parts, indent))\r
- lines = [prog] + lines\r
-\r
- # join lines into usage\r
- usage = '\n'.join(lines)\r
-\r
- # prefix with 'usage:'\r
- return '%s%s\n\n' % (prefix, usage)\r
-\r
- def _format_actions_usage(self, actions, groups):\r
- # find group indices and identify actions in groups\r
- group_actions = set()\r
- inserts = {}\r
- for group in groups:\r
- try:\r
- start = actions.index(group._group_actions[0])\r
- except ValueError:\r
- continue\r
- else:\r
- end = start + len(group._group_actions)\r
- if actions[start:end] == group._group_actions:\r
- for action in group._group_actions:\r
- group_actions.add(action)\r
- if not group.required:\r
- if start in inserts:\r
- inserts[start] += ' ['\r
- else:\r
- inserts[start] = '['\r
- inserts[end] = ']'\r
- else:\r
- if start in inserts:\r
- inserts[start] += ' ('\r
- else:\r
- inserts[start] = '('\r
- inserts[end] = ')'\r
- for i in range(start + 1, end):\r
- inserts[i] = '|'\r
-\r
- # collect all actions format strings\r
- parts = []\r
- for i, action in enumerate(actions):\r
-\r
- # suppressed arguments are marked with None\r
- # remove | separators for suppressed arguments\r
- if action.help is SUPPRESS:\r
- parts.append(None)\r
- if inserts.get(i) == '|':\r
- inserts.pop(i)\r
- elif inserts.get(i + 1) == '|':\r
- inserts.pop(i + 1)\r
-\r
- # produce all arg strings\r
- elif not action.option_strings:\r
- part = self._format_args(action, action.dest)\r
-\r
- # if it's in a group, strip the outer []\r
- if action in group_actions:\r
- if part[0] == '[' and part[-1] == ']':\r
- part = part[1:-1]\r
-\r
- # add the action string to the list\r
- parts.append(part)\r
-\r
- # produce the first way to invoke the option in brackets\r
- else:\r
- option_string = action.option_strings[0]\r
-\r
- # if the Optional doesn't take a value, format is:\r
- # -s or --long\r
- if action.nargs == 0:\r
- part = '%s' % option_string\r
-\r
- # if the Optional takes a value, format is:\r
- # -s ARGS or --long ARGS\r
- else:\r
- default = action.dest.upper()\r
- args_string = self._format_args(action, default)\r
- part = '%s %s' % (option_string, args_string)\r
-\r
- # make it look optional if it's not required or in a group\r
- if not action.required and action not in group_actions:\r
- part = '[%s]' % part\r
-\r
- # add the action string to the list\r
- parts.append(part)\r
-\r
- # insert things at the necessary indices\r
- for i in sorted(inserts, reverse=True):\r
- parts[i:i] = [inserts[i]]\r
-\r
- # join all the action items with spaces\r
- text = ' '.join([item for item in parts if item is not None])\r
-\r
- # clean up separators for mutually exclusive groups\r
- open = r'[\[(]'\r
- close = r'[\])]'\r
- text = _re.sub(r'(%s) ' % open, r'\1', text)\r
- text = _re.sub(r' (%s)' % close, r'\1', text)\r
- text = _re.sub(r'%s *%s' % (open, close), r'', text)\r
- text = _re.sub(r'\(([^|]*)\)', r'\1', text)\r
- text = text.strip()\r
-\r
- # return the text\r
- return text\r
-\r
- def _format_text(self, text):\r
- if '%(prog)' in text:\r
- text = text % dict(prog=self._prog)\r
- text_width = max(self._width - self._current_indent, 11)\r
- indent = ' ' * self._current_indent\r
- return self._fill_text(text, text_width, indent) + '\n\n'\r
-\r
- def _format_action(self, action):\r
- # determine the required width and the entry label\r
- help_position = min(self._action_max_length + 2,\r
- self._max_help_position)\r
- help_width = max(self._width - help_position, 11)\r
- action_width = help_position - self._current_indent - 2\r
- action_header = self._format_action_invocation(action)\r
-\r
- # ho nelp; start on same line and add a final newline\r
- if not action.help:\r
- tup = self._current_indent, '', action_header\r
- action_header = '%*s%s\n' % tup\r
-\r
- # short action name; start on the same line and pad two spaces\r
- elif len(action_header) <= action_width:\r
- tup = self._current_indent, '', action_width, action_header\r
- action_header = '%*s%-*s ' % tup\r
- indent_first = 0\r
-\r
- # long action name; start on the next line\r
- else:\r
- tup = self._current_indent, '', action_header\r
- action_header = '%*s%s\n' % tup\r
- indent_first = help_position\r
-\r
- # collect the pieces of the action help\r
- parts = [action_header]\r
-\r
- # if there was help for the action, add lines of help text\r
- if action.help:\r
- help_text = self._expand_help(action)\r
- help_lines = self._split_lines(help_text, help_width)\r
- parts.append('%*s%s\n' % (indent_first, '', help_lines[0]))\r
- for line in help_lines[1:]:\r
- parts.append('%*s%s\n' % (help_position, '', line))\r
-\r
- # or add a newline if the description doesn't end with one\r
- elif not action_header.endswith('\n'):\r
- parts.append('\n')\r
-\r
- # if there are any sub-actions, add their help as well\r
- for subaction in self._iter_indented_subactions(action):\r
- parts.append(self._format_action(subaction))\r
-\r
- # return a single string\r
- return self._join_parts(parts)\r
-\r
- def _format_action_invocation(self, action):\r
- if not action.option_strings:\r
- metavar, = self._metavar_formatter(action, action.dest)(1)\r
- return metavar\r
-\r
- else:\r
- parts = []\r
-\r
- # if the Optional doesn't take a value, format is:\r
- # -s, --long\r
- if action.nargs == 0:\r
- parts.extend(action.option_strings)\r
-\r
- # if the Optional takes a value, format is:\r
- # -s ARGS, --long ARGS\r
- else:\r
- default = action.dest.upper()\r
- args_string = self._format_args(action, default)\r
- for option_string in action.option_strings:\r
- parts.append('%s %s' % (option_string, args_string))\r
-\r
- return ', '.join(parts)\r
-\r
- def _metavar_formatter(self, action, default_metavar):\r
- if action.metavar is not None:\r
- result = action.metavar\r
- elif action.choices is not None:\r
- choice_strs = [str(choice) for choice in action.choices]\r
- result = '{%s}' % ','.join(choice_strs)\r
- else:\r
- result = default_metavar\r
-\r
- def format(tuple_size):\r
- if isinstance(result, tuple):\r
- return result\r
- else:\r
- return (result, ) * tuple_size\r
- return format\r
-\r
- def _format_args(self, action, default_metavar):\r
- get_metavar = self._metavar_formatter(action, default_metavar)\r
- if action.nargs is None:\r
- result = '%s' % get_metavar(1)\r
- elif action.nargs == OPTIONAL:\r
- result = '[%s]' % get_metavar(1)\r
- elif action.nargs == ZERO_OR_MORE:\r
- result = '[%s [%s ...]]' % get_metavar(2)\r
- elif action.nargs == ONE_OR_MORE:\r
- result = '%s [%s ...]' % get_metavar(2)\r
- elif action.nargs == REMAINDER:\r
- result = '...'\r
- elif action.nargs == PARSER:\r
- result = '%s ...' % get_metavar(1)\r
- else:\r
- formats = ['%s' for _ in range(action.nargs)]\r
- result = ' '.join(formats) % get_metavar(action.nargs)\r
- return result\r
-\r
- def _expand_help(self, action):\r
- params = dict(vars(action), prog=self._prog)\r
- for name in list(params):\r
- if params[name] is SUPPRESS:\r
- del params[name]\r
- for name in list(params):\r
- if hasattr(params[name], '__name__'):\r
- params[name] = params[name].__name__\r
- if params.get('choices') is not None:\r
- choices_str = ', '.join([str(c) for c in params['choices']])\r
- params['choices'] = choices_str\r
- return self._get_help_string(action) % params\r
-\r
- def _iter_indented_subactions(self, action):\r
- try:\r
- get_subactions = action._get_subactions\r
- except AttributeError:\r
- pass\r
- else:\r
- self._indent()\r
- for subaction in get_subactions():\r
- yield subaction\r
- self._dedent()\r
-\r
- def _split_lines(self, text, width):\r
- text = self._whitespace_matcher.sub(' ', text).strip()\r
- return _textwrap.wrap(text, width)\r
-\r
- def _fill_text(self, text, width, indent):\r
- text = self._whitespace_matcher.sub(' ', text).strip()\r
- return _textwrap.fill(text, width, initial_indent=indent,\r
- subsequent_indent=indent)\r
-\r
- def _get_help_string(self, action):\r
- return action.help\r
-\r
-\r
-class RawDescriptionHelpFormatter(HelpFormatter):\r
- """Help message formatter which retains any formatting in descriptions.\r
-\r
- Only the name of this class is considered a public API. All the methods\r
- provided by the class are considered an implementation detail.\r
- """\r
-\r
- def _fill_text(self, text, width, indent):\r
- return ''.join([indent + line for line in text.splitlines(True)])\r
-\r
-\r
-class RawTextHelpFormatter(RawDescriptionHelpFormatter):\r
- """Help message formatter which retains formatting of all help text.\r
-\r
- Only the name of this class is considered a public API. All the methods\r
- provided by the class are considered an implementation detail.\r
- """\r
-\r
- def _split_lines(self, text, width):\r
- return text.splitlines()\r
-\r
-\r
-class ArgumentDefaultsHelpFormatter(HelpFormatter):\r
- """Help message formatter which adds default values to argument help.\r
-\r
- Only the name of this class is considered a public API. All the methods\r
- provided by the class are considered an implementation detail.\r
- """\r
-\r
- def _get_help_string(self, action):\r
- help = action.help\r
- if '%(default)' not in action.help:\r
- if action.default is not SUPPRESS:\r
- defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]\r
- if action.option_strings or action.nargs in defaulting_nargs:\r
- help += ' (default: %(default)s)'\r
- return help\r
-\r
-\r
-# =====================\r
-# Options and Arguments\r
-# =====================\r
-\r
-def _get_action_name(argument):\r
- if argument is None:\r
- return None\r
- elif argument.option_strings:\r
- return '/'.join(argument.option_strings)\r
- elif argument.metavar not in (None, SUPPRESS):\r
- return argument.metavar\r
- elif argument.dest not in (None, SUPPRESS):\r
- return argument.dest\r
- else:\r
- return None\r
-\r
-\r
-class ArgumentError(Exception):\r
- """An error from creating or using an argument (optional or positional).\r
-\r
- The string value of this exception is the message, augmented with\r
- information about the argument that caused it.\r
- """\r
-\r
- def __init__(self, argument, message):\r
- self.argument_name = _get_action_name(argument)\r
- self.message = message\r
-\r
- def __str__(self):\r
- if self.argument_name is None:\r
- format = '%(message)s'\r
- else:\r
- format = 'argument %(argument_name)s: %(message)s'\r
- return format % dict(message=self.message,\r
- argument_name=self.argument_name)\r
-\r
-\r
-class ArgumentTypeError(Exception):\r
- """An error from trying to convert a command line string to a type."""\r
- pass\r
-\r
-\r
-# ==============\r
-# Action classes\r
-# ==============\r
-\r
-class Action(_AttributeHolder):\r
- """Information about how to convert command line strings to Python objects.\r
-\r
- Action objects are used by an ArgumentParser to represent the information\r
- needed to parse a single argument from one or more strings from the\r
- command line. The keyword arguments to the Action constructor are also\r
- all attributes of Action instances.\r
-\r
- Keyword Arguments:\r
-\r
- - option_strings -- A list of command-line option strings which\r
- should be associated with this action.\r
-\r
- - dest -- The name of the attribute to hold the created object(s)\r
-\r
- - nargs -- The number of command-line arguments that should be\r
- consumed. By default, one argument will be consumed and a single\r
- value will be produced. Other values include:\r
- - N (an integer) consumes N arguments (and produces a list)\r
- - '?' consumes zero or one arguments\r
- - '*' consumes zero or more arguments (and produces a list)\r
- - '+' consumes one or more arguments (and produces a list)\r
- Note that the difference between the default and nargs=1 is that\r
- with the default, a single value will be produced, while with\r
- nargs=1, a list containing a single value will be produced.\r
-\r
- - const -- The value to be produced if the option is specified and the\r
- option uses an action that takes no values.\r
-\r
- - default -- The value to be produced if the option is not specified.\r
-\r
- - type -- A callable that accepts a single string argument, and\r
- returns the converted value. The standard Python types str, int,\r
- float, and complex are useful examples of such callables. If None,\r
- str is used.\r
-\r
- - choices -- A container of values that should be allowed. If not None,\r
- after a command-line argument has been converted to the appropriate\r
- type, an exception will be raised if it is not a member of this\r
- collection.\r
-\r
- - required -- True if the action must always be specified at the\r
- command line. This is only meaningful for optional command-line\r
- arguments.\r
-\r
- - help -- The help string describing the argument.\r
-\r
- - metavar -- The name to be used for the option's argument with the\r
- help string. If None, the 'dest' value will be used as the name.\r
- """\r
-\r
- def __init__(self,\r
- option_strings,\r
- dest,\r
- nargs=None,\r
- const=None,\r
- default=None,\r
- type=None,\r
- choices=None,\r
- required=False,\r
- help=None,\r
- metavar=None):\r
- self.option_strings = option_strings\r
- self.dest = dest\r
- self.nargs = nargs\r
- self.const = const\r
- self.default = default\r
- self.type = type\r
- self.choices = choices\r
- self.required = required\r
- self.help = help\r
- self.metavar = metavar\r
-\r
- def _get_kwargs(self):\r
- names = [\r
- 'option_strings',\r
- 'dest',\r
- 'nargs',\r
- 'const',\r
- 'default',\r
- 'type',\r
- 'choices',\r
- 'help',\r
- 'metavar',\r
- ]\r
- return [(name, getattr(self, name)) for name in names]\r
-\r
- def __call__(self, parser, namespace, values, option_string=None):\r
- raise NotImplementedError(_('.__call__() not defined'))\r
-\r
-\r
-class _StoreAction(Action):\r
-\r
- def __init__(self,\r
- option_strings,\r
- dest,\r
- nargs=None,\r
- const=None,\r
- default=None,\r
- type=None,\r
- choices=None,\r
- required=False,\r
- help=None,\r
- metavar=None):\r
- if nargs == 0:\r
- raise ValueError('nargs for store actions must be > 0; if you '\r
- 'have nothing to store, actions such as store '\r
- 'true or store const may be more appropriate')\r
- if const is not None and nargs != OPTIONAL:\r
- raise ValueError('nargs must be %r to supply const' % OPTIONAL)\r
- super(_StoreAction, self).__init__(\r
- option_strings=option_strings,\r
- dest=dest,\r
- nargs=nargs,\r
- const=const,\r
- default=default,\r
- type=type,\r
- choices=choices,\r
- required=required,\r
- help=help,\r
- metavar=metavar)\r
-\r
- def __call__(self, parser, namespace, values, option_string=None):\r
- setattr(namespace, self.dest, values)\r
-\r
-\r
-class _StoreConstAction(Action):\r
-\r
- def __init__(self,\r
- option_strings,\r
- dest,\r
- const,\r
- default=None,\r
- required=False,\r
- help=None,\r
- metavar=None):\r
- super(_StoreConstAction, self).__init__(\r
- option_strings=option_strings,\r
- dest=dest,\r
- nargs=0,\r
- const=const,\r
- default=default,\r
- required=required,\r
- help=help)\r
-\r
- def __call__(self, parser, namespace, values, option_string=None):\r
- setattr(namespace, self.dest, self.const)\r
-\r
-\r
-class _StoreTrueAction(_StoreConstAction):\r
-\r
- def __init__(self,\r
- option_strings,\r
- dest,\r
- default=False,\r
- required=False,\r
- help=None):\r
- super(_StoreTrueAction, self).__init__(\r
- option_strings=option_strings,\r
- dest=dest,\r
- const=True,\r
- default=default,\r
- required=required,\r
- help=help)\r
-\r
-\r
-class _StoreFalseAction(_StoreConstAction):\r
-\r
- def __init__(self,\r
- option_strings,\r
- dest,\r
- default=True,\r
- required=False,\r
- help=None):\r
- super(_StoreFalseAction, self).__init__(\r
- option_strings=option_strings,\r
- dest=dest,\r
- const=False,\r
- default=default,\r
- required=required,\r
- help=help)\r
-\r
-\r
-class _AppendAction(Action):\r
-\r
- def __init__(self,\r
- option_strings,\r
- dest,\r
- nargs=None,\r
- const=None,\r
- default=None,\r
- type=None,\r
- choices=None,\r
- required=False,\r
- help=None,\r
- metavar=None):\r
- if nargs == 0:\r
- raise ValueError('nargs for append actions must be > 0; if arg '\r
- 'strings are not supplying the value to append, '\r
- 'the append const action may be more appropriate')\r
- if const is not None and nargs != OPTIONAL:\r
- raise ValueError('nargs must be %r to supply const' % OPTIONAL)\r
- super(_AppendAction, self).__init__(\r
- option_strings=option_strings,\r
- dest=dest,\r
- nargs=nargs,\r
- const=const,\r
- default=default,\r
- type=type,\r
- choices=choices,\r
- required=required,\r
- help=help,\r
- metavar=metavar)\r
-\r
- def __call__(self, parser, namespace, values, option_string=None):\r
- items = _copy.copy(_ensure_value(namespace, self.dest, []))\r
- items.append(values)\r
- setattr(namespace, self.dest, items)\r
-\r
-\r
-class _AppendConstAction(Action):\r
-\r
- def __init__(self,\r
- option_strings,\r
- dest,\r
- const,\r
- default=None,\r
- required=False,\r
- help=None,\r
- metavar=None):\r
- super(_AppendConstAction, self).__init__(\r
- option_strings=option_strings,\r
- dest=dest,\r
- nargs=0,\r
- const=const,\r
- default=default,\r
- required=required,\r
- help=help,\r
- metavar=metavar)\r
-\r
- def __call__(self, parser, namespace, values, option_string=None):\r
- items = _copy.copy(_ensure_value(namespace, self.dest, []))\r
- items.append(self.const)\r
- setattr(namespace, self.dest, items)\r
-\r
-\r
-class _CountAction(Action):\r
-\r
- def __init__(self,\r
- option_strings,\r
- dest,\r
- default=None,\r
- required=False,\r
- help=None):\r
- super(_CountAction, self).__init__(\r
- option_strings=option_strings,\r
- dest=dest,\r
- nargs=0,\r
- default=default,\r
- required=required,\r
- help=help)\r
-\r
- def __call__(self, parser, namespace, values, option_string=None):\r
- new_count = _ensure_value(namespace, self.dest, 0) + 1\r
- setattr(namespace, self.dest, new_count)\r
-\r
-\r
-class _HelpAction(Action):\r
-\r
- def __init__(self,\r
- option_strings,\r
- dest=SUPPRESS,\r
- default=SUPPRESS,\r
- help=None):\r
- super(_HelpAction, self).__init__(\r
- option_strings=option_strings,\r
- dest=dest,\r
- default=default,\r
- nargs=0,\r
- help=help)\r
-\r
- def __call__(self, parser, namespace, values, option_string=None):\r
- parser.print_help()\r
- parser.exit()\r
-\r
-\r
-class _VersionAction(Action):\r
-\r
- def __init__(self,\r
- option_strings,\r
- version=None,\r
- dest=SUPPRESS,\r
- default=SUPPRESS,\r
- help="show program's version number and exit"):\r
- super(_VersionAction, self).__init__(\r
- option_strings=option_strings,\r
- dest=dest,\r
- default=default,\r
- nargs=0,\r
- help=help)\r
- self.version = version\r
-\r
- def __call__(self, parser, namespace, values, option_string=None):\r
- version = self.version\r
- if version is None:\r
- version = parser.version\r
- formatter = parser._get_formatter()\r
- formatter.add_text(version)\r
- parser.exit(message=formatter.format_help())\r
-\r
-\r
-class _SubParsersAction(Action):\r
-\r
- class _ChoicesPseudoAction(Action):\r
-\r
- def __init__(self, name, help):\r
- sup = super(_SubParsersAction._ChoicesPseudoAction, self)\r
- sup.__init__(option_strings=[], dest=name, help=help)\r
-\r
- def __init__(self,\r
- option_strings,\r
- prog,\r
- parser_class,\r
- dest=SUPPRESS,\r
- help=None,\r
- metavar=None):\r
-\r
- self._prog_prefix = prog\r
- self._parser_class = parser_class\r
- self._name_parser_map = _collections.OrderedDict()\r
- self._choices_actions = []\r
-\r
- super(_SubParsersAction, self).__init__(\r
- option_strings=option_strings,\r
- dest=dest,\r
- nargs=PARSER,\r
- choices=self._name_parser_map,\r
- help=help,\r
- metavar=metavar)\r
-\r
- def add_parser(self, name, **kwargs):\r
- # set prog from the existing prefix\r
- if kwargs.get('prog') is None:\r
- kwargs['prog'] = '%s %s' % (self._prog_prefix, name)\r
-\r
- # create a pseudo-action to hold the choice help\r
- if 'help' in kwargs:\r
- help = kwargs.pop('help')\r
- choice_action = self._ChoicesPseudoAction(name, help)\r
- self._choices_actions.append(choice_action)\r
-\r
- # create the parser and add it to the map\r
- parser = self._parser_class(**kwargs)\r
- self._name_parser_map[name] = parser\r
- return parser\r
-\r
- def _get_subactions(self):\r
- return self._choices_actions\r
-\r
- def __call__(self, parser, namespace, values, option_string=None):\r
- parser_name = values[0]\r
- arg_strings = values[1:]\r
-\r
- # set the parser name if requested\r
- if self.dest is not SUPPRESS:\r
- setattr(namespace, self.dest, parser_name)\r
-\r
- # select the parser\r
- try:\r
- parser = self._name_parser_map[parser_name]\r
- except KeyError:\r
- tup = parser_name, ', '.join(self._name_parser_map)\r
- msg = _('unknown parser %r (choices: %s)') % tup\r
- raise ArgumentError(self, msg)\r
-\r
- # parse all the remaining options into the namespace\r
- # store any unrecognized options on the object, so that the top\r
- # level parser can decide what to do with them\r
-\r
- # In case this subparser defines new defaults, we parse them\r
- # in a new namespace object and then update the original\r
- # namespace for the relevant parts.\r
- subnamespace, arg_strings = parser.parse_known_args(arg_strings, None)\r
- for key, value in vars(subnamespace).items():\r
- setattr(namespace, key, value)\r
-\r
- if arg_strings:\r
- vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, [])\r
- getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings)\r
-\r
-\r
-# ==============\r
-# Type classes\r
-# ==============\r
-\r
-class FileType(object):\r
- """Factory for creating file object types\r
-\r
- Instances of FileType are typically passed as type= arguments to the\r
- ArgumentParser add_argument() method.\r
-\r
- Keyword Arguments:\r
- - mode -- A string indicating how the file is to be opened. Accepts the\r
- same values as the builtin open() function.\r
- - bufsize -- The file's desired buffer size. Accepts the same values as\r
- the builtin open() function.\r
- """\r
-\r
- def __init__(self, mode='r', bufsize=-1):\r
- self._mode = mode\r
- self._bufsize = bufsize\r
-\r
- def __call__(self, string):\r
- # the special argument "-" means sys.std{in,out}\r
- if string == '-':\r
- if 'r' in self._mode:\r
- return _sys.stdin\r
- elif 'w' in self._mode:\r
- return _sys.stdout\r
- else:\r
- msg = _('argument "-" with mode %r') % self._mode\r
- raise ValueError(msg)\r
-\r
- # all other arguments are used as file names\r
- try:\r
- return open(string, self._mode, self._bufsize)\r
- except IOError as e:\r
- message = _("can't open '%s': %s")\r
- raise ArgumentTypeError(message % (string, e))\r
-\r
- def __repr__(self):\r
- args = self._mode, self._bufsize\r
- args_str = ', '.join(repr(arg) for arg in args if arg != -1)\r
- return '%s(%s)' % (type(self).__name__, args_str)\r
-\r
-# ===========================\r
-# Optional and Positional Parsing\r
-# ===========================\r
-\r
-class Namespace(_AttributeHolder):\r
- """Simple object for storing attributes.\r
-\r
- Implements equality by attribute names and values, and provides a simple\r
- string representation.\r
- """\r
-\r
- def __init__(self, **kwargs):\r
- for name in kwargs:\r
- setattr(self, name, kwargs[name])\r
-\r
- __hash__ = None\r
-\r
- def __eq__(self, other):\r
- if not isinstance(other, Namespace):\r
- return NotImplemented\r
- return vars(self) == vars(other)\r
-\r
- def __ne__(self, other):\r
- if not isinstance(other, Namespace):\r
- return NotImplemented\r
- return not (self == other)\r
-\r
- def __contains__(self, key):\r
- return key in self.__dict__\r
-\r
-\r
-class _ActionsContainer(object):\r
-\r
- def __init__(self,\r
- description,\r
- prefix_chars,\r
- argument_default,\r
- conflict_handler):\r
- super(_ActionsContainer, self).__init__()\r
-\r
- self.description = description\r
- self.argument_default = argument_default\r
- self.prefix_chars = prefix_chars\r
- self.conflict_handler = conflict_handler\r
-\r
- # set up registries\r
- self._registries = {}\r
-\r
- # register actions\r
- self.register('action', None, _StoreAction)\r
- self.register('action', 'store', _StoreAction)\r
- self.register('action', 'store_const', _StoreConstAction)\r
- self.register('action', 'store_true', _StoreTrueAction)\r
- self.register('action', 'store_false', _StoreFalseAction)\r
- self.register('action', 'append', _AppendAction)\r
- self.register('action', 'append_const', _AppendConstAction)\r
- self.register('action', 'count', _CountAction)\r
- self.register('action', 'help', _HelpAction)\r
- self.register('action', 'version', _VersionAction)\r
- self.register('action', 'parsers', _SubParsersAction)\r
-\r
- # raise an exception if the conflict handler is invalid\r
- self._get_handler()\r
-\r
- # action storage\r
- self._actions = []\r
- self._option_string_actions = {}\r
-\r
- # groups\r
- self._action_groups = []\r
- self._mutually_exclusive_groups = []\r
-\r
- # defaults storage\r
- self._defaults = {}\r
-\r
- # determines whether an "option" looks like a negative number\r
- self._negative_number_matcher = _re.compile(r'^-\d+$|^-\d*\.\d+$')\r
-\r
- # whether or not there are any optionals that look like negative\r
- # numbers -- uses a list so it can be shared and edited\r
- self._has_negative_number_optionals = []\r
-\r
- # ====================\r
- # Registration methods\r
- # ====================\r
- def register(self, registry_name, value, object):\r
- registry = self._registries.setdefault(registry_name, {})\r
- registry[value] = object\r
-\r
- def _registry_get(self, registry_name, value, default=None):\r
- return self._registries[registry_name].get(value, default)\r
-\r
- # ==================================\r
- # Namespace default accessor methods\r
- # ==================================\r
- def set_defaults(self, **kwargs):\r
- self._defaults.update(kwargs)\r
-\r
- # if these defaults match any existing arguments, replace\r
- # the previous default on the object with the new one\r
- for action in self._actions:\r
- if action.dest in kwargs:\r
- action.default = kwargs[action.dest]\r
-\r
- def get_default(self, dest):\r
- for action in self._actions:\r
- if action.dest == dest and action.default is not None:\r
- return action.default\r
- return self._defaults.get(dest, None)\r
-\r
-\r
- # =======================\r
- # Adding argument actions\r
- # =======================\r
- def add_argument(self, *args, **kwargs):\r
- """\r
- add_argument(dest, ..., name=value, ...)\r
- add_argument(option_string, option_string, ..., name=value, ...)\r
- """\r
-\r
- # if no positional args are supplied or only one is supplied and\r
- # it doesn't look like an option string, parse a positional\r
- # argument\r
- chars = self.prefix_chars\r
- if not args or len(args) == 1 and args[0][0] not in chars:\r
- if args and 'dest' in kwargs:\r
- raise ValueError('dest supplied twice for positional argument')\r
- kwargs = self._get_positional_kwargs(*args, **kwargs)\r
-\r
- # otherwise, we're adding an optional argument\r
- else:\r
- kwargs = self._get_optional_kwargs(*args, **kwargs)\r
-\r
- # if no default was supplied, use the parser-level default\r
- if 'default' not in kwargs:\r
- dest = kwargs['dest']\r
- if dest in self._defaults:\r
- kwargs['default'] = self._defaults[dest]\r
- elif self.argument_default is not None:\r
- kwargs['default'] = self.argument_default\r
-\r
- # create the action object, and add it to the parser\r
- action_class = self._pop_action_class(kwargs)\r
- if not _callable(action_class):\r
- raise ValueError('unknown action "%s"' % (action_class,))\r
- action = action_class(**kwargs)\r
-\r
- # raise an error if the action type is not callable\r
- type_func = self._registry_get('type', action.type, action.type)\r
- if not _callable(type_func):\r
- raise ValueError('%r is not callable' % (type_func,))\r
-\r
- # raise an error if the metavar does not match the type\r
- if hasattr(self, "_get_formatter"):\r
- try:\r
- self._get_formatter()._format_args(action, None)\r
- except TypeError:\r
- raise ValueError("length of metavar tuple does not match nargs")\r
-\r
- return self._add_action(action)\r
-\r
- def add_argument_group(self, *args, **kwargs):\r
- group = _ArgumentGroup(self, *args, **kwargs)\r
- self._action_groups.append(group)\r
- return group\r
-\r
- def add_mutually_exclusive_group(self, **kwargs):\r
- group = _MutuallyExclusiveGroup(self, **kwargs)\r
- self._mutually_exclusive_groups.append(group)\r
- return group\r
-\r
- def _add_action(self, action):\r
- # resolve any conflicts\r
- self._check_conflict(action)\r
-\r
- # add to actions list\r
- self._actions.append(action)\r
- action.container = self\r
-\r
- # index the action by any option strings it has\r
- for option_string in action.option_strings:\r
- self._option_string_actions[option_string] = action\r
-\r
- # set the flag if any option strings look like negative numbers\r
- for option_string in action.option_strings:\r
- if self._negative_number_matcher.match(option_string):\r
- if not self._has_negative_number_optionals:\r
- self._has_negative_number_optionals.append(True)\r
-\r
- # return the created action\r
- return action\r
-\r
- def _remove_action(self, action):\r
- self._actions.remove(action)\r
-\r
- def _add_container_actions(self, container):\r
- # collect groups by titles\r
- title_group_map = {}\r
- for group in self._action_groups:\r
- if group.title in title_group_map:\r
- msg = _('cannot merge actions - two groups are named %r')\r
- raise ValueError(msg % (group.title))\r
- title_group_map[group.title] = group\r
-\r
- # map each action to its group\r
- group_map = {}\r
- for group in container._action_groups:\r
-\r
- # if a group with the title exists, use that, otherwise\r
- # create a new group matching the container's group\r
- if group.title not in title_group_map:\r
- title_group_map[group.title] = self.add_argument_group(\r
- title=group.title,\r
- description=group.description,\r
- conflict_handler=group.conflict_handler)\r
-\r
- # map the actions to their new group\r
- for action in group._group_actions:\r
- group_map[action] = title_group_map[group.title]\r
-\r
- # add container's mutually exclusive groups\r
- # NOTE: if add_mutually_exclusive_group ever gains title= and\r
- # description= then this code will need to be expanded as above\r
- for group in container._mutually_exclusive_groups:\r
- mutex_group = self.add_mutually_exclusive_group(\r
- required=group.required)\r
-\r
- # map the actions to their new mutex group\r
- for action in group._group_actions:\r
- group_map[action] = mutex_group\r
-\r
- # add all actions to this container or their group\r
- for action in container._actions:\r
- group_map.get(action, self)._add_action(action)\r
-\r
- def _get_positional_kwargs(self, dest, **kwargs):\r
- # make sure required is not specified\r
- if 'required' in kwargs:\r
- msg = _("'required' is an invalid argument for positionals")\r
- raise TypeError(msg)\r
-\r
- # mark positional arguments as required if at least one is\r
- # always required\r
- if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]:\r
- kwargs['required'] = True\r
- if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs:\r
- kwargs['required'] = True\r
-\r
- # return the keyword arguments with no option strings\r
- return dict(kwargs, dest=dest, option_strings=[])\r
-\r
- def _get_optional_kwargs(self, *args, **kwargs):\r
- # determine short and long option strings\r
- option_strings = []\r
- long_option_strings = []\r
- for option_string in args:\r
- # error on strings that don't start with an appropriate prefix\r
- if not option_string[0] in self.prefix_chars:\r
- msg = _('invalid option string %r: '\r
- 'must start with a character %r')\r
- tup = option_string, self.prefix_chars\r
- raise ValueError(msg % tup)\r
-\r
- # strings starting with two prefix characters are long options\r
- option_strings.append(option_string)\r
- if option_string[0] in self.prefix_chars:\r
- if len(option_string) > 1:\r
- if option_string[1] in self.prefix_chars:\r
- long_option_strings.append(option_string)\r
-\r
- # infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x'\r
- dest = kwargs.pop('dest', None)\r
- if dest is None:\r
- if long_option_strings:\r
- dest_option_string = long_option_strings[0]\r
- else:\r
- dest_option_string = option_strings[0]\r
- dest = dest_option_string.lstrip(self.prefix_chars)\r
- if not dest:\r
- msg = _('dest= is required for options like %r')\r
- raise ValueError(msg % option_string)\r
- dest = dest.replace('-', '_')\r
-\r
- # return the updated keyword arguments\r
- return dict(kwargs, dest=dest, option_strings=option_strings)\r
-\r
- def _pop_action_class(self, kwargs, default=None):\r
- action = kwargs.pop('action', default)\r
- return self._registry_get('action', action, action)\r
-\r
- def _get_handler(self):\r
- # determine function from conflict handler string\r
- handler_func_name = '_handle_conflict_%s' % self.conflict_handler\r
- try:\r
- return getattr(self, handler_func_name)\r
- except AttributeError:\r
- msg = _('invalid conflict_resolution value: %r')\r
- raise ValueError(msg % self.conflict_handler)\r
-\r
- def _check_conflict(self, action):\r
-\r
- # find all options that conflict with this option\r
- confl_optionals = []\r
- for option_string in action.option_strings:\r
- if option_string in self._option_string_actions:\r
- confl_optional = self._option_string_actions[option_string]\r
- confl_optionals.append((option_string, confl_optional))\r
-\r
- # resolve any conflicts\r
- if confl_optionals:\r
- conflict_handler = self._get_handler()\r
- conflict_handler(action, confl_optionals)\r
-\r
- def _handle_conflict_error(self, action, conflicting_actions):\r
- message = _('conflicting option string(s): %s')\r
- conflict_string = ', '.join([option_string\r
- for option_string, action\r
- in conflicting_actions])\r
- raise ArgumentError(action, message % conflict_string)\r
-\r
- def _handle_conflict_resolve(self, action, conflicting_actions):\r
-\r
- # remove all conflicting options\r
- for option_string, action in conflicting_actions:\r
-\r
- # remove the conflicting option\r
- action.option_strings.remove(option_string)\r
- self._option_string_actions.pop(option_string, None)\r
-\r
- # if the option now has no option string, remove it from the\r
- # container holding it\r
- if not action.option_strings:\r
- action.container._remove_action(action)\r
-\r
-\r
-class _ArgumentGroup(_ActionsContainer):\r
-\r
- def __init__(self, container, title=None, description=None, **kwargs):\r
- # add any missing keyword arguments by checking the container\r
- update = kwargs.setdefault\r
- update('conflict_handler', container.conflict_handler)\r
- update('prefix_chars', container.prefix_chars)\r
- update('argument_default', container.argument_default)\r
- super_init = super(_ArgumentGroup, self).__init__\r
- super_init(description=description, **kwargs)\r
-\r
- # group attributes\r
- self.title = title\r
- self._group_actions = []\r
-\r
- # share most attributes with the container\r
- self._registries = container._registries\r
- self._actions = container._actions\r
- self._option_string_actions = container._option_string_actions\r
- self._defaults = container._defaults\r
- self._has_negative_number_optionals = \\r
- container._has_negative_number_optionals\r
- self._mutually_exclusive_groups = container._mutually_exclusive_groups\r
-\r
- def _add_action(self, action):\r
- action = super(_ArgumentGroup, self)._add_action(action)\r
- self._group_actions.append(action)\r
- return action\r
-\r
- def _remove_action(self, action):\r
- super(_ArgumentGroup, self)._remove_action(action)\r
- self._group_actions.remove(action)\r
-\r
-\r
-class _MutuallyExclusiveGroup(_ArgumentGroup):\r
-\r
- def __init__(self, container, required=False):\r
- super(_MutuallyExclusiveGroup, self).__init__(container)\r
- self.required = required\r
- self._container = container\r
-\r
- def _add_action(self, action):\r
- if action.required:\r
- msg = _('mutually exclusive arguments must be optional')\r
- raise ValueError(msg)\r
- action = self._container._add_action(action)\r
- self._group_actions.append(action)\r
- return action\r
-\r
- def _remove_action(self, action):\r
- self._container._remove_action(action)\r
- self._group_actions.remove(action)\r
-\r
-\r
-class ArgumentParser(_AttributeHolder, _ActionsContainer):\r
- """Object for parsing command line strings into Python objects.\r
-\r
- Keyword Arguments:\r
- - prog -- The name of the program (default: sys.argv[0])\r
- - usage -- A usage message (default: auto-generated from arguments)\r
- - description -- A description of what the program does\r
- - epilog -- Text following the argument descriptions\r
- - parents -- Parsers whose arguments should be copied into this one\r
- - formatter_class -- HelpFormatter class for printing help messages\r
- - prefix_chars -- Characters that prefix optional arguments\r
- - fromfile_prefix_chars -- Characters that prefix files containing\r
- additional arguments\r
- - argument_default -- The default value for all arguments\r
- - conflict_handler -- String indicating how to handle conflicts\r
- - add_help -- Add a -h/-help option\r
- """\r
-\r
- def __init__(self,\r
- prog=None,\r
- usage=None,\r
- description=None,\r
- epilog=None,\r
- version=None,\r
- parents=[],\r
- formatter_class=HelpFormatter,\r
- prefix_chars='-',\r
- fromfile_prefix_chars=None,\r
- argument_default=None,\r
- conflict_handler='error',\r
- add_help=True):\r
-\r
- if version is not None:\r
- import warnings\r
- warnings.warn(\r
- """The "version" argument to ArgumentParser is deprecated. """\r
- """Please use """\r
- """"add_argument(..., action='version', version="N", ...)" """\r
- """instead""", DeprecationWarning)\r
-\r
- superinit = super(ArgumentParser, self).__init__\r
- superinit(description=description,\r
- prefix_chars=prefix_chars,\r
- argument_default=argument_default,\r
- conflict_handler=conflict_handler)\r
-\r
- # default setting for prog\r
- if prog is None:\r
- prog = _os.path.basename(_sys.argv[0])\r
-\r
- self.prog = prog\r
- self.usage = usage\r
- self.epilog = epilog\r
- self.version = version\r
- self.formatter_class = formatter_class\r
- self.fromfile_prefix_chars = fromfile_prefix_chars\r
- self.add_help = add_help\r
-\r
- add_group = self.add_argument_group\r
- self._positionals = add_group(_('positional arguments'))\r
- self._optionals = add_group(_('optional arguments'))\r
- self._subparsers = None\r
-\r
- # register types\r
- def identity(string):\r
- return string\r
- self.register('type', None, identity)\r
-\r
- # add help and version arguments if necessary\r
- # (using explicit default to override global argument_default)\r
- default_prefix = '-' if '-' in prefix_chars else prefix_chars[0]\r
- if self.add_help:\r
- self.add_argument(\r
- default_prefix+'h', default_prefix*2+'help',\r
- action='help', default=SUPPRESS,\r
- help=_('show this help message and exit'))\r
- if self.version:\r
- self.add_argument(\r
- default_prefix+'v', default_prefix*2+'version',\r
- action='version', default=SUPPRESS,\r
- version=self.version,\r
- help=_("show program's version number and exit"))\r
-\r
- # add parent arguments and defaults\r
- for parent in parents:\r
- self._add_container_actions(parent)\r
- try:\r
- defaults = parent._defaults\r
- except AttributeError:\r
- pass\r
- else:\r
- self._defaults.update(defaults)\r
-\r
- # =======================\r
- # Pretty __repr__ methods\r
- # =======================\r
- def _get_kwargs(self):\r
- names = [\r
- 'prog',\r
- 'usage',\r
- 'description',\r
- 'version',\r
- 'formatter_class',\r
- 'conflict_handler',\r
- 'add_help',\r
- ]\r
- return [(name, getattr(self, name)) for name in names]\r
-\r
- # ==================================\r
- # Optional/Positional adding methods\r
- # ==================================\r
- def add_subparsers(self, **kwargs):\r
- if self._subparsers is not None:\r
- self.error(_('cannot have multiple subparser arguments'))\r
-\r
- # add the parser class to the arguments if it's not present\r
- kwargs.setdefault('parser_class', type(self))\r
-\r
- if 'title' in kwargs or 'description' in kwargs:\r
- title = _(kwargs.pop('title', 'subcommands'))\r
- description = _(kwargs.pop('description', None))\r
- self._subparsers = self.add_argument_group(title, description)\r
- else:\r
- self._subparsers = self._positionals\r
-\r
- # prog defaults to the usage message of this parser, skipping\r
- # optional arguments and with no "usage:" prefix\r
- if kwargs.get('prog') is None:\r
- formatter = self._get_formatter()\r
- positionals = self._get_positional_actions()\r
- groups = self._mutually_exclusive_groups\r
- formatter.add_usage(self.usage, positionals, groups, '')\r
- kwargs['prog'] = formatter.format_help().strip()\r
-\r
- # create the parsers action and add it to the positionals list\r
- parsers_class = self._pop_action_class(kwargs, 'parsers')\r
- action = parsers_class(option_strings=[], **kwargs)\r
- self._subparsers._add_action(action)\r
-\r
- # return the created parsers action\r
- return action\r
-\r
- def _add_action(self, action):\r
- if action.option_strings:\r
- self._optionals._add_action(action)\r
- else:\r
- self._positionals._add_action(action)\r
- return action\r
-\r
- def _get_optional_actions(self):\r
- return [action\r
- for action in self._actions\r
- if action.option_strings]\r
-\r
- def _get_positional_actions(self):\r
- return [action\r
- for action in self._actions\r
- if not action.option_strings]\r
-\r
- # =====================================\r
- # Command line argument parsing methods\r
- # =====================================\r
- def parse_args(self, args=None, namespace=None):\r
- args, argv = self.parse_known_args(args, namespace)\r
- if argv:\r
- msg = _('unrecognized arguments: %s')\r
- self.error(msg % ' '.join(argv))\r
- return args\r
-\r
- def parse_known_args(self, args=None, namespace=None):\r
- if args is None:\r
- # args default to the system args\r
- args = _sys.argv[1:]\r
- else:\r
- # make sure that args are mutable\r
- args = list(args)\r
-\r
- # default Namespace built from parser defaults\r
- if namespace is None:\r
- namespace = Namespace()\r
-\r
- # add any action defaults that aren't present\r
- for action in self._actions:\r
- if action.dest is not SUPPRESS:\r
- if not hasattr(namespace, action.dest):\r
- if action.default is not SUPPRESS:\r
- setattr(namespace, action.dest, action.default)\r
-\r
- # add any parser defaults that aren't present\r
- for dest in self._defaults:\r
- if not hasattr(namespace, dest):\r
- setattr(namespace, dest, self._defaults[dest])\r
-\r
- # parse the arguments and exit if there are any errors\r
- try:\r
- namespace, args = self._parse_known_args(args, namespace)\r
- if hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR):\r
- args.extend(getattr(namespace, _UNRECOGNIZED_ARGS_ATTR))\r
- delattr(namespace, _UNRECOGNIZED_ARGS_ATTR)\r
- return namespace, args\r
- except ArgumentError:\r
- err = _sys.exc_info()[1]\r
- self.error(str(err))\r
-\r
- def _parse_known_args(self, arg_strings, namespace):\r
- # replace arg strings that are file references\r
- if self.fromfile_prefix_chars is not None:\r
- arg_strings = self._read_args_from_files(arg_strings)\r
-\r
- # map all mutually exclusive arguments to the other arguments\r
- # they can't occur with\r
- action_conflicts = {}\r
- for mutex_group in self._mutually_exclusive_groups:\r
- group_actions = mutex_group._group_actions\r
- for i, mutex_action in enumerate(mutex_group._group_actions):\r
- conflicts = action_conflicts.setdefault(mutex_action, [])\r
- conflicts.extend(group_actions[:i])\r
- conflicts.extend(group_actions[i + 1:])\r
-\r
- # find all option indices, and determine the arg_string_pattern\r
- # which has an 'O' if there is an option at an index,\r
- # an 'A' if there is an argument, or a '-' if there is a '--'\r
- option_string_indices = {}\r
- arg_string_pattern_parts = []\r
- arg_strings_iter = iter(arg_strings)\r
- for i, arg_string in enumerate(arg_strings_iter):\r
-\r
- # all args after -- are non-options\r
- if arg_string == '--':\r
- arg_string_pattern_parts.append('-')\r
- for arg_string in arg_strings_iter:\r
- arg_string_pattern_parts.append('A')\r
-\r
- # otherwise, add the arg to the arg strings\r
- # and note the index if it was an option\r
- else:\r
- option_tuple = self._parse_optional(arg_string)\r
- if option_tuple is None:\r
- pattern = 'A'\r
- else:\r
- option_string_indices[i] = option_tuple\r
- pattern = 'O'\r
- arg_string_pattern_parts.append(pattern)\r
-\r
- # join the pieces together to form the pattern\r
- arg_strings_pattern = ''.join(arg_string_pattern_parts)\r
-\r
- # converts arg strings to the appropriate and then takes the action\r
- seen_actions = set()\r
- seen_non_default_actions = set()\r
-\r
- def take_action(action, argument_strings, option_string=None):\r
- seen_actions.add(action)\r
- argument_values = self._get_values(action, argument_strings)\r
-\r
- # error if this argument is not allowed with other previously\r
- # seen arguments, assuming that actions that use the default\r
- # value don't really count as "present"\r
- if argument_values is not action.default:\r
- seen_non_default_actions.add(action)\r
- for conflict_action in action_conflicts.get(action, []):\r
- if conflict_action in seen_non_default_actions:\r
- msg = _('not allowed with argument %s')\r
- action_name = _get_action_name(conflict_action)\r
- raise ArgumentError(action, msg % action_name)\r
-\r
- # take the action if we didn't receive a SUPPRESS value\r
- # (e.g. from a default)\r
- if argument_values is not SUPPRESS:\r
- action(self, namespace, argument_values, option_string)\r
-\r
- # function to convert arg_strings into an optional action\r
- def consume_optional(start_index):\r
-\r
- # get the optional identified at this index\r
- option_tuple = option_string_indices[start_index]\r
- action, option_string, explicit_arg = option_tuple\r
-\r
- # identify additional optionals in the same arg string\r
- # (e.g. -xyz is the same as -x -y -z if no args are required)\r
- match_argument = self._match_argument\r
- action_tuples = []\r
- while True:\r
-\r
- # if we found no optional action, skip it\r
- if action is None:\r
- extras.append(arg_strings[start_index])\r
- return start_index + 1\r
-\r
- # if there is an explicit argument, try to match the\r
- # optional's string arguments to only this\r
- if explicit_arg is not None:\r
- arg_count = match_argument(action, 'A')\r
-\r
- # if the action is a single-dash option and takes no\r
- # arguments, try to parse more single-dash options out\r
- # of the tail of the option string\r
- chars = self.prefix_chars\r
- if arg_count == 0 and option_string[1] not in chars:\r
- action_tuples.append((action, [], option_string))\r
- char = option_string[0]\r
- option_string = char + explicit_arg[0]\r
- new_explicit_arg = explicit_arg[1:] or None\r
- optionals_map = self._option_string_actions\r
- if option_string in optionals_map:\r
- action = optionals_map[option_string]\r
- explicit_arg = new_explicit_arg\r
- else:\r
- msg = _('ignored explicit argument %r')\r
- raise ArgumentError(action, msg % explicit_arg)\r
-\r
- # if the action expect exactly one argument, we've\r
- # successfully matched the option; exit the loop\r
- elif arg_count == 1:\r
- stop = start_index + 1\r
- args = [explicit_arg]\r
- action_tuples.append((action, args, option_string))\r
- break\r
-\r
- # error if a double-dash option did not use the\r
- # explicit argument\r
- else:\r
- msg = _('ignored explicit argument %r')\r
- raise ArgumentError(action, msg % explicit_arg)\r
-\r
- # if there is no explicit argument, try to match the\r
- # optional's string arguments with the following strings\r
- # if successful, exit the loop\r
- else:\r
- start = start_index + 1\r
- selected_patterns = arg_strings_pattern[start:]\r
- arg_count = match_argument(action, selected_patterns)\r
- stop = start + arg_count\r
- args = arg_strings[start:stop]\r
- action_tuples.append((action, args, option_string))\r
- break\r
-\r
- # add the Optional to the list and return the index at which\r
- # the Optional's string args stopped\r
- assert action_tuples\r
- for action, args, option_string in action_tuples:\r
- take_action(action, args, option_string)\r
- return stop\r
-\r
- # the list of Positionals left to be parsed; this is modified\r
- # by consume_positionals()\r
- positionals = self._get_positional_actions()\r
-\r
- # function to convert arg_strings into positional actions\r
- def consume_positionals(start_index):\r
- # match as many Positionals as possible\r
- match_partial = self._match_arguments_partial\r
- selected_pattern = arg_strings_pattern[start_index:]\r
- arg_counts = match_partial(positionals, selected_pattern)\r
-\r
- # slice off the appropriate arg strings for each Positional\r
- # and add the Positional and its args to the list\r
- for action, arg_count in zip(positionals, arg_counts):\r
- args = arg_strings[start_index: start_index + arg_count]\r
- start_index += arg_count\r
- take_action(action, args)\r
-\r
- # slice off the Positionals that we just parsed and return the\r
- # index at which the Positionals' string args stopped\r
- positionals[:] = positionals[len(arg_counts):]\r
- return start_index\r
-\r
- # consume Positionals and Optionals alternately, until we have\r
- # passed the last option string\r
- extras = []\r
- start_index = 0\r
- if option_string_indices:\r
- max_option_string_index = max(option_string_indices)\r
- else:\r
- max_option_string_index = -1\r
- while start_index <= max_option_string_index:\r
-\r
- # consume any Positionals preceding the next option\r
- next_option_string_index = min([\r
- index\r
- for index in option_string_indices\r
- if index >= start_index])\r
- if start_index != next_option_string_index:\r
- positionals_end_index = consume_positionals(start_index)\r
-\r
- # only try to parse the next optional if we didn't consume\r
- # the option string during the positionals parsing\r
- if positionals_end_index > start_index:\r
- start_index = positionals_end_index\r
- continue\r
- else:\r
- start_index = positionals_end_index\r
-\r
- # if we consumed all the positionals we could and we're not\r
- # at the index of an option string, there were extra arguments\r
- if start_index not in option_string_indices:\r
- strings = arg_strings[start_index:next_option_string_index]\r
- extras.extend(strings)\r
- start_index = next_option_string_index\r
-\r
- # consume the next optional and any arguments for it\r
- start_index = consume_optional(start_index)\r
-\r
- # consume any positionals following the last Optional\r
- stop_index = consume_positionals(start_index)\r
-\r
- # if we didn't consume all the argument strings, there were extras\r
- extras.extend(arg_strings[stop_index:])\r
-\r
- # if we didn't use all the Positional objects, there were too few\r
- # arg strings supplied.\r
- if positionals:\r
- self.error(_('too few arguments'))\r
-\r
- # make sure all required actions were present, and convert defaults.\r
- for action in self._actions:\r
- if action not in seen_actions:\r
- if action.required:\r
- name = _get_action_name(action)\r
- self.error(_('argument %s is required') % name)\r
- else:\r
- # Convert action default now instead of doing it before\r
- # parsing arguments to avoid calling convert functions\r
- # twice (which may fail) if the argument was given, but\r
- # only if it was defined already in the namespace\r
- if (action.default is not None and\r
- isinstance(action.default, basestring) and\r
- hasattr(namespace, action.dest) and\r
- action.default is getattr(namespace, action.dest)):\r
- setattr(namespace, action.dest,\r
- self._get_value(action, action.default))\r
-\r
- # make sure all required groups had one option present\r
- for group in self._mutually_exclusive_groups:\r
- if group.required:\r
- for action in group._group_actions:\r
- if action in seen_non_default_actions:\r
- break\r
-\r
- # if no actions were used, report the error\r
- else:\r
- names = [_get_action_name(action)\r
- for action in group._group_actions\r
- if action.help is not SUPPRESS]\r
- msg = _('one of the arguments %s is required')\r
- self.error(msg % ' '.join(names))\r
-\r
- # return the updated namespace and the extra arguments\r
- return namespace, extras\r
-\r
- def _read_args_from_files(self, arg_strings):\r
- # expand arguments referencing files\r
- new_arg_strings = []\r
- for arg_string in arg_strings:\r
-\r
- # for regular arguments, just add them back into the list\r
- if not arg_string or arg_string[0] not in self.fromfile_prefix_chars:\r
- new_arg_strings.append(arg_string)\r
-\r
- # replace arguments referencing files with the file content\r
- else:\r
- try:\r
- args_file = open(arg_string[1:])\r
- try:\r
- arg_strings = []\r
- for arg_line in args_file.read().splitlines():\r
- for arg in self.convert_arg_line_to_args(arg_line):\r
- arg_strings.append(arg)\r
- arg_strings = self._read_args_from_files(arg_strings)\r
- new_arg_strings.extend(arg_strings)\r
- finally:\r
- args_file.close()\r
- except IOError:\r
- err = _sys.exc_info()[1]\r
- self.error(str(err))\r
-\r
- # return the modified argument list\r
- return new_arg_strings\r
-\r
- def convert_arg_line_to_args(self, arg_line):\r
- return [arg_line]\r
-\r
- def _match_argument(self, action, arg_strings_pattern):\r
- # match the pattern for this action to the arg strings\r
- nargs_pattern = self._get_nargs_pattern(action)\r
- match = _re.match(nargs_pattern, arg_strings_pattern)\r
-\r
- # raise an exception if we weren't able to find a match\r
- if match is None:\r
- nargs_errors = {\r
- None: _('expected one argument'),\r
- OPTIONAL: _('expected at most one argument'),\r
- ONE_OR_MORE: _('expected at least one argument'),\r
- }\r
- default = _('expected %s argument(s)') % action.nargs\r
- msg = nargs_errors.get(action.nargs, default)\r
- raise ArgumentError(action, msg)\r
-\r
- # return the number of arguments matched\r
- return len(match.group(1))\r
-\r
- def _match_arguments_partial(self, actions, arg_strings_pattern):\r
- # progressively shorten the actions list by slicing off the\r
- # final actions until we find a match\r
- result = []\r
- for i in range(len(actions), 0, -1):\r
- actions_slice = actions[:i]\r
- pattern = ''.join([self._get_nargs_pattern(action)\r
- for action in actions_slice])\r
- match = _re.match(pattern, arg_strings_pattern)\r
- if match is not None:\r
- result.extend([len(string) for string in match.groups()])\r
- break\r
-\r
- # return the list of arg string counts\r
- return result\r
-\r
- def _parse_optional(self, arg_string):\r
- # if it's an empty string, it was meant to be a positional\r
- if not arg_string:\r
- return None\r
-\r
- # if it doesn't start with a prefix, it was meant to be positional\r
- if not arg_string[0] in self.prefix_chars:\r
- return None\r
-\r
- # if the option string is present in the parser, return the action\r
- if arg_string in self._option_string_actions:\r
- action = self._option_string_actions[arg_string]\r
- return action, arg_string, None\r
-\r
- # if it's just a single character, it was meant to be positional\r
- if len(arg_string) == 1:\r
- return None\r
-\r
- # if the option string before the "=" is present, return the action\r
- if '=' in arg_string:\r
- option_string, explicit_arg = arg_string.split('=', 1)\r
- if option_string in self._option_string_actions:\r
- action = self._option_string_actions[option_string]\r
- return action, option_string, explicit_arg\r
-\r
- # search through all possible prefixes of the option string\r
- # and all actions in the parser for possible interpretations\r
- option_tuples = self._get_option_tuples(arg_string)\r
-\r
- # if multiple actions match, the option string was ambiguous\r
- if len(option_tuples) > 1:\r
- options = ', '.join([option_string\r
- for action, option_string, explicit_arg in option_tuples])\r
- tup = arg_string, options\r
- self.error(_('ambiguous option: %s could match %s') % tup)\r
-\r
- # if exactly one action matched, this segmentation is good,\r
- # so return the parsed action\r
- elif len(option_tuples) == 1:\r
- option_tuple, = option_tuples\r
- return option_tuple\r
-\r
- # if it was not found as an option, but it looks like a negative\r
- # number, it was meant to be positional\r
- # unless there are negative-number-like options\r
- if self._negative_number_matcher.match(arg_string):\r
- if not self._has_negative_number_optionals:\r
- return None\r
-\r
- # if it contains a space, it was meant to be a positional\r
- if ' ' in arg_string:\r
- return None\r
-\r
- # it was meant to be an optional but there is no such option\r
- # in this parser (though it might be a valid option in a subparser)\r
- return None, arg_string, None\r
-\r
- def _get_option_tuples(self, option_string):\r
- result = []\r
-\r
- # option strings starting with two prefix characters are only\r
- # split at the '='\r
- chars = self.prefix_chars\r
- if option_string[0] in chars and option_string[1] in chars:\r
- if '=' in option_string:\r
- option_prefix, explicit_arg = option_string.split('=', 1)\r
- else:\r
- option_prefix = option_string\r
- explicit_arg = None\r
- for option_string in self._option_string_actions:\r
- if option_string.startswith(option_prefix):\r
- action = self._option_string_actions[option_string]\r
- tup = action, option_string, explicit_arg\r
- result.append(tup)\r
-\r
- # single character options can be concatenated with their arguments\r
- # but multiple character options always have to have their argument\r
- # separate\r
- elif option_string[0] in chars and option_string[1] not in chars:\r
- option_prefix = option_string\r
- explicit_arg = None\r
- short_option_prefix = option_string[:2]\r
- short_explicit_arg = option_string[2:]\r
-\r
- for option_string in self._option_string_actions:\r
- if option_string == short_option_prefix:\r
- action = self._option_string_actions[option_string]\r
- tup = action, option_string, short_explicit_arg\r
- result.append(tup)\r
- elif option_string.startswith(option_prefix):\r
- action = self._option_string_actions[option_string]\r
- tup = action, option_string, explicit_arg\r
- result.append(tup)\r
-\r
- # shouldn't ever get here\r
- else:\r
- self.error(_('unexpected option string: %s') % option_string)\r
-\r
- # return the collected option tuples\r
- return result\r
-\r
- def _get_nargs_pattern(self, action):\r
- # in all examples below, we have to allow for '--' args\r
- # which are represented as '-' in the pattern\r
- nargs = action.nargs\r
-\r
- # the default (None) is assumed to be a single argument\r
- if nargs is None:\r
- nargs_pattern = '(-*A-*)'\r
-\r
- # allow zero or one arguments\r
- elif nargs == OPTIONAL:\r
- nargs_pattern = '(-*A?-*)'\r
-\r
- # allow zero or more arguments\r
- elif nargs == ZERO_OR_MORE:\r
- nargs_pattern = '(-*[A-]*)'\r
-\r
- # allow one or more arguments\r
- elif nargs == ONE_OR_MORE:\r
- nargs_pattern = '(-*A[A-]*)'\r
-\r
- # allow any number of options or arguments\r
- elif nargs == REMAINDER:\r
- nargs_pattern = '([-AO]*)'\r
-\r
- # allow one argument followed by any number of options or arguments\r
- elif nargs == PARSER:\r
- nargs_pattern = '(-*A[-AO]*)'\r
-\r
- # all others should be integers\r
- else:\r
- nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)\r
-\r
- # if this is an optional action, -- is not allowed\r
- if action.option_strings:\r
- nargs_pattern = nargs_pattern.replace('-*', '')\r
- nargs_pattern = nargs_pattern.replace('-', '')\r
-\r
- # return the pattern\r
- return nargs_pattern\r
-\r
- # ========================\r
- # Value conversion methods\r
- # ========================\r
- def _get_values(self, action, arg_strings):\r
- # for everything but PARSER, REMAINDER args, strip out first '--'\r
- if action.nargs not in [PARSER, REMAINDER]:\r
- try:\r
- arg_strings.remove('--')\r
- except ValueError:\r
- pass\r
-\r
- # optional argument produces a default when not present\r
- if not arg_strings and action.nargs == OPTIONAL:\r
- if action.option_strings:\r
- value = action.const\r
- else:\r
- value = action.default\r
- if isinstance(value, basestring):\r
- value = self._get_value(action, value)\r
- self._check_value(action, value)\r
-\r
- # when nargs='*' on a positional, if there were no command-line\r
- # args, use the default if it is anything other than None\r
- elif (not arg_strings and action.nargs == ZERO_OR_MORE and\r
- not action.option_strings):\r
- if action.default is not None:\r
- value = action.default\r
- else:\r
- value = arg_strings\r
- self._check_value(action, value)\r
-\r
- # single argument or optional argument produces a single value\r
- elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]:\r
- arg_string, = arg_strings\r
- value = self._get_value(action, arg_string)\r
- self._check_value(action, value)\r
-\r
- # REMAINDER arguments convert all values, checking none\r
- elif action.nargs == REMAINDER:\r
- value = [self._get_value(action, v) for v in arg_strings]\r
-\r
- # PARSER arguments convert all values, but check only the first\r
- elif action.nargs == PARSER:\r
- value = [self._get_value(action, v) for v in arg_strings]\r
- self._check_value(action, value[0])\r
-\r
- # all other types of nargs produce a list\r
- else:\r
- value = [self._get_value(action, v) for v in arg_strings]\r
- for v in value:\r
- self._check_value(action, v)\r
-\r
- # return the converted value\r
- return value\r
-\r
- def _get_value(self, action, arg_string):\r
- type_func = self._registry_get('type', action.type, action.type)\r
- if not _callable(type_func):\r
- msg = _('%r is not callable')\r
- raise ArgumentError(action, msg % type_func)\r
-\r
- # convert the value to the appropriate type\r
- try:\r
- result = type_func(arg_string)\r
-\r
- # ArgumentTypeErrors indicate errors\r
- except ArgumentTypeError:\r
- name = getattr(action.type, '__name__', repr(action.type))\r
- msg = str(_sys.exc_info()[1])\r
- raise ArgumentError(action, msg)\r
-\r
- # TypeErrors or ValueErrors also indicate errors\r
- except (TypeError, ValueError):\r
- name = getattr(action.type, '__name__', repr(action.type))\r
- msg = _('invalid %s value: %r')\r
- raise ArgumentError(action, msg % (name, arg_string))\r
-\r
- # return the converted value\r
- return result\r
-\r
- def _check_value(self, action, value):\r
- # converted value must be one of the choices (if specified)\r
- if action.choices is not None and value not in action.choices:\r
- tup = value, ', '.join(map(repr, action.choices))\r
- msg = _('invalid choice: %r (choose from %s)') % tup\r
- raise ArgumentError(action, msg)\r
-\r
- # =======================\r
- # Help-formatting methods\r
- # =======================\r
- def format_usage(self):\r
- formatter = self._get_formatter()\r
- formatter.add_usage(self.usage, self._actions,\r
- self._mutually_exclusive_groups)\r
- return formatter.format_help()\r
-\r
- def format_help(self):\r
- formatter = self._get_formatter()\r
-\r
- # usage\r
- formatter.add_usage(self.usage, self._actions,\r
- self._mutually_exclusive_groups)\r
-\r
- # description\r
- formatter.add_text(self.description)\r
-\r
- # positionals, optionals and user-defined groups\r
- for action_group in self._action_groups:\r
- formatter.start_section(action_group.title)\r
- formatter.add_text(action_group.description)\r
- formatter.add_arguments(action_group._group_actions)\r
- formatter.end_section()\r
-\r
- # epilog\r
- formatter.add_text(self.epilog)\r
-\r
- # determine help from format above\r
- return formatter.format_help()\r
-\r
- def format_version(self):\r
- import warnings\r
- warnings.warn(\r
- 'The format_version method is deprecated -- the "version" '\r
- 'argument to ArgumentParser is no longer supported.',\r
- DeprecationWarning)\r
- formatter = self._get_formatter()\r
- formatter.add_text(self.version)\r
- return formatter.format_help()\r
-\r
- def _get_formatter(self):\r
- return self.formatter_class(prog=self.prog)\r
-\r
- # =====================\r
- # Help-printing methods\r
- # =====================\r
- def print_usage(self, file=None):\r
- if file is None:\r
- file = _sys.stdout\r
- self._print_message(self.format_usage(), file)\r
-\r
- def print_help(self, file=None):\r
- if file is None:\r
- file = _sys.stdout\r
- self._print_message(self.format_help(), file)\r
-\r
- def print_version(self, file=None):\r
- import warnings\r
- warnings.warn(\r
- 'The print_version method is deprecated -- the "version" '\r
- 'argument to ArgumentParser is no longer supported.',\r
- DeprecationWarning)\r
- self._print_message(self.format_version(), file)\r
-\r
- def _print_message(self, message, file=None):\r
- if message:\r
- if file is None:\r
- file = _sys.stderr\r
- file.write(message)\r
-\r
- # ===============\r
- # Exiting methods\r
- # ===============\r
- def exit(self, status=0, message=None):\r
- if message:\r
- self._print_message(message, _sys.stderr)\r
- _sys.exit(status)\r
-\r
- def error(self, message):\r
- """error(message: string)\r
-\r
- Prints a usage message incorporating the message to stderr and\r
- exits.\r
-\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.prog, message))\r