Как обрабатывать зависимость от scipy в setup.py

Я пытаюсь создать setup.py для проекта, который зависит от SciPy. Следующий setup.py воспроизводит это:

setup(
    name='test',
    version='0.1',
    install_requires=['scipy']
)

При установке этого значения с помощью python setup.py develop он генерирует следующую ошибку:

ImportError: No module named numpy.distutils.core

Однако, когда я устанавливаю scipy с помощью pip, он установил его с колеса, и он отлично работает.

Итак, мои вопросы: как я могу создать setup.py, который зависит от SciPy? Почему setuptools не устанавливает зависимости от колес? Будет ли это работать лучше при использовании Python 3 (мы планируем все равно выполнить миграцию, поэтому, если он там работает, я просто подожду, пока миграция не завершится).

Я использую Python 2.7.8 в Mac OS X 10.10.1 с setuptools 3.6 и pip 1.5.6.

Ответы

Ответ 1

В конечном итоге это сработало для меня:

#!/usr/bin/env python

from setuptools import setup, Extension
from setuptools.command.build_ext import build_ext as _build_ext

#
# This cludge is necessary for horrible reasons: see comment below and
# http://stackoverflow.com/q/19919905/447288
#
class build_ext(_build_ext):
    def finalize_options(self):
        _build_ext.finalize_options(self)
        # Prevent numpy from thinking it is still in its setup process:
        __builtins__.__NUMPY_SETUP__ = False
        import numpy
        self.include_dirs.append(numpy.get_include())

setup(
    #
    # Amazingly, `pip install scipy` fails if `numpy` is not already installed.
    # Since we cannot control the order that dependencies are installed via
    # `install_requires`, use `setup_requires` to ensure that `numpy` is available
    # before `scipy` is installed.
    #
    # Unfortunately, this is *still* not sufficient: `numpy` has a guard to
    # check when it is in its setup process that we must circumvent with
    # the `cmdclass`.
    #
    setup_requires=['numpy'],
    cmdclass={'build_ext':build_ext},
    install_requires=[
        'numpy',
        'scipy',
    ],
    ...
)

Ответ 2

Используйте setup_requires для установки numpy до scipy:

setup(
    name='test',
    version='0.1',
    setup_requires=['numpy'],
    install_requires=['scipy']
)

Примечание. Также требуется компилятор Fortran для создания scipy. Вы можете установить его через brew:

brew install gcc

ps Если у вас есть AttributeError: 'module' object has no attribute 'get_include' посмотрите Почему setup_requires не работает правильно для numpy? Вопрос SO, предположим, для устранения этой проблемы.