From d574a6bc1f08b4020388be5a6b3a2b54a0db259c 2014-11-30 21:53:57 From: Jeroen Demeyer Date: 2014-11-30 21:53:57 Subject: [PATCH] Print exception instead of "KeyboardInterrupt" Whenever a KeyboardInterrupt exception occurs in the shell, we should print the actual exception instead of the string "KeyboardInterrupt". This is needed to support exceptions inherited from KeyboardInterrupt. --- diff --git a/IPython/core/debugger.py b/IPython/core/debugger.py index d156a0f..80c3ada 100644 --- a/IPython/core/debugger.py +++ b/IPython/core/debugger.py @@ -277,7 +277,7 @@ class Pdb(OldPdb): try: OldPdb.interaction(self, frame, traceback) except KeyboardInterrupt: - self.shell.write("\nKeyboardInterrupt\n") + self.shell.write('\n' + self.shell.get_exception_only()) break else: break diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index e4fce96..a736d32 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -22,6 +22,7 @@ import re import runpy import sys import tempfile +import traceback import types import subprocess from io import open as io_open @@ -1786,6 +1787,15 @@ class InteractiveShell(SingletonConfigurable): """ self.write_err("UsageError: %s" % exc) + def get_exception_only(self, exc_tuple=None): + """ + Return as a string (ending with a newline) the exception that + just occurred, without any traceback. + """ + etype, value, tb = self._get_exc_info(exc_tuple) + msg = traceback.format_exception_only(etype, value) + return ''.join(msg) + def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None, exception_only=False): """Display the exception that just occurred. @@ -1838,7 +1848,7 @@ class InteractiveShell(SingletonConfigurable): self._showtraceback(etype, value, stb) except KeyboardInterrupt: - self.write_err("\nKeyboardInterrupt\n") + self.write_err('\n' + self.get_exception_only()) def _showtraceback(self, etype, evalue, stb): """Actually show a traceback. @@ -2355,7 +2365,7 @@ class InteractiveShell(SingletonConfigurable): try: ec = os.system(cmd) except KeyboardInterrupt: - self.write_err("\nKeyboardInterrupt\n") + self.write_err('\n' + self.get_exception_only()) ec = -2 else: cmd = py3compat.unicode_to_str(cmd) @@ -2374,7 +2384,7 @@ class InteractiveShell(SingletonConfigurable): ec = subprocess.call(cmd, shell=True, executable=executable) except KeyboardInterrupt: # intercept control-C; a long traceback is not useful here - self.write_err("\nKeyboardInterrupt\n") + self.write_err('\n' + self.get_exception_only()) ec = 130 if ec > 128: ec = -(ec - 128) diff --git a/IPython/core/tests/test_interactiveshell.py b/IPython/core/tests/test_interactiveshell.py index 8374672..5c8f1a8 100644 --- a/IPython/core/tests/test_interactiveshell.py +++ b/IPython/core/tests/test_interactiveshell.py @@ -482,6 +482,21 @@ class InteractiveShellTestCase(unittest.TestCase): mod = ip.new_main_mod(u'%s.py' % name, name) self.assertEqual(mod.__name__, name) + def test_get_exception_only(self): + try: + raise KeyboardInterrupt + except KeyboardInterrupt: + msg = ip.get_exception_only() + self.assertEqual(msg, 'KeyboardInterrupt\n') + + class DerivedInterrupt(KeyboardInterrupt): + pass + try: + raise DerivedInterrupt("foo") + except KeyboardInterrupt: + msg = ip.get_exception_only() + self.assertEqual(msg, 'DerivedInterrupt: foo\n') + class TestSafeExecfileNonAsciiPath(unittest.TestCase): @onlyif_unicode_paths diff --git a/IPython/terminal/console/interactiveshell.py b/IPython/terminal/console/interactiveshell.py index 7f1d333..1daba8e 100644 --- a/IPython/terminal/console/interactiveshell.py +++ b/IPython/terminal/console/interactiveshell.py @@ -529,7 +529,7 @@ class ZMQTerminalInteractiveShell(TerminalInteractiveShell): except KeyboardInterrupt: #double-guard against keyboardinterrupts during kbdint handling try: - self.write('\nKeyboardInterrupt\n') + self.write('\n' + self.get_exception_only()) source_raw = self.input_splitter.raw_reset() hlen_b4_cell = self._replace_rlhist_multiline(source_raw, hlen_b4_cell) more = False diff --git a/IPython/terminal/interactiveshell.py b/IPython/terminal/interactiveshell.py index ff02a3f..939cf90 100644 --- a/IPython/terminal/interactiveshell.py +++ b/IPython/terminal/interactiveshell.py @@ -468,7 +468,7 @@ class TerminalInteractiveShell(InteractiveShell): except KeyboardInterrupt: #double-guard against keyboardinterrupts during kbdint handling try: - self.write('\nKeyboardInterrupt\n') + self.write('\n' + self.get_exception_only()) source_raw = self.input_splitter.raw_reset() hlen_b4_cell = \ self._replace_rlhist_multiline(source_raw, hlen_b4_cell)