2009-08-11 9 views
6

Ich versuche, das Verhalten von sys.excepthook wie von the recipe beschrieben anpassen.kann sys.excepthook nicht überschreiben

in ipython:

:import pdb, sys, traceback 
:def info(type, value, tb): 
: traceback.print_exception(type, value, tb) 
: pdb.pm() 
:sys.excepthook = info 
:-- 
>>> x[10] = 5 
------------------------------------------------- 
Traceback (most recent call last): 
    File "<ipython console>", line 1, in <module> 
NameError: name 'x' is not defined 
>>> 

pdb.pm() heißt nicht werden. Es scheint, dass sys.excepthook = info nicht in meiner Python 2.5-Installation funktioniert.

Antwort

11

ipython, das Sie anstelle der normalen interaktiven Python-Shell verwenden, fängt alle Ausnahmen selbst ein und verwendet sys.excepthook nicht. Führen Sie es als ipython -pdb anstelle von nur ipython aus, und es wird pdb automatisch nach nicht abgefangenen Ausnahmen aufrufen, genau wie Sie es mit Ihrem excepthook versuchen.

+0

Und wie würde jemand gehen etwa mit ipython außer Haken? – levesque

+1

Dies ist teilweise irreführend. ipython fängt Ausnahmen selbst ab, aber die Art und Weise, wie es funktioniert, ist die Verwendung von sys.excepthook, also kann man nicht sagen, dass es sys.excepthook nicht verwendet. ipython entfernt jedoch die Möglichkeit, diesen Hook außer Kraft zu setzen. – snapshoe

+0

@fugacity und Alex - Wie kann ich eine eingebettete Shell in dem Bereich starten, in dem die Ausnahme auftritt? Ich habe gerade eine Frage hier geöffnet: http://stackoverflow.com/questions/15752437/opening-an-ipython-shell-on-any-uncatched-exception und fand diesen Thread, die sehr relevant scheinen. Vielleicht wissen Sie, wie Sie das tun können. –

0

Sehen Sie this SO question und stellen Sie sicher, dass es in Ihrem sitecustomize.py nicht etwas gibt, das Debugging im interaktiven Modus verhindert.

8

Fünf Jahre, nachdem Sie dies geschrieben haben, funktioniert IPython immer noch auf diese Weise. Ich denke, eine Lösung könnte für Leute nützlich sein, die das googlen.

IPython ersetzt sys.excepthook jedes Mal, wenn Sie eine Codezeile ausführen, sodass das Überschreiben von sys.excepthook keine Auswirkungen hat. Außerdem ruft IPython nicht einmal sys.excepthook auf, es fängt alle Ausnahmen ab und behandelt sie selbst, bevor die Dinge so weit kommen.

Um den Ausnahmebehandler zu überschreiben, während IPython ausgeführt wird, können Sie die Methode showtraceback der Shell verwenden. Zum Beispiel, hier ist, wie ich außer Kraft zu geben, was wie ein gewöhnlicher Python Zurückverfolgungs sieht (weil Ich mag es nicht, wie ausführlich IPython die sind):

def showtraceback(self): 
    traceback_lines = traceback.format_exception(*sys.exc_info()) 
    del traceback_lines[1] 
    message = ''.join(traceback_lines) 
    sys.stderr.write(message) 

import sys 
import traceback 
import IPython 
IPython.core.interactiveshell.InteractiveShell.showtraceback = showtraceback 

Dies funktioniert sowohl in der normalen Terminalkonsole und die Qt-Konsole.

0

auf Chris Antwort erweitern, können Sie eine andere Funktion wie ein Dekorateur verwenden, um Ihre eigene Funktionalität zu jupyters showbacktrace hinzuzufügen:

from IPython.core.interactiveshell import InteractiveShell 
from functools import wraps 
import traceback 
import sys 

def change_function(func): 
    @wraps(func) 
    def showtraceback(*args, **kwargs): 
     # extract exception type, value and traceback 
     etype, evalue, tb = sys.exc_info() 
     if issubclass(etype, Exception): 
      print('caught an exception') 
     else: 
      # otherwise run the original hook 
      value = func(*args, **kwargs) 
      return value 
    return showtraceback 

InteractiveShell.showtraceback = change_function(InteractiveShell.showtraceback) 

raise IOError