Thursday, June 14, 2007

A workaround for the sys.excepthook bug

About two years ago I reported the bug sys.excepthook doesn't work in threads. Then just recently someone asked in #utahpython if I had a workaround. Here it is (also added as a comment to the bug report) -- all we do is monkeypatch Thread.run to run the excepthook manually if there is an uncaught exception:
def install_thread_excepthook():
    """
    Workaround for sys.excepthook thread bug
    (https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1230540&group_id=5470).
    Call once from __main__ before creating any threads.
    If using psyco, call psyco.cannotcompile(threading.Thread.run)
    since this replaces a new-style class method.
    """
    import sys, threading
    run_old = threading.Thread.run
    def run(*args, **kwargs):
        try:
            run_old(*args, **kwargs)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            sys.excepthook(*sys.exc_info())
    threading.Thread.run = run

2 comments:

Anonymous said...

Actually, this won't work, at least not if you create your own subclasses of threading.Thread.

Jonathan Ellis said...

I would think it's obvious that it won't work if you override Thread.run in a subclass, yes.

But there's usually no need to do that; good style is to just pass target and args options instead of subclassing.