summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md3
-rwxr-xr-xcmd2/cmd2.py4
-rwxr-xr-xexamples/dynamic_commands.py31
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()