Spec-Zone.ru › Python 3.13

pdb — Отладчик Python

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

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

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

См. также

Module faulthandler

Используется для явного вывода трассировок Python при ошибках, по истечении таймаута или при сигнале пользователя.

Module traceback

Стандартный интерфейс для извлечения, форматирования и вывода стековых трассировок программ Python.

Типичное использование для перехода в отладчик состоит в вставке:

import pdb; pdb.set_trace()

Или:

breakpoint()

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

Изменено в версии 3.7: Встроенная функция breakpoint(), когда вызывается с параметрами по умолчанию, может использоваться вместо import pdb; pdb.set_trace().

def double(x):
   breakpoint()
   return x * 2
val = 3
print(f"{val} * 2 is {double(val)}")

Подсказка отладчика — (Pdb), что указывает на то, что вы находитесь в режиме отладки:

> ...(2)double()
-> breakpoint()
(Pdb) p x
3
(Pdb) continue
3 * 2 is 6

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

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

python -m pdb myscript.py

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

Изменено в версии 3.2: Добавлен параметр -c для выполнения команд, как если бы они были указаны в файле .pdbrc; см. Команды отладчика.

Изменено в версии 3.7: Добавлен параметр -m для выполнения модулей аналогично тому, как это делает python -m. Как и со скриптом, отладчик приостановит выполнение непосредственно перед первой строкой модуля.

Типичное использование для выполнения инструкции под управлением отладчика:

>>> import pdb
>>> def f(x):
...     print(1 / x)
>>> pdb.run("f(2)")
> <string>(1)<module>()
(Pdb) continue
0.5
>>>

Типичное использование для проверки аварийной программы:

>>> import pdb
>>> def f(x):
...     print(1 / x)
...
>>> f(0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in f
ZeroDivisionError: division by zero
>>> pdb.pm()
> <stdin>(2)f()
(Pdb) p x
0
(Pdb)

Изменено в версии 3.13: Реализация PEP 667 означает, что присваивания имён, сделанные через 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.

Изменено в версии 3.13: set_trace() немедленно включит отладчик, а не на следующей строке кода, которая будет выполнена.

pdb.post_mortem(traceback=None)

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

pdb.pm()

Перейти к постмортальной отладке исключения, найденного в sys.last_exc.

Функции 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()

Вызывает событие аудита pdb.Pdb без аргументов.

Изменено в версии 3.1: Добавлен параметр skip.

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

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

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

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

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

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

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

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

Изменено в версии 3.13: Выражения/операторы, префикс которых является командой pdb, теперь правильно идентифицируются и выполняются.

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

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

Для установки временной глобальной переменной используйте удобную переменную. Удобная переменная — это переменная, имя которой начинается с $. Например, $foo = 1 устанавливает глобальную переменную $foo, которую можно использовать в сеансе отладчика. Удобные переменные очищаются при возобновлении выполнения программы, поэтому они менее склонны к конфликту с вашей программой по сравнению с использованием обычных переменных, например, foo = 1.

Существует три предопределённые удобные переменные:

  • $_frame: текущий кадр, который вы отлаживаете
  • $_retval: возвращаемое значение, если кадр возвращается
  • $_exception: исключение, если кадр поднимает исключение

Добавлен в версии 3.12: Добавлена функция удобной переменной.

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

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

Изменено в версии 3.11: .pdbrc теперь читается с кодировкой 'utf-8'. Раньше он читался с кодировкой системного локали.

h(elp) [command]

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

w(here)

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

d(own) [count]

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

u(p) [count]

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

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

С аргументом lineno устанавливает точку останова на строке lineno в текущем файле. Номер строки может быть префиксом с именем файла и двоеточием, чтобы указать точку останова в другом файле (возможно, ещё не загруженном). Файл ищется в sys.path. Допустимые формы имени файла — /abspath/to/file.py, relpath/file.py, module и package.module.

С аргументом функция устанавливает точку останова на первой исполняемой строке в данной функции. Функция может быть любым выражением, которое оценивается как функция в текущем пространстве имён.

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

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

Каждой точке останова присваивается номер, к которому ссылаются все другие команды точек останова.

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

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

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

С аргументом имя_файла:номер_строки очищает все точки останова в этой строке. Со списком номеров точек останова, разделенных пробелами, очищает эти точки останова. Без аргумента очищает все точки останова (но сначала спрашивает подтверждение).

disable bpnumber [bpnumber ...]

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

enable bpnumber [bpnumber ...]

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

ignore bpnumber [count]

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

condition bpnumber [condition]

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

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 и их сокращения) завершает список команд (как если бы эта команда была сразу за списком). Это происходит потому, что каждый раз, когда вы возобновляете выполнение (даже с простой командой next или step), вы можете столкнуться с другой точкой останова — которая может иметь свой собственный список команд, что приводит к неоднозначности относительно того, какой список выполнить.

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

s(tep)

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

n(ext)

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

unt(il) [lineno]

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

С аргументом lineno продолжить выполнение до достижения строки с номером, большим или равным 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]

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

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

Примечание

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

Пример:

lst = []
breakpoint()
pass
lst.append(1)
print(lst)

Отображение не поймёт, что lst был изменён, потому что результат вычисления изменяется на месте модулем lst.append(1) до сравнения:

> example.py(3)<module>()
-> pass
(Pdb) display lst
display lst: []
(Pdb) n
> example.py(4)<module>()
-> lst.append(1)
(Pdb) n
> example.py(5)<module>()
-> print(lst)
(Pdb)

Можно использовать некоторые приёмы с механизмом копирования, чтобы это работало:

> example.py(3)<module>()
-> pass
(Pdb) display lst[:]
display lst[:]: []
(Pdb) n
> example.py(4)<module>()
-> lst.append(1)
(Pdb) n
> example.py(5)<module>()
-> print(lst)
display lst[:]: [1]  [old: []]
(Pdb)

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

undisplay [expression]

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

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

interact

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

Примечание

Поскольку interact создаёт новое отдельное пространство имён для выполнения кода, присваивания переменным не повлияют на исходные пространства имён. Однако, изменения любых ссылающихся на изменяемые объекты будут отражены в исходных пространствах имён, как обычно.

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

Изменено в версии 3.13: exit() и quit() могут быть использованы для выхода из команды interact.

Изменено в версии 3.13: interact направляет свой вывод в канал вывода отладчика, а не в sys.stderr.

alias [name [command]]

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

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

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

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

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

! statement

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

(Pdb) ! n=42
(Pdb)

Для установки глобальной переменной можно префикснуть команду присваивания оператором global в той же строке, например:

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

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

q(uit)

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

END_OF_DOCUMENT_MARKER
debug code

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

retval

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

exceptions [excnumber]

Список или переход между цепочками исключений.

При использовании pdb.pm() или Pdb.post_mortem(...) с цепочкой исключений вместо трассировки стека, это позволяет пользователю перемещаться между цепочками исключений с помощью команды exceptions для просмотра исключений и exception <number> для перехода к этому исключению.

Пример:

def out():
    try:
        middle()
    except Exception as e:
        raise ValueError("reraise middle() error") from e

def middle():
    try:
        return inner(0)
    except Exception as e:
        raise ValueError("Middle fail")

def inner(x):
    1 / x

 out()

вызов pdb.pm() позволит переключаться между исключениями:

> example.py(5)out()
-> raise ValueError("reraise middle() error") from e

(Pdb) exceptions
  0 ZeroDivisionError('division by zero')
  1 ValueError('Middle fail')
> 2 ValueError('reraise middle() error')

(Pdb) exceptions 0
> example.py(16)inner()
-> 1 / x

(Pdb) up
> example.py(10)middle()
-> return inner(0)

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

Примечания

[1]

Определение того, происходит ли кадр от определенного модуля, определяется в __name__ в глобальных переменных фрейма.

© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/pdb.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API