python - `python setup.py sdist` 与 cython 扩展 : . pyx ' doesn' t 匹配任何文件

标签 python pip cython setuptools

我正在维护一个 python 包,其中包含一个基于 cython 的 c 扩展。
源码在github上:https://github.com/vlkit/vlkit .

这是我的 setup.py :

import os
from setuptools import setup, find_packages
from distutils.core import Extension

try:
    import numpy
except ImportError:  # We do not have numpy installed
    os.system("pip install numpy")

try:
    from Cython.Build import cythonize
except ImportError:  # We do not have Cython installed
    os.system("pip install Cython")

import numpy
from Cython.Build import cythonize

__version__ = "0.1.0-b3"

exts = [Extension(name='vltools.nms.nms_ext',
                  sources=["vltools/nms/nms_ext.pyx"],
                  include_dirs=[numpy.get_include()])
        ]

setup(name='vltools',
  version=__version__,
  description='vision and learning tools',
  url='https://github.com/vltools/vltools',
  author_email='a@b.c',
  license='MIT',
  packages=find_packages(),
  ext_modules=cythonize(exts),
  zip_safe=False,
  data_files=[("data", ["data/imagenet1000_clsidx_to_labels.txt"])]
)

使用 python setup build && python setup.py install 在本地构建时,一切顺利。

但是,当我尝试创建 时源码分发python setup.py sdist然后从生成的 dist/vltools-0.1.0b3.tar.gz 安装它遇到了一个错误:
ValueError: 'vltools/nms/nms_ext.pyx' doesn't match any files

据我了解,实际安装需要的是nms_ext.c这确实在生成的 dist/vltools-0.1.0b3.tar.gz 中.

但是,在我的 setup.py 中,源代码是“nms_ext.pyx”:
exts = [Extension(name='vltools.nms.nms_ext',
                  sources=["vltools/nms/nms_ext.pyx"],
                  include_dirs=[numpy.get_include()])
        ]

那么在使用 python setup.py sdist 创建源代码分发时我应该怎么做? ?

最佳答案

在您的安装脚本中有几件事情需要修复或改进。

声明构建和运行时依赖项

而不是运行 pip install {numpy,cython}在很多事情都可能出错的地方,声明依赖关系的正确方法是将它们传递给 setup()setup_requires/install_requires参数。 Cython 仅在构建阶段需要,但在 vltools 时不需要安装并导入 - 它将被添加到 setup_requires . numpy构建和运行包都需要,因此它包含在两个列表中:

setup(
    ...,
    setup_requires=["cython", "numpy"],
    install_requires=["numpy"],
)

这样做的好处是不会安装 Cython。它将被下载,用于构建,然后被删除。

您可以(并且应该)扩展 install_requires与其他软件包一起列出 vltools需要,例如 scipy , pillow等等。

推迟 Cython 和 numpy 导入

确保该软件包可安装在既没有 Cython 也没有 numpy 的系统上。事先安装好,我们要推迟他们的进口。我不会在这里详细介绍;退房 Add numpy.get_include() argument to setuptools without preinstalled numpy更多细节。在 build 的自定义实现中下面的命令,我使用 numpy 推迟了 cythonizing 和扩展扩展 header 包括:
class build(build_orig):

    def finalize_options(self):
        super().finalize_options()
        __builtins__.__NUMPY_SETUP__ = False
        import numpy
        for extension in self.distribution.ext_modules:
            extension.include_dirs.append(numpy.get_include())
        from Cython.Build import cythonize
        self.distribution.ext_modules = cythonize(self.distribution.ext_modules,
                                                  language_level=3)

通过 cmdclass 注册自定义命令 impl :
setup(
    ...,
    cmdclass={"build": build},
)

包装nms.h
目前,nms.h没有被添加到你的源 dist,使得安装不可能。这很容易通过例如包含它来解决package_data :
setup(
    ...,
    package_data={"vltools.nms": ["nms.h"]},
)

现在你还应该添加 nms.h 的父目录至 include_dirs :
exts = [Extension(name='vltools.nms.nms_ext',
                  sources=["vltools/nms/_nms_ext.c", "vltools/nms/nms_ext.pyx"],
                  include_dirs=["vltools/nms"])]

完整的设置脚本
import os
from setuptools import setup, find_packages
from setuptools import Extension
from distutils.command.build import build as build_orig

__version__ = "0.1.0b3"

exts = [Extension(name='vltools.nms.nms_ext',
                  sources=["vltools/nms/_nms_ext.c", "vltools/nms/nms_ext.pyx"],
                  include_dirs=["vltools/nms"])]


class build(build_orig):

    def finalize_options(self):
        super().finalize_options()
        __builtins__.__NUMPY_SETUP__ = False
        import numpy
        for extension in self.distribution.ext_modules:
            extension.include_dirs.append(numpy.get_include())
        from Cython.Build import cythonize
        self.distribution.ext_modules = cythonize(self.distribution.ext_modules,
                                                  language_level=3)


setup(name='vltools',
    version=__version__,
    description='vision and learning tools',
    url='https://github.com/vltools/vltools',
    author_email='kz@kaizhao.net',
    license='MIT',
    packages=find_packages(),
    ext_modules=exts,
    setup_requires=["cython", "numpy"],
    install_requires=["numpy"],
    zip_safe=False,
    data_files=[("data", ["data/imagenet1000_clsidx_to_labels.txt"])],
    package_data={"vltools.nms": ["nms.h"]},
    cmdclass={"build": build},
)

附言Two years have passed在这里我们又见面了;-)

关于python - `python setup.py sdist` 与 cython 扩展 : . pyx ' doesn' t 匹配任何文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60717795/

相关文章:

python - 如何在Python中实现流水线?

python - F# 字典初始化就像在 Python 中一样

python - pyobjc-3.0.3 不会安装在 OS X 10.10 上

python - 使用 Cython 传递 int 和 struct 包装 C 代码的最小示例

python - 在 python 中,我如何迭代具有动态嵌套数的嵌套字典?

python - TensorFlow,为什么选择 python 语言?

python - 如何将 Spacy en_core_web_md 模型放入 Python 包中

python - PyPI 分类器列表

multithreading - __sync_bool_compare_and_swap 在 Cython 中具有不同的参数类型

macos - Cython:prange 正在重复而不是并行化