如何以及谁应该将 wheel 指定为 Python 包依赖项?

How and who should specify wheel as a Python package dependency?

我正在编写一个源包(不是完全打包的模块,而是一些具有依赖性的脚本),以便在框架应用程序中安装和执行(具体来说,Amazon SageMaker 的 TensorFlow serving container - 运行 Python3.5).

我的一个依赖项是 matplotlib,它又需要 kiwisolver,它有 C++ 组件。

我的目标容器似乎没有默认安装 wheel,因为当我只提供一个 requirements.txt 文件时,我得到了 中描述的错误。

我想我是通过提供一个 setup.py 来实现它的工作的,按照 对那个 Travis CI 问题的建议 setup_requires=["wheel"]

我的 Python packaging-fu 很弱,所以我的问题是:谁 应该 指定这个依赖关系,因为看起来不应该是我?

如果有人可以解释这个答案是否随着 PEP 518setup_requires 的弃用而改变,那就更好了:S

通常 wheel 可以被认为是 build-time 依赖而不是 install-time 依赖。但实际上,wheel 只是一种分发 Python 项目(库或应用程序)的方式,因此它通常不是强制依赖项。

构建库的一个系统 (kiwisolver) 可能需要安装 wheel 工具。但是,如果我没记错的话,pip 的最新版本已经捆绑了 wheel,所以现在通常不需要显式安装它。

在许多情况下,wheels 已经构建在 PyPI 上可用。但有时没有 wheels 与目标系统兼容(Python 解释器版本、操作系统、CPU 位数)。在您的情况下,kiwisolver has a wide range of wheels available but not for Python 3.5.

所以您要安装 kiwisolver 的系统似乎与 wheels 上可用的任何 wheels 不兼容29=]PyPI。所以 pip 必须在本地构建它。通常 pip 会先尝试构建一个 wheel,但据我所知,如果 wheel 无法构建然后 pip 通常只是继续并安装项目而不去 wheel 中间步骤。

但仍然 pip 必须能够 构建 库,这可能需要一些 C/C++ 编译器或在本地系统上满足其他异常条件。这就是为什么将库分发为 wheel 非常舒服,因为 build 步骤已经完成。

所以总结一下,在我看来,没有人真的需要将 wheel 声明为依赖项或安装 wheel除非他们真的想要制造 车轮 。但是 wheel 实际上只是一个中间的可选步骤。这是一种分发 Python 项目(库或应用程序)的方式。我没有看到 绝对需要wheel 添加到 setuptools' setup_requires已弃用 或接近它)也不是 pyproject.tomlbuild-system.requires,它更像是一种(非常常见且准标准的)便利。

现在遇到你的情况我该怎么办?

  • 在从包含 kiwisolverrequirements.txt 文件安装之前(直接或间接)确保 pip 已启动- 最新或显式安装 wheel,并且:
    • 使用 Python 的 wheels 版本已在 PyPI.
    • 上可用
    • 如果您想继续 Python 3.5
      • 确保目标系统能够构建 kiwisolver 本身(可能需要 C/C++ 编译器加上一些其他本地库)。