使用Cython进行setup_requires?

时间:2016-05-26 21:28:16

标签: python build cython setuptools software-distribution

我正在为包含一些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值。

3 个答案:

答案 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-

本质上:

  1. 使用以下内容创建文件pyproject.toml
[build-system]
requires = ["setuptools", "wheel", "Cython"]
  1. 使用pip install -e .进行设置