summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Van Brunt <kmvanbrunt@gmail.com>2020-09-30 20:57:02 -0400
committerKevin Van Brunt <kmvanbrunt@gmail.com>2020-09-30 20:57:52 -0400
commit457ee75d83e35c5dae397b8c001b74600e286eac (patch)
treec7191a4de75b13e9ee074770838aa32a5ca0b3c8
parentad646aa05031121db825cb9a963452b7327f7bc7 (diff)
downloadcmd2-git-457ee75d83e35c5dae397b8c001b74600e286eac.tar.gz
Fixed issue where instantiating more than one cmd2-based class which uses the @as_subcommand_toduplicate_subcommand
decorator resulted in duplicated help text in the base command the subcommands belong to.
-rw-r--r--CHANGELOG.md2
-rw-r--r--cmd2/argparse_custom.py24
-rw-r--r--cmd2/cmd2.py8
3 files changed, 23 insertions, 11 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e2ada12f..1b41df31 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,8 @@
* Bug Fixes
* Fixed issue where quoted redirectors and terminators in aliases and macros were not being
restored when read from a startup script.
+ * Fixed issue where instantiating more than one cmd2-based class which uses the `@as_subcommand_to`
+ decorator resulted in duplicated help text in the base command the subcommands belong to.
## 1.3.10 (September 17, 2020)
* Enhancements
diff --git a/cmd2/argparse_custom.py b/cmd2/argparse_custom.py
index 45abe6b2..d773f851 100644
--- a/cmd2/argparse_custom.py
+++ b/cmd2/argparse_custom.py
@@ -550,6 +550,7 @@ argparse.ArgumentParser._match_argument = _match_argument_wrapper
# Patch argparse._SubParsersAction to add remove_parser function
############################################################################################################
+# noinspection PyPep8Naming
def _SubParsersAction_remove_parser(self, name: str):
"""
Removes a sub-parser from a sub-parsers group
@@ -558,23 +559,23 @@ def _SubParsersAction_remove_parser(self, name: str):
class so cmd2 can remove subcommands from a parser.
:param self: instance of the _SubParsersAction being edited
- :param name: name of the sub-parser to remove
+ :param name: name of the subcommand for the sub-parser to remove
"""
+ # Remove this subcommand from its base command's help text
for choice_action in self._choices_actions:
if choice_action.dest == name:
self._choices_actions.remove(choice_action)
break
- subparser = self._name_parser_map[name]
- to_remove = []
- for name, parser in self._name_parser_map.items():
- if parser is subparser:
- to_remove.append(name)
- for name in to_remove:
- del self._name_parser_map[name]
-
- if name in self.choices:
- del self.choices[name]
+ # Remove this subcommand and all its aliases from the base command
+ subparser = self._name_parser_map.get(name)
+ if subparser is not None:
+ to_remove = []
+ for cur_name, cur_parser in self._name_parser_map.items():
+ if cur_parser is subparser:
+ to_remove.append(cur_name)
+ for cur_name in to_remove:
+ del self._name_parser_map[cur_name]
# noinspection PyProtectedMember
@@ -733,6 +734,7 @@ class Cmd2HelpFormatter(argparse.RawTextHelpFormatter):
return ', '.join(action.option_strings) + ' ' + args_string
# End cmd2 customization
+ # noinspection PyMethodMayBeStatic
def _determine_metavar(self, action, default_metavar) -> Union[str, Tuple]:
"""Custom method to determine what to use as the metavar value of an action"""
if action.metavar is not None:
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index 8810025a..ea4e01de 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -692,6 +692,14 @@ class Cmd(cmd.Cmd):
for action in target_parser._actions:
if isinstance(action, argparse._SubParsersAction):
+ # Temporary workaround for avoiding subcommand help text repeatedly getting added to
+ # action._choices_actions. Until we have instance-specific parser objects, we will remove
+ # any existing subcommand which has the same name before replacing it. This problem is
+ # exercised when more than one cmd2.Cmd-based object is created and the same subcommands
+ # get added each time. Argparse overwrites the previous subcommand but keeps growing the help
+ # text which is shown by running something like 'alias -h'.
+ action.remove_parser(subcommand_name)
+
# Get the kwargs for add_parser()
add_parser_kwargs = getattr(method, constants.SUBCMD_ATTR_ADD_PARSER_KWARGS, {})