summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcmd2.py10
-rw-r--r--tests/test_cmd2.py41
2 files changed, 50 insertions, 1 deletions
diff --git a/cmd2.py b/cmd2.py
index e1fa7369..0fa31ebb 100755
--- a/cmd2.py
+++ b/cmd2.py
@@ -1016,6 +1016,7 @@ class Cmd(cmd.Cmd):
allow_cli_args = True # Should arguments passed on the command-line be processed as commands?
allow_redirection = True # Should output redirection and pipes be allowed
default_to_shell = False # Attempt to run unrecognized commands as shell commands
+ quit_on_sigint = True # Quit the loop on interrupt instead of just resetting prompt
reserved_words = []
# Attributes which ARE dynamically settable at runtime
@@ -1889,7 +1890,14 @@ class Cmd(cmd.Cmd):
self.poutput('{}{}'.format(self.prompt, line))
else:
# Otherwise, read a command from stdin
- line = self.pseudo_raw_input(self.prompt)
+ if not self.quit_on_sigint:
+ try:
+ line = self.pseudo_raw_input(self.prompt)
+ except KeyboardInterrupt:
+ self.poutput('^C')
+ line = ''
+ else:
+ line = self.pseudo_raw_input(self.prompt)
# Run the command along with all associated pre and post hooks
stop = self.onecmd_plus_hooks(line)
diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py
index 92f21757..e22212d4 100644
--- a/tests/test_cmd2.py
+++ b/tests/test_cmd2.py
@@ -900,6 +900,47 @@ def test_precmd_hook_failure(hook_failure):
assert out == True
+class SayApp(cmd2.Cmd):
+ def __init__(self, *args, **kwargs):
+ # Need to use this older form of invoking super class constructor to support Python 2.x and Python 3.x
+ cmd2.Cmd.__init__(self, *args, **kwargs)
+
+ def do_say(self, arg):
+ self.poutput(arg)
+
+@pytest.fixture
+def say_app():
+ app = SayApp()
+ app.stdout = StdOut()
+ return app
+
+def test_interrupt_quit(say_app):
+ # Mock out the input call so we don't actually wait for a user's response on stdin
+ m = mock.MagicMock(name='input')
+ m.side_effect = ['say hello', KeyboardInterrupt(), 'say goodbye', 'eof']
+ sm.input = m
+
+ say_app.cmdloop()
+
+ # And verify the expected output to stdout
+ out = say_app.stdout.buffer
+ assert out == 'hello\n'
+
+def test_interrupt_noquit(say_app):
+ say_app.quit_on_sigint = False
+
+ # Mock out the input call so we don't actually wait for a user's response on stdin
+ m = mock.MagicMock(name='input')
+ m.side_effect = ['say hello', KeyboardInterrupt(), 'say goodbye', 'eof']
+ sm.input = m
+
+ say_app.cmdloop()
+
+ # And verify the expected output to stdout
+ out = say_app.stdout.buffer
+ assert out == 'hello\n^C\ngoodbye\n'
+
+
class ShellApp(cmd2.Cmd):
def __init__(self, *args, **kwargs):
# Need to use this older form of invoking super class constructor to support Python 2.x and Python 3.x