Статьи

Преобразование мира в Python: упаковка Debian


Пришло время для очередной части моей
текущей
миссии по преобразованию мира в Python 3! На этот раз немного Debian package-fu для модификации существующего пакета Python 2 для включения поддержки Python 3 из того же пакета с исходным кодом.

Сегодня я добавил пакет python3-feedparser в Ubuntu Precise. Что интересно, так это то, что, несмотря на
различные
обнаруженные проблемы,
вышестоящий feedparser 5.1 заявляет о поддержке Python 3 посредством
преобразования
2to3 . И это действительно так (хотя тестовый набор этого не делает).

До сегодняшнего дня Ubuntu имел
в своем архиве
feedparser 5.0.1, и хотя была проделана определенная работа по обновлению
пакета Debian до 5.1, это не было выпущено. Неинтересным предшественником упаковки Python 3 было обновление версии исходного пакета python-feedparser для версии Ubuntu до 5.1. Я избавлю вас от скучных подробностей о пропущенных файлах данных в архиве исходных кодов и других проблемах, поскольку они на самом деле не связаны с усилиями Python 3.

Первоначально Автор Барри Варшавы

Первым шагом было проверить, что feedparser 5.1 работает с Python 3.2 в virtualenv, и это действительно так. Это хорошая новость, потому что это означает, что
setup.py делает правильные вещи, что всегда является лучшим способом начать поддерживать Python 3. Я обнаружил, что гораздо проще создать надежный пакет Debian, если у вас есть надежная
установка. пи в верхнем течении для начала.

Теперь я хотел бы дать вам рецепт для изменения существующих
файлов каталога
debian /, чтобы добавить поддержку Python 3 в пакет, который уже существует для Python 2. Это немного сложнее для feedparser, поскольку он использовал более старую версию
debhelperстандарт, и нес в себе некоторые грубые старые вещи в своем файле правил. Моим первым шагом было обновить его до уровня совместимости debhelper 8 и значительно упростить
файл debian / rules . Вот как это могло бы выглядеть при поддержке только Python 2, так что давайте начнем с этого.

    #!/usr/bin/make -f
    export DH_VERBOSE=1

    %:
        dh $@ --with python2

    override_dh_auto_clean:
        dh_auto_clean
        rm -rf build .*egg-info

    override_dh_auto_test:
    ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
        cd feedparser && python ./feedparsertest.py
    else
        @echo "nocheck set, not running tests"
    endif

    override_dh_installdocs:
        dh_installdocs -Xtests

Это все довольно стандартные вещи. 
Используется dh_python2 (
опция
—with python2 для
dh ), и мы просто предоставляем несколько переопределений для идиосинкразий в пакете feedparser. Мы убираем пару лишних вещей, которые не очищаются автоматически, и запускаем тестовый набор немного нестандартным способом, который требуется для апстрима. Кроме того, мы отменяем установку огромного количества тестовых файлов, которые в противном случае были бы установлены как документация (они не являются документами).

Все идет нормально. Что мы должны сделать, чтобы добавить поддержку Python 3?

Во-первых, нам нужно внести несколько изменений в
файл debian / control . Текущее соглашение с
dh_python2 заключается в использовании
Заголовок X-Python-Version в разделе исходного пакета, поэтому нам просто нужно добавить этот заголовок в тот же раздел для Python 3:

X-Python3-Version: >= 3.2

Это просто говорит о том, что мы поддерживаем любую версию Python 3 начиная с 3.2. Вам также необходимо добавить несколько дополнительных пакетов в
Build-Depends . В случае feedparser я добавил следующие зависимости сборки:
python3 ,
python3-chardet ,
python3-setuptools . Несмотря на то, что для Python 2 есть несколько других зависимостей сборки (например,
python-libxml2 и
python-utidylib ), они не доступны для Python 3, но, к счастью для нас, они в любом случае являются необязательными.

Далее необходимо добавить новый раздел бинарного пакета. Уже был
python-feedparserраздел бинарного пакета для поддержки Python 2. В Debian Python 3 предоставляется в виде отдельного стека, то есть пакеты для Python 3 всегда будут начинаться с
префикса
python3 . Таким образом, довольно просто скопировать
раздел python-feedparser и вставить его в
конец
debian / rules , изменив имя пакета на
python3-feedparser . Вы должны обновить
строку
Depends, чтобы использовать
$ {python3: Depends}, и я обновил
строку
Recommended, чтобы назвать
python3-chardet , и это было об этом. Вот как выглядит новая строфа:

Package: python3-feedparser
Architecture: all
Depends: ${misc:Depends}, ${python3:Depends}
Recommends: python3-chardet
Description: Universal Feed Parser for Python
 Python module for downloading and parsing syndicated feeds. It can
 handle RSS 0.90, Netscape RSS 0.91, Userland RSS 0.91, RSS 0.92, RSS
 0.93, RSS 0.94, RSS 1.0, RSS 2.0, Atom, and CDF feeds.
 .
 It provides the same API to all formats, and sanitizes URIs and HTML.
 .
 This is the Python 3 version of the package.

Опять же, пока все хорошо. Теперь давайте посмотрим на
файл debian / rules .

Первое, что нужно сделать, это добавить поддержку
dh_python3 , которая аналогична
dh_python2 и является единственным принятым помощником для Python 3. Строка правил становится:

    %:
        dh $@ --with python2,python3

Теперь одна проблема с debhelper заключается в том, что он не имеет встроенной поддержки Python 3, как это делает для Python 2. Это означает, что
dh не будет автоматически собирать или устанавливать какие-либо пакеты Python 3, поэтому вам придется делать это вручную. В конце концов,
это будет исправлено , и, к счастью, с твердым
файлом
setup.py вам не нужно ничего делать, но об этом нужно знать. В случае feedparser нам нужно добавить переопределения для
dh_auto_build и
dh_auto_install . Вот как выглядят эти правила:

override_dh_auto_build:
    dh_auto_build
    set -ex; for python in $(shell py3versions -r); do \
        $$python setup.py build; \
    done;

override_dh_auto_install:
    dh_auto_install
    set -ex; for python in $(shell py3versions -r); do \
        $$python setup.py install --root=$(CURDIR)/debian/tmp --install-layout=deb; \
    done;
    cp feedparser/sgmllib3.py $(CURDIR)/debian/tmp/usr/lib/python3/dist-packages/feedparser_sgmllib3.py

Не так уж и плохо, а? Вы заметите, что первое, что делают эти правила, это вызывает стандартные
dh_auto_build и
dh_auto_install соответственно. Это сохраняет поддержку Python 2. Затем мы просто перебираем все доступные версии Python 3, выполняя довольно обычный эквивалент
установки setup.py (разбитый на этап сборки и этап установки). Правило установки выглядит немного странно, но должно быть знакомо хакерам Debian Python. Он просто устанавливает пакет в соответствующие местоположения Debian и будет практически таким же, как и любой пакет Python 3, который вы собираете.

Один нечетный бит — последняя строка в
override_dh_auto_installправить. Это просто для того, чтобы обойти эту особенность в пакете upstream feedparser 5.1, где он зависит от
sgmllib.py, но этого больше нет в стандартной библиотеке Python в Python 3. Upstream предоставляет уже конвертированную версию 2to3 и рекомендует Вы устанавливаете модуль как
sgmllib.py где-нибудь в вашем Python 3
sys.path . Ну, мне не нравится загрязнение пространства имен, которое может вызвать, поэтому я устанавливаю файл как
feedparser_sgmllib3.py и добавляю
лоскутное одеяло в пакет, чтобы попытаться импортировать этот модуль, если импорт
sgmllib завершится неудачно (как это будет в Python 3) ,

В стороне: если вы посмотрите в
Debian / Правилафайл для того, что я на самом деле загрузил, вы увидите некоторые дополнительные модификации
override_dh_auto_test . Это просто работает вокруг ошибки в исходном коде, когда некоторые файлы данных тестового набора были случайно пропущены из архива выпуска. Вы можете в значительной степени игнорировать эти строки для целей этой статьи.

Мы почти закончили. Последнее, что нам нужно сделать, это убедиться, что debhelper устанавливает правильные файлы в правильные двоичные пакеты. Мы хотим,
чтобы бинарный пакет python-feedparser включал только файлы Python 2, а
python3-feedparser бинарный пакет, включающий только файлы Python 3. Помните, что когда исходный пакет собирает только один двоичный пакет (как это было до того, как я добавил поддержку Python 3), debhelper будет включать все содержимое подкаталога debian / tmp каталога сборки
в единый двоичный пакет. Вот почему вы видите, что все устанавливается в
$ (CURDIR) / debian / tmp . Но когда исходный пакет собирает несколько двоичных пакетов, как это происходит сейчас, мы должны сообщить debhelper, какие файлы входят в какие двоичные пакеты. Мы делаем это, добавляя два новых файла в
каталог
debian :
python-feedparser.install и
python3-feedparser.install

Чтение man- страницы для
dh_installобъяснит причины этого и опишет формат содержимого файла. В нашем случае нам действительно повезло, потому что для Python 2 все устанавливается в
usr / lib / python2. *, А в Python 3 все устанавливается в
usr / lib / python3 (относительно
$ (CURDIR) / debian / тм ). Вы заметите несколько вещей здесь. Поскольку мы могли бы собирать для нескольких версий Python 2, мы должны подстановить подстановочный знак фактический каталог в
usr / lib , например, это может быть
python2.6 или
python2.7 . Но потому что у нас есть
PEP 3147 и
PEP 3149в Python 3.2 существует только один каталог для всех поддерживаемых версий Python 3, поэтому нам не нужно подстановочный знак подкаталога. Кроме того, если вы посмотрите на фактические
файлы
.install в пакете, вы увидите несколько других компонентов конечного пути, поэтому фактическое содержимое файлов:

usr/lib/python2.*/*-packages/*

и

    usr/lib/python3/*-packages/*

для
файлов
python-feedparser.install и
python3-feedparser.install соответственно. Конечные биты просто подстановочные знаки, которые в системе Debian всегда будут
dist-пакетами , просто для безопасности (груз, культивирующий FTW!).

И это действительно так! Конечно, все может быть немного сложнее, если у вас есть модули расширения, но, возможно, не намного больше, и если пакет, в который вы добавляете поддержку Python 3, не
основан на setuptools , у вас может быть больше работы даже до сих пор. В пакете feedparser есть несколько других странностей, которые действительно не связаны с добавлением поддержки Python 3, поэтому я их здесь игнорирую, но не стесняюсь спрашивать дополнительную информацию в комментариях, в IRC или по электронной почте.

Надеемся, что это даст вам некоторое представление о том, как расширить существующий пакет Debian для Python 2, включив в него поддержку Python 3, учитывая, что ваш апстрим уже поддерживает Python 3. Теперь пошли и взломали!

Приложение : мой коллега
Колин Уотсон только что упаковал
очень хороший пакет Python
Бенджамина Петерсона под названием
шесть, Это хороший пакет, который предоставляет несколько отличных утилит совместимости Python 2 и 3. Это может оказаться полезным, если вы пытаетесь поддерживать как Python 2, так и Python 3 в единой кодовой базе, особенно если вам необходимо вернуться к Python 2.4 (плохо, вы :). Это будет доступно в Ubuntu Precise, хотя, если вы отправляете исправления обратно, вам, возможно, придется убедить вышестоящего автора принять дополнительную зависимость. Стоит добавить еще немного любви к Python 3 в мир.


Источник: http://www.wefearchange.org/2012/01/debian-package-for-python-2-and-3.html