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

时间:2017-06-14 21:18:42

标签: python pip cython setup.py

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

4 个答案:

答案 0 :(得分:3)

对此的一个解决方案是不要使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

答案 1 :(得分:2)

据我所知,这是PEP 518出现的地方-也见其作者之一的some clarifications

想法是您将另一个文件添加到Python项目/包中:pyproject.toml。它应该包含有关构建环境依赖项的信息(长期而言)。 pip(或其他任何软件包管理器)可以调查此文件,并在运行setup.py (或任何其他构建脚本)之前安装所需的构建环境。 pyproject.toml可能看起来像这样:

[build-system]
requires = ["setuptools", "wheel", "Cython"]

这是一个相当新的进展,到目前为止(2019年1月),虽然support was added to pip于2017年5月(10.0版)发布,但尚未得到Python社区的最终确定/批准。

答案 2 :(得分:1)

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

还有另一个setup()关键字参数setup_requires,它可以在表单中显示为并行并用于install_requires,但这是一种幻觉。鉴于install_requires在缺少其所依赖的依赖关系的环境中触发了一个可爱的自动安装芭蕾,setup_requires比自动化更多的文档。它不会自动安装,当然也不会神奇地跳回到自动安装已在import语句中调用过的模块。

the setuptools docs上还有更多内容,但快速回答是您正好试图自动安装自己的设置先决条件的模块感到困惑

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

答案 3 :(得分:0)

使用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 will try to import cython在满足setup_requires之后:

...
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,情况会变得更加复杂,但这也是可能的-请参见this SO post