2009-08-11 10 views
6

Provo a personalizzare il comportamento di sys.excepthook come descritto da the recipe.non può sovrascrivere sys.excepthook

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() non viene chiamato. Sembra che sys.excepthook = info non funzioni nella mia installazione di python 2.5.

risposta

11

ipython, che si sta utilizzando al posto della normale shell interattiva Python, intercetta tutte le eccezioni e NON usa sys.excepthook. Eseguilo come ipython -pdb anziché solo ipython e invocherà automaticamente pdb su eccezioni non rilevate, proprio come si sta tentando di fare con il tuo eccethook.

+0

E come qualcuno andare sull'utilizzo tranne ganci con ipython? – levesque

+1

Questo è parzialmente fuorviante. ipython intercetta le eccezioni, ma il modo in cui lo fa è usando sys.excepthook, quindi non si può dire che non usi sys.excepthook. ipython rimuove tuttavia dall'utente la possibilità di sovrascrivere questo hook. – snapshoe

+0

@fugacity e Alex - Come posso avviare una shell incorporata nell'ambito in cui si verifica l'eccezione? Ho appena aperto una domanda qui: http://stackoverflow.com/questions/15752437/opening-an-ipython-shell-on-any-uncatched-exception e ho trovato questa discussione che sembra molto rilevante. Forse potresti sapere come farlo. –

0

Vedere this SO question e assicurarsi che non ci sia qualcosa nel proprio sitecustomize.py che impedisce il debug in modalità interattiva.

8

Cinque anni dopo aver scritto questo, IPython funziona ancora in questo modo, quindi immagino che una soluzione possa essere utile a chi la usa su Google.

IPython sostituisce sys.excepthook ogni volta che si esegue una riga di codice, quindi l'override di sys.excepthook non ha alcun effetto. Inoltre, IPython non chiama nemmeno sys.excepthook, prende tutte le eccezioni e le gestisce da sé prima che le cose arrivino così lontano.

Per eseguire l'override del gestore di eccezioni mentre IPython è in esecuzione, è possibile eseguire la monkeypatch tramite il metodo showtraceback della shell. Ad esempio, ecco come sovrascrivo a dare quello che sembra un traceback Python ordinario (perché non mi piace come verbose ipython di sono):

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 

Questo funziona sia nel normale console terminale e la console Qt.

0

ampliando Chris risposta, è possibile utilizzare un'altra funzione come un decoratore di aggiungere le proprie funzionalità per jupyters showbacktrace:

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 
Problemi correlati