summaryrefslogtreecommitdiffstats
path: root/Lib/argparse.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/argparse.py')
-rw-r--r--Lib/argparse.py100
1 files changed, 28 insertions, 72 deletions
diff --git a/Lib/argparse.py b/Lib/argparse.py
index 0dbdd67..55bf8cd 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -328,17 +328,8 @@ class HelpFormatter(object):
if len(prefix) + len(usage) > text_width:
# break usage into wrappable parts
- part_regexp = (
- r'\(.*?\)+(?=\s|$)|'
- r'\[.*?\]+(?=\s|$)|'
- r'\S+'
- )
- opt_usage = format(optionals, groups)
- pos_usage = format(positionals, groups)
- opt_parts = _re.findall(part_regexp, opt_usage)
- pos_parts = _re.findall(part_regexp, pos_usage)
- assert ' '.join(opt_parts) == opt_usage
- assert ' '.join(pos_parts) == pos_usage
+ opt_parts = self._get_actions_usage_parts(optionals, groups)
+ pos_parts = self._get_actions_usage_parts(positionals, groups)
# helper for wrapping lines
def get_lines(parts, indent, prefix=None):
@@ -391,6 +382,9 @@ class HelpFormatter(object):
return '%s%s\n\n' % (prefix, usage)
def _format_actions_usage(self, actions, groups):
+ return ' '.join(self._get_actions_usage_parts(actions, groups))
+
+ def _get_actions_usage_parts(self, actions, groups):
# find group indices and identify actions in groups
group_actions = set()
inserts = {}
@@ -398,58 +392,26 @@ class HelpFormatter(object):
if not group._group_actions:
raise ValueError(f'empty group {group}')
+ if all(action.help is SUPPRESS for action in group._group_actions):
+ continue
+
try:
start = actions.index(group._group_actions[0])
except ValueError:
continue
else:
- group_action_count = len(group._group_actions)
- end = start + group_action_count
+ end = start + len(group._group_actions)
if actions[start:end] == group._group_actions:
-
- suppressed_actions_count = 0
- for action in group._group_actions:
- group_actions.add(action)
- if action.help is SUPPRESS:
- suppressed_actions_count += 1
-
- exposed_actions_count = group_action_count - suppressed_actions_count
- if not exposed_actions_count:
- continue
-
- if not group.required:
- if start in inserts:
- inserts[start] += ' ['
- else:
- inserts[start] = '['
- if end in inserts:
- inserts[end] += ']'
- else:
- inserts[end] = ']'
- elif exposed_actions_count > 1:
- if start in inserts:
- inserts[start] += ' ('
- else:
- inserts[start] = '('
- if end in inserts:
- inserts[end] += ')'
- else:
- inserts[end] = ')'
- for i in range(start + 1, end):
- inserts[i] = '|'
+ group_actions.update(group._group_actions)
+ inserts[start, end] = group
# collect all actions format strings
parts = []
- for i, action in enumerate(actions):
+ for action in actions:
# suppressed arguments are marked with None
- # remove | separators for suppressed arguments
if action.help is SUPPRESS:
- parts.append(None)
- if inserts.get(i) == '|':
- inserts.pop(i)
- elif inserts.get(i + 1) == '|':
- inserts.pop(i + 1)
+ part = None
# produce all arg strings
elif not action.option_strings:
@@ -461,9 +423,6 @@ class HelpFormatter(object):
if part[0] == '[' and part[-1] == ']':
part = part[1:-1]
- # add the action string to the list
- parts.append(part)
-
# produce the first way to invoke the option in brackets
else:
option_string = action.option_strings[0]
@@ -484,26 +443,23 @@ class HelpFormatter(object):
if not action.required and action not in group_actions:
part = '[%s]' % part
- # add the action string to the list
- parts.append(part)
+ # add the action string to the list
+ parts.append(part)
- # insert things at the necessary indices
- for i in sorted(inserts, reverse=True):
- parts[i:i] = [inserts[i]]
-
- # join all the action items with spaces
- text = ' '.join([item for item in parts if item is not None])
-
- # clean up separators for mutually exclusive groups
- open = r'[\[(]'
- close = r'[\])]'
- text = _re.sub(r'(%s) ' % open, r'\1', text)
- text = _re.sub(r' (%s)' % close, r'\1', text)
- text = _re.sub(r'%s *%s' % (open, close), r'', text)
- text = text.strip()
+ # group mutually exclusive actions
+ 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]
+ if group.required:
+ open, close = "()" if len(group_parts) > 1 else ("", "")
+ else:
+ open, close = "[]"
+ parts[start] = open + " | ".join(group_parts) + close
+ for i in range(start + 1, end):
+ parts[i] = None
- # return the text
- return text
+ # return the usage parts
+ return [item for item in parts if item is not None]
def _format_text(self, text):
if '%(prog)' in text: