@@ -252,13 +252,13 @@ def get_choices(self) -> Choices:
252252cmd2 has patched ``argparse._SubParsersAction`` with new functions to better facilitate the
253253addition and removal of subcommand parsers.
254254
255- ``argparse._SubParsersAction.remove_parser`` - new function which removes a
256- sub-parser from a sub-parsers group. See ``_SubParsersAction_remove_parser`` for
257- more details.
258-
259- ``argparse._SubParsersAction.add_existing_parser`` - new function which allows you to attach
260- an existing ArgumentParser to a sub-parsers group. See ``_SubParsersAction_add_existing_parser``
255+ ``argparse._SubParsersAction.attach_parser`` - new function to attach
256+ an existing ArgumentParser to a subparsers action. See ``_SubParsersAction_attach_parser``
261257for more details.
258+
259+ ``argparse._SubParsersAction.detach_parser`` - new function to detach a
260+ parser from a subparsers action. See ``_SubParsersAction_detach_parser`` for
261+ more details.
262262"""
263263
264264import argparse
@@ -945,62 +945,25 @@ def _ArgumentParser_check_value(_self: argparse.ArgumentParser, action: argparse
945945
946946
947947############################################################################################################
948- # Patch argparse._SubParsersAction to add remove_parser function
949- ############################################################################################################
950-
951-
952- def _SubParsersAction_remove_parser ( # noqa: N802
953- self : argparse ._SubParsersAction , # type: ignore[type-arg]
954- name : str ,
955- ) -> None :
956- """Remove a sub-parser from a sub-parsers group. Used to remove subcommands from a parser.
957-
958- This function is added by cmd2 as a method called ``remove_parser()`` to ``argparse._SubParsersAction`` class.
959-
960- To call: ``action.remove_parser(name)``
961-
962- :param self: instance of the _SubParsersAction being edited
963- :param name: name of the subcommand for the sub-parser to remove
964- """
965- # Remove this subcommand from its base command's help text
966- for choice_action in self ._choices_actions :
967- if choice_action .dest == name :
968- self ._choices_actions .remove (choice_action )
969- break
970-
971- # Remove this subcommand and all its aliases from the base command
972- subparser = self ._name_parser_map .get (name )
973- if subparser is not None :
974- to_remove = []
975- for cur_name , cur_parser in self ._name_parser_map .items ():
976- if cur_parser is subparser :
977- to_remove .append (cur_name )
978- for cur_name in to_remove :
979- del self ._name_parser_map [cur_name ]
980-
981-
982- setattr (argparse ._SubParsersAction , 'remove_parser' , _SubParsersAction_remove_parser )
983-
984- ############################################################################################################
985- # Patch argparse._SubParsersAction to add add_existing_parser function
948+ # Patch argparse._SubParsersAction to add attach_parser function
986949############################################################################################################
987950
988951
989- def _SubParsersAction_add_existing_parser ( # noqa: N802
952+ def _SubParsersAction_attach_parser ( # noqa: N802
990953 self : argparse ._SubParsersAction , # type: ignore[type-arg]
991954 name : str ,
992955 subcmd_parser : argparse .ArgumentParser ,
993956 ** add_parser_kwargs : Any ,
994957) -> None :
995- """Attach an existing ArgumentParser to a sub-parsers group .
958+ """Attach an existing ArgumentParser to a subparsers action .
996959
997960 This is useful when a parser is pre-configured (e.g. by cmd2's subcommand decorator)
998961 and needs to be attached to a parent parser.
999962
1000- This function is added by cmd2 as a method called ``add_existing_parser ()``
963+ This function is added by cmd2 as a method called ``attach_parser ()``
1001964 to ``argparse._SubParsersAction`` class.
1002965
1003- To call: ``action.add_existing_parser (name, subcmd_parser, **add_parser_kwargs)``
966+ To call: ``action.attach_parser (name, subcmd_parser, **add_parser_kwargs)``
1004967
1005968 :param self: instance of the _SubParsersAction being edited
1006969 :param name: name of the subcommand to add
@@ -1019,7 +982,48 @@ def _SubParsersAction_add_existing_parser( # noqa: N802
1019982 self ._name_parser_map [alias ] = subcmd_parser
1020983
1021984
1022- setattr (argparse ._SubParsersAction , 'add_existing_parser' , _SubParsersAction_add_existing_parser )
985+ setattr (argparse ._SubParsersAction , 'attach_parser' , _SubParsersAction_attach_parser )
986+
987+ ############################################################################################################
988+ # Patch argparse._SubParsersAction to add detach_parser function
989+ ############################################################################################################
990+
991+
992+ def _SubParsersAction_detach_parser ( # noqa: N802
993+ self : argparse ._SubParsersAction , # type: ignore[type-arg]
994+ name : str ,
995+ ) -> argparse .ArgumentParser | None :
996+ """Detach a parser from a subparsers action and return it.
997+
998+ This function is added by cmd2 as a method called ``detach_parser()`` to ``argparse._SubParsersAction`` class.
999+
1000+ To call: ``action.detach_parser(name)``
1001+
1002+ :param self: instance of the _SubParsersAction being edited
1003+ :param name: name of the subcommand for the parser to detach
1004+ :return: the parser which was detached or None if the subcommand doesn't exist
1005+ """
1006+ subparser = self ._name_parser_map .get (name )
1007+
1008+ if subparser is not None :
1009+ # Remove this subcommand and all its aliases from the base command
1010+ to_remove = []
1011+ for cur_name , cur_parser in self ._name_parser_map .items ():
1012+ if cur_parser is subparser :
1013+ to_remove .append (cur_name )
1014+ for cur_name in to_remove :
1015+ del self ._name_parser_map [cur_name ]
1016+
1017+ # Remove this subcommand from its base command's help text
1018+ for choice_action in self ._choices_actions :
1019+ if choice_action .dest == name :
1020+ self ._choices_actions .remove (choice_action )
1021+ break
1022+
1023+ return subparser
1024+
1025+
1026+ setattr (argparse ._SubParsersAction , 'detach_parser' , _SubParsersAction_detach_parser )
10231027
10241028############################################################################################################
10251029# Unless otherwise noted, everything below this point are copied from Python's
0 commit comments