我正在为包含一些Cython扩展模块的项目创建一个setup.py
文件。
我已经让这个工作了:
from setuptools import setup, Extension
from Cython.Build import cythonize
setup(
name=...,
...,
ext_modules=cythonize([ ... ]),
)
这个安装很好。但是,这假设已安装Cython。如果没有安装怎么办?我理解这是setup_requires
参数的用途:
from setuptools import setup, Extension
from Cython.Build import cythonize
setup(
name=...,
...,
setup_requires=['Cython'],
...,
ext_modules=cythonize([ ... ]),
)
但是,如果Cython尚未安装,那么这当然会失败:
$ python setup.py install
Traceback (most recent call last):
File "setup.py", line 2, in <module>
from Cython.Build import cythonize
ImportError: No module named Cython.Build
这样做的正确方法是什么?我只需要在Cython
步骤运行后以某种方式导入setup_requires
,但我需要Cython
才能指定ext_modules
值。
答案 0 :(得分:25)
从setuptools
发布Cython
(2015-06-23发布),可以在setup_requires
中指定*.pyx
并传递setuptools.Extension
个模块常规from setuptools import setup, Extension
setup(
# ...
setup_requires=[
# Setuptools 18.0 properly handles Cython extensions.
'setuptools>=18.0',
'cython',
],
ext_modules=[
Extension(
'mylib',
sources=['src/mylib.pyx'],
),
],
)
的来源:
{{1}}
答案 1 :(得分:5)
您必须将from Cython.Build import cythonize
包裹在try-except
中,并在except
中将cythonize
定义为虚拟函数。通过这种方式,可以加载脚本而不会失败ImportError
。
稍后当处理setup_requires
参数时,将安装Cython
并重新执行安装脚本。由于此时安装了Cython
,您将能够成功导入cythonize
try:
from Cython.Build import cythonize
except ImportError:
def cythonize(*args, **kwargs):
from Cython.Build import cythonize
return cythonize(*args, **kwargs)
修改
正如评论中所述,在setuptools处理缺少的依赖项后,它不会重新加载Cython。我以前没想过,但你也可以尝试一种后期绑定方法来剔除cythonize
答案 2 :(得分:2)
在执行此处描述的实际setup.py
(需要pip
)之前,似乎有第三种方法来安装构建依赖项:
https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html#basic-setup-
本质上:
pyproject.toml
:[build-system]
requires = ["setuptools", "wheel", "Cython"]
pip install -e .
进行设置