Skip to content

Commit 8c1dd52

Browse files
committed
close, but not quite right
1 parent 46af816 commit 8c1dd52

1 file changed

Lines changed: 40 additions & 6 deletions

File tree

argparse.py

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@
9090

9191
from gettext import gettext as _
9292

93+
# XXX.bewest: remove
94+
from pprint import pprint
95+
9396
try:
9497
set
9598
except NameError:
@@ -123,6 +126,7 @@ def _callable(obj):
123126
ZERO_OR_MORE = '*'
124127
ONE_OR_MORE = '+'
125128
PARSER = 'A...'
129+
_OPTIONAL_PARSER = 'A?..'
126130
REMAINDER = '...'
127131
_UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args'
128132

@@ -601,7 +605,7 @@ def _format_args(self, action, default_metavar):
601605
result = '%s [%s ...]' % get_metavar(2)
602606
elif action.nargs == REMAINDER:
603607
result = '...'
604-
elif action.nargs == PARSER:
608+
elif action.nargs in [ PARSER, _OPTIONAL_PARSER ]:
605609
result = '%s ...' % get_metavar(1)
606610
else:
607611
formats = ['%s' for _ in range(action.nargs)]
@@ -1055,17 +1059,23 @@ def __init__(self,
10551059
parser_class,
10561060
dest=SUPPRESS,
10571061
help=None,
1062+
default=None,
10581063
metavar=None):
10591064

10601065
self._prog_prefix = prog
10611066
self._parser_class = parser_class
10621067
self._name_parser_map = {}
10631068
self._choices_actions = []
10641069

1070+
nargs = PARSER
1071+
if default is not None:
1072+
nargs = _OPTIONAL_PARSER
1073+
10651074
super(_SubParsersAction, self).__init__(
10661075
option_strings=option_strings,
10671076
dest=dest,
1068-
nargs=PARSER,
1077+
nargs=nargs,
1078+
default=default,
10691079
choices=self._name_parser_map,
10701080
help=help,
10711081
metavar=metavar)
@@ -1097,6 +1107,7 @@ def __call__(self, parser, namespace, values, option_string=None):
10971107
if self.dest is not SUPPRESS:
10981108
setattr(namespace, self.dest, parser_name)
10991109

1110+
pprint(['select parser', vars( )])
11001111
# select the parser
11011112
try:
11021113
parser = self._name_parser_map[parser_name]
@@ -1674,6 +1685,7 @@ def add_subparsers(self, **kwargs):
16741685
# create the parsers action and add it to the positionals list
16751686
parsers_class = self._pop_action_class(kwargs, 'parsers')
16761687
action = parsers_class(option_strings=[], **kwargs)
1688+
pprint(['add subparsers', parsers_class, kwargs ])
16771689
self._subparsers._add_action(action)
16781690

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

1807+
pprint(['take action', action, argument_strings])
1808+
17951809
# error if this argument is not allowed with other previously
17961810
# seen arguments, assuming that actions that use the default
17971811
# value don't really count as "present"
@@ -1808,6 +1822,7 @@ def take_action(action, argument_strings, option_string=None):
18081822
if argument_values is not SUPPRESS:
18091823
action(self, namespace, argument_values, option_string)
18101824

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

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

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

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

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

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

19401959
# consume the next optional and any arguments for it
1960+
pprint('calling consume optionals')
19411961
start_index = consume_optional(start_index)
19421962

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

2036+
pprint(['match argument', nargs_pattern, match])
20162037
# raise an exception if we weren't able to find a match
20172038
if match is None:
20182039
nargs_errors = {
@@ -2036,6 +2057,7 @@ def _match_arguments_partial(self, actions, arg_strings_pattern):
20362057
pattern = ''.join([self._get_nargs_pattern(action)
20372058
for action in actions_slice])
20382059
match = _re.match(pattern, arg_strings_pattern)
2060+
pprint(['match arguments partial', pattern, match])
20392061
if match is not None:
20402062
result.extend([len(string) for string in match.groups()])
20412063
break
@@ -2173,6 +2195,13 @@ def _get_nargs_pattern(self, action):
21732195
elif nargs == PARSER:
21742196
nargs_pattern = '(-*A[-AO]*)'
21752197

2198+
# allow one optional argument followed by any number of options or
2199+
# arguments
2200+
elif nargs == _OPTIONAL_PARSER:
2201+
# XXX.bewest: This doesn't quite work.
2202+
nargs_pattern = '(-*A?-[-AO]*)?'
2203+
nargs_pattern = '([-AO]*)'
2204+
21762205
# all others should be integers
21772206
else:
21782207
nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)
@@ -2182,6 +2211,7 @@ def _get_nargs_pattern(self, action):
21822211
nargs_pattern = nargs_pattern.replace('-*', '')
21832212
nargs_pattern = nargs_pattern.replace('-', '')
21842213

2214+
print nargs_pattern, nargs
21852215
# return the pattern
21862216
return nargs_pattern
21872217

@@ -2190,19 +2220,23 @@ def _get_nargs_pattern(self, action):
21902220
# ========================
21912221
def _get_values(self, action, arg_strings):
21922222
# for everything but PARSER args, strip out '--'
2193-
if action.nargs not in [PARSER, REMAINDER]:
2223+
#if action.nargs not in [PARSER, REMAINDER]:
2224+
if action.nargs not in [_OPTIONAL_PARSER, PARSER, REMAINDER]:
21942225
arg_strings = [s for s in arg_strings if s != '--']
21952226

21962227
# optional argument produces a default when not present
2197-
if not arg_strings and action.nargs == OPTIONAL:
2228+
opt_types = [ OPTIONAL, _OPTIONAL_PARSER ]
2229+
pprint(['get values', action, arg_strings])
2230+
#if not arg_strings and action.nargs == OPTIONAL:
2231+
if not arg_strings and action.nargs in opt_types:
21982232
if action.option_strings:
21992233
value = action.const
22002234
else:
22012235
value = action.default
22022236
if isinstance(value, basestring):
22032237
value = self._get_value(action, value)
22042238
self._check_value(action, value)
2205-
2239+
pprint(['VALUE', value])
22062240
# when nargs='*' on a positional, if there were no command-line
22072241
# args, use the default if it is anything other than None
22082242
elif (not arg_strings and action.nargs == ZERO_OR_MORE and
@@ -2224,7 +2258,7 @@ def _get_values(self, action, arg_strings):
22242258
value = [self._get_value(action, v) for v in arg_strings]
22252259

22262260
# PARSER arguments convert all values, but check only the first
2227-
elif action.nargs == PARSER:
2261+
elif action.nargs in [ PARSER, _OPTIONAL_PARSER ]:
22282262
value = [self._get_value(action, v) for v in arg_strings]
22292263
self._check_value(action, value[0])
22302264

0 commit comments

Comments
 (0)