Как установить Bootstrap numpy в setup.py

У меня есть проект с расширением C, который требует numpy. В идеале, мне бы хотелось, чтобы кто-либо загрузил мой проект, чтобы просто запустить python setup.py install или использовать один вызов для pip . Проблема в том, что в моей setup.py мне нужно импортировать numpy, чтобы получить расположение заголовков, но я бы хотел, чтобы numpy был просто регулярным требованием в install_requires чтобы он автоматически загружался из индекса пакета Python ,

Вот пример того, что я пытаюсь сделать:

 from setuptools import setup, Extension import numpy as np ext_modules = [Extension('vme', ['vme.c'], extra_link_args=['-lvme'], include_dirs=[np.get_include()])] setup(name='vme', version='0.1', description='Module for communicating over VME with CAEN digitizers.', ext_modules=ext_modules, install_requires=['numpy','pyzmq', 'Sphinx']) 

Очевидно, я не могу import numpy наверху, прежде чем он будет установлен. Я видел аргумент setup_requires переданный setup() но не могу найти документацию о том, для чего он предназначен.

Это возможно?

Следующее работает как минимум с numpy1.8 и python {2.6.2.7.3.3}:

 from setuptools import setup from setuptools.command.build_ext import build_ext as _build_ext 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( ... cmdclass={'build_ext':build_ext}, setup_requires=['numpy'], ... ) 

Для небольшого объяснения, посмотрите, почему он терпит неудачу без «взлома», см. Этот ответ .

Обратите внимание, что использование setup_requires имеет тонкий недостаток: numpy будет не только скомпилирован до создания расширений, но и при выполнении python setup.py --help , например. Чтобы этого избежать, вы можете проверить параметры командной строки, например, предложенные в https://github.com/scipy/scipy/blob/master/setup.py#L205 , но, с другой стороны, я действительно не думаю, что это стоит усилие.

Это фундаментальная проблема с пакетами, которые должны использовать numpy (для distutils или get_include). Я не знаю, как использовать «boot-strap», используя pip или easy-install.

Тем не менее, легко сделать пакет conda для вашего модуля и предоставить список зависимостей, чтобы кто-то мог просто установить pda-имя для conda, которое будет загружать и устанавливать все необходимое.

Conda доступен в Anaconda или в Miniconda (python + just conda).

См. Этот сайт: http://docs.continuum.io/conda/index.html или эту слайд-колону для получения дополнительной информации: https://speakerdeck.com/teoliphant/packaging-and-deployment-with-conda

Возможно, более практичное решение – просто потребовать, чтобы numpy был установлен заранее и import numpy внутри области функций. Решение @coldfix работает, но компиляция numpy берет навсегда. Гораздо быстрее, чтобы установить его сначала как пакет колес, особенно теперь, когда у нас есть колеса для большинства систем благодаря усилиям, таким как manylinux .

 from __future__ import print_function import sys import textwrap import pkg_resources from setuptools import setup, Extension def is_installed(requirement): try: pkg_resources.require(requirement) except pkg_resources.ResolutionError: return False else: return True if not is_installed('numpy>=1.11.0'): print(textwrap.dedent(""" Error: numpy needs to be installed first. You can install it via: $ pip install numpy """), file=sys.stderr) exit(1) def ext_modules(): import numpy as np some_extention = Extension(..., include_dirs=[np.get_include()]) return [some_extention] setup( ext_modules=ext_modules(), ) 

Чтобы заставить работу работать, вы можете сделать так же, как Scipy: https://github.com/scipy/scipy/blob/master/setup.py#L205

А именно, команда egg_info должна быть передана в стандартный setuptools / distutils, но другие команды могут использовать numpy.distutils .