pdb — Отладчик Python

Исходный код: Lib/pdb.py.


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

Отладчик является расширяемым - он фактически определен как класс Pdb. В настоящее время это не документировано, но легко понять, прочитав исходный текст. Интерфейс расширения использует модули bdb и cmd.

Подсказка отладчика - (Pdb). Типичное использование для запуска программы под управлением отладчика:

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

Изменено в версии 3.3: Для команд и аргументов команд доступно заполнение табуляции через модуль readline, например, в качестве аргументов команды p предлагаются текущие глобальные и локальные имена.

pdb.py также может быть вызван как сценарий для отладки других сценариев. Например:

python3 -m pdb myscript.py

При вызове в качестве сценария pdb автоматически переходит к посмертной отладке, если отлаживаемая программа завершается аномально. После посмертной отладки (или после нормального завершения программы) pdb перезапустит программу. Автоматический перезапуск сохраняет состояние pdb (например, точки останова) и в большинстве случаев более полезен, чем выход из отладчика при завершении программы.

Добавлено в версии 3.2: pdb.py теперь принимает опцию -c, которая выполняет команды, как если бы они были заданы в файле .pdbrc, см. Команды отладчика.

Добавлено в версии 3.7: pdb.py теперь принимает опцию -m, которая выполняет модули аналогично тому, как это делает python3 -m. Как и в случае со сценарием, отладчик приостановит выполнение непосредственно перед первой строкой модуля.

Типичным способом проникновения в отладчик является вставка:

import pdb; pdb.set_trace()

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

Добавлено в версии 3.7: Вместо breakpoint() можно использовать встроенный import pdb; pdb.set_trace(), вызываемый с параметрами по умолчанию.

Для проверки сбойной программы обычно используется:

>>> import pdb
>>> import mymodule
>>> mymodule.test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "./mymodule.py", line 4, in test
    test2()
  File "./mymodule.py", line 3, in test2
    print(spam)
NameError: spam
>>> pdb.pm()
> ./mymodule.py(3)test2()
-> print(spam)
(Pdb)

В модуле определены следующие функции; каждая из них входит в отладчик немного по-разному:

pdb.run(statement, globals=None, locals=None)

Выполнить выражение (заданное в виде строки или объекта кода) под контролем отладчика. Перед выполнением любого кода появляется приглашение отладчика; вы можете установить точки останова и ввести continue, или вы можете пройтись по утверждению, используя step или next (все эти команды объясняются ниже). Необязательные аргументы globals и locals определяют среду, в которой выполняется код; по умолчанию используется словарь модуля __main__. (См. объяснение встроенных функций exec() или eval()).

pdb.runeval(expression, globals=None, locals=None)

Оценить выражение (заданное в виде строки или объекта кода) под контролем отладчика. При возврате runeval() возвращает значение выражения. В остальном эта функция аналогична run().

pdb.runcall(function, *args, **kwds)

Вызывает функцию (объект функции или метода, а не строку) с заданными аргументами. Когда возвращается runcall(), возвращается то, что вернул вызов функции. При вводе функции появляется подсказка отладчика.

pdb.set_trace(*, header=None)

Ввести отладчик на вызывающем стековом фрейме. Это полезно для жесткого кодирования точки останова в заданной точке программы, даже если код не отлаживается (например, когда утверждение не выполняется). Если задано, заголовок будет выведен на консоль непосредственно перед началом отладки.

Изменено в версии 3.7: Аргумент header, содержащий только ключевое слово.

pdb.post_mortem(traceback=None)

Ввести посмертную отладку заданного объекта traceback. Если объект traceback не указан, то используется объект исключения, которое обрабатывается в данный момент (исключение должно обрабатываться, если используется значение по умолчанию).

pdb.pm()

Введите посмертную отладку трассировки, найденной в sys.last_traceback.

Функции run* и set_trace() являются псевдонимами для инстанцирования класса Pdb и вызова одноименного метода. Если вы хотите получить доступ к дальнейшим функциям, вы должны сделать это самостоятельно:

class pdb.Pdb(completekey='tab', stdin=None, stdout=None, skip=None, nosigint=False, readrc=True)

Pdb - это класс отладчика.

Аргументы completekey, stdin и stdout передаются в базовый класс cmd.Cmd; см. его описание.

Аргумент skip, если он задан, должен быть итерацией шаблонов имен модулей в стиле glob. Отладчик не будет входить во фреймы, происходящие из модуля, который соответствует одному из этих шаблонов. 1

По умолчанию Pdb устанавливает обработчик сигнала SIGINT (который посылается, когда пользователь нажимает Ctrl-C на консоли), когда вы даете команду continue. Это позволяет вам снова проникнуть в отладчик, нажав Ctrl-C. Если вы хотите, чтобы Pdb не трогал обработчик SIGINT, установите nosigint в true.

Аргумент readrc по умолчанию равен true и определяет, будет ли Pdb загружать файлы .pdbrc из файловой системы.

Пример вызова для включения трассировки с skip:

import pdb; pdb.Pdb(skip=['django.*']).set_trace()

Вызывает auditing event pdb.Pdb без аргументов.

Добавлено в версии 3.1: Аргумент пропустить.

Добавлено в версии 3.2: Аргумент nosigint. Ранее обработчик SIGINT никогда не устанавливался Pdb.

Изменено в версии 3.6: Аргумент readrc.

run(statement, globals=None, locals=None)
runeval(expression, globals=None, locals=None)
runcall(function, *args, **kwds)
set_trace()

См. документацию по функциям, описанным выше.

Команды отладчика

Команды, распознаваемые отладчиком, перечислены ниже. Большинство команд можно сократить до одной или двух букв, как указано; например, h(elp) означает, что для ввода команды help можно использовать либо h, либо help (но не he или hel, ни H, ни Help, ни HELP). Аргументы команд должны быть разделены пробелами (пробелы или табуляция). Необязательные аргументы заключаются в квадратные скобки ([]) в синтаксисе команды; квадратные скобки не должны быть напечатаны. Альтернативы в синтаксисе команды разделяются вертикальной чертой (|).

При вводе пустой строки повторяется последняя введенная команда. Исключение: если последней командой была команда list, перечисляются следующие 11 строк.

Команды, которые отладчик не распознает, принимаются за утверждения Python и выполняются в контексте отлаживаемой программы. Утверждения Python также могут иметь префикс в виде восклицательного знака (!). Это мощный способ проверки отлаживаемой программы; можно даже изменить переменную или вызвать функцию. Когда в таком операторе возникает исключение, имя исключения печатается, но состояние отладчика не изменяется.

Отладчик поддерживает aliases. Псевдонимы могут иметь параметры, что позволяет достичь определенного уровня адаптивности к исследуемому контексту.

Несколько команд могут быть введены на одной строке, разделенные символом ;;. (Одиночный ; не используется, так как он является разделителем для нескольких команд в строке, которая передается синтаксическому анализатору Python). Для разделения команд не применяется никаких умственных действий; ввод разделяется по первой паре ;;, даже если она находится в середине строки, заключенной в кавычки. Обходным решением для строк с двойными точками с запятой является использование неявной конкатенации строк ';'';' или ";"";".

Если файл .pdbrc существует в домашнем каталоге пользователя или в текущем каталоге, он считывается и выполняется, как если бы он был набран в приглашении отладчика. Это особенно полезно для псевдонимов. Если оба файла существуют, то сначала считывается тот, который находится в домашнем каталоге, и псевдонимы, определенные в нем, могут быть отменены локальным файлом.

Изменено в версии 3.2: .pdbrc теперь может содержать команды, продолжающие отладку, такие как continue или next. Ранее эти команды не имели никакого эффекта.

h(elp) [command]

Без аргумента выводит список доступных команд. С командой в качестве аргумента выводит справку по этой команде. help pdb выводит полную документацию (docstring модуля pdb). Поскольку аргумент команда должен быть идентификатором, для получения справки по команде help exec необходимо ввести !.

w(here)

Выведите трассировку стека с последним кадром внизу. Стрелка указывает на текущий кадр, который определяет контекст большинства команд.

d(own) [count]

Переместить текущий кадр на количество (по умолчанию один) уровней вниз в трассировке стека (на более новый кадр).

u(p) [count]

Переместить текущий кадр на количество (по умолчанию один) уровней вверх в трассировке стека (на более старый кадр).

b(reak) [([filename:]lineno | function) [, condition]]

С аргументом lineno устанавливает прерывание в текущем файле. С аргументом функция установит прерывание на первом исполняемом операторе в этой функции. Номер строки может быть дополнен именем файла и двоеточием, чтобы указать точку останова в другом файле (возможно, еще не загруженном). Поиск в файле выполняется по команде sys.path. Обратите внимание, что каждой точке останова присваивается номер, на который ссылаются все остальные команды поиска точек останова.

Если присутствует второй аргумент, то это выражение, которое должно быть оценено как true, прежде чем точка останова будет выполнена.

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

tbreak [([filename:]lineno | function) [, condition]]

Временная точка останова, которая удаляется автоматически при первом попадании в нее. Аргументы те же, что и для break.

cl(ear) [filename:lineno | bpnumber ...]

С аргументом filename:lineno очистите все точки останова на этой строке. Со списком номеров точек останова, разделенных пробелами, очистите эти точки останова. Без аргумента очистить все точки останова (но сначала запросить подтверждение).

disable [bpnumber ...]

Отключить точки останова, заданные в виде списка номеров точек останова, разделенных пробелами. Отключение точки останова означает, что она не может привести к остановке выполнения программы, но в отличие от очистки точки останова, она остается в списке точек останова и может быть (повторно) включена.

enable [bpnumber ...]

Включить указанные точки останова.

ignore bpnumber [count]

Устанавливает счетчик игнорирования для заданного номера точки останова. Если значение count опущено, счетчик игнорирования устанавливается в 0. Точка останова становится активной, когда счетчик игнорирования равен нулю. Если счетчик не равен нулю, он уменьшается каждый раз, когда точка останова достигнута, и точка останова не отключена, а любое связанное с ней условие оценивается как true.

condition bpnumber [condition]

Задает новое условие для точки останова, выражение, которое должно быть оценено как true, прежде чем точка останова будет выполнена. Если условие отсутствует, любое существующее условие удаляется; т.е. точка останова становится безусловной.

commands [bpnumber]

Укажите список команд для точки останова с номером bpnumber. Сами команды появляются в следующих строках. Введите строку, содержащую только end для завершения команд. Пример:

(Pdb) commands 1
(com) p some_variable
(com) end
(Pdb)

Чтобы удалить все команды из точки останова, введите commands и сразу же за ним end; то есть, не давайте никаких команд.

Если аргумент bpnumber отсутствует, commands ссылается на последнюю установленную точку останова.

Вы можете использовать команды точки останова, чтобы снова запустить свою программу. Просто используйте команду continue, или step, или любую другую команду, которая возобновляет выполнение.

Указание любой команды, возобновляющей выполнение (в настоящее время continue, step, next, return, jump, quit и их сокращения), завершает список команд (как если бы за этой командой сразу следовал end). Это связано с тем, что при любом возобновлении выполнения (даже при простом next или step) вы можете столкнуться с другой точкой останова, которая может иметь свой собственный список команд, что приведет к неоднозначности в вопросе о том, какой список выполнять.

Если вы используете команду „silent“ в списке команд, обычное сообщение об остановке в точке останова не печатается. Это может быть желательно для точек останова, которые должны вывести определенное сообщение, а затем продолжить работу. Если ни одна из других команд ничего не выводит, вы не видите никаких признаков того, что точка останова была достигнута.

s(tep)

Выполнить текущую строку, остановиться в первом возможном случае (либо в вызываемой функции, либо на следующей строке в текущей функции).

n(ext)

Продолжать выполнение до тех пор, пока не будет достигнута следующая строка в текущей функции или она не вернется. (Разница между next и step заключается в том, что step останавливается внутри вызываемой функции, а next выполняет вызываемые функции на (почти) полной скорости, останавливаясь только на следующей строке в текущей функции).

unt(il) [lineno]

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

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

Изменено в версии 3.2: Разрешить указывать явный номер строки.

r(eturn)

Продолжайте выполнение до тех пор, пока не вернется текущая функция.

c(ont(inue))

Продолжать выполнение, останавливаться только при возникновении точки останова.

j(ump) lineno

Установка следующей строки, которая будет выполнена. Доступно только в самом нижнем фрейме. Это позволяет вернуться назад и выполнить код снова или перейти вперед, чтобы пропустить код, который вы не хотите выполнять.

Следует отметить, что не все переходы разрешены - например, нельзя переходить в середину цикла for или из клаузы finally.

l(ist) [first[, last]]

Перечислить исходный код для текущего файла. Без аргументов перечислить 11 строк вокруг текущей строки или продолжить предыдущий листинг. С аргументом . перечислить 11 строк вокруг текущей строки. С одним аргументом перечислить 11 строк вокруг данной строки. С двумя аргументами перечислить заданный диапазон; если второй аргумент меньше первого, он интерпретируется как счетчик.

Текущая строка в текущем фрейме обозначается ->. Если отлаживается исключение, то строка, в которой оно было первоначально вызвано или распространено, обозначается >>, если она отличается от текущей строки.

Добавлено в версии 3.2: Маркер >>.

ll | longlist

Вывести весь исходный код для текущей функции или кадра. Интересные строки помечаются как для list.

Добавлено в версии 3.2.

a(rgs)

Вывести список аргументов текущей функции.

p expression

Оценить выражение в текущем контексте и вывести его значение.

Примечание

Также можно использовать print(), но это не команда отладчика - она выполняет функцию Python print().

pp expression

Аналогично команде p, только значение выражения выводится с помощью модуля pprint.

whatis expression

Выведите тип выражения.

source expression

Попытаться получить исходный код для заданного объекта и отобразить его.

Добавлено в версии 3.2.

display [expression]

Отображение значения выражения, если оно изменилось, каждый раз, когда выполнение останавливается в текущем кадре.

Без выражения - список всех выражений отображения для текущего кадра.

Добавлено в версии 3.2.

undisplay [expression]

Больше не отображать выражение в текущем кадре. Без выражения - очистить все отображаемые выражения для текущего кадра.

Добавлено в версии 3.2.

interact

Запуск интерактивного интерпретатора (с использованием модуля code), глобальное пространство имен которого содержит все (глобальные и локальные) имена, находящиеся в текущей области видимости.

Добавлено в версии 3.2.

alias [name [command]]

Создайте псевдоним name, выполняющий команду. Команда не должна быть заключена в кавычки. Заменяемые параметры могут быть обозначены %1, %2 и так далее, а %* заменяется всеми параметрами. Если команда не задана, будет показан текущий псевдоним для name. Если аргументы не указаны, перечисляются все псевдонимы.

Псевдонимы могут быть вложенными и могут содержать все, что может быть законно набрано в подсказке pdb. Обратите внимание, что внутренние команды pdb могут быть отменены псевдонимами. Такая команда будет скрыта до тех пор, пока псевдоним не будет удален. Псевдоним рекурсивно применяется к первому слову командной строки; все остальные слова в строке остаются без изменений.

В качестве примера, вот два полезных псевдонима (особенно если их поместить в файл .pdbrc):

# Print instance variables (usage "pi classInst")
alias pi for k in %1.__dict__.keys(): print("%1.",k,"=",%1.__dict__[k])
# Print instance variables in self
alias ps pi self
unalias name

Удалить указанный псевдоним.

! statement

Выполнить (однострочное) выражение в контексте текущего фрейма стека. Восклицательный знак можно опустить, если первое слово утверждения не напоминает команду отладчика. Чтобы задать глобальную переменную, вы можете префикснуть команду присваивания с оператором global в той же строке, например:

(Pdb) global list_options; list_options = ['-l']
(Pdb)
run [args ...]
restart [args ...]

Перезапуск отлаживаемой программы Python. Если указан аргумент, он разделяется с помощью shlex и результат используется в качестве нового sys.argv. История, точки останова, действия и опции отладчика сохраняются. restart является псевдонимом для run.

q(uit)

Выход из отладчика. Выполняемая программа прерывается.

debug code

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

retval

Выведите значение возврата для последнего возврата функции.

Сноски

1

Считается ли кадр происходящим из определенного модуля, определяется __name__ в глобалах кадров.

Вернуться на верх