@@ -875,7 +875,8 @@ def unregister_command_set(self, cmdset: CommandSet) -> None:
875875 if command in self ._cmd_to_command_sets :
876876 del self ._cmd_to_command_sets [command ]
877877
878- # A command synonym does not own the parser.
878+ # Only remove the parser if this is the actual
879+ # command since command synonyms don't own it.
879880 if cmd_func_name == command_method .__name__ :
880881 self ._command_parsers .remove (command_method )
881882
@@ -890,6 +891,18 @@ def unregister_command_set(self, cmdset: CommandSet) -> None:
890891 self ._installed_command_sets .remove (cmdset )
891892
892893 def _check_uninstallable (self , cmdset : CommandSet ) -> None :
894+ def check_parser_uninstallable (parser : argparse .ArgumentParser ) -> None :
895+ for action in parser ._actions :
896+ if isinstance (action , argparse ._SubParsersAction ):
897+ for subparser in action .choices .values ():
898+ attached_cmdset = getattr (subparser , constants .PARSER_ATTR_COMMANDSET , None )
899+ if attached_cmdset is not None and attached_cmdset is not cmdset :
900+ raise CommandSetRegistrationError (
901+ 'Cannot uninstall CommandSet when another CommandSet depends on it'
902+ )
903+ check_parser_uninstallable (subparser )
904+ break
905+
893906 methods : List [Tuple [str , Callable [..., Any ]]] = inspect .getmembers (
894907 cmdset ,
895908 predicate = lambda meth : isinstance (meth , Callable ) # type: ignore[arg-type]
@@ -898,26 +911,12 @@ def _check_uninstallable(self, cmdset: CommandSet) -> None:
898911 )
899912
900913 for cmd_func_name , command_method in methods :
901- # Do nothing if this is a command synonym since it does not own the parser.
902- if cmd_func_name != command_method .__name__ :
903- continue
904-
905- command_parser = self ._command_parsers .get (command_method )
906-
907- def check_parser_uninstallable (parser : argparse .ArgumentParser ) -> None :
908- for action in parser ._actions :
909- if isinstance (action , argparse ._SubParsersAction ):
910- for subparser in action .choices .values ():
911- attached_cmdset = getattr (subparser , constants .PARSER_ATTR_COMMANDSET , None )
912- if attached_cmdset is not None and attached_cmdset is not cmdset :
913- raise CommandSetRegistrationError (
914- 'Cannot uninstall CommandSet when another CommandSet depends on it'
915- )
916- check_parser_uninstallable (subparser )
917- break
918-
919- if command_parser is not None :
920- check_parser_uninstallable (command_parser )
914+ # We only need to check if it's safe to remove the parser if this
915+ # is the actual command since command synonyms don't own it.
916+ if cmd_func_name == command_method .__name__ :
917+ command_parser = self ._command_parsers .get (command_method )
918+ if command_parser is not None :
919+ check_parser_uninstallable (command_parser )
921920
922921 def _register_subcommands (self , cmdset : Union [CommandSet , 'Cmd' ]) -> None :
923922 """
0 commit comments