diff options
author | Kevin Van Brunt <kmvanbrunt@gmail.com> | 2019-06-07 16:15:12 -0400 |
---|---|---|
committer | Kevin Van Brunt <kmvanbrunt@gmail.com> | 2019-06-07 16:15:12 -0400 |
commit | ab1ae68d2747b82812b03edbbccfbca39cf1c638 (patch) | |
tree | 812e74a9b465da44f15eee0e211d0baf7f4b209b | |
parent | ee699c35159a621e59bf8205c555d0fbf8aa3734 (diff) | |
download | cmd2-git-ab1ae68d2747b82812b03edbbccfbca39cf1c638.tar.gz |
Removed self._should_quit from cmd2 and add logic to PyscriptBridge to return whether a command returned True for stop.
Added stop to CommandResult so pyscripts can now know the return value of a command's do_* function.
-rw-r--r-- | cmd2/cmd2.py | 9 | ||||
-rw-r--r-- | cmd2/pyscript_bridge.py | 24 | ||||
-rw-r--r-- | tests/test_cmd2.py | 1 |
3 files changed, 19 insertions, 15 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index 65574095..29f34175 100644 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -425,9 +425,6 @@ class Cmd(cmd.Cmd): shortcuts=shortcuts) self._transcript_files = transcript_files - # Used to enable the ability for a Python script to quit the application - self._should_quit = False - # True if running inside a Python script or interactive console, False otherwise self._in_py = False @@ -2836,7 +2833,6 @@ class Cmd(cmd.Cmd): @with_argparser(ACArgumentParser()) def do_quit(self, _: argparse.Namespace) -> bool: """Exit this application""" - self._should_quit = True # Return True to stop the command loop return True @@ -3053,6 +3049,8 @@ class Cmd(cmd.Cmd): self.perror(err, traceback_war=False) return False + bridge = PyscriptBridge(self) + try: self._in_py = True @@ -3078,7 +3076,6 @@ class Cmd(cmd.Cmd): raise EmbeddedConsoleExit # Set up Python environment - bridge = PyscriptBridge(self) self.pystate[self.pyscript_name] = bridge self.pystate['run'] = py_run self.pystate['quit'] = py_quit @@ -3223,7 +3220,7 @@ class Cmd(cmd.Cmd): finally: self._in_py = False - return self._should_quit + return bridge.stop pyscript_parser = ACArgumentParser() setattr(pyscript_parser.add_argument('script_path', help='path to the script file'), diff --git a/cmd2/pyscript_bridge.py b/cmd2/pyscript_bridge.py index 1c720cf9..a8e17555 100644 --- a/cmd2/pyscript_bridge.py +++ b/cmd2/pyscript_bridge.py @@ -20,17 +20,18 @@ else: from contextlib import redirect_stdout, redirect_stderr -class CommandResult(namedtuple_with_defaults('CommandResult', ['stdout', 'stderr', 'data'])): - """Encapsulates the results from a command. +class CommandResult(namedtuple_with_defaults('CommandResult', ['stdout', 'stderr', 'stop', 'data'])): + """Encapsulates the results from a cmd2 app command Named tuple attributes ---------------------- - stdout: str - Output captured from stdout while this command is executing - stderr: str - Output captured from stderr while this command is executing. None if no error captured. - data - Data returned by the command. + stdout: str - output captured from stdout while this command is executing + stderr: str - output captured from stderr while this command is executing. None if no error captured. + stop: bool - return value of the command's corresponding do_* function + data - possible data populated by the command. Any combination of these fields can be used when developing a scripting API for a given command. - By default stdout and stderr will be captured for you. If there is additional command specific data, + By default stdout, stderr, and stop will be captured for you. If there is additional command specific data, then write that to cmd2's _last_result member. That becomes the data member of this tuple. In some cases, the data member may contain everything needed for a command and storing stdout @@ -67,6 +68,9 @@ class PyscriptBridge(object): self._cmd2_app = cmd2_app self.cmd_echo = False + # Tells if any of the commands run via __call__ returned True for stop + self.stop = False + def __dir__(self): """Return a custom set of attribute names""" attributes = [] @@ -95,16 +99,20 @@ class PyscriptBridge(object): self._cmd2_app._last_result = None + stop = False try: self._cmd2_app.stdout = copy_cmd_stdout with redirect_stdout(copy_cmd_stdout): with redirect_stderr(copy_stderr): - self._cmd2_app.onecmd_plus_hooks(command, pyscript_bridge_call=True) + stop = self._cmd2_app.onecmd_plus_hooks(command, pyscript_bridge_call=True) finally: - self._cmd2_app.stdout = copy_cmd_stdout.inner_stream + with self._cmd2_app.sigint_protection: + self._cmd2_app.stdout = copy_cmd_stdout.inner_stream + self.stop = stop or self.stop # Save the output. If stderr is empty, set it to None. result = CommandResult(stdout=copy_cmd_stdout.getvalue(), stderr=copy_stderr.getvalue() if copy_stderr.getvalue() else None, + stop=stop, data=self._cmd2_app._last_result) return result diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py index 7ea4f227..3ce4123c 100644 --- a/tests/test_cmd2.py +++ b/tests/test_cmd2.py @@ -1949,7 +1949,6 @@ Usage: exit [exit_code] self.perror("{} isn't a valid integer exit code".format(arg_list[0])) self.exit_code = -1 - self._should_quit = True # Return True to stop the command loop return True |