summaryrefslogtreecommitdiffstats
path: root/Lib/argparse.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/argparse.py')
-rw-r--r--Lib/argparse.py77
1 files changed, 46 insertions, 31 deletions
diff --git a/Lib/argparse.py b/Lib/argparse.py
index 30bae57..eb894ca 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -89,11 +89,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=='
@@ -1024,9 +1020,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 +1054,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 +1087,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 +1160,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 +1282,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 +1397,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 +1454,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])
@@ -1948,7 +1957,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
# 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
+ isinstance(action.default, str) and
hasattr(namespace, action.dest) and
action.default is getattr(namespace, action.dest)):
setattr(namespace, action.dest,
@@ -2016,7 +2025,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 +2083,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 +2210,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 +2250,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 +2267,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 +2277,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
@@ -2358,4 +2372,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)