Ответ, данный @ vebjorn-ljosa, правильный, но он вызывает проблемы при использовании в сочетании с install_requires=['numpy']
. В этой ситуации ваш setup.py должен импортировать numpy, что приведет к ошибке, если вы попытаетесь pip install
вашего проекта без запуска pip install numpy
вначале.
Если ваш проект зависит от numpy, и вы хотите, чтобы numpy устанавливался автоматически как зависимость, вам нужно устанавливать include_dirs только тогда, когда ваши расширения фактически строятся. Вы можете сделать это, создав подклассы build_ext
:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
class CustomBuildExtCommand(build_ext):
"""build_ext command for use when numpy headers are needed."""
def run(self):
# Import numpy here, only when headers are needed
import numpy
# Add numpy headers to include_dirs
self.include_dirs.append(numpy.get_include())
# Call original build_ext command
build_ext.run(self)
ext_modules = [Extension("hello", ["hello.pyx"])]
setup(
name = 'Hello world app',
cmdclass = {'build_ext': CustomBuildExtCommand},
install_requires=['numpy'],
ext_modules = ext_modules
)
И вы можете использовать аналогичный трюк для добавления Cython в качестве автоматически устанавливаемой зависимости:
from distutils.core import setup
from distutils.extension import Extension
try:
from Cython.setuptools import build_ext
except:
# If we couldn't import Cython, use the normal setuptools
# and look for a pre-compiled .c file instead of a .pyx file
from setuptools.command.build_ext import build_ext
ext_modules = [Extension("hello", ["hello.c"])]
else:
# If we successfully imported Cython, look for a .pyx file
ext_modules = [Extension("hello", ["hello.pyx"])]
class CustomBuildExtCommand(build_ext):
"""build_ext command for use when numpy headers are needed."""
def run(self):
# Import numpy here, only when headers are needed
import numpy
# Add numpy headers to include_dirs
self.include_dirs.append(numpy.get_include())
# Call original build_ext command
build_ext.run(self)
setup(
name = 'Hello world app',
cmdclass = {'build_ext': CustomBuildExtCommand},
install_requires=['cython', 'numpy'],
ext_modules = ext_modules
)
Примечание: эти подходы работают только с pip install .
. Они не будут работать для python setup.py install
или python setup.py develop
, поскольку в этих командах устанавливаются зависимости после вашего проекта, а не до.