@@ -344,9 +344,6 @@ class Cmd:
344344 # Header for table listing help topics not related to a command.
345345 MISC_HEADER : ClassVar [str ] = "Miscellaneous Help Topics"
346346
347- # Header for table listing commands that have no help info.
348- UNDOC_HEADER : ClassVar [str ] = "Undocumented Commands"
349-
350347 def __init__ (
351348 self ,
352349 completekey : str | None = None ,
@@ -868,7 +865,7 @@ def register_command_set(self, cmdset: CommandSet) -> None:
868865 self ._cmd_to_command_sets [command ] = cmdset
869866
870867 # If this command is in a disabled category, then disable it
871- command_category = getattr (command_method , constants . CMD_ATTR_HELP_CATEGORY , None )
868+ command_category = self . _get_command_category (command_method )
872869 if command_category in self .disabled_categories :
873870 message_to_print = self .disabled_categories [command_category ]
874871 self .disable_command (command , message_to_print )
@@ -3338,6 +3335,23 @@ def cmd_func(self, command: str) -> CommandFunc | None:
33383335 func = getattr (self , func_name , None )
33393336 return cast (CommandFunc , func ) if callable (func ) else None
33403337
3338+ def _get_command_category (self , func : CommandFunc ) -> str :
3339+ """Determine the category for a command.
3340+
3341+ :param func: the do_* function implementing the command
3342+ :return: category name
3343+ """
3344+ # Check if the command function has a category.
3345+ if hasattr (func , constants .CMD_ATTR_HELP_CATEGORY ):
3346+ category : str = getattr (func , constants .CMD_ATTR_HELP_CATEGORY )
3347+
3348+ # Otherwise get the category from its defining class.
3349+ else :
3350+ defining_cls = get_defining_class (func )
3351+ category = getattr (defining_cls , 'DEFAULT_CATEGORY' , self .DEFAULT_CATEGORY )
3352+
3353+ return category
3354+
33413355 def onecmd (self , statement : Statement | str , * , add_to_history : bool = True ) -> bool :
33423356 """Execute the actual do_* method for a command.
33433357
@@ -4214,12 +4228,11 @@ def complete_help_subcommands(
42144228 completer = argparse_completer .DEFAULT_AP_COMPLETER (argparser , self )
42154229 return completer .complete_subcommand_help (text , line , begidx , endidx , arg_tokens ['subcommands' ])
42164230
4217- def _build_command_info (self ) -> tuple [dict [str , list [str ]], list [str ], list [ str ] ]:
4231+ def _build_command_info (self ) -> tuple [dict [str , list [str ]], list [str ]]:
42184232 """Categorizes and sorts visible commands and help topics for display.
42194233
42204234 :return: tuple containing:
42214235 - dictionary mapping category names to lists of command names
4222- - list of undocumented command names
42234236 - list of help topic names that are not also commands
42244237 """
42254238 # Get a sorted list of help topics
@@ -4228,36 +4241,18 @@ def _build_command_info(self) -> tuple[dict[str, list[str]], list[str], list[str
42284241 # Get a sorted list of visible command names
42294242 visible_commands = sorted (self .get_visible_commands (), key = utils .DEFAULT_STR_SORT_KEY )
42304243 cmds_cats : dict [str , list [str ]] = {}
4231- cmds_undoc : list [str ] = []
42324244
42334245 for command in visible_commands :
4234- func = cast (CommandFunc , self .cmd_func (command ))
4235- has_help_func = False
4236- has_parser = func in self ._command_parsers
4237-
4246+ # Prevent the command from showing as both a command and help topic in the output
42384247 if command in help_topics :
4239- # Prevent the command from showing as both a command and help topic in the output
42404248 help_topics .remove (command )
42414249
4242- # Non-argparse commands can have help_functions for their documentation
4243- has_help_func = not has_parser
4244-
4245- # Determine the category
4246- category : str | None = None
4247-
4248- if hasattr (func , constants .CMD_ATTR_HELP_CATEGORY ):
4249- category = getattr (func , constants .CMD_ATTR_HELP_CATEGORY )
4250- elif func .__doc__ or has_help_func or has_parser :
4251- defining_cls = get_defining_class (func )
4252- category = getattr (defining_cls , 'DEFAULT_CATEGORY' , self .DEFAULT_CATEGORY )
4253-
4254- # Store the command
4255- if category is not None :
4256- cmds_cats .setdefault (category , []).append (command )
4257- else :
4258- cmds_undoc .append (command )
4250+ # Store the command within its category
4251+ func = cast (CommandFunc , self .cmd_func (command ))
4252+ category = self ._get_command_category (func )
4253+ cmds_cats .setdefault (category , []).append (command )
42594254
4260- return cmds_cats , cmds_undoc , help_topics
4255+ return cmds_cats , help_topics
42614256
42624257 @classmethod
42634258 def _build_help_parser (cls ) -> Cmd2ArgumentParser :
@@ -4290,7 +4285,7 @@ def do_help(self, args: argparse.Namespace) -> None:
42904285 self .last_result = True
42914286
42924287 if not args .command or args .verbose :
4293- cmds_cats , cmds_undoc , help_topics = self ._build_command_info ()
4288+ cmds_cats , help_topics = self ._build_command_info ()
42944289
42954290 if self .doc_leader :
42964291 self .poutput ()
@@ -4311,11 +4306,10 @@ def do_help(self, args: argparse.Namespace) -> None:
43114306 self ._print_documented_command_topics (category , commands , args .verbose )
43124307 previous_table_printed = bool (commands ) and args .verbose
43134308
4314- if previous_table_printed and ( help_topics or cmds_undoc ) :
4309+ if previous_table_printed and help_topics :
43154310 self .poutput ()
43164311
43174312 self .print_topics (self .MISC_HEADER , help_topics , 15 , 80 )
4318- self .print_topics (self .UNDOC_HEADER , cmds_undoc , 15 , 80 )
43194313
43204314 else :
43214315 # Getting help for a specific command
@@ -5622,7 +5616,7 @@ def enable_category(self, category: str) -> None:
56225616
56235617 for cmd_name in list (self .disabled_commands ):
56245618 func = self .disabled_commands [cmd_name ].command_function
5625- if getattr (func , constants . CMD_ATTR_HELP_CATEGORY , None ) == category :
5619+ if self . _get_command_category (func ) == category :
56265620 self .enable_command (cmd_name )
56275621
56285622 del self .disabled_categories [category ]
@@ -5683,8 +5677,8 @@ def disable_category(self, category: str, message_to_print: str) -> None:
56835677 all_commands = self .get_all_commands ()
56845678
56855679 for cmd_name in all_commands :
5686- func = self .cmd_func (cmd_name )
5687- if getattr (func , constants . CMD_ATTR_HELP_CATEGORY , None ) == category :
5680+ func = cast ( CommandFunc , self .cmd_func (cmd_name ) )
5681+ if self . _get_command_category (func ) == category :
56885682 self .disable_command (cmd_name , message_to_print )
56895683
56905684 self .disabled_categories [category ] = message_to_print
0 commit comments