Как объявить зависимости времени сборки, не нарушая другие пакеты?


Я столкнулся с проблемой при установке пакета, который зависел от python-daemon. В конечном счете я проследил его до последней версии пакета python-daemon (2.0.3), выпущенной вчера. Тестирование в виртуальной среде на машине Ubuntu 14.04 и выдача следующих команд:

(venv) $ pip list
argparse (1.2.1)
pip (1.5.6)
setuptools (3.6)
wsgiref (0.1.2)
(venv) $ pip install redis
 ... works fine ....
(venv) $ pip install python-daemon
 ...
 snip
 ...   
 File "/home/pwj/.virtualenvs/venv/local/lib/python2.7/site-packages/pkg_resources.py", line 2147, in load

['__name__'])

ImportError: No module named version

(venv)02:15 PM tmp$ pip list
argparse (1.2.1)
lockfile (0.10.2)
pip (1.5.6)
python-daemon (2.0.3)
setuptools (3.6)
wsgiref (0.1.2)

Таким образом, установка python-daemon, Казалось, работала, но что-то повлияло на pip или setuptools, потому что другие пакеты (celery, flask), я пытаюсь установить с pip после этого дает мне тот же traceback:

 ...
 snip
 ...   

 File "/home/pwj/.virtualenvs/venv/local/lib/python2.7/site-packages/pkg_resources.py", line 2147, in load

['__name__'])

ImportError: No module named version

Если Я снова удаляю python-daemon с Pip-вещами, и пакеты, которые не устанавливались, теперь устанавливаются нормально. Кто-нибудь еще сталкивался с этим или чем-то подобным с другим проектом? Мое решение состояло в том, чтобы pip установить предыдущую версию

(venv) $ pip install python-daemon==2.0.2
... works ...
Но мне было интересно, что могло вызвать такую ошибку.
1 8

1 ответ:

(это поведение исправлено в python-daemon версии 2.0.4 и более поздних версиях.)

У этого есть две стороны:

    Setuptools предполагает, что это центр всего.
  • версия 2.0.3 python-daemon не учитывает этого.

Более подробное объяснение: существует некоторый сложный код, использующий Docutils, вовлеченный в процесс python-daemon build, который не нужен после установки и не является частью библиотеки код.

Слишком сложно оставить в не-импортируемом (и, следовательно, не-юнит-тестируемом) setup.py, так что код сборки шунтируется в отдельный тестируемый Модуль version (в файле version.py), который сам использует Docutils.

Но тогда setup.py имеет циклическую зависимость: как импортировать version, когда Docutils еще не установлен? Как использовать Setuptools для обеспечения установки Docutils, когда запуск setup.py до завершения потребуется version? Все возможные решения уродливы и запутанным.

Подход, принятый в "python-daemon" 2.0.3, заключается в объявлении Docutils, необходимых для установки, и объявлении точки входа Setuptools для работы, которая требует version. Таким образом, setup.py получает возможность устанавливать Docutils перед любой из точек входа, которые будут использовать version. Но теперь мы подходим к первому пункту, что Setuptools присваивает себе роль центра всего. Объявив точку входа, setup.py модифицировал каждое последующее действие Setuptools и каждый пакет потерпит неудачу, если он не сможет найти точки входа. И, поскольку большинство из них не имеют version или указанных функций в этом модуле, они аварийно завершают Setuptools.

То, что по сути является ошибкой, подлежащей исправлению, показывает плохо понятный угловой случай в Setuptools. Так что я голосую за ваш вопрос.

Кажется, что нет хорошего решения для этого: наличие модулей, доступных для setup.py , но обеспечение выполнения требований в первую очередь. Setuptools предполагает, что это единственная необходимая система сборки чтобы удовлетворить все зависимости для всего, и когда это предположение терпит неудачу, его очень трудно обойти.

Спасибо Python Packaging Authority folks, а также distutils-sig forum , за то, что объяснил мне это.