diff -r 694110bc91d8 -r ed0fce615582 Lib/argparse.py --- a/Lib/argparse.py Sat Jan 07 18:34:24 2012 +0100 +++ b/Lib/argparse.py Sat Jan 07 12:36:35 2012 -0800 @@ -99,6 +99,7 @@ ZERO_OR_MORE = '*' ONE_OR_MORE = '+' PARSER = 'A...' +_OPTIONAL_PARSER = 'A...?' REMAINDER = '...' _UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args' @@ -579,7 +580,7 @@ result = '%s [%s ...]' % get_metavar(2) elif action.nargs == REMAINDER: result = '...' - elif action.nargs == PARSER: + elif action.nargs in [ PARSER, _OPTIONAL_PARSER ]: result = '%s ...' % get_metavar(1) else: formats = ['%s' for _ in range(action.nargs)] @@ -1059,6 +1060,7 @@ parser_class, dest=SUPPRESS, help=None, + default=None, metavar=None): self._prog_prefix = prog @@ -1066,10 +1068,15 @@ self._name_parser_map = _collections.OrderedDict() self._choices_actions = [] + nargs = PARSER + if default is not None: + nargs = _OPTIONAL_PARSER + super(_SubParsersAction, self).__init__( option_strings=option_strings, dest=dest, - nargs=PARSER, + nargs=nargs, + default=default, choices=self._name_parser_map, help=help, metavar=metavar) @@ -2190,6 +2197,11 @@ elif nargs == PARSER: nargs_pattern = '(-*A[-AO]*)' + # allow one optional argument followed by any number of options or + # arguments + elif nargs == _OPTIONAL_PARSER: + nargs_pattern = '(-*A?[-AO]*)?' + # all others should be integers else: nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs) @@ -2207,7 +2219,8 @@ # ======================== def _get_values(self, action, arg_strings): # for everything but PARSER args, strip out '--' - if action.nargs not in [PARSER, REMAINDER]: + #if action.nargs not in [PARSER, REMAINDER]: + if action.nargs not in [_OPTIONAL_PARSER, PARSER, REMAINDER]: arg_strings = [s for s in arg_strings if s != '--'] # optional argument produces a default when not present @@ -2219,7 +2232,6 @@ if isinstance(value, str): value = self._get_value(action, value) self._check_value(action, value) - # when nargs='*' on a positional, if there were no command-line # args, use the default if it is anything other than None elif (not arg_strings and action.nargs == ZERO_OR_MORE and @@ -2241,8 +2253,11 @@ value = [self._get_value(action, v) for v in arg_strings] # PARSER arguments convert all values, but check only the first - elif action.nargs == PARSER: + elif action.nargs in [ PARSER, _OPTIONAL_PARSER ]: value = [self._get_value(action, v) for v in arg_strings] + if (not arg_strings and action.default is not None + and action.nargs == _OPTIONAL_PARSER): + value = [action.default] self._check_value(action, value[0]) # all other types of nargs produce a list