Skip to content

Commit

Permalink
Merge pull request #1028 from reef-technologies/better_help
Browse files Browse the repository at this point in the history
further help formatting cleanup
  • Loading branch information
mjurbanski-reef committed May 1, 2024
2 parents 8021203 + 4767dde commit 0c36eb1
Showing 1 changed file with 37 additions and 44 deletions.
81 changes: 37 additions & 44 deletions b2/_internal/arg_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from __future__ import annotations

import argparse
import contextlib
import functools
import locale
import re
Expand Down Expand Up @@ -39,7 +40,7 @@ def add_usage(self, usage, actions, groups, prefix=None):
def add_argument(self, action):
if isinstance(action, argparse._SubParsersAction) and action.help is not argparse.SUPPRESS:
usages = []
for choice in self._unique_choice_values(action):
for choice in action.choices.values():
deprecated = getattr(choice, 'deprecated', False)
if deprecated:
if self.show_all:
Expand All @@ -50,14 +51,6 @@ def add_argument(self, action):
else:
super().add_argument(action)

@classmethod
def _unique_choice_values(cls, action):
seen = set()
seen_add = seen.add
for _, value in sorted(action.choices.items()):
if not (value in seen or seen_add(value)):
yield value


class _HelpAllAction(argparse._HelpAction):
"""Like argparse._HelpAction but prints help for all subcommands (even deprecated ones)."""
Expand Down Expand Up @@ -143,44 +136,44 @@ def _get_encoding(cls):
def print_help(self, *args, show_all: bool = False, **kwargs):
"""
Print help message.
"""
with unittest.mock.patch.object(
self, 'formatter_class', functools.partial(B2RawTextHelpFormatter, show_all=show_all)
):
super().print_help(*args, **kwargs)
def format_usage(self):
"""
Format usage message.
All subcommands are sorted alphabetically.
Unless show_all is True, it hides deprecated options and subcommands.
In additional all subcommand aliases (such as `sub_command` alias for `sub-command) are hidden.
Deduplicate subcommands aliases if they only differ by underscores.
Due how deep changes are in argparse stack this is done through temporary patches.
"""
# TODO We don't want to list underscore aliases subcommands in the usage.
# Unfortunately the only way found was to temporarily remove the aliases,
# print the usage and then restore the aliases since the formatting is deep
# inside the Python argparse module.
# We restore the original dictionary which we don't modify, just in case
# someone else has taken a reference to it.
subparsers_action = None
original_choices = None
if self._subparsers is not None:
for action in self._subparsers._actions:
if isinstance(action, argparse._SubParsersAction):
subparsers_action = action
original_choices = action.choices
action.choices = {}
choice_values = set()
# sort alphabetically; this also makes `-` come before `_`
for key, choice in sorted(original_choices.items()):
if choice not in choice_values:
action.choices[key] = choice
choice_values.add(choice)
# only one subparser supported
break
usage = super().format_usage()
if subparsers_action is not None:
subparsers_action.choices = original_choices
return usage
patches = [
unittest.mock.patch.object(
self, 'formatter_class',
functools.partial(B2RawTextHelpFormatter, show_all=show_all)
)
]
if self._subparsers is not None and not show_all:
patches.extend(
[
self._hide_duplicated_action_choices(action)
for action in self._subparsers._actions
if isinstance(action, argparse._SubParsersAction)
]
)
with contextlib.ExitStack() as stack:
for patch in patches:
stack.enter_context(patch)
super().print_help(*args, **kwargs)

@contextlib.contextmanager
def _hide_duplicated_action_choices(self, action):
original_choices = action.choices
seen_choices = set()
filtered_choices = {}
for name, choice in sorted(original_choices.items()):
if (not getattr(choice, 'deprecated', False)) and choice not in seen_choices:
filtered_choices[name] = choice
seen_choices.add(choice)
action.choices = filtered_choices
yield
action.choices = original_choices


SUPPORT_CAMEL_CASE_ARGUMENTS = False
Expand Down

0 comments on commit 0c36eb1

Please sign in to comment.