@@ -1982,7 +1982,7 @@ def consume_optional(start_index):
19821982
19831983 # get the optional identified at this index
19841984 option_tuple = option_string_indices [start_index ]
1985- action , option_string , explicit_arg = option_tuple
1985+ action , option_string , sep , explicit_arg = option_tuple
19861986
19871987 # identify additional optionals in the same arg string
19881988 # (e.g. -xyz is the same as -x -y -z if no args are required)
@@ -2009,18 +2009,27 @@ def consume_optional(start_index):
20092009 and option_string [1 ] not in chars
20102010 and explicit_arg != ''
20112011 ):
2012+ if sep or explicit_arg [0 ] in chars :
2013+ msg = _ ('ignored explicit argument %r' )
2014+ raise ArgumentError (action , msg % explicit_arg )
20122015 action_tuples .append ((action , [], option_string ))
20132016 char = option_string [0 ]
20142017 option_string = char + explicit_arg [0 ]
2015- new_explicit_arg = explicit_arg [1 :] or None
20162018 optionals_map = self ._option_string_actions
20172019 if option_string in optionals_map :
20182020 action = optionals_map [option_string ]
2019- explicit_arg = new_explicit_arg
2021+ explicit_arg = explicit_arg [1 :]
2022+ if not explicit_arg :
2023+ sep = explicit_arg = None
2024+ elif explicit_arg [0 ] == '=' :
2025+ sep = '='
2026+ explicit_arg = explicit_arg [1 :]
2027+ else :
2028+ sep = ''
20202029 else :
2021- msg = _ ( 'ignored explicit argument %r' )
2022- raise ArgumentError ( action , msg % explicit_arg )
2023-
2030+ extras . append ( char + explicit_arg )
2031+ stop = start_index + 1
2032+ break
20242033 # if the action expect exactly one argument, we've
20252034 # successfully matched the option; exit the loop
20262035 elif arg_count == 1 :
@@ -2238,18 +2247,17 @@ def _parse_optional(self, arg_string):
22382247 # if the option string is present in the parser, return the action
22392248 if arg_string in self ._option_string_actions :
22402249 action = self ._option_string_actions [arg_string ]
2241- return action , arg_string , None
2250+ return action , arg_string , None , None
22422251
22432252 # if it's just a single character, it was meant to be positional
22442253 if len (arg_string ) == 1 :
22452254 return None
22462255
22472256 # if the option string before the "=" is present, return the action
2248- if '=' in arg_string :
2249- option_string , explicit_arg = arg_string .split ('=' , 1 )
2250- if option_string in self ._option_string_actions :
2251- action = self ._option_string_actions [option_string ]
2252- return action , option_string , explicit_arg
2257+ option_string , sep , explicit_arg = arg_string .partition ('=' )
2258+ if sep and option_string in self ._option_string_actions :
2259+ action = self ._option_string_actions [option_string ]
2260+ return action , option_string , sep , explicit_arg
22532261
22542262 # search through all possible prefixes of the option string
22552263 # and all actions in the parser for possible interpretations
@@ -2258,7 +2266,7 @@ def _parse_optional(self, arg_string):
22582266 # if multiple actions match, the option string was ambiguous
22592267 if len (option_tuples ) > 1 :
22602268 options = ', ' .join ([option_string
2261- for action , option_string , explicit_arg in option_tuples ])
2269+ for action , option_string , sep , explicit_arg in option_tuples ])
22622270 args = {'option' : arg_string , 'matches' : options }
22632271 msg = _ ('ambiguous option: %(option)s could match %(matches)s' )
22642272 self .error (msg % args )
@@ -2282,7 +2290,7 @@ def _parse_optional(self, arg_string):
22822290
22832291 # it was meant to be an optional but there is no such option
22842292 # in this parser (though it might be a valid option in a subparser)
2285- return None , arg_string , None
2293+ return None , arg_string , None , None
22862294
22872295 def _get_option_tuples (self , option_string ):
22882296 result = []
@@ -2292,34 +2300,31 @@ def _get_option_tuples(self, option_string):
22922300 chars = self .prefix_chars
22932301 if option_string [0 ] in chars and option_string [1 ] in chars :
22942302 if self .allow_abbrev :
2295- if '=' in option_string :
2296- option_prefix , explicit_arg = option_string .split ('=' , 1 )
2297- else :
2298- option_prefix = option_string
2299- explicit_arg = None
2303+ option_prefix , sep , explicit_arg = option_string .partition ('=' )
2304+ if not sep :
2305+ sep = explicit_arg = None
23002306 for option_string in self ._option_string_actions :
23012307 if option_string .startswith (option_prefix ):
23022308 action = self ._option_string_actions [option_string ]
2303- tup = action , option_string , explicit_arg
2309+ tup = action , option_string , sep , explicit_arg
23042310 result .append (tup )
23052311
23062312 # single character options can be concatenated with their arguments
23072313 # but multiple character options always have to have their argument
23082314 # separate
23092315 elif option_string [0 ] in chars and option_string [1 ] not in chars :
23102316 option_prefix = option_string
2311- explicit_arg = None
23122317 short_option_prefix = option_string [:2 ]
23132318 short_explicit_arg = option_string [2 :]
23142319
23152320 for option_string in self ._option_string_actions :
23162321 if option_string == short_option_prefix :
23172322 action = self ._option_string_actions [option_string ]
2318- tup = action , option_string , short_explicit_arg
2323+ tup = action , option_string , '' , short_explicit_arg
23192324 result .append (tup )
23202325 elif option_string .startswith (option_prefix ):
23212326 action = self ._option_string_actions [option_string ]
2322- tup = action , option_string , explicit_arg
2327+ tup = action , option_string , None , None
23232328 result .append (tup )
23242329
23252330 # shouldn't ever get here
0 commit comments