summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd2/cmd2.py9
-rw-r--r--cmd2/pyscript_bridge.py24
-rw-r--r--tests/test_cmd2.py1
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