@@ -358,7 +358,7 @@ def _format_usage(self, usage, actions, groups, prefix):
358358 # keep optionals and positionals together to preserve
359359 # mutually exclusive group formatting (gh-75949)
360360 all_actions = optionals + positionals
361- parts , pos_start = self ._get_actions_usage_parts_split (
361+ parts , pos_start = self ._get_actions_usage_parts (
362362 all_actions , groups , len (optionals )
363363 )
364364 opt_parts = parts [:pos_start ]
@@ -420,23 +420,13 @@ def get_lines(parts, indent, prefix=None):
420420 return f'{ t .usage } { prefix } { t .reset } { usage } \n \n '
421421
422422 def _format_actions_usage (self , actions , groups ):
423- return ' ' .join (self ._get_actions_usage_parts (actions , groups ))
423+ parts , _ = self ._get_actions_usage_parts (actions , groups )
424+ return ' ' .join (parts )
424425
425426 def _is_long_option (self , string ):
426427 return len (string ) > 2
427428
428- def _get_actions_usage_parts (self , actions , groups ):
429- parts , _ = self ._get_actions_usage_parts_split (actions , groups , None )
430- return parts
431-
432- def _get_actions_usage_parts_split (self , actions , groups , opt_count ):
433- """Get usage parts with split index for optionals/positionals.
434-
435- Returns (parts, pos_start) where pos_start is the index in parts
436- where positionals begin. When opt_count is None, pos_start is None.
437- This preserves mutually exclusive group formatting across the
438- optionals/positionals boundary (gh-75949).
439- """
429+ def _get_actions_usage_parts (self , actions , groups , opt_count = None ):
440430 # find group indices and identify actions in groups
441431 group_actions = set ()
442432 inserts = {}
@@ -532,15 +522,15 @@ def _get_actions_usage_parts_split(self, actions, groups, opt_count):
532522 for i in range (start + group_size , end ):
533523 parts [i ] = None
534524
535- # calculate the split point for optionals/positionals
536- # before filtering out None entries
525+ # if opt_count is provided, calculate where positionals start in
526+ # the final parts list (for wrapping onto separate lines).
527+ # Count before filtering None entries since indices shift after.
537528 if opt_count is not None :
538- # Count non-None parts in the optionals section
539529 pos_start = sum (1 for p in parts [:opt_count ] if p is not None )
540530 else :
541531 pos_start = None
542532
543- # return the usage parts and split point
533+ # return the usage parts and split point (gh-75949)
544534 return [item for item in parts if item is not None ], pos_start
545535
546536 def _format_text (self , text ):
0 commit comments