繁体   English   中英

在涉及 Cython 的 setup.py 中,如果 install_requires,那么如何从库中导入一些东西?

[英]In a setup.py involving Cython, if install_requires, then how can from library import something?

这对我来说没有意义。 如何使用 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 build

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用),但使用setuptools.Extension代替cythonize将 cython-extension 添加到设置中。

它现在应该可以工作了。 原因: setuptoolssetup_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-extension 使用numpy ,它会变得更加复杂,但这也是可能的 - 请参阅此 SO post

一般来说没有意义。 正如您怀疑的那样,这是尝试使用(可能)尚未安装的东西。 如果在已安装依赖项的系统上进行测试,您可能不会注意到此缺陷。 但是在没有您的依赖项的系统上运行它,您肯定会注意到。

还有另一个setup()关键字参数setup_requires ,它在形式上似乎与install_requires平行,但这是一种错觉。 install_requires在缺乏它所命名的依赖项的环境中触发了自动安装的可setup_requires ,而setup_requires是更多的文档而不是自动化。 它不会自动安装,当然也不会神奇地及时跳回到自动安装已经在import语句中调用的模块。

setuptools docs 中有更多关于此的内容,但快速回答是您对试图自动安装自己的安装先决条件的模块感到困惑是正确的。

对于实际的解决方法,请尝试单独安装cython ,然后运行此设置。 虽然它不会解决此设置脚本的形而上学幻觉,但它会解决要求并让您继续前进。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM