Skip to content
4 changes: 2 additions & 2 deletions Lib/argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,12 +395,12 @@ def _get_actions_usage_parts(self, actions, groups):
continue

try:
start = actions.index(group._group_actions[0])
start = min(actions.index(item) for item in group._group_actions)
except ValueError:
continue
else:
end = start + len(group._group_actions)
if actions[start:end] == group._group_actions:
if set(actions[start:end]) == set(group._group_actions):
group_actions.update(group._group_actions)
inserts[start, end] = group

Expand Down
23 changes: 23 additions & 0 deletions Lib/test/test_argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -2902,6 +2902,29 @@ def test_help(self):
'''
self.assertEqual(parser.format_help(), textwrap.dedent(expected))

def test_optional_order(self):
parser = ErrorRaisingArgumentParser(prog='PROG')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('--foo')
group.add_argument('bar', nargs='?')
expected = '''\
usage: PROG [-h] (--foo FOO | bar)

positional arguments:
bar

options:
-h, --help show this help message and exit
--foo FOO
'''
self.assertEqual(parser.format_help(), textwrap.dedent(expected))

parser = ErrorRaisingArgumentParser(prog='PROG')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('bar', nargs='?')
group.add_argument('--foo')
self.assertEqual(parser.format_help(), textwrap.dedent(expected))

def test_help_subparser_all_mutually_exclusive_group_members_suppressed(self):
self.maxDiff = None
parser = ErrorRaisingArgumentParser(prog='PROG')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Correct argparse usage output for required, mutually exclusive groups containing a positional argument
Loading