9090
9191from gettext import gettext as _
9292
93+ # XXX.bewest: remove
94+ from pprint import pprint
95+
9396try :
9497 set
9598except NameError :
@@ -123,6 +126,7 @@ def _callable(obj):
123126ZERO_OR_MORE = '*'
124127ONE_OR_MORE = '+'
125128PARSER = 'A...'
129+ _OPTIONAL_PARSER = 'A?..'
126130REMAINDER = '...'
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