summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd2/cmd2.py84
1 files changed, 46 insertions, 38 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index 7cfd31c7..12a53f34 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -122,6 +122,9 @@ except ImportError: # pragma: no cover
HELP_CATEGORY = 'help_category'
HELP_SUMMARY = 'help_summary'
+# All command functions start with this
+COMMAND_PREFIX = 'do_'
+
def categorize(func: Union[Callable, Iterable], category: str) -> None:
"""Categorize a function.
@@ -400,7 +403,7 @@ class Cmd(cmd.Cmd):
self.pystate = {}
self.py_history = []
self.pyscript_name = 'app'
- self.keywords = self.reserved_words + [fname[3:] for fname in dir(self) if fname.startswith('do_')]
+ self.keywords = self.reserved_words + self.get_all_commands()
self.statement_parser = StatementParser(
allow_redirection=self.allow_redirection,
terminators=self.terminators,
@@ -1471,16 +1474,15 @@ class Cmd(cmd.Cmd):
# Check if a valid command was entered
if command in self.get_all_commands():
# Get the completer function for this command
- try:
- compfunc = getattr(self, 'complete_' + command)
- except AttributeError:
+ compfunc = getattr(self, 'complete_' + command, None)
+
+ if compfunc is None:
# There's no completer function, next see if the command uses argparser
- try:
- cmd_func = getattr(self, 'do_' + command)
- argparser = getattr(cmd_func, 'argparser')
- # Command uses argparser, switch to the default argparse completer
- compfunc = functools.partial(self._autocomplete_default, argparser=argparser)
- except AttributeError:
+ cmd_func = self._cmd_func(command)
+ if cmd_func and hasattr(cmd_func, 'argparser'):
+ compfunc = functools.partial(self._autocomplete_default,
+ argparser=getattr(cmd_func, 'argparser'))
+ else:
compfunc = self.completedefault
# Check if a macro was entered
@@ -1596,8 +1598,8 @@ class Cmd(cmd.Cmd):
def get_all_commands(self) -> List[str]:
"""Returns a list of all commands."""
- return [name[3:] for name in self.get_names()
- if name.startswith('do_') and callable(getattr(self, name))]
+ return [name[len(COMMAND_PREFIX):] for name in self.get_names()
+ if name.startswith(COMMAND_PREFIX) and callable(getattr(self, name))]
def get_visible_commands(self) -> List[str]:
"""Returns a list of commands that have not been hidden."""
@@ -1663,13 +1665,10 @@ class Cmd(cmd.Cmd):
# check if the command uses argparser
elif index >= subcmd_index:
- try:
- cmd_func = getattr(self, 'do_' + tokens[cmd_index])
- parser = getattr(cmd_func, 'argparser')
- completer = AutoCompleter(parser, cmd2_app=self)
+ cmd_func = self._cmd_func(tokens[cmd_index])
+ if cmd_func and hasattr(cmd_func, 'argparser'):
+ completer = AutoCompleter(getattr(cmd_func, 'argparser'), cmd2_app=self)
matches = completer.complete_command_help(tokens[1:], text, line, begidx, endidx)
- except AttributeError:
- pass
return matches
@@ -2003,13 +2002,23 @@ class Cmd(cmd.Cmd):
self.redirecting = False
- def _func_named(self, arg: str) -> str:
- """Gets the method name associated with a given command.
+ def _cmd_func(self, command: str) -> Optional[Callable]:
+ """
+ Get the function for a command
+ :param arg: the name of the command
+ """
+ func_name = self._cmd_func_name(command)
+ if func_name:
+ return getattr(self, func_name)
+ return None
+
+ def _cmd_func_name(self, command: str) -> str:
+ """Get the method name associated with a given command.
:param arg: command to look up method name which implements it
:return: method name which implements the given command
"""
- target = 'do_' + arg
+ target = COMMAND_PREFIX + command
return target if callable(getattr(self, target, None)) else ''
def onecmd(self, statement: Union[Statement, str]) -> bool:
@@ -2029,10 +2038,9 @@ class Cmd(cmd.Cmd):
if statement.command in self.macros:
stop = self._run_macro(statement)
else:
- funcname = self._func_named(statement.command)
- if funcname:
- func = getattr(self, funcname)
- stop = func(statement)
+ cmd_func = self._cmd_func(statement.command)
+ if cmd_func:
+ stop = cmd_func(statement)
# Since we have a valid command store it in the history
if statement.command not in self.exclude_from_history:
@@ -2588,20 +2596,18 @@ class Cmd(cmd.Cmd):
self._help_menu(verbose)
else:
# Getting help for a specific command
- funcname = self._func_named(arglist[0])
- if funcname:
+ cmd_func = self._cmd_func(arglist[0])
+ if cmd_func:
# Check to see if this function was decorated with an argparse ArgumentParser
- func = getattr(self, funcname)
- if hasattr(func, 'argparser'):
- completer = AutoCompleter(getattr(func, 'argparser'), cmd2_app=self)
-
+ if hasattr(cmd_func, 'argparser'):
+ completer = AutoCompleter(getattr(cmd_func, 'argparser'), cmd2_app=self)
self.poutput(completer.format_help(arglist))
else:
# No special behavior needed, delegate to cmd base class do_help()
- cmd.Cmd.do_help(self, funcname[3:])
+ super().do_help(arglist[0])
else:
# This could be a help topic
- cmd.Cmd.do_help(self, arglist[0])
+ super().do_help(arglist[0])
def _help_menu(self, verbose: bool=False) -> None:
"""Show a list of commands which help can be displayed for.
@@ -2617,11 +2623,12 @@ class Cmd(cmd.Cmd):
cmds_cats = {}
for command in visible_commands:
- if command in help_topics or getattr(self, self._func_named(command)).__doc__:
+ cmd_func = self._cmd_func(command)
+ if command in help_topics or cmd_func.__doc__:
if command in help_topics:
help_topics.remove(command)
- if hasattr(getattr(self, self._func_named(command)), HELP_CATEGORY):
- category = getattr(getattr(self, self._func_named(command)), HELP_CATEGORY)
+ if hasattr(cmd_func, HELP_CATEGORY):
+ category = getattr(cmd_func, HELP_CATEGORY)
cmds_cats.setdefault(category, [])
cmds_cats[category].append(command)
else:
@@ -2674,12 +2681,13 @@ class Cmd(cmd.Cmd):
func = getattr(self, 'help_' + command)
except AttributeError:
# Couldn't find a help function
+ cmd_func = self._cmd_func(command)
try:
# Now see if help_summary has been set
- doc = getattr(self, self._func_named(command)).help_summary
+ doc = cmd_func.help_summary
except AttributeError:
# Last, try to directly access the function's doc-string
- doc = getattr(self, self._func_named(command)).__doc__
+ doc = cmd_func.__doc__
else:
# we found the help function
result = io.StringIO()