Отладка Python приложений с помощью pdb

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

Отладка Python-кода с помощью print

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

Но самая большая проблема в использовании print() — это необходимость вносить изменения в код и перезапускать приложение, чтобы увидеть изменения. Давайте разберёмся, почему отладчики эффективнее.

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

Главная задача отладчика — предоставить возможность заглянуть в процесс выполнения кода. Так, например, можно просмотреть стек вызовов, узнать значения переменных, установить брейкпоинты или запустить выполнение кода построчно. Можно провести аналогию с тем, как автомеханик заглядывает под капот автомобиля и начинает перебирать деталь за деталью, пока не найдет причину поломки.

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

Python есть встроенный отладчик под названием pdb. Это простая консольная утилита, которая обладает основной функциональностью для отладки кода. Но если вы ищете что-то более продвинутое, то стоит обратить внимание на ipdb – отладчик с функциональностью из IPython.

Проще всего вызвать pdb из кода, где вы работаете:

import pdb; pdb.set_trace() 

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

list (l)

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

up (p) и down (d)

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

step (s) и next (n)

Другая пара не менее важных команд. С их помощью можно выполнять код построчно. Единственное различие между ними в том, что next(n) перейдёт к следующей строке вне зависимости от вызываемых функций, а step(s) перейдёт в вызванную функцию, если это возможно.

break (b)

Эта команда позволяет создавать брейкпоинты без внесений изменений в код. Ниже разберём этот этап более детально.

Краткий список команд pdb:

  • args (a) — выводит аргументы функции;
  • continue (c) или (cont) — продолжит выполнение до первого брейкпоинта или до завершения программы;
  • help (h) — выводит список доступных команд или подсказки по определённой команде;
  • jump (j) — перепрыгивает к выполнению указанной строчки кода;
  • list (i) — выводит исходный код программы вокруг выбранной строки;
  • expression (p) — выводит значение выражения;
  • pp — выводит значение в «красивом» виде;
  • quit или exit (q) — отменяет выполнение программы;
  • return (r) — завершает выполнение текущей функции.

Продолжаем изучать отладчик Python

Рассмотренный ранее способ работы с отладчиком требовал внесения изменения в код для вывода чего-нибудь или установки брейкпоинта. Но часто при работе с внешними библиотеками появляется необходимость в их отладке. Конечно, можно открыть исходный код библиотеки и вызвать pdb.

Но теперь есть возможность запускать приложение напрямую из отладчика без внесения изменения в код. Для этого воспользуемся следующей командой:

$ python3 -m pdb <имя скрипта>

Давайте разберём на примере. Есть простое приложение, которое отслеживает рабочее время. Для её работы используется библиотека requests, отвечающая за выполнение HTTP-запросов. Попробуем прервать выполнение во время запроса. Как это сделать? Запустим приложение через отладчик и установим брейкпоинт внутри библиотеки requests.

$ python3 -m pdb run.py
> /Users/.........................../run.py(1)<module>()
-> from TimeLog.app import run_app
(Pdb) b requests/sessions.py:555
Breakpoint 1 at /..................../lib/python3.6/site-packages/requests/sessions.py:555
(Pdb) c

Как можно заметить, не нужно указывать полный путь до библиотеки. Можно указать относительную ссылку от sys.path. Таким же образом можно отлаживать и ваше приложение.

Теперь куда проще отлаживать код. Не надо вносить изменения в приложение или во внешние библиотеки.

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

В данном примере прерывание произойдёт только в случае, если json будет иметь в себе ключ time_entry.

$ python3 -m pdb run.py 
> /Users/...../run.py(1)<module>()
-> from TimeLog.app import run_app
(Pdb) b requests/sessions.py:555, json is not None and 'time_entry' in json
Breakpoint 1 at /Users/....../lib/python3.6/site-packages/requests/sessions.py:555 
(Pdb) c

Отладка кода Django

Если вы используете Django, то скорее всего знаете, что, если в настройках значение параметра DEBUG установлено как True, то для каждого исключения будет выводиться отдельная страница с указанием типа исключения, стек вызовов, локальные переменные и т.д.

Если вы хотите прокачать отладчик, то установите django-extensions и используйте команду runserver_plus для запуска сервера. Также можно указать пароль для доступа к отладке следующей командой:

WERKZEUG_DEBUG_PIN=1234 ./manage.py runserver_plus

Прим. перев. В WERKZEUG, начиная с версии 0.11, появилась возможность доступа по паролю к отладчику. Это сделано для повышения безопасности при попытках несанкционированного доступа.

Если вы используете django-extensions, то получите страницу со всеми вызовами, кодом и окном отладчика.

Процесс отладки осуществляется с помощью WSGI библиотеки Werkzeug.

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

 

Перевод статьи «Debugging Python Applications with pdb»

Подобрали два теста для вас:
— А здесь можно применить блокчейн?
Серверы для котиков: выберите лучшее решение для проекта и проверьте себя.