繁体   English   中英

带有 cython 扩展名的 `python setup.py sdist`:.pyx' 不匹配任何文件

[英]`python setup.py sdist` with cython extension: .pyx' doesn't match any files

我正在维护一个 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 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_requires / install_requires参数中的setup() Cython 仅在构建阶段需要,但在安装和导入vltoolsvltools - 它将被添加到setup_requires 构建和运行包都需要numpy ,因此它包含在两个列表中:

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

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

您可以(并且应该)使用vltools需要的其他软件包扩展install_requires列表,例如scipypillow等。

推迟 Cython 和 numpy 导入

为了确保该软件包可以安装在既没有安装 Cython 也没有安装numpy系统上,我们必须推迟它们的导入。 我不会在这里详细介绍; 查看将 numpy.get_include() 参数添加到没有预安装 numpy 的 setuptools以了解更多详细信息。 在下面build命令的自定义 impl 中,我使用numpy延迟了 cythonizing 和扩展扩展标头,包括:

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没有被添加到你的源代码目录中,因此无法安装。 这很容易通过例如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},
)

PS两年过去了,我们又见面了;-)

正如@hoefling 建议的那样,我已经更新了我的setup.py

但是,从.tar.gz文件安装时仍然出现错误,找不到“vltools/nms/nms_ext.pyx”。

setup.py hoefling 发布:

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},
)

使用python setup.py sdist && cd dist && pip install vltools-0.1.0b3.tar.gz ,出现错误提示:

ValueError: 'vltools/nms/nms_ext.pyx' doesn't match any files

因为pyx文件没有打包到 tar.gz 中。

要在 tar.gz 文件中包含“vltools/nms/nms_ext.pyx”,我将其添加到package_data列表中:

package_data={"vltools.nms": ["nms.h", "nms_ext.pyx"]}

最后,我的完整 setup.py 是:

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", "nms_ext.pyx"]},
    cmdclass={"build": build},
)

暂无
暂无

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

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