【发布时间】:2019-06-04 16:18:36
【问题描述】:
我目前正在开发一个使用cython 和numpy 的python 包,我希望可以使用pip install 命令从干净的python 安装中安装该包。所有依赖项都应该自动安装。我正在使用setuptools 和以下setup.py:
import setuptools
my_c_lib_ext = setuptools.Extension(
name="my_c_lib",
sources=["my_c_lib/some_file.pyx"]
)
setuptools.setup(
name="my_lib",
version="0.0.1",
author="Me",
author_email="me@myself.com",
description="Some python library",
packages=["my_lib"],
ext_modules=[my_c_lib_ext],
setup_requires=["cython >= 0.29"],
install_requires=["numpy >= 1.15"],
classifiers=[
"Programming Language :: Python :: 3",
"Operating System :: OS Independent"
]
)
到目前为止效果很好。 pip install 命令下载 cython 进行构建,并且能够构建我的包并将其与 numpy 一起安装。
现在我想提高我的cython 代码的性能,这导致我的setup.py 发生了一些变化。我需要将include_dirs=[numpy.get_include()] 添加到setuptools.Extension(...) 或setuptools.setup(...) 的调用中,这意味着我还需要import numpy。 (有关有理数,请参阅 http://docs.cython.org/en/latest/src/tutorial/numpy.html 和 Make distutils look for numpy header files in the correct place。)
这很糟糕。现在用户无法从干净的环境中调用pip install,因为import numpy 将失败。在安装我的库之前,用户需要pip install numpy。即使我将"numpy >= 1.15" 从install_requires 移动到setup_requires,安装也会失败,因为import numpy 被较早地评估。
有没有办法在安装的后期评估include_dirs,例如,在解决了来自setup_requires 或install_requires 的依赖项之后?我真的很喜欢自动解决所有依赖关系,我不希望用户输入多个pip install 命令。
以下 sn-p 有效,但未得到官方支持,因为它使用了一种未记录(和私有)的方法:
class NumpyExtension(setuptools.Extension):
# setuptools calls this function after installing dependencies
def _convert_pyx_sources_to_lang(self):
import numpy
self.include_dirs.append(numpy.get_include())
super()._convert_pyx_sources_to_lang()
my_c_lib_ext = NumpyExtension(
name="my_c_lib",
sources=["my_c_lib/some_file.pyx"]
)
文章How to Bootstrap numpy installation in setup.py 建议使用带有自定义build_ext 类的cmdclass。不幸的是,这破坏了cython 扩展的构建,因为cython 还自定义了build_ext。
【问题讨论】:
-
@ead 这不起作用,因为
cython还自定义了build_ext。如果我使用建议的解决方案,cython构建失败并显示Don't know how to compile my_c_lib/some_file.pyx,这意味着不再使用cython的自定义build_ext命令。 -
我看不是那么直截了当...
-
看看 pybind11 here 做了什么来推迟导入 - 尚未测试,但我认为类似的工作在这里。
-
pybind11 的诀窍在进行小改动后就可以工作了。我必须从
os.PathLike继承而不是object,因为cython需要str、bytes或PathLike对象,而str/bytes不起作用,因为它们是不可变的。你想从你的评论中创建一个答案,我应该自己回答我的问题吗?
标签: python-3.x numpy cython setuptools