не может переопределить sys.excepthook - PullRequest
9 голосов
/ 11 августа 2009

Я пытаюсь настроить поведение sys.excepthook, как описано в рецепте .

в 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() не вызывается. Кажется, что sys.excepthook = info не работает в моей установке Python 2.5.

Ответы [ 4 ]

13 голосов
/ 27 февраля 2015

Спустя пять лет после того, как вы написали это, IPython по-прежнему работает таким образом, так что я думаю, что решение может быть полезным для людей, гуглящих это.

IPython заменяет sys.excepthook каждый раз, когда вы выполняете строку кода, поэтому переопределение sys.excepthook не имеет никакого эффекта. Более того, IPython даже не вызывает sys.excepthook, он перехватывает все исключения и обрабатывает их сам, прежде чем что-то достигнет.

Чтобы переопределить обработчик исключений во время работы IPython, вы можете monkeypatch через метод showtraceback их оболочки. Например, вот как я переопределяю, чтобы дать то, что выглядит как обычная трассировка Python (потому что мне не нравится, насколько подробны IPython):

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

Это работает как в обычной терминальной консоли, так и в консоли Qt.

12 голосов
/ 11 августа 2009

ipython, который вы используете вместо обычной интерактивной оболочки Python, перехватывает все исключения самостоятельно и НЕ использует sys.excepthook. Запустите его как ipython -pdb вместо просто ipython, и он автоматически вызовет pdb при необработанных исключениях, точно так же, как вы пытаетесь сделать с вашим исключением.

0 голосов
/ 08 марта 2018

Расширяя ответ Криса, вы можете использовать другую функцию, например, декоратор, чтобы добавить свои собственные функции в showbacktrace для jupyters:

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
0 голосов
/ 11 августа 2009

См. этот вопрос и убедитесь, что в вашем sitecustomize.py нет чего-то, что препятствует отладке в интерактивном режиме.

...