Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cannot override sys.excepthook

I try to customize behavior of sys.excepthook as described by the recipe.

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() is not being called. It seems that sys.excepthook = info doesn't work in my python 2.5 installation.

like image 201
Mert Nuhoglu Avatar asked Aug 11 '09 16:08

Mert Nuhoglu


2 Answers

Five years after you wrote this, IPython still works this way, so I guess a solution might be useful to people googling this.

IPython replaces sys.excepthook every time you execute a line of code, so your overriding of sys.excepthook has no effect. Furthermore, IPython doesn't even call sys.excepthook, it catches all exceptions and handles them itself before things get that far.

To override the exception handler whilst IPython is running, you can monkeypatch over their shell's showtraceback method. For example, here's how I override to give what looks like an ordinary Python traceback (because I don't like how verbose IPython's are):

def showtraceback(self, *args, **kwargs):
    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

This works in both the normal terminal console and the Qt console.

like image 141
Chris Billington Avatar answered Sep 21 '22 16:09

Chris Billington


sys.excepthook won't work in ipython. I think the recommended way of hooking to exceptions is to use the set_custom_exc method, like this:

from IPython import get_ipython
ip = get_ipython()


def exception_handler(self, etype, evalue, tb, tb_offset=None):
    print("##### Oh no!!! #####")  # your handling of exception here
    self.showtraceback((etype, evalue, tb), tb_offset=tb_offset)  # standard IPython's printout

    
ip.set_custom_exc((Exception,), exception_handler)  # register your handler
raise Exception("##### Bad things happened! #####")  # see it in action

See the docs for more details: https://ipython.readthedocs.io/en/stable/api/generated/IPython.core.interactiveshell.html#IPython.core.interactiveshell.InteractiveShell.set_custom_exc

like image 44
Michał Jabłoński Avatar answered Sep 19 '22 16:09

Michał Jabłoński