diff options
Diffstat (limited to 'Lib/argparse.py')
-rw-r--r-- | Lib/argparse.py | 169 |
1 files changed, 87 insertions, 82 deletions
diff --git a/Lib/argparse.py b/Lib/argparse.py index 30bae57896..f25b1b6610 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -71,6 +71,7 @@ __all__ = [ 'ArgumentDefaultsHelpFormatter', 'RawDescriptionHelpFormatter', 'RawTextHelpFormatter', + 'MetavarTypeHelpFormatter', 'Namespace', 'Action', 'ONE_OR_MORE', @@ -89,11 +90,7 @@ import re as _re import sys as _sys import textwrap as _textwrap -from gettext import gettext as _ - - -def _callable(obj): - return hasattr(obj, '__call__') or hasattr(obj, '__bases__') +from gettext import gettext as _, ngettext SUPPRESS = '==SUPPRESS==' @@ -423,7 +420,8 @@ class HelpFormatter(object): # produce all arg strings elif not action.option_strings: - part = self._format_args(action, action.dest) + default = self._get_default_metavar_for_positional(action) + part = self._format_args(action, default) # if it's in a group, strip the outer [] if action in group_actions: @@ -445,7 +443,7 @@ class HelpFormatter(object): # if the Optional takes a value, format is: # -s ARGS or --long ARGS else: - default = action.dest.upper() + default = self._get_default_metavar_for_optional(action) args_string = self._format_args(action, default) part = '%s %s' % (option_string, args_string) @@ -531,7 +529,8 @@ class HelpFormatter(object): def _format_action_invocation(self, action): if not action.option_strings: - metavar, = self._metavar_formatter(action, action.dest)(1) + default = self._get_default_metavar_for_positional(action) + metavar, = self._metavar_formatter(action, default)(1) return metavar else: @@ -545,7 +544,7 @@ class HelpFormatter(object): # if the Optional takes a value, format is: # -s ARGS, --long ARGS else: - default = action.dest.upper() + default = self._get_default_metavar_for_optional(action) args_string = self._format_args(action, default) for option_string in action.option_strings: parts.append('%s %s' % (option_string, args_string)) @@ -623,6 +622,12 @@ class HelpFormatter(object): def _get_help_string(self, action): return action.help + def _get_default_metavar_for_optional(self, action): + return action.dest.upper() + + def _get_default_metavar_for_positional(self, action): + return action.dest + class RawDescriptionHelpFormatter(HelpFormatter): """Help message formatter which retains any formatting in descriptions. @@ -632,7 +637,7 @@ class RawDescriptionHelpFormatter(HelpFormatter): """ def _fill_text(self, text, width, indent): - return ''.join([indent + line for line in text.splitlines(True)]) + return ''.join(indent + line for line in text.splitlines(keepends=True)) class RawTextHelpFormatter(RawDescriptionHelpFormatter): @@ -663,6 +668,22 @@ class ArgumentDefaultsHelpFormatter(HelpFormatter): return help +class MetavarTypeHelpFormatter(HelpFormatter): + """Help message formatter which uses the argument 'type' as the default + metavar value (instead of the argument 'dest') + + Only the name of this class is considered a public API. All the methods + provided by the class are considered an implementation detail. + """ + + def _get_default_metavar_for_optional(self, action): + return action.type.__name__ + + def _get_default_metavar_for_positional(self, action): + return action.type.__name__ + + + # ===================== # Options and Arguments # ===================== @@ -1024,9 +1045,13 @@ class _SubParsersAction(Action): class _ChoicesPseudoAction(Action): - def __init__(self, name, help): + def __init__(self, name, aliases, help): + metavar = dest = name + if aliases: + metavar += ' (%s)' % ', '.join(aliases) sup = super(_SubParsersAction._ChoicesPseudoAction, self) - sup.__init__(option_strings=[], dest=name, help=help) + sup.__init__(option_strings=[], dest=dest, help=help, + metavar=metavar) def __init__(self, option_strings, @@ -1054,15 +1079,22 @@ class _SubParsersAction(Action): if kwargs.get('prog') is None: kwargs['prog'] = '%s %s' % (self._prog_prefix, name) + aliases = kwargs.pop('aliases', ()) + # create a pseudo-action to hold the choice help if 'help' in kwargs: help = kwargs.pop('help') - choice_action = self._ChoicesPseudoAction(name, help) + choice_action = self._ChoicesPseudoAction(name, aliases, help) self._choices_actions.append(choice_action) # create the parser and add it to the map parser = self._parser_class(**kwargs) self._name_parser_map[name] = parser + + # make parser available under aliases also + for alias in aliases: + self._name_parser_map[alias] = parser + return parser def _get_subactions(self): @@ -1080,8 +1112,9 @@ class _SubParsersAction(Action): try: parser = self._name_parser_map[parser_name] except KeyError: - tup = parser_name, ', '.join(self._name_parser_map) - msg = _('unknown parser %r (choices: %s)') % tup + args = {'parser_name': parser_name, + 'choices': ', '.join(self._name_parser_map)} + msg = _('unknown parser %(parser_name)r (choices: %(choices)s)') % args raise ArgumentError(self, msg) # parse all the remaining options into the namespace @@ -1152,8 +1185,6 @@ class Namespace(_AttributeHolder): for name in kwargs: setattr(self, name, kwargs[name]) - __hash__ = None - def __eq__(self, other): return vars(self) == vars(other) @@ -1276,13 +1307,13 @@ class _ActionsContainer(object): # create the action object, and add it to the parser action_class = self._pop_action_class(kwargs) - if not _callable(action_class): + if not callable(action_class): raise ValueError('unknown action "%s"' % (action_class,)) action = action_class(**kwargs) # raise an error if the action type is not callable type_func = self._registry_get('type', action.type, action.type) - if not _callable(type_func): + if not callable(type_func): raise ValueError('%r is not callable' % (type_func,)) # raise an error if the metavar does not match the type @@ -1391,10 +1422,11 @@ class _ActionsContainer(object): for option_string in args: # error on strings that don't start with an appropriate prefix if not option_string[0] in self.prefix_chars: - msg = _('invalid option string %r: ' - 'must start with a character %r') - tup = option_string, self.prefix_chars - raise ValueError(msg % tup) + args = {'option': option_string, + 'prefix_chars': self.prefix_chars} + msg = _('invalid option string %(option)r: ' + 'must start with a character %(prefix_chars)r') + raise ValueError(msg % args) # strings starting with two prefix characters are long options option_strings.append(option_string) @@ -1447,7 +1479,9 @@ class _ActionsContainer(object): conflict_handler(action, confl_optionals) def _handle_conflict_error(self, action, conflicting_actions): - message = _('conflicting option string(s): %s') + message = ngettext('conflicting option string: %s', + 'conflicting option strings: %s', + len(conflicting_actions)) conflict_string = ', '.join([option_string for option_string, action in conflicting_actions]) @@ -1545,7 +1579,6 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): usage=None, description=None, epilog=None, - version=None, parents=[], formatter_class=HelpFormatter, prefix_chars='-', @@ -1554,14 +1587,6 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): conflict_handler='error', add_help=True): - if version is not None: - import warnings - warnings.warn( - """The "version" argument to ArgumentParser is deprecated. """ - """Please use """ - """"add_argument(..., action='version', version="N", ...)" """ - """instead""", DeprecationWarning) - superinit = super(ArgumentParser, self).__init__ superinit(description=description, prefix_chars=prefix_chars, @@ -1575,7 +1600,6 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): self.prog = prog self.usage = usage self.epilog = epilog - self.version = version self.formatter_class = formatter_class self.fromfile_prefix_chars = fromfile_prefix_chars self.add_help = add_help @@ -1590,7 +1614,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): return string self.register('type', None, identity) - # add help and version arguments if necessary + # add help argument if necessary # (using explicit default to override global argument_default) default_prefix = '-' if '-' in prefix_chars else prefix_chars[0] if self.add_help: @@ -1598,12 +1622,6 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): default_prefix+'h', default_prefix*2+'help', action='help', default=SUPPRESS, help=_('show this help message and exit')) - if self.version: - self.add_argument( - default_prefix+'v', default_prefix*2+'version', - action='version', default=SUPPRESS, - version=self.version, - help=_("show program's version number and exit")) # add parent arguments and defaults for parent in parents: @@ -1623,7 +1641,6 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): 'prog', 'usage', 'description', - 'version', 'formatter_class', 'conflict_handler', 'add_help', @@ -1931,29 +1948,29 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): # if we didn't consume all the argument strings, there were extras extras.extend(arg_strings[stop_index:]) - # if we didn't use all the Positional objects, there were too few - # arg strings supplied. - if positionals: - self.error(_('too few arguments')) - - # make sure all required actions were present, and convert defaults. + # make sure all required actions were present and also convert + # action defaults which were not given as arguments + required_actions = [] for action in self._actions: if action not in seen_actions: if action.required: - name = _get_action_name(action) - self.error(_('argument %s is required') % name) + required_actions.append(_get_action_name(action)) else: # Convert action default now instead of doing it before # parsing arguments to avoid calling convert functions # twice (which may fail) if the argument was given, but # only if it was defined already in the namespace if (action.default is not None and - isinstance(action.default, basestring) and - hasattr(namespace, action.dest) and - action.default is getattr(namespace, action.dest)): + isinstance(action.default, str) and + hasattr(namespace, action.dest) and + action.default is getattr(namespace, action.dest)): setattr(namespace, action.dest, self._get_value(action, action.default)) + if required_actions: + self.error(_('the following arguments are required: %s') % + ', '.join(required_actions)) + # make sure all required groups had one option present for group in self._mutually_exclusive_groups: if group.required: @@ -2016,7 +2033,9 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): OPTIONAL: _('expected at most one argument'), ONE_OR_MORE: _('expected at least one argument'), } - default = _('expected %s argument(s)') % action.nargs + default = ngettext('expected %s argument', + 'expected %s arguments', + action.nargs) % action.nargs msg = nargs_errors.get(action.nargs, default) raise ArgumentError(action, msg) @@ -2072,8 +2091,9 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): if len(option_tuples) > 1: options = ', '.join([option_string for action, option_string, explicit_arg in option_tuples]) - tup = arg_string, options - self.error(_('ambiguous option: %s could match %s') % tup) + args = {'option': arg_string, 'matches': options} + msg = _('ambiguous option: %(option)s could match %(matches)s') + self.error(msg % args) # if exactly one action matched, this segmentation is good, # so return the parsed action @@ -2198,7 +2218,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): value = action.const else: value = action.default - if isinstance(value, basestring): + if isinstance(value, str): value = self._get_value(action, value) self._check_value(action, value) @@ -2238,7 +2258,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): def _get_value(self, action, arg_string): type_func = self._registry_get('type', action.type, action.type) - if not _callable(type_func): + if not callable(type_func): msg = _('%r is not callable') raise ArgumentError(action, msg % type_func) @@ -2255,8 +2275,9 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): # TypeErrors or ValueErrors also indicate errors except (TypeError, ValueError): name = getattr(action.type, '__name__', repr(action.type)) - msg = _('invalid %s value: %r') - raise ArgumentError(action, msg % (name, arg_string)) + args = {'type': name, 'value': arg_string} + msg = _('invalid %(type)s value: %(value)r') + raise ArgumentError(action, msg % args) # return the converted value return result @@ -2264,9 +2285,10 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): def _check_value(self, action, value): # converted value must be one of the choices (if specified) if action.choices is not None and value not in action.choices: - tup = value, ', '.join(map(repr, action.choices)) - msg = _('invalid choice: %r (choose from %s)') % tup - raise ArgumentError(action, msg) + args = {'value': value, + 'choices': ', '.join(map(repr, action.choices))} + msg = _('invalid choice: %(value)r (choose from %(choices)s)') + raise ArgumentError(action, msg % args) # ======================= # Help-formatting methods @@ -2300,16 +2322,6 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): # determine help from format above return formatter.format_help() - def format_version(self): - import warnings - warnings.warn( - 'The format_version method is deprecated -- the "version" ' - 'argument to ArgumentParser is no longer supported.', - DeprecationWarning) - formatter = self._get_formatter() - formatter.add_text(self.version) - return formatter.format_help() - def _get_formatter(self): return self.formatter_class(prog=self.prog) @@ -2326,14 +2338,6 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): file = _sys.stdout self._print_message(self.format_help(), file) - def print_version(self, file=None): - import warnings - warnings.warn( - 'The print_version method is deprecated -- the "version" ' - 'argument to ArgumentParser is no longer supported.', - DeprecationWarning) - self._print_message(self.format_version(), file) - def _print_message(self, message, file=None): if message: if file is None: @@ -2358,4 +2362,5 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): should either exit or raise an exception. """ self.print_usage(_sys.stderr) - self.exit(2, _('%s: error: %s\n') % (self.prog, message)) + args = {'prog': self.prog, 'message': message} + self.exit(2, _('%(prog)s: error: %(message)s\n') % args) |