вторник, 17 апреля 2007 г.

Удаленная отладка приложений на Python в Eclipse с Pydev Extensions

Тем кто до сих пор не определился с тем, какой IDE для Python лучше всех, скажу, что лучший IDE — это Eclipse с плагином Pydev. Функции и вкусности перечислять не буду, скажу только что всё чего вам скорее всего захочется, в нем есть, и можно органично использовать все остальные прелести Eclipse, например интеграцию с системой контроля версий. Можете со мной спорить, но это мой блог, что хочу то и пишу :)

К базовому бесплатному Pydev также существует расширение Pydev Extensions, которое, кроме того что все-таки уже стоит денег — $42,5, на которые финансируется разработка "бесплатного" Pydev — хотя, по правде говоря, позволяет работать и бесплатно, только настойчиво напоминая о том, что хочет денег. Pydev Extensions дополняет базовый пакет некоторыми приятными возможностями, среди которых — возможность удаленной отладки. Под удаленной я имею в виду отладку во внешнем по отношению к Eclipse процессе. Он может работать как на той же машине, на которой работает Eclipse, так и на удаленной, "разговаривая" с Eclipse по TCP/IP. Простая отладка возможна и без использования Pydev Extensions.

На практике это означает, что можно запросить страницу из вашего приложения, скажем на Django, и трассировать процесс генерации страницы в Eclipse. На блоге разработчиков есть статья о том как подружить Pydev с Django, в принципе, все как обычно в Eclipse. Там же описано как запустить Django из Eclipse и делать отладку обычным дебагером, тоже не ядерная физика. Я же остановлюсь на удаленной отладке (для чего нам понадобятся Pydev Extensions).

По поводу удаленной отладки разработчики также написали у себя в блоге. Информация там дана очень сжато и в моем случае не совсем соответствует действительности (в той части где про то где находятся кнопки для запуска и останова debug server). Моя инструкция будет такая.

  1. Для работы удаленного дебагера нужно, чтобы из процесса python, который мы собираемся трассировать, был доступен модуль pydevd. Исходники модуля и всего что он требует — в каталоге org.python.pydev.debug_<версия pydev>/pysrc, что в каталоге установки плагинов Eclipse (под Linux это может быть подкаталог .eclipse вашего домашнего каталога). Копируем каталог pysrc со всем содержимым туда, откуда он будет доступен через PYTHONPATH вашего приложения. Переименовываем скопированный каталог в более подходящее название — pydev.


  2. Для того, чтобы Eclipse получала команды от удаленного отладчика, нужно запустить debug server в Eclipse. Для этого нужно открыть перспективу Debug и в ней нажать кнопку, указанную на картинке:



    После нажатия появится информация о запущенном сервере:



  3. Для того чтобы начать отладку, необходимо запустить функцию из пакета pydev, который мы сделали на шаге 1. Для этого выберите место в коде, с которого хотите начать трассировку, и добавьте выше него следующий код:

    from pydev import pydevd;pydevd.settrace(myIp)


    Аргумент myIp для функции settrace — это IP-адрес машины, на которой запущена Eclipse (и debug server, соответственно). Для удобства это значение можно установить в settings.py и вызывать settrace, например, так: pydevd.settrace(settings.REMOTE_DEBUG_HOST).
    Если приложение запущено не под встроенным сервером Django, а под mod_python или в режиме FastCGI, то нужно будет перезапустить Apache или процесс приложения соответственно.

  4. В-общем, всё готово для сеанса удаленной отладки. Откройте браузер, отправьте запрос приложению и переключитесь обратно в Eclipse. Если код трассировщика, который мы добавили на предыдущем шаге, будет задействован в процессе обработки запроса, то вы увидите примерно такую картину:



    Вверху вы видите стек вызовов, справа — локальные переменные, внизу - код в процессе отладки. Подсвеченная строка - следующая инструкция после вызова settrace. Вы можете трассировать код дальше как обычно, перемещаться по стеку и просматривать значения переменных.


В настоящее время с удаленным дебагером связано одно неудобство. Состоит оно в следующем.
Удаленный дебаг-сервер (код которого в пакете pydev, который мы устанавливали на первом шаге) передает в Eclipse отладочную информацию, и в ней в качестве имени файла, в котором идет отладка, передается полный путь к файлу на удаленной машине. Этот путь почти наверняка не будут совпадать с именем файла на машине разработчика, где и запущен Eclipse, если это — не та же машина, на которой запущено трассируемое приложение. Если обе машины работают под сходными системами (например, обе - под Windows или под Unix/Linux), то это затруднение преодолимо. Если же машина, на которой запущено веб-приложение, работает под Linux, а машина разработчика — Windows (ситуация распространенная), то стандартными средствами это несовпадение путей решить не получится.
В результате дебагер не будет находить нужный файл на вашей машине, и будет спрашивать вас на каждом шаге, какой именно файл имелся в виду.

Для этой проблемы я нашел следующее решение. В коде pydevd была найдена функция, которая определяет путь к файлу на удаленной машине, который затем и отправляется вместе с отладочной информацией. Эта функция переработана так, чтобы она транслировала путь на удаленной машине в соответствующий путь на локальной машине. Найдите в файле pydevd_comm.py в пакете pydev функцию NormFile и перепишите ее так:

FILE_TRANS_MAP = {'/home/max/project/': 'z:/',
'/usr/lib/python2.4/': 'c:/Python24/Lib/'}

def NormFile(filename):
try:
rPath = os.path.realpath #@UndefinedVariable
except:
# jython does not support os.path.realpath
# realpath is a no-op on systems without islink support
rPath = os.path.abspath
fname = os.path.normcase(rPath(filename))
for _from, _to in FILE_TRANS_MAP.items():
if fname.startswith(_from):
fname = fname.replace(_from, _to, 1)
break
return fname


В словаре FILE_TRANS_MAP укажите свои соответствия (в моем случае транслируются пути к стандартной установке Python и каталогу проекта, который подключен к машине под Windows через Samba). После этого дебагер Eclipse будет получать имена файлов в том виде, в котором они доступны на локальной машине.

Конечно, было бы удобнее задавать соответстия путей не в коде удаленного сервера, а в свойствах проекта в самом Eclipse. Такое предложение отправлено разработчикам и они собираются внедрить его в одной из ближайших версий Pydev Extensions, а пока можно пользоваться этим рецептом.

Happy debugging :)

8 комментариев:

  1. Спасибо за подробную статью. Как раз хотел на досуге попробывать прикрутить django в Eclipse pydev.

    ОтветитьУдалить
  2. Супер! Спасибо за наводку. Попробовал, и у меня получилось. Протащился как удав по гравию, просто супер. ;)

    ОтветитьУдалить
  3. А я лучшим IDE для Питона считаю WingIDE.

    ОтветитьУдалить
  4. А мне нравится PyScripter, жалко только что под линукс версии нет

    ОтветитьУдалить
  5. Решил попробовать PyDev, сразу возникла небольшая проблемка. Извиняюсь, что не в тему. У меня Ubuntu и django из svn, в site-packages символическая ссылка на django (как рекомендовалось в документации). PyDev напрочь отказывается обрабатывать каталоги, заданные таким образом. Обойти этот баг (фичу?) просто, но нехорошо :(

    ОтветитьУдалить
  6. &gt;&gt;stoune Says:
    &gt;&gt;25-05-2007 at 4:33
    &gt;&gt;
    &gt;&gt;А я лучшим IDE для Питона &gt;&gt;считаю WingIDE

    А как насчет того что это есть платное как это можно использовать без покупки?

    ОтветитьУдалить
  7. А как у нас все в России используется?... ;) мне лично тоже он понравился

    ОтветитьУдалить
  8. Сам перешел с винга на пайдев. Самый большой вопрос, который меня интересует - как заставить его табы вставлять как табы, и ни в коем случае на пробелы. А то что он туда вставляет - похоже от фазы луны зависит.

    ОтветитьУдалить

Постоянные читатели