Готовим 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

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

[email protected]:~$ mkdir -p /usr/local/egg/[email protected]:~$ mkdir -p /usr/local/egg/lib/python2.4/site-packages

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

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

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

[email protected]:~$ echo $PATH/home/pythy/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/usr/local/egg/[email protected]:~$ echo $PYTHONPATH:/usr/local/egg/lib/python2.4/site-packages

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

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

[email protected]:~$ wget -q http://peak.telecommunity.com/dist/[email protected]:~$ python ez_setup.pyDownloading http://cheeseshop.python.org/packages/2.4/s/setuptools/setuptools-0.6c3-py2.4.eggCreating /usr/local/egg/lib/python2.4/site-packages/site.pyProcessing setuptools-0.6c3-py2.4.eggcreating /usr/local/egg/lib/python2.4/site-packages/setuptools-0.6c3-py2.4.eggExtracting setuptools-0.6c3-py2.4.egg to /usr/local/egg/lib/python2.4/site-packagesAdding setuptools 0.6c3 to easy-install.pth fileInstalling easy_install script to /usr/local/egg/binInstalling easy_install-2.4 script to /usr/local/egg/binInstalled /usr/local/egg/lib/python2.4/site-packages/setuptools-0.6c3-py2.4.eggProcessing dependencies for setuptools==0.6c3

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

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

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

[email protected]:~/tmp/py$ python setup.py install --prefix=/usr/local/stow/PackageName

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

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

[email protected]:~/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\pythyC:\> echo %PATH%C:\WINDOWS;C:\WINDOWS\System32;C:\WINDOWS\System32\Wbem;c:\Python\egg\Scripts;c:\Python\local\Scripts;c:\Python\ScriptsC:\> 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: скачиваем и запускаем:

C:\temp> c:\Python\python.exe ez_setup.pyDownloading http://cheeseshop.python.org/packages/2.4/s/setuptools/setuptools-0.6c3-py2.4.eggCreating c:\python\egg\Lib\site-packages\site.pyProcessing setuptools-0.6c3-py2.4.eggcreating c:\python\egg\Lib\site-packages\setuptools-0.6c3-py2.4.eggExtracting setuptools-0.6c3-py2.4.egg to c:\python\egg\Lib\site-packagesAdding setuptools 0.6c3 to easy-install.pth fileInstalling easy_install-script.py script to c:\python\egg\ScriptsInstalling easy_install.exe script to c:\python\egg\ScriptsInstalling easy_install-2.4-script.py script to c:\python\egg\ScriptsInstalling easy_install-2.4.exe script to c:\python\egg\ScriptsInstalled c:\python\egg\Lib\site-packages\setuptools-0.6c3-py2.4.eggProcessing 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 страшно кривой; да тот же не ставится через easy_install). В-третьих, документация к setuptools такая, что чтобы что-то найти нужно перерыть ее всю. И не факт, что найдешь.

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

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

Подписаться Комментировать

Комментарии

21.12.2006 3:39 Юревич Юрий

Эта зараза WP съел все слеши в Windows-путях.

22.12.2006 13:41 Юревич Юрий

Stow крутая штука! Спасибо за инфу.

23.12.2006 2:37 Юревич Юрий

Спасибо, статья была очень полезной.

Форма комментирования для «Готовим Python Eggs»

Обязательное поле. Не больше 30 символов.

Обязательное поле

Пожалуйста, введите символы, которые вы видите на изображении

29.12.2006 21:14 Юревич Юрий

в ручную” - очепятка.

29.12.2006 22:13 Юревич Юрий

Спасибо, поправил.

4.01.2007 15:27 Юревич Юрий

Спасибо за инструкции, только что настроил и поставил под Линуксом, все работает.

4.01.2007 23:34 Юревич Юрий

Вышеописанные вещи — результат опыта использования “яиц” на 4 машинах (3 из них на Линуксе). Предлагаемый в документации к Python Eggs “lib_install” и “scripts_install” засчитан как менее эффективный по сравнению с “prefix”

12.01.2007 11:16 Юревич Юрий

Вроде как появился setuptools в виде инсталятора для win:

12.01.2007 11:40 Юревич Юрий

Да, похоже вышла версия . Хм, даже src.rpm сделали :-)

18.02.2007 14:29 Юревич Юрий

[…] setuptools позволяют определять точки входа для плагинов. Эти точки определяются у плагинов, а программа, которая хочет использовать плагины “спрашивает” у setuptools, кто реализует данную EP (entry point, точка входа). Прежде чем начать, советую познакомиться с Python eggs и с тем, как их правильно устанавливать. […]

25.04.2007 20:55 Юревич Юрий

приготовил сегодня правильные яйца на свежепоставленном debian etch

что характерно в etch /usr/local drwxrwsr-x root staff
в ubuntu dapper drwxr-xr-x root root

космонавт лажает :(

10.05.2007 17:38 Юревич Юрий

Дальнейшее развитие этой идеи — ставить egg пакеты при помощи stow. Унификация позволит не прописывать дополнительные пути. (Отписал об этом у себя в блоге =)

11.03.2008 15:47 Stan. S. Krupoderov
Спасибо за статью, весьма интересно. http://easy-deb.sourceforge.net/ — создание пакетов Debian из egg файлов.
16.03.2008 15:59 dvs
Способы пакетирования модулей питона: обзор со стороны администратора” http://zope3.ru/stati/sposoby-paketirovaniya-moduley-pitona/
26.03.2009 18:01 Shum_beliy

проделал всё что ты советуешь, но теперь не могу поставить библиотеку вот что пишет:

C:\python\pydelicious>setup.py installC:\python\pydelicious\src__init__.py:27: DeprecationWarning: the md5 module isdeprecated; use hashlib instead import md5Feedparser not available, no RSS parsing.running installrunning bdist_eggrunning egg_infowriting requirements to pydelicious.egg-info\requires.txtwriting pydelicious.egg-info\PKG-INFOwriting top-level names to pydelicious.egg-info\top_level.txtwriting dependency_links to pydelicious.egg-info\dependency_links.txtTraceback (most recent call last): File “C:\python\pydelicious\setup.py”, line 54, in <module> ‘test’: Test, File “c:\Python26\lib\distutils\core.py”, line 152, in setup dist.run_commands() File “c:\Python26\lib\distutils\dist.py”, line 975, in run_commands self.run_command(cmd) File “c:\Python26\lib\distutils\dist.py”, line 995, in run_command cmd_obj.run() File “c:\Python26\egg\Lib\site-packages\setuptools-0.6c9-py2.6.egg\setuptools\command\install.py”, line 76, in run File “c:\Python26\egg\Lib\site-packages\setuptools-0.6c9-py2.6.egg\setuptools\command\install.py”, line 96, in do_egg_install File “c:\Python26\lib\distutils\cmd.py”, line 333, in run_command self.distribution.run_command(command) File “c:\Python26\lib\distutils\dist.py”, line 995, in run_command cmd_obj.run() File “c:\Python26\egg\Lib\site-packages\setuptools-0.6c9-py2.6.egg\setuptools\command\bdist_egg.py”, line 167, in run File “c:\Python26\lib\distutils\cmd.py”, line 333, in run_command self.distribution.run_command(command) File “c:\Python26\lib\distutils\dist.py”, line 995, in run_command cmd_obj.run() File “c:\Python26\egg\Lib\site-packages\setuptools-0.6c9-py2.6.egg\setuptools\command\egg_info.py”, line 177, in run File “c:\Python26\egg\Lib\site-packages\setuptools-0.6c9-py2.6.egg\setuptools\command\egg_info.py”, line 252, in find_sources File “c:\Python26\egg\Lib\site-packages\setuptools-0.6c9-py2.6.egg\setuptools\command\egg_info.py”, line 306, in run File “c:\Python26\egg\Lib\site-packages\setuptools-0.6c9-py2.6.egg\setuptools\command\egg_info.py”, line 330, in add_defaults File “c:\Python26\lib\distutils\command\sdist.py”, line 296, in add_defaults build_py = self.get_finalized_command(‘build_py’) File “c:\Python26\lib\distutils\cmd.py”, line 319, in get_finalized_command cmd_obj.ensure_finalized() File “c:\Python26\lib\distutils\cmd.py”, line 117, in ensure_finalized self.finalize_options() File “c:\Python26\egg\Lib\site-packages\setuptools-0.6c9-py2.6.egg\setuptools\command\build_py.py”, line 16, in finalize_options File “c:\Python26\lib\distutils\command\build_py.py”, line 59, in finalize_options self.package_dir[name] = convert_path(path) File “c:\Python26\lib\distutils\util.py”, line 166, in convert_path raise ValueError, “path ‘%s’ cannot end with ‘/’” % pathnameValueError: path ‘src/’ cannot end with ’/’

C:\python\pydelicious>

28.03.2009 23:37 Юревич Юрий

Вероятно, это ошибка в пакете. Попробуй заменить

package_dir = { 'pydelicious': 'src/' },

на

package_dir = { 'pydelicious': 'src' },

в setup.py. Если поможет — посылай багрепорт разработчикам.

4.04.2009 17:21 Shum_beliy

спасибо

C:\python\pydelicious>setup.py install

так теперь работаета так(по провославному как надо):

C:\python\pydelicious>setup.py install --prefix=c:\Python26\lokal

нет(((вот что пишет:

C:\python\pydelicious>setup.py install --prefix=c:\Python26\lokalC:\python\pydelicious\src\__init__.py:27: DeprecationWarning: the md5 module is deprecated; use hashlib insteadimport md5running installChecking .pth file support in c:\Python26\lokal\Lib\site-packages\error: can't create or remove files in install directoryThe following error occurred while trying to add or remove files in the installation directory:[Errno 2] No such file or directory: 'c:\\Python26\\lokal\\Lib\\site-packags\\test-easy-install-2680.pth'The installation directory you specified (via --install-dir, --prefix, or the distutils default setting) was:c:\Python26\lokal\Lib\site-packages\This directory does not currently exist.  Please create it and try again, or choose a different installation directory (using the -d or --install-dir option).C:\python\pydelicious>

спасибо тебе большое)))))очень помог

4.04.2009 17:23 Shum_beliy

фигня какая то с код

4.04.2009 18:59 Юревич Юрий

Это markdown, нужно отступ в четыре пробела делать.

4.04.2009 19:00 Юревич Юрий

очень помог

велкам