-
-
Notifications
You must be signed in to change notification settings - Fork 33.6k
gh-142346: Fix usage formatting for mutually exclusive groups in argparse #142381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3398,12 +3398,11 @@ def test_help_subparser_all_mutually_exclusive_group_members_suppressed(self): | |
| ''' | ||
| self.assertEqual(cmd_foo.format_help(), textwrap.dedent(expected)) | ||
|
|
||
| def test_empty_group(self): | ||
| def test_usage_empty_group(self): | ||
| # See issue 26952 | ||
| parser = argparse.ArgumentParser() | ||
| parser = ErrorRaisingArgumentParser(prog='PROG') | ||
| group = parser.add_mutually_exclusive_group() | ||
| with self.assertRaises(ValueError): | ||
| parser.parse_args(['-h']) | ||
| self.assertEqual(parser.format_usage(), 'usage: PROG [-h]\n') | ||
|
|
||
| def test_nested_mutex_groups(self): | ||
| parser = argparse.ArgumentParser(prog='PROG') | ||
|
|
@@ -3671,25 +3670,29 @@ def get_parser(self, required): | |
| group.add_argument('-b', action='store_true', help='b help') | ||
| parser.add_argument('-y', action='store_true', help='y help') | ||
| group.add_argument('-c', action='store_true', help='c help') | ||
| parser.add_argument('-z', action='store_true', help='z help') | ||
| return parser | ||
|
|
||
| failures = ['-a -b', '-b -c', '-a -c', '-a -b -c'] | ||
| successes = [ | ||
| ('-a', NS(a=True, b=False, c=False, x=False, y=False)), | ||
| ('-b', NS(a=False, b=True, c=False, x=False, y=False)), | ||
| ('-c', NS(a=False, b=False, c=True, x=False, y=False)), | ||
| ('-a -x', NS(a=True, b=False, c=False, x=True, y=False)), | ||
| ('-y -b', NS(a=False, b=True, c=False, x=False, y=True)), | ||
| ('-x -y -c', NS(a=False, b=False, c=True, x=True, y=True)), | ||
| ('-a', NS(a=True, b=False, c=False, x=False, y=False, z=False)), | ||
| ('-b', NS(a=False, b=True, c=False, x=False, y=False, z=False)), | ||
| ('-c', NS(a=False, b=False, c=True, x=False, y=False, z=False)), | ||
| ('-a -x', NS(a=True, b=False, c=False, x=True, y=False, z=False)), | ||
| ('-y -b', NS(a=False, b=True, c=False, x=False, y=True, z=False)), | ||
| ('-x -y -c', NS(a=False, b=False, c=True, x=True, y=True, z=False)), | ||
| ] | ||
| successes_when_not_required = [ | ||
| ('', NS(a=False, b=False, c=False, x=False, y=False)), | ||
| ('-x', NS(a=False, b=False, c=False, x=True, y=False)), | ||
| ('-y', NS(a=False, b=False, c=False, x=False, y=True)), | ||
| ('', NS(a=False, b=False, c=False, x=False, y=False, z=False)), | ||
| ('-x', NS(a=False, b=False, c=False, x=True, y=False, z=False)), | ||
| ('-y', NS(a=False, b=False, c=False, x=False, y=True, z=False)), | ||
|
Comment on lines
+3678
to
+3688
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All these changes are not important. They are just the result of adding yet one argument |
||
| ] | ||
|
|
||
| usage_when_required = usage_when_not_required = '''\ | ||
| usage: PROG [-h] [-x] [-a] [-b] [-y] [-c] | ||
| usage_when_not_required = '''\ | ||
| usage: PROG [-h] [-x] [-a | -b | -c] [-y] [-z] | ||
| ''' | ||
| usage_when_required = '''\ | ||
| usage: PROG [-h] [-x] (-a | -b | -c) [-y] [-z] | ||
|
Comment on lines
+3691
to
+3695
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The old result was incorrect (group was not formatted). |
||
| ''' | ||
| help = '''\ | ||
|
|
||
|
|
@@ -3700,6 +3703,7 @@ def get_parser(self, required): | |
| -b b help | ||
| -y y help | ||
| -c c help | ||
| -z z help | ||
| ''' | ||
|
|
||
|
|
||
|
|
@@ -3753,23 +3757,27 @@ def get_parser(self, required): | |
| group.add_argument('a', nargs='?', help='a help') | ||
| group.add_argument('-b', action='store_true', help='b help') | ||
| group.add_argument('-c', action='store_true', help='c help') | ||
| parser.add_argument('-z', action='store_true', help='z help') | ||
| return parser | ||
|
|
||
| failures = ['X A -b', '-b -c', '-c X A'] | ||
| successes = [ | ||
| ('X A', NS(a='A', b=False, c=False, x='X', y=False)), | ||
| ('X -b', NS(a=None, b=True, c=False, x='X', y=False)), | ||
| ('X -c', NS(a=None, b=False, c=True, x='X', y=False)), | ||
| ('X A -y', NS(a='A', b=False, c=False, x='X', y=True)), | ||
| ('X -y -b', NS(a=None, b=True, c=False, x='X', y=True)), | ||
| ('X A', NS(a='A', b=False, c=False, x='X', y=False, z=False)), | ||
| ('X -b', NS(a=None, b=True, c=False, x='X', y=False, z=False)), | ||
| ('X -c', NS(a=None, b=False, c=True, x='X', y=False, z=False)), | ||
| ('X A -y', NS(a='A', b=False, c=False, x='X', y=True, z=False)), | ||
| ('X -y -b', NS(a=None, b=True, c=False, x='X', y=True, z=False)), | ||
|
Comment on lines
+3765
to
+3769
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be ignored as above. |
||
| ] | ||
| successes_when_not_required = [ | ||
| ('X', NS(a=None, b=False, c=False, x='X', y=False)), | ||
| ('X -y', NS(a=None, b=False, c=False, x='X', y=True)), | ||
| ('X', NS(a=None, b=False, c=False, x='X', y=False, z=False)), | ||
| ('X -y', NS(a=None, b=False, c=False, x='X', y=True, z=False)), | ||
| ] | ||
|
|
||
| usage_when_required = usage_when_not_required = '''\ | ||
| usage: PROG [-h] [-y] [-b] [-c] x [a] | ||
| usage_when_not_required = '''\ | ||
| usage: PROG [-h] [-y] [-z] x [-b | -c | a] | ||
| ''' | ||
| usage_when_required = '''\ | ||
| usage: PROG [-h] [-y] [-z] x (-b | -c | a) | ||
|
Comment on lines
+3776
to
+3780
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yest one incorrect result in old tests. |
||
| ''' | ||
| help = '''\ | ||
|
|
||
|
|
@@ -3782,6 +3790,7 @@ def get_parser(self, required): | |
| -y y help | ||
| -b b help | ||
| -c c help | ||
| -z z help | ||
| ''' | ||
|
|
||
|
|
||
|
|
@@ -4989,9 +4998,9 @@ def test_mutex_groups_with_mixed_optionals_positionals_wrap(self): | |
| g.add_argument('positional', nargs='?') | ||
|
|
||
| usage = textwrap.dedent('''\ | ||
| usage: PROG [-h] [-v | -q | -x [EXTRA_LONG_OPTION_NAME] | | ||
| -y [YET_ANOTHER_LONG_OPTION] | | ||
| positional] | ||
| usage: PROG [-h] | ||
| [-v | -q | -x [EXTRA_LONG_OPTION_NAME] | | ||
| -y [YET_ANOTHER_LONG_OPTION] | positional] | ||
|
Comment on lines
+5001
to
+5003
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The line break is now forced not before the first positional argument, but before the first group containing a positional argument. |
||
| ''') | ||
| self.assertEqual(parser.format_usage(), usage) | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| Fix usage formatting for mutually exclusive groups in :mod:`argparse` | ||
| when they are preceded by positional arguments or followed or intermixed | ||
| with other optional arguments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ValueError was only raised to hide IndexError. Now this is not needed, empty groups are simply ignored (as well as groups with all suppressed arguments).