diff options
-rwxr-xr-x | cmd2.py | 10 | ||||
-rw-r--r-- | tests/test_cmd2.py | 41 |
2 files changed, 50 insertions, 1 deletions
@@ -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 |