This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author gregory.p.smith
Recipients draghuram, gregory.p.smith, isandler, r.david.murray
Date 2010-02-28.20:23:28
SpamBayes Score 3.8857806e-16
Marked as misclassified No
Message-id <001636c5c297cf24040480aebe93@google.com>
In-reply-to
Content
Reviewers: gregory.p.smith, Benjamin, ilya.sandler,

Message:
Also, can you take a look at how the pdb unittests work and see if you
can come up with a way to unittest the KeyboardInterrupt behavior?

Particular for the 4 scenarios you outlined in your prior comments in
the bug (those all make sense to me).

http://codereview.appspot.com/216067/diff/2001/2002
File Lib/pdb.py (right):

http://codereview.appspot.com/216067/diff/2001/2002#newcode63
Lib/pdb.py:63: def sigint_handler(self, signum, frame):
Please move this below the __init__ definition.  It makes classes odd to
read when __init__ isn't the first method defined when people are
looking for the constructor to see how to use it.

http://codereview.appspot.com/216067/diff/2001/2002#newcode64
Lib/pdb.py:64: if self.allow_kbdint:
Initialize self.allow_kdbint in __init__ so that a SIGINT coming in
before _cmdloop has run doesn't cause an AttributeError.

http://codereview.appspot.com/216067/diff/2001/2002#newcode215
Lib/pdb.py:215: # keyboard interrupts allow for an easy way to interrupt
"to cancel the current command"

http://codereview.appspot.com/216067/diff/2001/2002#newcode356
Lib/pdb.py:356: #it appears that that when pdb is reading input from a
pipe
Space after the # please.

Also, could you add a comment in here describing what the effect of this
code is?

It looks like you catch KeyboardInterrupt here and remove the particular
interrupted command from the list of commands to run at the current
breakpoint but I may be misreading things as I haven't spent much time
in pdb.py.

Please review this at http://codereview.appspot.com/216067/show

Affected files:
   M     Lib/pdb.py

Index: Lib/pdb.py
===================================================================
--- Lib/pdb.py	(revision 78520)
+++ Lib/pdb.py	(working copy)
@@ -13,8 +13,10 @@
  import re
  import pprint
  import traceback
+import signal

+
  class Restart(Exception):
      """Causes a debugger to be restarted for the debugged python  
program."""
      pass
@@ -58,6 +60,13 @@

  class Pdb(bdb.Bdb, cmd.Cmd):

+    def sigint_handler(self, signum, frame):
+        if self.allow_kbdint:
+            raise KeyboardInterrupt()
+        print >>self.stdout, "\nProgram interrupted. (Use 'cont' to  
resume)."
+        self.set_step()
+        self.set_trace(frame)
+
      def __init__(self, completekey='tab', stdin=None, stdout=None,  
skip=None):
          bdb.Bdb.__init__(self, skip=skip)
          cmd.Cmd.__init__(self, completekey, stdin, stdout)
@@ -72,6 +81,7 @@
              import readline
          except ImportError:
              pass
+        signal.signal(signal.SIGINT, self.sigint_handler)

          # Read $HOME/.pdbrc and ./.pdbrc
          self.rcLines = []
@@ -176,7 +186,7 @@
              if not self.commands_silent[currentbp]:
                  self.print_stack_entry(self.stack[self.curindex])
              if self.commands_doprompt[currentbp]:
-                self.cmdloop()
+                self._cmdloop()
              self.forget()
              return
          return 1
@@ -199,11 +209,22 @@
          self.interaction(frame, exc_traceback)

      # General interaction function
+    def _cmdloop(self):
+        while 1:
+            try:
+                # keyboard interrupts allow for an easy way to interrupt
+                # cancel current command
+                self.allow_kbdint = True
+                self.cmdloop()
+                self.allow_kbdint = False
+                break
+            except KeyboardInterrupt:
+                print >>self.stdout, '--KeyboardInterrupt--'

      def interaction(self, frame, traceback):
          self.setup(frame, traceback)
          self.print_stack_entry(self.stack[self.curindex])
-        self.cmdloop()
+        self._cmdloop()
          self.forget()

      def displayhook(self, obj):
@@ -329,9 +350,18 @@
          prompt_back = self.prompt
          self.prompt = '(com) '
          self.commands_defining = True
-        self.cmdloop()
-        self.commands_defining = False
-        self.prompt = prompt_back
+        try:
+            self.cmdloop()
+        except (KeyboardInterrupt, IOError):
+            #it appears that that when pdb is reading input from a pipe
+            # we may get IOErrors, rather than KeyboardInterrupt
+            self.commands.pop(bnum)   # remove this cmd list
+            self.commands_doprompt.pop(bnum)
+            self.commands_silent.pop(bnum)
+            raise KeyboardInterrupt()
+        finally:
+            self.commands_defining = False
+            self.prompt = prompt_back

      def do_break(self, arg, temporary = 0):
          # break [ ([filename:]lineno | function) [, "condition"] ]
History
Date User Action Args
2010-02-28 20:23:31gregory.p.smithsetrecipients: + draghuram, r.david.murray
2010-02-28 20:23:29gregory.p.smithlinkissue7245 messages
2010-02-28 20:23:28gregory.p.smithcreate