https://github.com/python/cpython/commit/013a0929750ed2b46ae990b59d02e3db84337474
commit: 013a0929750ed2b46ae990b59d02e3db84337474
branch: main
author: Ali Hamdan <ali.hamdan....@gmail.com>
committer: encukou <encu...@gmail.com>
date: 2024-08-07T15:20:38+02:00
summary:

gh-121151: argparse: Fix wrapping of long usage text of arguments inside a 
mutually exclusive groups (GH-121159)

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 83189115bf85f7..100ef9f55cd2f7 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 84fe74a1063fb6..fd111be18aed6e 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -2959,12 +2959,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 = '''\
 
@@ -4347,6 +4347,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 -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to