@@ -1224,7 +1224,8 @@ def __call__(self, parser, namespace, values, option_string=None):
1224
1224
setattr (namespace , key , value )
1225
1225
1226
1226
if arg_strings :
1227
- vars (namespace ).setdefault (_UNRECOGNIZED_ARGS_ATTR , [])
1227
+ if not hasattr (namespace , _UNRECOGNIZED_ARGS_ATTR ):
1228
+ setattr (namespace , _UNRECOGNIZED_ARGS_ATTR , [])
1228
1229
getattr (namespace , _UNRECOGNIZED_ARGS_ATTR ).extend (arg_strings )
1229
1230
1230
1231
class _ExtendAction (_AppendAction ):
@@ -1927,11 +1928,11 @@ def _parse_known_args(self, arg_strings, namespace):
1927
1928
# otherwise, add the arg to the arg strings
1928
1929
# and note the index if it was an option
1929
1930
else :
1930
- option_tuple = self ._parse_optional (arg_string )
1931
- if option_tuple is None :
1931
+ option_tuples = self ._parse_optional (arg_string )
1932
+ if option_tuples is None :
1932
1933
pattern = 'A'
1933
1934
else :
1934
- option_string_indices [i ] = option_tuple
1935
+ option_string_indices [i ] = option_tuples
1935
1936
pattern = 'O'
1936
1937
arg_string_pattern_parts .append (pattern )
1937
1938
@@ -1966,8 +1967,16 @@ def take_action(action, argument_strings, option_string=None):
1966
1967
def consume_optional (start_index ):
1967
1968
1968
1969
# get the optional identified at this index
1969
- option_tuple = option_string_indices [start_index ]
1970
- action , option_string , sep , explicit_arg = option_tuple
1970
+ option_tuples = option_string_indices [start_index ]
1971
+ # if multiple actions match, the option string was ambiguous
1972
+ if len (option_tuples ) > 1 :
1973
+ options = ', ' .join ([option_string
1974
+ for action , option_string , sep , explicit_arg in option_tuples ])
1975
+ args = {'option' : arg_string , 'matches' : options }
1976
+ msg = _ ('ambiguous option: %(option)s could match %(matches)s' )
1977
+ raise ArgumentError (None , msg % args )
1978
+
1979
+ action , option_string , sep , explicit_arg = option_tuples [0 ]
1971
1980
1972
1981
# identify additional optionals in the same arg string
1973
1982
# (e.g. -xyz is the same as -x -y -z if no args are required)
@@ -2253,7 +2262,7 @@ def _parse_optional(self, arg_string):
2253
2262
# if the option string is present in the parser, return the action
2254
2263
if arg_string in self ._option_string_actions :
2255
2264
action = self ._option_string_actions [arg_string ]
2256
- return action , arg_string , None , None
2265
+ return [( action , arg_string , None , None )]
2257
2266
2258
2267
# if it's just a single character, it was meant to be positional
2259
2268
if len (arg_string ) == 1 :
@@ -2263,25 +2272,14 @@ def _parse_optional(self, arg_string):
2263
2272
option_string , sep , explicit_arg = arg_string .partition ('=' )
2264
2273
if sep and option_string in self ._option_string_actions :
2265
2274
action = self ._option_string_actions [option_string ]
2266
- return action , option_string , sep , explicit_arg
2275
+ return [( action , option_string , sep , explicit_arg )]
2267
2276
2268
2277
# search through all possible prefixes of the option string
2269
2278
# and all actions in the parser for possible interpretations
2270
2279
option_tuples = self ._get_option_tuples (arg_string )
2271
2280
2272
- # if multiple actions match, the option string was ambiguous
2273
- if len (option_tuples ) > 1 :
2274
- options = ', ' .join ([option_string
2275
- for action , option_string , sep , explicit_arg in option_tuples ])
2276
- args = {'option' : arg_string , 'matches' : options }
2277
- msg = _ ('ambiguous option: %(option)s could match %(matches)s' )
2278
- raise ArgumentError (None , msg % args )
2279
-
2280
- # if exactly one action matched, this segmentation is good,
2281
- # so return the parsed action
2282
- elif len (option_tuples ) == 1 :
2283
- option_tuple , = option_tuples
2284
- return option_tuple
2281
+ if option_tuples :
2282
+ return option_tuples
2285
2283
2286
2284
# if it was not found as an option, but it looks like a negative
2287
2285
# number, it was meant to be positional
@@ -2296,7 +2294,7 @@ def _parse_optional(self, arg_string):
2296
2294
2297
2295
# it was meant to be an optional but there is no such option
2298
2296
# in this parser (though it might be a valid option in a subparser)
2299
- return None , arg_string , None , None
2297
+ return [( None , arg_string , None , None )]
2300
2298
2301
2299
def _get_option_tuples (self , option_string ):
2302
2300
result = []
@@ -2319,7 +2317,9 @@ def _get_option_tuples(self, option_string):
2319
2317
# but multiple character options always have to have their argument
2320
2318
# separate
2321
2319
elif option_string [0 ] in chars and option_string [1 ] not in chars :
2322
- option_prefix = option_string
2320
+ option_prefix , sep , explicit_arg = option_string .partition ('=' )
2321
+ if not sep :
2322
+ sep = explicit_arg = None
2323
2323
short_option_prefix = option_string [:2 ]
2324
2324
short_explicit_arg = option_string [2 :]
2325
2325
@@ -2328,9 +2328,9 @@ def _get_option_tuples(self, option_string):
2328
2328
action = self ._option_string_actions [option_string ]
2329
2329
tup = action , option_string , '' , short_explicit_arg
2330
2330
result .append (tup )
2331
- elif option_string .startswith (option_prefix ):
2331
+ elif self . allow_abbrev and option_string .startswith (option_prefix ):
2332
2332
action = self ._option_string_actions [option_string ]
2333
- tup = action , option_string , None , None
2333
+ tup = action , option_string , sep , explicit_arg
2334
2334
result .append (tup )
2335
2335
2336
2336
# shouldn't ever get here
@@ -2344,43 +2344,40 @@ def _get_nargs_pattern(self, action):
2344
2344
# in all examples below, we have to allow for '--' args
2345
2345
# which are represented as '-' in the pattern
2346
2346
nargs = action .nargs
2347
+ # if this is an optional action, -- is not allowed
2348
+ option = action .option_strings
2347
2349
2348
2350
# the default (None) is assumed to be a single argument
2349
2351
if nargs is None :
2350
- nargs_pattern = '(-*A-*)'
2352
+ nargs_pattern = '([A])' if option else '( -*A-*)'
2351
2353
2352
2354
# allow zero or one arguments
2353
2355
elif nargs == OPTIONAL :
2354
- nargs_pattern = '(-*A?-*)'
2356
+ nargs_pattern = '(A?)' if option else '( -*A?-*)'
2355
2357
2356
2358
# allow zero or more arguments
2357
2359
elif nargs == ZERO_OR_MORE :
2358
- nargs_pattern = '(-*[A-]*)'
2360
+ nargs_pattern = '(A*)' if option else '( -*[A-]*)'
2359
2361
2360
2362
# allow one or more arguments
2361
2363
elif nargs == ONE_OR_MORE :
2362
- nargs_pattern = '(-*A[A-]*)'
2364
+ nargs_pattern = '(A+)' if option else '( -*A[A-]*)'
2363
2365
2364
2366
# allow any number of options or arguments
2365
2367
elif nargs == REMAINDER :
2366
- nargs_pattern = '([- AO]*)'
2368
+ nargs_pattern = '([AO]*)' if option else '(. *)'
2367
2369
2368
2370
# allow one argument followed by any number of options or arguments
2369
2371
elif nargs == PARSER :
2370
- nargs_pattern = '(-*A[-AO]*)'
2372
+ nargs_pattern = '(A[AO]*)' if option else '( -*A[-AO]*)'
2371
2373
2372
2374
# suppress action, like nargs=0
2373
2375
elif nargs == SUPPRESS :
2374
- nargs_pattern = '(-* -*)'
2376
+ nargs_pattern = '()' if option else '( -*)'
2375
2377
2376
2378
# all others should be integers
2377
2379
else :
2378
- nargs_pattern = '(-*%s-*)' % '-*' .join ('A' * nargs )
2379
-
2380
- # if this is an optional action, -- is not allowed
2381
- if action .option_strings :
2382
- nargs_pattern = nargs_pattern .replace ('-*' , '' )
2383
- nargs_pattern = nargs_pattern .replace ('-' , '' )
2380
+ nargs_pattern = '([AO]{%d})' % nargs if option else '((?:-*A){%d}-*)' % nargs
2384
2381
2385
2382
# return the pattern
2386
2383
return nargs_pattern
@@ -2483,21 +2480,17 @@ def _get_values(self, action, arg_strings):
2483
2480
value = action .const
2484
2481
else :
2485
2482
value = action .default
2486
- if isinstance (value , str ):
2483
+ if isinstance (value , str ) and value is not SUPPRESS :
2487
2484
value = self ._get_value (action , value )
2488
- self ._check_value (action , value )
2489
2485
2490
2486
# when nargs='*' on a positional, if there were no command-line
2491
2487
# args, use the default if it is anything other than None
2492
2488
elif (not arg_strings and action .nargs == ZERO_OR_MORE and
2493
2489
not action .option_strings ):
2494
2490
if action .default is not None :
2495
2491
value = action .default
2496
- self ._check_value (action , value )
2497
2492
else :
2498
- # since arg_strings is always [] at this point
2499
- # there is no need to use self._check_value(action, value)
2500
- value = arg_strings
2493
+ value = []
2501
2494
2502
2495
# single argument or optional argument produces a single value
2503
2496
elif len (arg_strings ) == 1 and action .nargs in [None , OPTIONAL ]:
@@ -2554,11 +2547,15 @@ def _get_value(self, action, arg_string):
2554
2547
2555
2548
def _check_value (self , action , value ):
2556
2549
# converted value must be one of the choices (if specified)
2557
- if action .choices is not None and value not in action .choices :
2558
- args = {'value' : value ,
2559
- 'choices' : ', ' .join (map (repr , action .choices ))}
2560
- msg = _ ('invalid choice: %(value)r (choose from %(choices)s)' )
2561
- raise ArgumentError (action , msg % args )
2550
+ choices = action .choices
2551
+ if choices is not None :
2552
+ if isinstance (choices , str ):
2553
+ choices = iter (choices )
2554
+ if value not in choices :
2555
+ args = {'value' : value ,
2556
+ 'choices' : ', ' .join (map (repr , action .choices ))}
2557
+ msg = _ ('invalid choice: %(value)r (choose from %(choices)s)' )
2558
+ raise ArgumentError (action , msg % args )
2562
2559
2563
2560
# =======================
2564
2561
# Help-formatting methods
0 commit comments