title: Catching KeyboardInterrupt in Python during program shutdown
body: <p>I'm writing a command line utility in Python which, since it is production code, ought to be able to shut down cleanly without dumping a bunch of stuff (error codes, stack traces, etc.) to the screen.  This means I need to catch keyboard interrupts.</p>
  
  <p>I've tried using both a try catch block like:</p>
  
  <pre><code>if __name__ == '__main__':
      try:
          main()
      except KeyboardInterrupt:
          print 'Interrupted'
          sys.exit(0)
  </code></pre>
  
  <p>and catching the signal itself (as in <a href="https://stackoverflow.com/questions/6990474/how-can-i-override-the-keyboard-interrupt-python/6990487#6990487">this post</a>):</p>
  
  <pre><code>import signal
  import sys
  
  def sigint_handler(signal, frame):
      print 'Interrupted'
      sys.exit(0)
  signal.signal(signal.SIGINT, sigint_handler)
  </code></pre>
  
  <p>Both methods seem to work quite well during normal operation.  However, if the interrupt comes during cleanup code at the end of the application, Python seems to always print something to the screen.  Catching the interrupt gives</p>
  
  <pre class="lang-none prettyprint-override"><code>^CInterrupted
  Exception KeyboardInterrupt in &lt;bound method MyClass.__del__ of &lt;path.to.MyClass object at 0x802852b90&gt;&gt; ignored
  </code></pre>
  
  <p>whereas handling the signal gives either</p>
  
  <pre class="lang-none prettyprint-override"><code>^CInterrupted
  Exception SystemExit: 0 in &lt;Finalize object, dead&gt; ignored
  </code></pre>
  
  <p>or</p>
  
  <pre class="lang-none prettyprint-override"><code>^CInterrupted
  Exception SystemExit: 0 in &lt;bound method MyClass.__del__ of &lt;path.to.MyClass object at 0x802854a90&gt;&gt; ignored
  </code></pre>
  
  <p>Not only are these errors ugly, they're not very helpful (especially to an end user with no source code)!</p>
  
  <p>The cleanup code for this application is fairly big, so there's a decent chance that this issue will be hit by real users.  Is there any way to catch or block this output, or is it just something I'll have to deal with?</p>