Готовим 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 Юревич Юрий

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

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>

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

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

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

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

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

4.04.2009 17:23 Shum_beliy

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

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

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

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

очень помог

велкам