Fork me on GitHub
21/12/2006

Готовим Python Eggs

Более чем уверен, что работая с Python, вы рано или поздно столкнетесь (или уже столкнулись) с Python Eggs, в просторечии - яйцами. И я, встретив их достаточно давно, какое то время избегал пользоваться ими. Как выяснилось - зря. Чтобы ваше знакомство с eggs было легким и непринужденным, я и написал эту заметку.

Установка пакетов

Существует три способа поставить Python-пакет:

  1. Стандартным для системы способом (пакет для Linux, инсталлятор для Windows)
  2. Из исходных текстов
  3. Python eggs

Первый и последний -- это пакеты в бинарном виде, т.е. скомпилированные под определенную версию Python: 2.3, 2.4, 2.5. Второй является универсальным, однако зачастую требует C-компилятора.

Естественно, рекомендуемым способом является первый. Но тут есть одно "но": если у Linux-систем с зависимостями между пакетами всё в относительном порядке, то в Windows не всё гладко. Инструмента, который бы отслеживал зависимости программ, в Windows просто нет. Поэтому, авторам пакетов в виде инсталляторов лишь остается указывать в документации, что необходимо поставить, чтобы данный пакет заработал.

Python eggs позволяют использовать кроссплатформенный механизм зависимостей для Python-пакетов. В отличии от принятой в Linux-дистрибутивах концепции, зависимости eggs-пакета пытаются "разрешиться" уже после установки пакета. Для Windows это весьма большой шаг вперед, а вот для Linux не однозначно: дело в том, что системные инструменты (APT в случае Debian и Ubuntu) ничего не знают об установленных при помощи easy_install пакетах, и наоборот - easy_install не находит уже установленные при помощи APT пакеты, скачивая их заново. Было бы очень здорово, если бы существовал инструмент конвертации из egg в deb. Часто в deb просто нет пакетов, которые есть в egg (например, Pylons), либо они опаздывают по версиям (например, Paste).

Стоит отметить, что eggs хороши, когда есть постоянное подключение к Internet, или хотя бы во время выполнения команды easy_install, в других случаях они не так удобны.

Linux

Информация к размышлению

Немного отвлекусь от разговора об eggs и поясню как и куда ставятся Python-пакеты. Системные пакеты (т.е. те, которые устанавливаются при помощи APT или другого менеджера пакетов) помещаются в /usr/lib/python2.4/site-packages. Если вы сами ставите пакет при помощи python setup.py install, то он по умолчанию помещается в вышеуказанный каталог, куда доступ на запись - только у root. Так что, чтобы установить установить "руками" пакет в рекомендуемый /usr/local/lib/python2.4/site-packages нужно указать опцию prefix. Иными словами, полагается, что в /usr пользователь вообще ничего не меняет вручную, всё делается при помощи соответствующих инструментов (или, как говорят, в /usr не должно быть ничего, что не знает APT).

Во-первых, я рассматриваю варианты, когда используется стабильная версия Debian (3.1 Sarge) или LTS-версия Ubuntu (6.06 Dapper Drake). Во-вторых, предполагаю использование Python-2.4. Любое из этих предположений не принципиально, однако принято для определенности. В более свежих версиях Debian и Ubuntu поменялась Python-инфраструктура, но лишь для пакетов, устанавливаемых при помощи APT, так что для сегодняшнего разговора это не столь важно.

Вот тут и выходит на сцену setuptools: easy_install по умолчанию желает ставить eggs в /usr/lib/python2.4/site-packages, т.е. в каталог, который доступен на запись только пользователю root. И очень многие соглашаются с этим желанием и используют команду sudo easy_install NeededPackage, т.е. запускают easy_install с root-привилегиями и это в корне не верно. А правильный способ - это указать setuptools ставить eggs в отдельный каталог. И я бы советовал не использовать для этого дела /usr/local/lib/python2.4/site-packages по простой причине - держать яйца в разных корзинах. И тогда вы точно будете знать, какой пакет поставили при помощи APT, какой "руками", а какой - при помощи easy_install. Более того, при установке пакетов "руками" я бы вам советовал воспользоваться stow чтобы точно знать какой файл кому принадлежит.

Однако есть один момент: для easy_install (при помощи которого ставятся eggs) и distutils (который "работает", когда вы делаете python setup.py install используются одни и те же конфигурационные файлы. Я предлагаю такой подход: в конфиге указываем опции для eggs и ставим их просто easy_install NeededPackage, а для установки "руками" используем опцию --prefix.

Пошаговые инструкции

Прежде чем ставить setuptools, нужно написать конфиг ~/.pydistutils.cfg. В конфиге указываем где будут библиотеки и где исполняемые файлы. Я предлагаю ставить в /usr/local/egg.

[install]
prefix=/usr/local/egg

Далее, нужно создать необходимые каталоги:

pythy@axcel:~$ mkdir -p /usr/local/egg/bin
pythy@axcel:~$ mkdir -p /usr/local/egg/lib/python2.4/site-packages

Теперь время подготовить переменные окружения. Добавьте строки

export PATH="${PATH}":/usr/local/egg/bin
export PYTHONPATH="${PYTHONPATH}":/usr/local/egg/lib/python2.4/site-packages

в ~/.bashrc и выйти и зайдите в систему. Проверьте, что переменные установлены:

pythy@axcel:~$ echo $PATH
/home/pythy/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/usr/local/egg/bin
pythy@axcel:~$ echo $PYTHONPATH
:/usr/local/egg/lib/python2.4/site-packages

Всё, теперь вы готовы к установке setuptools. Рекомендуемый мной способ - установка штатным для системы образом. Т.е. для Debian и Ubuntu это aptitude install python-setutools. Однако, может такое случится, что нужна более свежая версия, чем есть в пакетах. В этом случае, как запасной вариант, можно установить и как egg:

Для работы setuptools понадобится пакет python-dev, так что установите его заблаговременно

pythy@axcel:~$ wget -q http://peak.telecommunity.com/dist/ez_setup.py
pythy@axcel:~$ python ez_setup.py
Downloading http://cheeseshop.python.org/packages/2.4/s/setuptools/setuptools-0.6c3-py2.4.egg
Creating /usr/local/egg/lib/python2.4/site-packages/site.py
Processing setuptools-0.6c3-py2.4.egg
creating /usr/local/egg/lib/python2.4/site-packages/setuptools-0.6c3-py2.4.egg
Extracting setuptools-0.6c3-py2.4.egg to /usr/local/egg/lib/python2.4/site-packages
Adding setuptools 0.6c3 to easy-install.pth file
Installing easy_install script to /usr/local/egg/bin
Installing easy_install-2.4 script to /usr/local/egg/bin

Installed /usr/local/egg/lib/python2.4/site-packages/setuptools-0.6c3-py2.4.egg
Processing dependencies for setuptools==0.6c3

После этого можете спокойно пользоваться easy_install для установки необходимых пакетов.

Установка пакетов "вручную"

Я рекомендую использовать stow для контроля приложений, установленных "руками", в том числе и Python-пакеты. Используется очень просто: в качестве префикса для установки указываем /usr/local/stow/PackageName:

pythy@axcel:~/tmp/py$ python setup.py install --prefix=/usr/local/stow/PackageName

после этого идем в /usr/local/stow и выполняем команду stow PackageName. В результате имеем в /usr/local/lib и /usr/local/bin только симлинки, по адресу которых можно легко определить к какому пакету относится тот или иной файл.

Если же вам не хочется использовать stow, то можете ставить Python-пакеты так:

pythy@axcel:~/tmp/py$ python setup.py install --prefix=/usr/local

В этом случае все скрипты будут в /usr/local/bin, а все пакеты - в /usr/local/lib/python2.4/site-packages.

Windows

Информация к размышлению

Тут ситуация примерно такая же, но немного с другими нюансами. В Windows есть три способа поставить Python-пакет: инсталлятор, стандартный python setup.py install и eggs. Второй способ менее распространен, в силу того, что в случае C-расширения всё упирается в отсутствие C-компилятора под Windows, поэтому наибольшее распространение под Windows получил первый способ (ну и третий, с некоторых пор). По умолчанию пакеты, установленные любым из трех способов, помещаются в C:\Python\Lib\site-packages (полагая C:\Python каталогом, куда вы ставили Python). Как и в Linux, я бы советовал не смешивать пакеты, установленные разными способами и указать для eggs отдельное место, равно как и для "ручной" установки.

Пошаговые инструкции

Прежде чем ставить setuptools, нужно написать конфиг ~/pydistutils.cfg. Но тут есть одно "но": конфиг не будет считываться до тех пор, пока не определена переменная окружения %HOME%. Поэтому, прежде чем писать конфиг, настроим переменные окружения: Мой компьютер->Свойства->Дополнительно->Переменные окружения. Если у вас аккаунт администратора, то можете изменять общесистемные переменные. Если же у вам пользовательский аккаунт, то остаются переменные пользовательского уровня.

Переменная Значение Примечание
HOME c:\Documents and Settings\pythy Вместо pythy указываете имя пользователя. Рекомендуется зайти в D&S и посмотреть.
PATH c:\Python\egg\Scripts;c:\Python\local\Scripts;c:\Python\Scripts Добавляем в путь по умолчанию все каталоги, куда будут помещаться скрипты (соответственно, установлены как egg, "руками" и инсталлятором)
PYTHONPATH c:\Python\egg\Lib\site-packages;c:\Python\local\Lib\site-packages c:\Python - это место, куда установлен Python

Проверяем в командной строке:

C:\> echo %HOME%
c:\Documents and Settings\pythy
C:\> echo %PATH%
C:\WINDOWS;C:\WINDOWS\System32;C:\WINDOWS\System32\Wbem;c:\Python\egg\Scripts;c:\Python\local\Scripts;c:\Python\Scripts
C:\> echo %PYTHONPATH%
c:\Python\egg\Lib\site-packages;c:\Python\local\Lib\site-packages

Теперь в каталоге, который указали как %HOME% создаем конфигурационный файл pydistutils.cfg (без точки в начале имени!) примерно такого содержимого:

[install]
prefix=c:\Python\egg

Теперь создаем указанные в %PATH% и %PYTHONPATH% каталоги.

Вроде всё. Поскольку setuptools в виде инсталлятора нет, то ставим в виде egg: скачиваем ez_setup.py и запускаем:

C:\temp> c:\Python\python.exe ez_setup.py
Downloading http://cheeseshop.python.org/packages/2.4/s/setuptools/setuptools-0.6c3-py2.4.egg
Creating c:\python\egg\Lib\site-packages\site.py
Processing setuptools-0.6c3-py2.4.egg
creating c:\python\egg\Lib\site-packages\setuptools-0.6c3-py2.4.egg
Extracting setuptools-0.6c3-py2.4.egg to c:\python\egg\Lib\site-packages
Adding setuptools 0.6c3 to easy-install.pth file
Installing easy_install-script.py script to c:\python\egg\Scripts
Installing easy_install.exe script to c:\python\egg\Scripts
Installing easy_install-2.4-script.py script to c:\python\egg\Scripts
Installing easy_install-2.4.exe script to c:\python\egg\Scripts

Installed c:\python\egg\Lib\site-packages\setuptools-0.6c3-py2.4.egg
Processing dependencies for setuptools==0.6c3

После этого можете спокойно пользоваться easy_install для установки необходимых пакетов.

Установка пакетов "вручную"

Аналогично Linux-случаю, только stow для Windows нет, так что особого варианта у нас не остается, поэтому используем

C:\temp> c:\Python\python.exe setup.py install --prefix=c:\Python\local

О чем я не рассказал

Откуда собственно скачиваются пакеты. Описание пакетов ищутся на cheese shop, сами пакеты берутся либо с cheese shop (если есть), либо с домашней страницы (поле "Home page" в описании), либо со страницы скачивания (поле "Download page" в описании). Если файл называется не в виде "PackageName-version.tar.gz" или "PackageName-pyX.Y.egg", то easy_install не найдет его. Пример такого случая - PIL (на cheese shop пакет называется PIL, на странице скачивания - Imaging). Опцией -f можно указать URL для поиска пакетов.

О недостатках. Во-первых, нет нормального способа удалить egg. Только вручную. Очень и очень глупо. Во-вторых, достаточно часто встречаются пакеты, авторы которых не умеют нормально собирать их (на вскидку, Pythonutils в egg страшно кривой; да тот же Django-0.95 не ставится через easy_install). В-третьих, документация к setuptools такая, что чтобы что-то найти нужно перерыть ее всю. И не факт, что найдешь.

Об интеграции с svn. При наличии установленной Subversion, setuptools умеет делать eggs из svn-срезов, а также работать в devel-режиме (когда пакет физически не копируется, а делается симлинк).

О плагинах. В setuptools есть схема плагинов, называемая "entry points", точками входа. Достаточно широко используется разработчиками TurboGears, Pylons, Paste. Про это потом напишу отдельно.

Комментарии

Все статьи