Импорт функциональности яйца во время установки в сборке

Файл setup.py в пакете, который я поддерживаю, использует код из другого пакета для создания расширений:

from setuptools import setup, find_packages
from mydependence import build_ext
...
setup(
    name='mypackage',
    version='1.0.0',
    ...
    setup_requires = [
      'mydependence', # is this being checked properly?
    ],
    ...
    install_requires = [
      'mydependence',
    ],
    ...
    )

Я хотел бы собрать текущий пакет с помощью zc.buildout, поэтому я создаю простой файл buildout.cfg, например:

[buildout]
parts = python
eggs = mypackage

[python]
recipe = zc.recipe.egg
interpreter = python
eggs = ${buildout:eggs}

К сожалению, это не работает, как я ожидаю - когда я выполняю ./bin/buildout и setup.py читается, он жалуется, что mydependence не найден. Когда buildout запускает мой setup.py, его sys.path ничего не знает о пакетах, установленных в каталоге eggs (кроме самого setuptools!). По-видимому, пакеты в "яйцах" и "развитии яиц" не включены в пути ./bin/buildout, пока он запускает пакет setup.py.

Вопрос: как заставить это работать?


person André Anjos    schedule 02.02.2013    source источник
comment
Пакеты IIRC setup_requires загружаются и временно устанавливаются в извлеченный пакет перед запуском setup.py; buildout повторно использует setuptools для этого напрямую, поэтому я думал, что это сработает.   -  person Martijn Pieters    schedule 03.02.2013
comment
Кажется, это не работает для меня в том виде, в каком оно есть. Нужно ли setuptools находить пакет в индексе? В моей текущей настройке mydependence существует только локально, в каталоге src (управляется mr.developer< /а>). Я ожидал, что buildout сообщит setuptools, что, возможно, какие-то яйца уже есть.   -  person André Anjos    schedule 04.02.2013
comment
Ах да, это важное отличие. setuptools действует сам по себе и, боюсь, игнорирует ресурсы сборки для них.   -  person Martijn Pieters    schedule 04.02.2013
comment
Это, конечно, требует, чтобы я упаковал mydependence перед его тестированием, что не очень удобно. можно ли это исправить? Если нет, то как создать рецепт, который может это сделать?   -  person André Anjos    schedule 04.02.2013
comment
Будет обходной путь; дайте мне немного времени, чтобы написать один, но у меня сейчас очень мало времени, так что это может занять некоторое время.   -  person Martijn Pieters    schedule 04.02.2013
comment
Я более подробно изучил это и не вижу решения через zc.recipe.egg/zc.buildout. Проблема: в рецепте zc.recipe.egg:develop нет места или нет обходного пути для чтения setup_requires записи пакета. Вы можете проверить это, прочитав исходный код здесь, перейдите к строке 827. Там вы увидите buildout write sa wrapper setup.py, который используется для установки вашего пакета. Этот setup.py файл имеет 2 пути и только 2: один для рецепта и один для setuptools.   -  person André Anjos    schedule 08.02.2013
comment
Это то, что я говорил; в самой сборке нет поддержки install_requires, для этого потребуется некоторая специальная обработка.   -  person Martijn Pieters    schedule 08.02.2013
comment
этот ответ вообще помогает? Не уверен, что он будет повторно использовать локальный пакет в вашей сборке.   -  person Martijn Pieters    schedule 14.02.2013


Ответы (1)


Основная проблема заключается в том, что вы уже импортируете данные из mydependence до того, как вызовете метод setup(). Я не вижу способа, которым setuptools (или сборка в этом отношении) могут игнорировать ImportError, которые вы получите.

Если я посмотрю пример кода, например, из http://pythonhosted.org/py2app/examples.html я вижу такой код:

from setuptools import setup
setup(
    app=["MyApplication.py"],
    setup_requires=["py2app"],
)

Обратите внимание, что нет импорта py2app. Таким образом, setup_requires, по-видимому, является способом загрузки «расширений» к основным функциям setuptools. Это не способ обойти основные ошибки импорта Python.

Обновление: см. комментарий ниже @MartijnPieters, у которого есть решение в https://stackoverflow.com/a/12061891/27401 .

Пример Мартейна в вашем случае будет выглядеть так:

import setuptools

setuptools.dist.Distribution(dict(setup_requires='mydependence'))
# `setup_requires` is parsed and acted upon immediately; 
# from here on out the package `mydependence` is installed
# and importable.

from mydependence import build_ext

setup(
    ...
    install_requires = [
      'mydependence',
    ],
    ....
    )
person Reinout van Rees    schedule 13.02.2013
comment
Вы знаете, я не правильно прочитал код операции? Но есть способ обойти это; setup.py проверяет и устанавливает setup_requires, но вы не можете выполнить импорт сверху. Не могу сейчас полностью вспомнить, как вы затем можете импортировать установленную зависимость позже в setup.py, но я видел, как это делается. - person Martijn Pieters; 14.02.2013
comment
А, быстрый поиск в Google приводит к: Лучший способ поделиться кодом между несколькими сценариями setup.py? - person Martijn Pieters; 14.02.2013
comment
Хороший трюк, @MartijnPieters! Я обновил свой ответ, указав на ваш. - person Reinout van Rees; 14.02.2013
comment
Вы бы поверили мне, если бы я сказал, что даже не понял, что этот ответ был моим? Я не смотрел на автора, просто смутно вспомнил, что уже решал это раньше.. :-P - person Martijn Pieters; 14.02.2013
comment
С вашей оценкой stackoverflow я могу вам поверить :-) - person Reinout van Rees; 14.02.2013