diff options
-rw-r--r-- | CHANGELOG.md | 3 | ||||
-rwxr-xr-x | cmd2/cmd2.py | 4 | ||||
-rwxr-xr-x | examples/dynamic_commands.py | 31 |
3 files changed, 37 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 2216d3a3..f6e14f11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,11 @@ * Fixed a bug when running a cmd2 application on Linux without Gtk libraries installed * Enhancements * No longer treating empty text scripts as an error condition + * Allow dynamically extending a `cmd2.Cmd` object instance with a `do_xxx` method at runtime * Choices/Completer functions can now be passed a dictionary that maps command-line tokens to their argparse argument. This is helpful when one argument determines what is tab completed for another argument. If these functions have an argument called `arg_tokens`, then AutoCompleter will automatically pass this - Namespace to them. + dictionary to them. ## 0.9.16 (August 7, 2019) * Bug Fixes diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index 2cc412a9..69de58b0 100755 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -1606,6 +1606,10 @@ class Cmd(cmd.Cmd): tokens_to_parse = raw_tokens if preserve_quotes else tokens return completer.complete_command(tokens_to_parse, text, line, begidx, endidx) + def get_names(self): + """Return an alphabetized list of names comprising the attributes of the cmd2 class instance.""" + return dir(self) + def get_all_commands(self) -> List[str]: """Return a list of all commands""" return [name[len(COMMAND_FUNC_PREFIX):] for name in self.get_names() diff --git a/examples/dynamic_commands.py b/examples/dynamic_commands.py new file mode 100755 index 00000000..69816d40 --- /dev/null +++ b/examples/dynamic_commands.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +# coding=utf-8 +"""A simple example demonstrating how do_* commands can be created in a loop. +""" +import functools +import cmd2 +COMMAND_LIST = ['foo', 'bar', 'baz'] + + +class CommandsInLoop(cmd2.Cmd): + """Example of dynamically adding do_* commands.""" + def __init__(self): + super().__init__(use_ipython=True) + + def send_text(self, args: cmd2.Statement, *, text: str): + """Simulate sending text to a server and printing the response.""" + self.poutput(text.capitalize()) + + def text_help(self, *, text: str): + """Deal with printing help for the dynamically added commands.""" + self.poutput("Simulate sending {!r} to a server and printing the response".format(text)) + + +for command in COMMAND_LIST: + setattr(CommandsInLoop, 'do_{}'.format(command), functools.partialmethod(CommandsInLoop.send_text, text=command)) + setattr(CommandsInLoop, 'help_{}'.format(command), functools.partialmethod(CommandsInLoop.text_help, text=command)) + + +if __name__ == '__main__': + app = CommandsInLoop() + app.cmdloop() |