@@ -2033,7 +2033,7 @@ def consume_optional(start_index):
20332033
20342034 # get the optional identified at this index
20352035 option_tuple = option_string_indices [start_index ]
2036- action , option_string , explicit_arg = option_tuple
2036+ action , option_string , sep , explicit_arg = option_tuple
20372037
20382038 # identify additional optionals in the same arg string
20392039 # (e.g. -xyz is the same as -x -y -z if no args are required)
@@ -2060,18 +2060,27 @@ def consume_optional(start_index):
20602060 and option_string [1 ] not in chars
20612061 and explicit_arg != ''
20622062 ):
2063+ if sep or explicit_arg [0 ] in chars :
2064+ msg = _ ('ignored explicit argument %r' )
2065+ raise ArgumentError (action , msg % explicit_arg )
20632066 action_tuples .append ((action , [], option_string ))
20642067 char = option_string [0 ]
20652068 option_string = char + explicit_arg [0 ]
2066- new_explicit_arg = explicit_arg [1 :] or None
20672069 optionals_map = self ._option_string_actions
20682070 if option_string in optionals_map :
20692071 action = optionals_map [option_string ]
2070- explicit_arg = new_explicit_arg
2072+ explicit_arg = explicit_arg [1 :]
2073+ if not explicit_arg :
2074+ sep = explicit_arg = None
2075+ elif explicit_arg [0 ] == '=' :
2076+ sep = '='
2077+ explicit_arg = explicit_arg [1 :]
2078+ else :
2079+ sep = ''
20712080 else :
2072- msg = _ ( 'ignored explicit argument %r' )
2073- raise ArgumentError ( action , msg % explicit_arg )
2074-
2081+ extras . append ( char + explicit_arg )
2082+ stop = start_index + 1
2083+ break
20752084 # if the action expect exactly one argument, we've
20762085 # successfully matched the option; exit the loop
20772086 elif arg_count == 1 :
@@ -2299,18 +2308,17 @@ def _parse_optional(self, arg_string):
22992308 # if the option string is present in the parser, return the action
23002309 if arg_string in self ._option_string_actions :
23012310 action = self ._option_string_actions [arg_string ]
2302- return action , arg_string , None
2311+ return action , arg_string , None , None
23032312
23042313 # if it's just a single character, it was meant to be positional
23052314 if len (arg_string ) == 1 :
23062315 return None
23072316
23082317 # if the option string before the "=" is present, return the action
2309- if '=' in arg_string :
2310- option_string , explicit_arg = arg_string .split ('=' , 1 )
2311- if option_string in self ._option_string_actions :
2312- action = self ._option_string_actions [option_string ]
2313- return action , option_string , explicit_arg
2318+ option_string , sep , explicit_arg = arg_string .partition ('=' )
2319+ if sep and option_string in self ._option_string_actions :
2320+ action = self ._option_string_actions [option_string ]
2321+ return action , option_string , sep , explicit_arg
23142322
23152323 # search through all possible prefixes of the option string
23162324 # and all actions in the parser for possible interpretations
@@ -2319,7 +2327,7 @@ def _parse_optional(self, arg_string):
23192327 # if multiple actions match, the option string was ambiguous
23202328 if len (option_tuples ) > 1 :
23212329 options = ', ' .join ([option_string
2322- for action , option_string , explicit_arg in option_tuples ])
2330+ for action , option_string , sep , explicit_arg in option_tuples ])
23232331 args = {'option' : arg_string , 'matches' : options }
23242332 msg = _ ('ambiguous option: %(option)s could match %(matches)s' )
23252333 self .error (msg % args )
@@ -2343,7 +2351,7 @@ def _parse_optional(self, arg_string):
23432351
23442352 # it was meant to be an optional but there is no such option
23452353 # in this parser (though it might be a valid option in a subparser)
2346- return None , arg_string , None
2354+ return None , arg_string , None , None
23472355
23482356 def _get_option_tuples (self , option_string ):
23492357 result = []
@@ -2353,34 +2361,31 @@ def _get_option_tuples(self, option_string):
23532361 chars = self .prefix_chars
23542362 if option_string [0 ] in chars and option_string [1 ] in chars :
23552363 if self .allow_abbrev :
2356- if '=' in option_string :
2357- option_prefix , explicit_arg = option_string .split ('=' , 1 )
2358- else :
2359- option_prefix = option_string
2360- explicit_arg = None
2364+ option_prefix , sep , explicit_arg = option_string .partition ('=' )
2365+ if not sep :
2366+ sep = explicit_arg = None
23612367 for option_string in self ._option_string_actions :
23622368 if option_string .startswith (option_prefix ):
23632369 action = self ._option_string_actions [option_string ]
2364- tup = action , option_string , explicit_arg
2370+ tup = action , option_string , sep , explicit_arg
23652371 result .append (tup )
23662372
23672373 # single character options can be concatenated with their arguments
23682374 # but multiple character options always have to have their argument
23692375 # separate
23702376 elif option_string [0 ] in chars and option_string [1 ] not in chars :
23712377 option_prefix = option_string
2372- explicit_arg = None
23732378 short_option_prefix = option_string [:2 ]
23742379 short_explicit_arg = option_string [2 :]
23752380
23762381 for option_string in self ._option_string_actions :
23772382 if option_string == short_option_prefix :
23782383 action = self ._option_string_actions [option_string ]
2379- tup = action , option_string , short_explicit_arg
2384+ tup = action , option_string , '' , short_explicit_arg
23802385 result .append (tup )
23812386 elif option_string .startswith (option_prefix ):
23822387 action = self ._option_string_actions [option_string ]
2383- tup = action , option_string , explicit_arg
2388+ tup = action , option_string , None , None
23842389 result .append (tup )
23852390
23862391 # shouldn't ever get here
0 commit comments