Skip to content

Commit

Permalink
close, but not quite right
Browse files Browse the repository at this point in the history
  • Loading branch information
bewest committed Sep 24, 2011
1 parent 46af816 commit 8c1dd52
Showing 1 changed file with 40 additions and 6 deletions.
46 changes: 40 additions & 6 deletions argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@

from gettext import gettext as _

# XXX.bewest: remove
from pprint import pprint

try:
set
except NameError:
Expand Down Expand Up @@ -123,6 +126,7 @@ def _callable(obj):
ZERO_OR_MORE = '*'
ONE_OR_MORE = '+'
PARSER = 'A...'
_OPTIONAL_PARSER = 'A?..'
REMAINDER = '...'
_UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args'

Expand Down Expand Up @@ -601,7 +605,7 @@ def _format_args(self, action, default_metavar):
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)]
Expand Down Expand Up @@ -1055,17 +1059,23 @@ def __init__(self,
parser_class,
dest=SUPPRESS,
help=None,
default=None,
metavar=None):

self._prog_prefix = prog
self._parser_class = parser_class
self._name_parser_map = {}
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)
Expand Down Expand Up @@ -1097,6 +1107,7 @@ def __call__(self, parser, namespace, values, option_string=None):
if self.dest is not SUPPRESS:
setattr(namespace, self.dest, parser_name)

pprint(['select parser', vars( )])
# select the parser
try:
parser = self._name_parser_map[parser_name]
Expand Down Expand Up @@ -1674,6 +1685,7 @@ def add_subparsers(self, **kwargs):
# create the parsers action and add it to the positionals list
parsers_class = self._pop_action_class(kwargs, 'parsers')
action = parsers_class(option_strings=[], **kwargs)
pprint(['add subparsers', parsers_class, kwargs ])
self._subparsers._add_action(action)

# return the created parsers action
Expand Down Expand Up @@ -1792,6 +1804,8 @@ def take_action(action, argument_strings, option_string=None):
seen_actions.add(action)
argument_values = self._get_values(action, argument_strings)

pprint(['take action', action, argument_strings])

# error if this argument is not allowed with other previously
# seen arguments, assuming that actions that use the default
# value don't really count as "present"
Expand All @@ -1808,6 +1822,7 @@ def take_action(action, argument_strings, option_string=None):
if argument_values is not SUPPRESS:
action(self, namespace, argument_values, option_string)

pprint(['consume optionals'])
# function to convert arg_strings into an optional action
def consume_optional(start_index):

Expand All @@ -1818,6 +1833,7 @@ def consume_optional(start_index):
# identify additional optionals in the same arg string
# (e.g. -xyz is the same as -x -y -z if no args are required)
match_argument = self._match_argument
pprint(['consume optional', vars( )])
action_tuples = []
while True:

Expand Down Expand Up @@ -1884,6 +1900,7 @@ def consume_optional(start_index):
# the list of Positionals left to be parsed; this is modified
# by consume_positionals()
positionals = self._get_positional_actions()
pprint(['remaining positionals', positionals])

# function to convert arg_strings into positional actions
def consume_positionals(start_index):
Expand All @@ -1892,11 +1909,13 @@ def consume_positionals(start_index):
selected_pattern = arg_strings_pattern[start_index:]
arg_counts = match_partial(positionals, selected_pattern)

pprint(['consume positionals', vars( )])
# slice off the appropriate arg strings for each Positional
# and add the Positional and its args to the list
for action, arg_count in zip(positionals, arg_counts):
args = arg_strings[start_index: start_index + arg_count]
start_index += arg_count
pprint(['loop', action, arg_count ])
take_action(action, args)

# slice off the Positionals that we just parsed and return the
Expand Down Expand Up @@ -1938,6 +1957,7 @@ def consume_positionals(start_index):
start_index = next_option_string_index

# consume the next optional and any arguments for it
pprint('calling consume optionals')
start_index = consume_optional(start_index)

# consume any positionals following the last Optional
Expand Down Expand Up @@ -2013,6 +2033,7 @@ def _match_argument(self, action, arg_strings_pattern):
nargs_pattern = self._get_nargs_pattern(action)
match = _re.match(nargs_pattern, arg_strings_pattern)

pprint(['match argument', nargs_pattern, match])
# raise an exception if we weren't able to find a match
if match is None:
nargs_errors = {
Expand All @@ -2036,6 +2057,7 @@ def _match_arguments_partial(self, actions, arg_strings_pattern):
pattern = ''.join([self._get_nargs_pattern(action)
for action in actions_slice])
match = _re.match(pattern, arg_strings_pattern)
pprint(['match arguments partial', pattern, match])
if match is not None:
result.extend([len(string) for string in match.groups()])
break
Expand Down Expand Up @@ -2173,6 +2195,13 @@ def _get_nargs_pattern(self, action):
elif nargs == PARSER:
nargs_pattern = '(-*A[-AO]*)'

# allow one optional argument followed by any number of options or
# arguments
elif nargs == _OPTIONAL_PARSER:
# XXX.bewest: This doesn't quite work.

This comment has been minimized.

Copy link
@bewest

bewest Sep 24, 2011

Author Owner

This regexp doesn't work, and I'm having trouble getting the right one.

This is towards http://bugs.python.org/issue9253

nargs_pattern = '(-*A?-[-AO]*)?'
nargs_pattern = '([-AO]*)'

# all others should be integers
else:
nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)
Expand All @@ -2182,6 +2211,7 @@ def _get_nargs_pattern(self, action):
nargs_pattern = nargs_pattern.replace('-*', '')
nargs_pattern = nargs_pattern.replace('-', '')

print nargs_pattern, nargs
# return the pattern
return nargs_pattern

Expand All @@ -2190,19 +2220,23 @@ def _get_nargs_pattern(self, action):
# ========================
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
if not arg_strings and action.nargs == OPTIONAL:
opt_types = [ OPTIONAL, _OPTIONAL_PARSER ]
pprint(['get values', action, arg_strings])
#if not arg_strings and action.nargs == OPTIONAL:
if not arg_strings and action.nargs in opt_types:
if action.option_strings:
value = action.const
else:
value = action.default
if isinstance(value, basestring):
value = self._get_value(action, value)
self._check_value(action, value)

pprint(['VALUE', 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
Expand All @@ -2224,7 +2258,7 @@ def _get_values(self, action, arg_strings):
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]
self._check_value(action, value[0])

Expand Down

0 comments on commit 8c1dd52

Please sign in to comment.