Python - запуск интерактивного отладчика, когда исключение будет иначе брошено

Есть ли способ заставить программу python запускать интерактивный отладчик, например, что import pdb; pdb.set_trace() вместо того, чтобы на самом деле бросать исключение?

Я знаю трудность выполнения этой работы, но она была бы намного более ценной, чем огромная трассировка стека, после которой я должен был бы использовать, чтобы определить, куда вставлять точки останова, а затем перезапускать программу для ее отладки. Я знаю, что просто сделать запуск отладчика вместо того, чтобы бросать исключение, не имеет смысла, потому что любое исключение можно поймать на том или ином уровне, поэтому, если бы я мог просто выбрать список исключений, для которых был бы запущен интерактивный сеанс отладки вместо этого их бросают (потому что я знаю, что исключения в этом списке действительно будут "ошибками", и после этого не последует никакого значимого поведения программы)...

Я слышал, что Common Lisp имеет что-то вроде этого, но я не знаю, как он работает точно, просто "истинные lispers" хвалили его много...

Ответ 1

Самый простой способ - обернуть весь код внутри блока try следующим образом:

if __name__ == '__main__':

    try:
        raise Exception()
    except:
        import pdb
        pdb.set_trace()

Существует более сложное решение, которое использует sys.excepthook, чтобы переопределить обработку исключенных исключений, как описано в этот рецепт:

## {{{ http://code.activestate.com/recipes/65287/ (r5)
# code snippet, to be included in 'sitecustomize.py'
import sys

def info(type, value, tb):
   if hasattr(sys, 'ps1') or not sys.stderr.isatty():
      # we are in interactive mode or we don't have a tty-like
      # device, so we call the default hook
      sys.__excepthook__(type, value, tb)
   else:
      import traceback, pdb
      # we are NOT in interactive mode, print the exception...
      traceback.print_exception(type, value, tb)
      print
      # ...then start the debugger in post-mortem mode.
      pdb.pm()

sys.excepthook = info
## end of http://code.activestate.com/recipes/65287/ }}}

Вышеприведенный код должен быть включен в файл sitecustomize.py внутри каталога site-packages, который автоматически импортируется с помощью python. Отладчик запускается только тогда, когда python запускается в неинтерактивном режиме.

Ответ 2

Этот вопрос довольно старый, так что это в основном для будущего меня

try:
    ...
except:
    import traceback, pdb, sys
    traceback.print_exc()
    print ''
    pdb.post_mortem()
    sys.exit(1)