Pdb python debugger

Теги: tests  python 

Дебагер python из стандартной библиотеки. Реализует интерактивную среду отладки, поддерживает приостановку выполнения, просмотр переменных и выполнение в пошаговом режиме.

Документация

>>> import pdb
>>> import mymodule
>>> pdb.run('mymodule.test()')
> <string>(0)?()
(Pdb) continue
> <string>(1)?()
(Pdb) continue
NameError: 'spam'
> <string>(1)?()
(Pdb)

Отладчик можно запускать:

  • из командной строки
  • из интерпретатора
  • из программы
  • поставарийно

При запуске из командной строки отладчик прекращает выполнение как только встречает первую инструкцию. Инструкции можно передать аргументы и увидеть результат выполнения. Запуск производится вот так:

python3 -m pdb myscript.py

Отладчик можно вызвать из интерпретатора. Для этого следует запустить интерактивную оболочку интепретатора, импортировать тестируемый скрипт и pdb, а затем запустить pdb.run() или pdb.runeval() передав им тестируемый объект с требуемыми аргументами в виде строки.

Из программы отладчик запускается с помщью set_trace(). Это устанавливает точку старта - отладчик остановит выполнение на ближайшей инструкции

import pdb


class MyObj:

    def __init__(self, num_loops):
        self.count = num_loops

    def go(self):
        for i in range(self.count):
            pdb.set_trace() # start
            print(i) # stop
        return

if __name__ == '__main__':
    MyObj(5).go()

За поставарийный трейсинг отвечает pdb.pm() - функция ищет активный объект traceback. содержащий трассировочную информацию, и запускает трассировщик в той точке стека вызовов, в которой возникло исключение

Управление

Управление производится с помозью спец.команд, которые позволяют перемещаться по стеку вызова, изменять значения переменных и выполнять скрипт под управлением отладчика. Здесь используется readline из [python-standart-library] для получения команд и автозаполнения через <TAB>.

Список команд тут

Основные команды:

  • w(here) - возвращает точную позицию выполняемой строки скрипта
  • l(ist) [first[, last]] - выводит исходный код с указанной строки по указанную строку. Без аргументов - выводит 11 строк аокруг теущей строки. Если предоставлен только один аргусент - выводится 11 стрко начиная с указанной строки. ll | longlist выводит весь сорцкод текущей функции или фрейма. source - весь исходный код
  • u(p), d(own) вверх/вниз по стеку/фрейму. Можно передать числовой аргумент шага
  • a(args) все аргументы функции
  • p вычисляет выражение, предоставленное в качестве аргумента ((Pdb) p somearg). Изменять значение аргументов/переменных можно через ! вот так: !somearg='some changes'
  • pp возвращает значение через pprint
  • можно выходить из отладчика в интерпретатор через interact и обратно обычным выходом из интерпертатора
  • whatis возвращает тип выражения
  • s(tep) пошаговое выполнение
  • n(ext) выполняет весь вызов текущей функции до начала следующей
  • unt(il) [lineno] без аргумента продолжить выполнение до тех пор, пока не будет достигнута строка с номером больше текущего. С номером строки продолжайте выполнение до тех пор, пока не будет достигнута строка с номером, большим или равным этому. В обоих случаях также останавливайтесь при завершении текущего фрейма. Передаваемый номер строки должен превышать текущий
  • r(eturn) перейти к ближайшему ретурну
  • возможна установка точек останова - через b(reak) [([filename:]lineno | function) [, condition]] с указанием номера строки или файла и имени функции. break без аргументов выводит список точек останова
  • c(ont(inue)) возобновляет выполнение до следующей точки останова
  • точкам останова присваивается идентификатор. disable [bpnumber ...] позволяет выключить точки по айдишнику без их удаления. cl(ear) [filename:lineno | bpnumber ...] сбрасывает точки
  • tbreak [([filename:]lineno | function) [, condition]] создает временную точку, котоаря будет сброшена после первого прогона
  • condition при установке точек позволяет задать условия, при которых поток будет останавливатсья в точке (например это может быть значение определенных переменных). Так же условие можно применить к существующей точке через condition bpnumber [condition]
  • ignore bpnumber [count] игнорировать точку определенное число проходов (полезно, когда в коде есть рекурсии или циклы)
  • commands [bpnumber] запуск простых сценариев по достижению точки. Команды вводятся вручную по одной на строку (это могут быть принты, сравнения и т.п.). Ввод команд завершается через end
  • display [expression] выводит значение предоставленного выражения на каждом шаге (полезно для контроля переменных в коде)
  • j(ump) lineno перемещает по потоку выполнения. Переходы вперед перемещают поток вперед без выполнения промежуточных инструкций. Перемещение назад приводит к повторному выполнению. При этом jump не допускает переход в функцию, аргумент которой не определен, с ним нельзя входить внутрь цикла или в инструкции [try-except]. Выход из finally также невозможен, так как код в этой инструкции должен быть всегда выполнен
  • отладчик автоматически перезапускает скрипт в конце программы или явно через run [args ...] или restart [args ...]. Аргументы передаются следующему запуску в качестве аргументво командной строки (анализируются через shlex - смотри [argparsing])
  • alias [name [command]] создает псевдонимы длинным команда. Без аргументов команда выведет список алиасов. unalias удаляет алиас
  • q(uit) выход
  • h(elp) [command] подсказка. h pdb вся дока

Все настройки можно прописать в специальном файле настроек .pdbrc. В нем можно прописат ьвсе алиасы, точки останова и т.п.