https://github.com/python/cpython/commit/f1a6d2254f691e476541deaea67a3f679a339691 commit: f1a6d2254f691e476541deaea67a3f679a339691 branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: Yhg1s <[email protected]> date: 2024-09-02T12:55:16+02:00 summary:
[3.13] gh-121151: argparse: Fix wrapping of long usage text of arguments inside a mutually exclusive groups (GH-121159) (#122777) gh-121151: argparse: Fix wrapping of long usage text of arguments inside a mutually exclusive groups (GH-121159) (cherry picked from commit 013a0929750ed2b46ae990b59d02e3db84337474) Co-authored-by: Ali Hamdan <[email protected]> files: A Misc/NEWS.d/next/Library/2024-06-29-15-23-26.gh-issue-121151.HeLEvq.rst M Lib/argparse.py M Lib/test/test_argparse.py diff --git a/Lib/argparse.py b/Lib/argparse.py index 7e5e3129dbd47b..bf17af0faf75e4 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -447,15 +447,24 @@ def _get_actions_usage_parts(self, actions, groups): parts.append(part) # group mutually exclusive actions + inserted_separators_indices = set() for start, end in sorted(inserts, reverse=True): group = inserts[start, end] group_parts = [item for item in parts[start:end] if item is not None] + group_size = len(group_parts) if group.required: - open, close = "()" if len(group_parts) > 1 else ("", "") + open, close = "()" if group_size > 1 else ("", "") else: open, close = "[]" - parts[start] = open + " | ".join(group_parts) + close - for i in range(start + 1, end): + group_parts[0] = open + group_parts[0] + group_parts[-1] = group_parts[-1] + close + for i, part in enumerate(group_parts[:-1], start=start): + # insert a separator if not already done in a nested group + if i not in inserted_separators_indices: + parts[i] = part + ' |' + inserted_separators_indices.add(i) + parts[start + group_size - 1] = group_parts[-1] + for i in range(start + group_size, end): parts[i] = None # return the usage parts diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index d461911307703c..b1f72a3abd46a1 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -3002,12 +3002,12 @@ def get_parser(self, required=None): ] usage_when_not_required = '''\ - usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ] - [--klmno KLMNO | --pqrst PQRST] + usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ] [--klmno KLMNO | + --pqrst PQRST] ''' usage_when_required = '''\ - usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ] - (--klmno KLMNO | --pqrst PQRST) + usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ] (--klmno KLMNO | + --pqrst PQRST) ''' help = '''\ @@ -4390,6 +4390,24 @@ def test_nested_mutex_groups(self): ''') self.assertEqual(parser.format_usage(), usage) + def test_long_mutex_groups_wrap(self): + parser = argparse.ArgumentParser(prog='PROG') + g = parser.add_mutually_exclusive_group() + g.add_argument('--op1', metavar='MET', nargs='?') + g.add_argument('--op2', metavar=('MET1', 'MET2'), nargs='*') + g.add_argument('--op3', nargs='*') + g.add_argument('--op4', metavar=('MET1', 'MET2'), nargs='+') + g.add_argument('--op5', nargs='+') + g.add_argument('--op6', nargs=3) + g.add_argument('--op7', metavar=('MET1', 'MET2', 'MET3'), nargs=3) + + usage = textwrap.dedent('''\ + usage: PROG [-h] [--op1 [MET] | --op2 [MET1 [MET2 ...]] | --op3 [OP3 ...] | + --op4 MET1 [MET2 ...] | --op5 OP5 [OP5 ...] | --op6 OP6 OP6 OP6 | + --op7 MET1 MET2 MET3] + ''') + self.assertEqual(parser.format_usage(), usage) + class TestHelpVariableExpansion(HelpTestCase): """Test that variables are expanded properly in help messages""" diff --git a/Misc/NEWS.d/next/Library/2024-06-29-15-23-26.gh-issue-121151.HeLEvq.rst b/Misc/NEWS.d/next/Library/2024-06-29-15-23-26.gh-issue-121151.HeLEvq.rst new file mode 100644 index 00000000000000..f08b6131a702f7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-06-29-15-23-26.gh-issue-121151.HeLEvq.rst @@ -0,0 +1,2 @@ +Fix wrapping of long usage text of arguments inside a mutually exclusive +group in :mod:`argparse`. _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: [email protected]
