2009-08-11 16 views
6

Intento personalizar el comportamiento de sys.excepthook como se describe en the recipe.no puede anular sys.excepthook

en 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() no se está llamando. Parece que sys.excepthook = info no funciona en mi instalación de python 2.5.

Respuesta

11

ipython, que está utilizando en lugar del shell interactivo de Python normal, atrapa todas las excepciones y NO usa sys.excepthook. Ejecútelo como ipython -pdb en lugar de solo ipython, e invocará automáticamente pdb ante excepciones no detectadas, del mismo modo que está tratando de hacer con su excepción.

+0

Y cómo alguien a ir sobre el uso de ganchos con excepción ipython? – levesque

+1

Esto es parcialmente engañoso. ipython sí atrapa excepciones, pero la forma en que lo hace es mediante el uso de sys.excepthook, por lo que no puede decir que no usa sys.excepthook. Sin embargo, ipython elimina del usuario la posibilidad de anular este enganche. – snapshoe

+0

@fugacity y Alex: ¿cómo puedo abrir un shell incrustado en el ámbito donde se produce la excepción? Acabo de abrir una pregunta aquí: http://stackoverflow.com/questions/15752437/opening-an-ipython-shell-on-any-uncatched-exception y encontré este hilo que parece muy relevante. Quizás puedas saber cómo hacer esto. –

0

Consulte this SO question y asegúrese de que no haya nada en su sitecustomize.py que impida la depuración en modo interactivo.

8

Cinco años después de haber escrito esto, IPython sigue funcionando de esta manera, así que supongo que una solución podría ser útil para las personas que buscan en Google.

IPython reemplaza sys.excepthook cada vez que ejecuta una línea de código, por lo que su anulación de sys.excepthook no tiene ningún efecto. Además, IPython ni siquiera llama al sys.excepthook, detecta todas las excepciones y las maneja antes de que las cosas lleguen tan lejos.

Para anular el manejador de excepciones mientras se está ejecutando IPython, puede parchear sobre el método showtraceback de su caparazón. Por ejemplo, aquí es cómo puedo reemplazar a dar lo que parece un rastreo de Python ordinaria (porque no me gusta el nivel de detalle de IPython son):

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 

Esto funciona tanto en la consola de terminal normal y la consola Qt.

0

expandiendo sobre Chris respuesta, puede utilizar otra función como un decorador de añadir su propia funcionalidad a 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 
Cuestiones relacionadas