Документация Python неофициальный перевод
Содержание страницы

pdb – Отладчик Pythonpdb – The Python Debugger

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


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

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

См. также

Модуль faulthandler

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

Модуль 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.

Интерфейс командной строкиCommand-line interface

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

python -m pdb [-c command] (-m module | pyfile) [args ...]

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

-c, --command <command>

Для выполнения команд, как если бы они были заданы в файле .pdbrc; см. Команды отладчика.

Изменено в версии 3.2: Добавлена опция -c.

-m <module>

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

Изменено в версии 3.7: Добавлена опция -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)

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

Изменено в версии 3.7: Добавлен именованный аргумент header.

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

pdb.post_mortem(t=None)

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

Изменено в версии 3.13: Добавлена поддержка объектов исключений.

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. Ранее обработчик SIGINT никогда не устанавливался Pdb.

Изменено в версии 3.6: Добавлен аргумент readrc.

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

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

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

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

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

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

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

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

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

Чтобы установить временную глобальную переменную, используйте удобную переменную (convenience variable). Удобная переменная – это переменная, имя которой начинается с $. Например, $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 отображает полную документацию (docstring модуля pdb). Поскольку аргумент команда должен быть идентификатором, для получения справки по команде ! необходимо ввести help exec.

w(here)

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

d(own) [count]

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

u(p) [count]

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

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

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

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

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

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

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

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

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

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

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

disable bpnumber [bpnumber ...]

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

enable bpnumber [bpnumber ...]

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

ignore bpnumber [count]

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

condition bpnumber [condition]

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

Вычисляет expression в текущем контексте и выводит его значение.

Примечание

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

pp expression

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

whatis expression

Выводит тип expression.

source expression

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

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

display [expression]

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

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

Примечание

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

Пример:

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

Display не заметит, что 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]

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

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

interact

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

Примечание

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

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

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

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

alias [name [command]]

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

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

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

# Вывести переменные экземпляра (использование "pi classInst")
alias pi for k in %1.__dict__.keys(): print(f"%1.{k} = {%1.__dict__[k]}")
# Вывести переменные экземпляра в self
alias ps pi self
unalias name

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

! statement

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

(Pdb) ! n=42
(Pdb)

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

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

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

q(uit)

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

debug code

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

retval

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

exceptions [excnumber]

Список или переключение между связанными исключениями.

При использовании pdb.pm() или Pdb.post_mortem(...) со связанным исключением вместо трассировки стека это позволяет пользователю перемещаться между связанными исключениями с помощью команды exceptions для вывода списка исключений и exceptions <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.

Сноски