Подтвердить что ты не робот

Запустить оболочку IPython для исключения

Есть ли способ запустить оболочку или приглашение IPython, когда моя программа запускает строку, которая вызывает исключение?

В основном меня интересует контекст, переменные, в области (и подкосе), где было создано исключение. Что-то вроде отладки Visual Studio, когда исключение выбрасывается, но не улавливается кем-либо, Visual Studio останавливается и дает мне стек вызовов и переменные, присутствующие на каждом уровне.

Как вы думаете, есть ли способ получить что-то подобное с помощью IPython?

EDIT: Параметр -pdb при запуске IPython, похоже, не делает то, что я хочу (или, может быть, я не знаю, как правильно его использовать, что вполне возможно). Я запускаю следующий script:

def func():
    z = 2
    g = 'b'
    raise NameError("This error will not be caught, but IPython still"
                    "won't summon pdb, and I won't be able to consult"
                    "the z or g variables.")

x = 1
y = 'a'

func()

Используя команду:

ipython -pdb exceptionTest.py

Что прекращает выполнение при возникновении ошибки, но приносит мне приглашение IPython, где у меня есть доступ к глобальным переменным script, но не к локальным переменным функции func. pdb вызывается только при прямом вводе команды в ipython, которая вызывает ошибку, т.е. raise NameError("This, sent from the IPython prompt, will trigger pdb.").

Мне не обязательно использовать pdb, я просто хочу иметь доступ к переменным внутри func.

РЕДАКТИРОВАТЬ 2:. В настоящее время IPython -pdb теперь работает так, как я хочу. Это означает, что когда я создаю исключение, я могу вернуться в область func и без проблем прочитать его переменные z и g. Даже не устанавливая параметр -pdb, можно запустить IPython в интерактивном режиме, а затем вызвать волшебную функцию %debug после выхода программы с ошибкой - это также приведет вас к интерактивной подсказке ipdb со всеми доступными доступными областями.

4b9b3361

Ответ 1

Обновление для IPython v0.13:

import sys
from IPython.core import ultratb
sys.excepthook = ultratb.FormattedTB(mode='Verbose',
     color_scheme='Linux', call_pdb=1)

Ответ 2

Doing:

ipython --pdb -c "%run exceptionTest.py"

запускает script после инициализации IPython и вы попадаете в обычную среду IPython + pdb.

Ответ 3

ipdb интегрирует функции IPython в pdb. Я использую следующий код, чтобы выбросить мои приложения в отладчик IPython после непредвиденного исключения.

import sys, ipdb, traceback

def info(type, value, tb):
    traceback.print_exception(type, value, tb)
    print
    ipdb.pm()

sys.excepthook = info

Ответ 4

@snapshoe ответ не работает с новыми версиями IPython.

Это однако:

import sys 
from IPython import embed

def excepthook(type, value, traceback):
    embed()

sys.excepthook = excepthook

Ответ 5

Вы можете сделать что-то вроде следующего:

import sys
from IPython.Shell import IPShellEmbed
ipshell = IPShellEmbed()

def excepthook(type, value, traceback):
    ipshell()

sys.excepthook = excepthook

Смотрите sys.excepthook и Внедрение IPython.

Ответ 6

Эта справочная страница говорит, что iPython имеет опцию --[no]pdb, которая должна быть передана в командной строке, чтобы запустить iPython для неперехваченных исключений. Вы ищете еще?

EDIT: python -m pdb pythonscript.py может запускать pdb. Однако не уверен в том, что с iPython. Если вы ищете трассировку стека и общую посмертную информацию об аномальном выходе программы, это должно сработать.

Ответ 7

@Adam работает как шарм, за исключением того, что IPython загружается немного медленно (800 мс на моей машине). Здесь у меня есть трюк, чтобы сделать нагрузку ленивой.

class ExceptionHook:
    instance = None

    def __call__(self, *args, **kwargs):
        if self.instance is None:
            from IPython.core import ultratb
            self.instance = ultratb.FormattedTB(mode='Verbose',
                 color_scheme='Linux', call_pdb=1)
        return self.instance(*args, **kwargs)
sys.excepthook = ExceptionHook()

Теперь нам не нужно ждать в самом начале. Только при сбое программы будет вызван IPython.

Ответ 8

Вы можете попробовать следующее:

from ipdb import launch_ipdb_on_exception

def main():
    with launch_ipdb_on_exception():
        # The rest of the code goes here.
        [...]

Ответ 10

Если вы хотите как получить трассировку, так и открыть оболочку IPython со средой в точке исключения:

def exceptHook(*args):
    '''A routine to be called when an exception occurs. It prints the traceback
    with fancy formatting and then calls an IPython shell with the environment
    of the exception location.
    '''
    from IPython.core import ultratb
    ultratb.FormattedTB(call_pdb=False,color_scheme='LightBG')(*args)
    from IPython.terminal.embed import InteractiveShellEmbed
    import inspect
    frame = inspect.getinnerframes(args[2])[-1][0]
    msg   = 'Entering IPython console at {0.f_code.co_filename} at line {0.f_lineno}'.format(frame)
    savehook = sys.excepthook # save the exception hook
    InteractiveShellEmbed()(msg,local_ns=frame.f_locals,global_ns=frame.f_globals)
    sys.excepthook = savehook # reset IPython change to the exception hook

import sys
sys.excepthook = exceptHook

Обратите внимание, что необходимо вытащить, чем информацию о пространстве имен из последнего кадра, на который ссылается трассировка (arg [2])