From dac009f17c58df4b8d4dbcd3c621bf6ef2481a96 Mon Sep 17 00:00:00 2001 From: Eric Lin Date: Thu, 30 Jul 2020 01:32:29 -0400 Subject: Removed sub-class and instead patch argparse._SubParsersAction --- cmd2/argparse_custom.py | 50 +++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) (limited to 'cmd2/argparse_custom.py') diff --git a/cmd2/argparse_custom.py b/cmd2/argparse_custom.py index 9dde5347..6cfa66ae 100644 --- a/cmd2/argparse_custom.py +++ b/cmd2/argparse_custom.py @@ -528,6 +528,31 @@ def _match_argument_wrapper(self, action, arg_strings_pattern) -> int: # noinspection PyProtectedMember argparse.ArgumentParser._match_argument = _match_argument_wrapper + +############################################################################################################ +# Patch argparse._SubParsersAction to add remove_parser function +############################################################################################################ + +def _SubParsersAction_remove_parser(self, name): + """Removes a sub-parser from the sub-parsers group""" + 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] + + +# noinspection PyProtectedMember +setattr(argparse._SubParsersAction, 'remove_parser', _SubParsersAction_remove_parser) + + ############################################################################################################ # Unless otherwise noted, everything below this point are copied from Python's # argparse implementation with minor tweaks to adjust output. @@ -724,24 +749,6 @@ class Cmd2HelpFormatter(argparse.RawTextHelpFormatter): return result -class _UnloadableSubParsersAction(argparse._SubParsersAction): - """Extends the argparse internal SubParsers action to allow sub-parsers to be removed dynamically""" - def remove_parser(self, name): - """Removes a sub-parser from the sub-parsers group""" - 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] - - # noinspection PyCompatibility class Cmd2ArgumentParser(argparse.ArgumentParser): """Custom ArgumentParser class that improves error and help output""" @@ -772,22 +779,17 @@ class Cmd2ArgumentParser(argparse.ArgumentParser): conflict_handler=conflict_handler, add_help=add_help, allow_abbrev=allow_abbrev) - self.register('action', 'unloadable_parsers', _UnloadableSubParsersAction) - def add_subparsers(self, unloadable: bool = False, **kwargs): + def add_subparsers(self, **kwargs): """ Custom override. Sets a default title if one was not given. - :param unloadable: Flag whether this sub-parsers group will support unloading parsers :param kwargs: additional keyword arguments :return: argparse Subparser Action """ if 'title' not in kwargs: kwargs['title'] = 'subcommands' - if unloadable: - kwargs['action'] = 'unloadable_parsers' - return super().add_subparsers(**kwargs) def error(self, message: str) -> None: -- cgit v1.2.1