【问题标题】:`python setup.py sdist` with cython extension: .pyx' doesn't match any files带有cython扩展名的`python setup.py sdist`:.pyx'不匹配任何文件
【发布时间】:2020-06-28 06:19:22
【问题描述】:

我正在维护一个包含基于 cython 的 c 扩展的 python 包。 源码在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 创建源分发时应该怎么做?

【问题讨论】:

  • 为我工作。尝试升级pipsetuptoolCython
  • 能否添加您正在使用的python、pip等版本?您还可以添加遇到错误时键入的确切命令吗? (我猜是pip3 install --user dist/vltools-0.1.0b3.tar.gz,但最好在问题中确认)
  • 这个stackoverflow.com/questions/29227836/…有什么帮助吗?
  • 顺便说一句,try: import numpy except: os.system(pip install numpy) 是个坏主意。只是让错误引发就可以了。因为通常,如果找不到 numpy,则意味着您没有使用您认为正在使用的 exe(例如,如果 python2 安装在 python3 旁边)。
  • 感谢您的帮助。我发现@hoefling 的回答解决了我的问题。

标签: python pip cython setuptools


【解决方案1】:

您的安装脚本中有几处需要修复或改进。

声明构建和运行时依赖项

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

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

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

您可以(并且应该)将install_requires 列表扩展为其他包vltools 需要,例如scipypillow 等。

推迟 Cython 和 numpy 导入

为确保该软件包可安装在既未安装 Cython 也未安装 numpy 的系统上,我们必须推迟它们的导入。我不会在这里详细介绍;查看Add numpy.get_include() argument to setuptools without preinstalled numpy 了解更多详情。在下面 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 未添加到您的源 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 我们又见面了 ;-)

【讨论】:

  • 哇,太棒了,你又帮助了我!我已经更新了!
【解决方案2】:

作为@hoefling suggested,我更新了我的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},
)

【讨论】:

  • 有趣,正如我已经检查过的那样,nms_ext.pyx 包含在 sdist tar 中,而无需显式添加它。安装的软件包可能有所不同吗?这是我在虚拟环境中安装的:Cython==0.29.15numpy==1.18.2pip==20.0.2setuptools==45.2.0wheel==0.34.2。除此之外,目前不知道。
猜你喜欢
  • 2014-03-16
  • 1970-01-01
  • 1970-01-01
  • 2020-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-12
  • 1970-01-01
相关资源
最近更新 更多