Запустить оболочку IPython в исключительных случаях - PullRequest
46 голосов
/ 20 ноября 2010

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

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

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

РЕДАКТИРОВАТЬ: Опция -pdb при запуске IPython, кажется, не делает то, что я хочу (или, возможно, я не знаю, как правильно его использовать, чтовполне возможно).Я запускаю следующий скрипт:

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, где у меня есть доступ к глобальномупеременные скрипта, но не локальные переменные функции 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 со всеми доступными областями действия.

Ответы [ 10 ]

23 голосов
/ 14 февраля 2013

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

import sys
from IPython.core import ultratb
sys.excepthook = ultratb.FormattedTB(mode='Verbose',
     color_scheme='Linux', call_pdb=1)
19 голосов
/ 22 декабря 2010

Выполнение:

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

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

12 голосов
/ 18 апреля 2012

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

import sys, ipdb, traceback

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

sys.excepthook = info
7 голосов
/ 06 декабря 2013

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

Однако это работает:

import sys 
from IPython import embed

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

sys.excepthook = excepthook
6 голосов
/ 13 июня 2016

Вы можете попробовать это:

from ipdb import launch_ipdb_on_exception

def main():
    with launch_ipdb_on_exception():
        # The rest of the code goes here.
        [...]
4 голосов
/ 20 ноября 2010

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

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

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

sys.excepthook = excepthook

См. sys.excepthook и Встраивание IPython .

3 голосов
/ 08 января 2014

@ Адам работает как шарм, за исключением того, что 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 будет импортирован.

2 голосов
/ 20 ноября 2010

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

РЕДАКТИРОВАТЬ: python -m pdb pythonscript.py может запустить pdb.Не уверен насчет того же в iPython.Если вы ищете трассировку стека и общие последствия аварийного выхода из программы, это должно сработать.

1 голос
/ 03 ноября 2014

Если вы хотите получить трассировку и открыть оболочку 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's change to the exception hook

import sys
sys.excepthook = exceptHook

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

1 голос
/ 22 февраля 2011

Вы действительно хотите открыть сеанс pdb в каждой точке исключения?(как я думаю, сеанс pdb, открытый из ipython, такой же, как и сеанс, открытый в обычной оболочке).Если это так, вот хитрость: http://code.activestate.com/recipes/65287-automatically-start-the-debugger-on-an-exception/

...