Show More
@@ -290,7 +290,7 b' class Pdb(OldPdb):' | |||||
290 | try: |
|
290 | try: | |
291 | OldPdb.interaction(self, frame, traceback) |
|
291 | OldPdb.interaction(self, frame, traceback) | |
292 | except KeyboardInterrupt: |
|
292 | except KeyboardInterrupt: | |
293 | raise |
|
293 | self.stdout.write('\n' + self.shell.get_exception_only()) | |
294 |
|
294 | |||
295 | def new_do_up(self, arg): |
|
295 | def new_do_up(self, arg): | |
296 | OldPdb.do_up(self, arg) |
|
296 | OldPdb.do_up(self, arg) | |
@@ -627,8 +627,22 b' class Pdb(OldPdb):' | |||||
627 |
|
627 | |||
628 | do_w = do_where |
|
628 | do_w = do_where | |
629 |
|
629 | |||
|
630 | ||||
|
631 | class InterruptiblePdb(Pdb): | |||
|
632 | """Version of debugger where KeyboardInterrupt exits the debugger altogether.""" | |||
|
633 | ||||
|
634 | def cmdloop(self): | |||
|
635 | """Wrap cmdloop() such that KeyboardInterrupt stops the debugger.""" | |||
|
636 | try: | |||
|
637 | return OldPdb.cmdloop(self) | |||
|
638 | except KeyboardInterrupt: | |||
|
639 | self.stop_here = lambda frame: False | |||
|
640 | self.do_quit("") | |||
|
641 | sys.settrace(None) | |||
|
642 | self.quitting = False | |||
|
643 | raise | |||
|
644 | ||||
630 | def _cmdloop(self): |
|
645 | def _cmdloop(self): | |
631 | # Variant that doesn't catch KeyboardInterrupts. |
|
|||
632 | while True: |
|
646 | while True: | |
633 | try: |
|
647 | try: | |
634 | # keyboard interrupts allow for an easy way to cancel |
|
648 | # keyboard interrupts allow for an easy way to cancel | |
@@ -638,6 +652,7 b' class Pdb(OldPdb):' | |||||
638 | self.allow_kbdint = False |
|
652 | self.allow_kbdint = False | |
639 | break |
|
653 | break | |
640 | except KeyboardInterrupt: |
|
654 | except KeyboardInterrupt: | |
|
655 | self.message('--KeyboardInterrupt--') | |||
641 | raise |
|
656 | raise | |
642 |
|
657 | |||
643 |
|
658 |
@@ -13,6 +13,7 b' from subprocess import check_output, CalledProcessError, PIPE' | |||||
13 | import subprocess |
|
13 | import subprocess | |
14 | from unittest.mock import patch |
|
14 | from unittest.mock import patch | |
15 | import builtins |
|
15 | import builtins | |
|
16 | import bdb | |||
16 |
|
17 | |||
17 | import nose.tools as nt |
|
18 | import nose.tools as nt | |
18 |
|
19 | |||
@@ -236,11 +237,15 b' def test_interruptible_core_debugger():' | |||||
236 | (this is implemented in ipykernel). We want to ensure the |
|
237 | (this is implemented in ipykernel). We want to ensure the | |
237 | KeyboardInterrupt cause debugging to cease. |
|
238 | KeyboardInterrupt cause debugging to cease. | |
238 | """ |
|
239 | """ | |
239 | def raising_input(msg=""): |
|
240 | def raising_input(msg="", called=[0]): | |
240 | raise KeyboardInterrupt() |
|
241 | called[0] += 1 | |
|
242 | if called[0] == 1: | |||
|
243 | raise KeyboardInterrupt() | |||
|
244 | else: | |||
|
245 | raise AssertionError("input() should only be called once!") | |||
241 |
|
246 | |||
242 | with patch.object(builtins, "input", raising_input): |
|
247 | with patch.object(builtins, "input", raising_input): | |
243 | debugger.set_trace() |
|
248 | debugger.InterruptiblePdb().set_trace() | |
244 | # The way this test will fail is by set_trace() never exiting, |
|
249 | # The way this test will fail is by set_trace() never exiting, | |
245 | # resulting in a timeout by the test runner. The alternative |
|
250 | # resulting in a timeout by the test runner. The alternative | |
246 | # implementation would involve a subprocess, but that adds issues with |
|
251 | # implementation would involve a subprocess, but that adds issues with |
General Comments 0
You need to be logged in to leave comments.
Login now