blob: a234173c881e895703f7a930be7aacb7e3612242 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
.. cmd2 documentation for integration with other tools
Integrating cmd2 with external tools
====================================
Throughout this documentation we have focused on the **90%** use case, that is the use case we believe around 90+% of
our user base is looking for. This focuses on ease of use and the best out-of-the-box experience where developers get
the most functionality for the least amount of effort. We are talking about running cmd2 applications with the
``cmdloop()`` method::
from cmd2 import Cmd
class App(Cmd):
# customized attributes and methods here
app = App()
app.cmdloop()
However, there are some limitations to this way of using
``cmd2``, mainly that ``cmd2`` owns the inner loop of a program. This can be unnecessarily restrictive and can prevent
using libraries which depend on controlling their own event loop.
Integrating cmd2 with event loops
---------------------------------
Many Python concurrency libraries involve or require an event loop which they are in control of such as asyncio_,
gevent_, Twisted_, etc.
.. _asyncio: https://docs.python.org/3/library/asyncio.html
.. _gevent: http://www.gevent.org/
.. _Twisted: https://twistedmatrix.com
``cmd2`` applications can be executed in a fashion where ``cmd2`` doesn't own the main loop for the program by using
code like the following::
import cmd2
class Cmd2EventBased(cmd2.Cmd):
def __init__(self):
cmd2.Cmd.__init__(self)
# ... your class code here ...
if __name__ == '__main__':
app = Cmd2EventBased()
app.preloop()
# Do this within whatever event loop mechanism you wish to run a single command
cmd_line_text = "help history"
app.runcmds_plus_hooks([cmd_line_text])
app.postloop()
The **runcmds_plus_hooks()** method is a convenience method to run multiple commands via **onecmd_plus_hooks()**. It
properly deals with ``load`` commands which under the hood put commands in a FIFO queue as it reads them in from a
script file.
The **onecmd_plus_hooks()** method will do the following to execute a single ``cmd2`` command in a normal fashion:
1. Call `preparse()` - for backwards compatibility with prior releases of cmd2, now deprecated
2. Parse user input into `Statement` object
3. Call methods registered with `register_postparsing_hook()`
4. Call `postparsing_precmd()` - for backwards compatibility with prior releases of cmd2, now deprecated
5. Redirect output, if user asked for it and it's allowed
6. Start timer
7. Call methods registered with `register_precmd_hook()`
8. Call `precmd()` - for backwards compatibility with ``cmd.Cmd``
9. Add statement to history
10. Call `do_command` method
11. Call methods registered with `register_postcmd_hook()`
12. Call `postcmd(stop, statement)` - for backwards compatibility with ``cmd.Cmd``
13. Stop timer and display the elapsed time
14. Stop redirecting output if it was redirected
15. Call methods registered with `register_cmdfinalization_hook()`
16. Call `postparsing_postcmd()` - for backwards compatibility - deprecated
Running in this fashion enables the ability to integrate with an external event loop. However, how to integrate with
any specific event loop is beyond the scope of this documentation. Please note that running in this fashion comes with
several disadvantages, including:
* Requires the developer to write more code
* Does not support transcript testing
* Does not allow commands at invocation via command-line arguments
Here is a little more info on ``runcmds_plus_hooks``:
.. automethod:: cmd2.cmd2.Cmd.runcmds_plus_hooks
|