这对我来说没有意义。如何使用 setup.py 安装 Cython,然后使用该 setup.py 编译库代理?
import sys, imp, os, glob
from setuptools import setup
from Cython.Build import cythonize # this isn't installed yet
setup(
name='mylib',
version='1.0',
package_dir={'mylib': 'mylib', 'mylib.tests': 'tests'},
packages=['mylib', 'mylib.tests'],
ext_modules = cythonize("mylib_proxy.pyx"), #how can we call cythonize here?
install_requires=['cython'],
test_suite='tests',
)
后: Python setup.py 构建
Traceback (most recent call last):
File "setup.py", line 3, in <module>
from Cython.Build import cythonize
ImportError: No module named Cython.Build
这是因为cython尚未安装。
奇怪的是,很多项目都是这样写的。 快速的github搜索揭示了以下几点: https://github.com/search?utf8=%E2%9C%93&q=install_requires+cython&type=Code
据我了解,这就是 PEP 518 的用武之地 - 另请参阅其作者之一的一些澄清。
这个想法是你在你的Python项目/包中添加另一个文件:pyproject.toml
。它应该包含有关构建环境依赖关系的信息(以及其他长期内容)。pip
(或任何其他包管理器)可以查看此文件,并在运行 setup.py(或任何其他构建脚本)之前安装所需的构建环境。因此,pyproject.toml
可能如下所示:
[build-system]
requires = ["setuptools", "wheel", "Cython"]
这是一个相当新的发展,截至目前(2019年1月),它尚未最终确定/得到Python社区的批准,尽管(有限的)支持在2017年5月/10.0版本中添加到pip。
一种解决方案是不使Cython成为构建要求,而是将Cython生成的C
文件与包一起分发。 我敢肯定某处有一个更简单的例子,但这就是pandas
所做的 - 它有条件地导入 Cython,如果不存在,可以从 c 文件构建。
https://github.com/pandas-dev/pandas/blob/3ff845b4e81d4dde403c29908f5a9bbfe4a87788/setup.py#L433
编辑:来自@danny的文档链接有一个更容易理解的示例。 http://docs.cython.org/en/latest/src/reference/compilation.html#distributing-cython-modules
当你使用setuptool时,你应该cython
添加到setup_requires
(如果安装使用cython,也要添加install_requires
),即
# don't import cython, it isn't yet there
from setuptools import setup, Extension
# use Extension, rather than cythonize (it is not yet available)
cy_extension = Extension(name="mylib_proxy", sources=["mylib_proxy.pyx"])
setup(
name='mylib',
...
ext_modules = [cy_extension],
setup_requires=["cython"],
...
)
Cython
不会导入(setup.py
启动时尚不可用),但使用setuptools.Extension
而不是cythonize
将 cython 扩展添加到设置中。
它现在应该可以工作了。原因是:setuptools
在满足setup_requires
后会尝试导入cython:
...
try:
# Attempt to use Cython for building extensions, if available
from Cython.Distutils.build_ext import build_ext as _build_ext
# Additionally, assert that the compiler module will load
# also. Ref #1229.
__import__('Cython.Compiler.Main')
except ImportError:
_build_ext = _du_build_ext
...
如果您的 Cython 扩展使用numpy
,它会变得更加复杂,但这也是可能的 - 请参阅此 SO 帖子。
这通常没有意义。正如您所怀疑的那样,这是尝试使用(可能)尚未安装的东西。如果在已安装依赖项的系统上进行测试,则可能不会注意到此缺陷。但是在不存在依赖项的系统上运行它,您肯定会注意到。
还有另一个setup()
关键字参数,setup_requires
,在形式上似乎平行,用于install_requires
,但这是一种错觉。虽然install_requires
在缺乏其命名的依赖项的环境中触发了自动安装的可爱芭蕾舞,但setup_requires
更多的是文档而不是自动化。它不会自动安装,当然也不会神奇地及时跳回到自动安装import
语句中已经调用的模块。
在setuptools文档中有更多关于这一点的内容,但快速的答案是,您对尝试自动安装自己的设置先决条件的模块感到困惑是正确的。
有关实用的解决方法,请尝试单独安装cython
,然后运行此设置。虽然它不会修复这个安装脚本的形而上学幻想,但它会解决需求并让你继续前进。