summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Leonhardt <todd.leonhardt@gmail.com>2018-09-25 14:12:22 -0400
committerGitHub <noreply@github.com>2018-09-25 14:12:22 -0400
commit38aed327422e043370a92e82ed0e56381885f60e (patch)
tree88281b4a47a30cd584c9ce2d4e3429a611e0b549
parent79689b22b211f3387ee0475a448e2c6006978cff (diff)
parent38f070a5876e91945bfadd3fe60ddcb8b21b96c3 (diff)
downloadcmd2-git-38aed327422e043370a92e82ed0e56381885f60e.tar.gz
Merge branch 'master' into alert_printer
-rw-r--r--CHANGELOG.md5
-rw-r--r--cmd2/cmd2.py62
-rw-r--r--docs/hooks.rst51
-rw-r--r--docs/integrating.rst29
-rw-r--r--tests/test_cmd2.py7
-rw-r--r--tests/test_plugin.py5
6 files changed, 42 insertions, 117 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6bf3c961..c03a2323 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,11 @@
for formatting help/description text
* Aliases are now sorted alphabetically
* The **set** command now tab-completes settable parameter names
+* Deletions
+ * The ``preparse``, ``postparsing_precmd``, and ``postparsing_postcmd`` methods *deprecated* in the previous release
+ have been deleted
+ * The new application lifecycle hook system allows for registration of callbacks to be called at various points
+ in the lifecycle and is more powerful and flexible than the previous system
## 0.9.4 (August 21, 2018)
* Bug Fixes
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index ba8e47ed..72676deb 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -1649,58 +1649,6 @@ class Cmd(cmd.Cmd):
"""
return statement
- # ----- Methods which are cmd2-specific lifecycle hooks which are not present in cmd -----
-
- # noinspection PyMethodMayBeStatic
- def preparse(self, raw: str) -> str:
- """Hook method executed before user input is parsed.
-
- WARNING: If it's a multiline command, `preparse()` may not get all the
- user input. _complete_statement() really does two things: a) parse the
- user input, and b) accept more input in case it's a multiline command
- the passed string doesn't have a terminator. `preparse()` is currently
- called before we know whether it's a multiline command, and before we
- know whether the user input includes a termination character.
-
- If you want a reliable pre parsing hook method, register a postparsing
- hook, modify the user input, and then reparse it.
-
- :param raw: raw command line input :return: potentially modified raw command line input
- :return: a potentially modified version of the raw input string
- """
- return raw
-
- # noinspection PyMethodMayBeStatic
- def postparsing_precmd(self, statement: Statement) -> Tuple[bool, Statement]:
- """This runs after parsing the command-line, but before anything else; even before adding cmd to history.
-
- NOTE: This runs before precmd() and prior to any potential output redirection or piping.
-
- If you wish to fatally fail this command and exit the application entirely, set stop = True.
-
- If you wish to just fail this command you can do so by raising an exception:
-
- - raise EmptyStatement - will silently fail and do nothing
- - raise <AnyOtherException> - will fail and print an error message
-
- :param statement: the parsed command-line statement as a Statement object
- :return: (stop, statement) containing a potentially modified version of the statement object
- """
- stop = False
- return stop, statement
-
- # noinspection PyMethodMayBeStatic
- def postparsing_postcmd(self, stop: bool) -> bool:
- """This runs after everything else, including after postcmd().
-
- It even runs when an empty line is entered. Thus, if you need to do something like update the prompt due
- to notifications from a background thread, then this is the method you want to override to do it.
-
- :param stop: True implies the entire application should exit.
- :return: True implies the entire application should exit.
- """
- return stop
-
def parseline(self, line: str) -> Tuple[str, str, str]:
"""Parse the line into a command name and a string containing the arguments.
@@ -1740,9 +1688,6 @@ class Cmd(cmd.Cmd):
data = func(data)
if data.stop:
break
- # postparsing_precmd is deprecated
- if not data.stop:
- (data.stop, data.statement) = self.postparsing_precmd(data.statement)
# unpack the data object
statement = data.statement
stop = data.stop
@@ -1807,9 +1752,7 @@ class Cmd(cmd.Cmd):
data = func(data)
# retrieve the final value of stop, ignoring any
# modifications to the statement
- stop = data.stop
- # postparsing_postcmd is deprecated
- return self.postparsing_postcmd(stop)
+ return data.stop
except Exception as ex:
self.perror(ex)
@@ -1863,9 +1806,6 @@ class Cmd(cmd.Cmd):
pipe runs out. We can't refactor it because we need to retain
backwards compatibility with the standard library version of cmd.
"""
- # preparse() is deprecated, use self.register_postparsing_hook() instead
- line = self.preparse(line)
-
while True:
try:
statement = self.statement_parser.parse(line)
diff --git a/docs/hooks.rst b/docs/hooks.rst
index 2a5d7b5f..1696d365 100644
--- a/docs/hooks.rst
+++ b/docs/hooks.rst
@@ -76,24 +76,21 @@ Command Processing Loop
When you call `.cmdloop()`, the following sequence of events are repeated until
the application exits:
-1. Output the prompt
-2. Accept user input
-3. Call `preparse()` - for backwards compatibility with prior releases of cmd2, now deprecated
-4. Parse user input into `Statement` object
-5. Call methods registered with `register_postparsing_hook()`
-6. Call `postparsing_precmd()` - for backwards compatibility with prior releases of cmd2, now deprecated
-7. Redirect output, if user asked for it and it's allowed
-8. Start timer
-9. Call methods registered with `register_precmd_hook()`
-10. Call `precmd()` - for backwards compatibility with ``cmd.Cmd``
-11. Add statement to history
-12. Call `do_command` method
-13. Call methods registered with `register_postcmd_hook()`
-14. Call `postcmd(stop, statement)` - for backwards compatibility with ``cmd.Cmd``
-15. Stop timer and display the elapsed time
-16. Stop redirecting output if it was redirected
-17. Call methods registered with `register_cmdfinalization_hook()`
-18. Call `postparsing_postcmd()` - for backwards compatibility - deprecated
+#. Output the prompt
+#. Accept user input
+#. Parse user input into `Statement` object
+#. Call methods registered with `register_postparsing_hook()`
+#. Redirect output, if user asked for it and it's allowed
+#. Start timer
+#. Call methods registered with `register_precmd_hook()`
+#. Call `precmd()` - for backwards compatibility with ``cmd.Cmd``
+#. Add statement to history
+#. Call `do_command` method
+#. Call methods registered with `register_postcmd_hook()`
+#. Call `postcmd(stop, statement)` - for backwards compatibility with ``cmd.Cmd``
+#. Stop timer and display the elapsed time
+#. Stop redirecting output if it was redirected
+#. Call methods registered with `register_cmdfinalization_hook()`
By registering hook methods, steps 4, 8, 12, and 16 allow you to run code
during, and control the flow of the command processing loop. Be aware that
@@ -305,21 +302,3 @@ If any command finalization hook raises an exception, no more command
finalization hooks will be called. If the last hook to return a value returned
``True``, then the exception will be rendered, and the application will
terminate.
-
-Deprecated Command Processing Hooks
------------------------------------
-
-Inside the main loop, every time the user hits <Enter> the line is processed by the ``onecmd_plus_hooks`` method.
-
-.. automethod:: cmd2.cmd2.Cmd.onecmd_plus_hooks
-
-As the ``onecmd_plus_hooks`` name implies, there are a number of *hook* methods that can be defined in order to inject
-application-specific behavior at various points during the processing of a line of text entered by the user. ``cmd2``
-increases the 2 hooks provided by ``cmd`` (**precmd** and **postcmd**) to 6 for greater flexibility. Here are
-the various hook methods, presented in chronological order starting with the ones called earliest in the process.
-
-.. automethod:: cmd2.cmd2.Cmd.preparse
-
-.. automethod:: cmd2.cmd2.Cmd.postparsing_precmd
-
-.. automethod:: cmd2.cmd2.Cmd.postparsing_postcmd
diff --git a/docs/integrating.rst b/docs/integrating.rst
index 8f605e06..a8377fdb 100644
--- a/docs/integrating.rst
+++ b/docs/integrating.rst
@@ -135,22 +135,19 @@ 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
+#. Parse user input into `Statement` object
+#. Call methods registered with `register_postparsing_hook()`
+#. Redirect output, if user asked for it and it's allowed
+#. Start timer
+#. Call methods registered with `register_precmd_hook()`
+#. Call `precmd()` - for backwards compatibility with ``cmd.Cmd``
+#. Add statement to history
+#. Call `do_command` method
+#. Call methods registered with `register_postcmd_hook()`
+#. Call `postcmd(stop, statement)` - for backwards compatibility with ``cmd.Cmd``
+#. Stop timer and display the elapsed time
+#. Stop redirecting output if it was redirected
+#. Call methods registered with `register_cmdfinalization_hook()`
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
diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py
index 10c60d71..f3ec29dc 100644
--- a/tests/test_cmd2.py
+++ b/tests/test_cmd2.py
@@ -993,10 +993,13 @@ def test_cmdloop_without_rawinput():
class HookFailureApp(cmd2.Cmd):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
+ # register a postparsing hook method
+ self.register_postparsing_hook(self.postparsing_precmd)
- def postparsing_precmd(self, statement):
+ def postparsing_precmd(self, data: cmd2.plugin.PostparsingData) -> cmd2.plugin.PostparsingData:
"""Simulate precmd hook failure."""
- return True, statement
+ data.stop = True
+ return data
@pytest.fixture
def hook_failure():
diff --git a/tests/test_plugin.py b/tests/test_plugin.py
index 20f2f32c..81dd7683 100644
--- a/tests/test_plugin.py
+++ b/tests/test_plugin.py
@@ -51,10 +51,10 @@ class Plugin:
# preparse hook
#
###
- def preparse(self, line: str) -> str:
+ def preparse(self, data: cmd2.plugin.PostparsingData) -> cmd2.plugin.PostparsingData:
"""Preparsing hook"""
self.called_preparse += 1
- return line
+ return data
###
#
@@ -322,6 +322,7 @@ def test_postloop_hooks(capsys):
###
def test_preparse(capsys):
app = PluggedApp()
+ app.register_postparsing_hook(app.preparse)
app.onecmd_plus_hooks('say hello')
out, err = capsys.readouterr()
assert out == 'hello\n'