解决新的 pip 回溯运行时问题

Run*_*ith 74 python pip

随 20.3 版一起发布的新 pip 依赖项解析器安装包的时间过长。昨天在我们的 CI 管道中,在 1 小时的 pip 安装消息之后,过去需要约 10 分钟的 docker 构建超时(几乎对于任何依赖项安装的每个库,都有类似的日志输出):

INFO: pip is looking at multiple versions of setuptools to determine which version is compatible with other requirements. This could take a while.
  Downloading setuptools-50.0.0-py3-none-any.whl (783 kB)
  Downloading setuptools-49.6.0-py3-none-any.whl (803 kB)
  Downloading setuptools-49.5.0-py3-none-any.whl (803 kB)
  Downloading setuptools-49.4.0-py3-none-any.whl (803 kB)
  Downloading setuptools-49.3.2-py3-none-any.whl (790 kB)
INFO: This is taking longer than usual. You might need to provide the dependency resolver with stricter constraints to reduce runtime. If you want to abort this run, you can press Ctrl + C to do so. To improve how pip performs, tell us what happened here: https://pip.pypa.io/surveys/backtracking
  Downloading setuptools-49.3.1-py3-none-any.whl (790 kB)
  Downloading setuptools-49.3.0-py3-none-any.whl (790 kB)
  Downloading setuptools-49.2.1-py3-none-any.whl (789 kB)
  Downloading setuptools-49.2.0-py3-none-any.whl (789 kB)
  Downloading setuptools-49.1.3-py3-none-any.whl (789 kB)
  Downloading setuptools-49.1.2-py3-none-any.whl (789 kB)
  Downloading setuptools-49.1.1-py3-none-any.whl (789 kB)
  Downloading setuptools-49.1.0-py3-none-any.whl (789 kB)
  Downloading setuptools-49.0.1-py3-none-any.whl (789 kB)
  Downloading setuptools-49.0.0-py3-none-any.whl (789 kB)
  Downloading setuptools-48.0.0-py3-none-any.whl (786 kB)
  Downloading setuptools-47.3.2-py3-none-any.whl (582 kB)
  Downloading setuptools-47.3.1-py3-none-any.whl (582 kB)
  Downloading setuptools-47.3.0-py3-none-any.whl (583 kB)
  Downloading setuptools-47.2.0-py3-none-any.whl (583 kB)
  Downloading setuptools-47.1.1-py3-none-any.whl (583 kB)
  Downloading setuptools-47.1.0-py3-none-any.whl (583 kB)
  Downloading setuptools-47.0.0-py3-none-any.whl (583 kB)
  Downloading setuptools-46.4.0-py3-none-any.whl (583 kB)
  Downloading setuptools-46.3.1-py3-none-any.whl (582 kB)
  Downloading setuptools-46.3.0-py3-none-any.whl (582 kB)
  Downloading setuptools-46.2.0-py3-none-any.whl (582 kB)
  Downloading setuptools-46.1.3-py3-none-any.whl (582 kB)
  Downloading setuptools-46.1.2-py3-none-any.whl (582 kB)
  Downloading setuptools-46.1.1-py3-none-any.whl (582 kB)
  Downloading setuptools-46.1.0-py3-none-any.whl (582 kB)
  Downloading setuptools-46.0.0-py3-none-any.whl (582 kB)
  Downloading setuptools-45.3.0-py3-none-any.whl (585 kB)
  Downloading setuptools-45.2.0-py3-none-any.whl (584 kB)
  Downloading setuptools-45.1.0-py3-none-any.whl (583 kB)
  Downloading setuptools-45.0.0-py2.py3-none-any.whl (583 kB)
  Downloading setuptools-44.1.1-py2.py3-none-any.whl (583 kB)
  Downloading setuptools-44.1.0-py2.py3-none-any.whl (583 kB)
  Downloading setuptools-44.0.0-py2.py3-none-any.whl (583 kB)
  Downloading setuptools-43.0.0-py2.py3-none-any.whl (583 kB)
  Downloading setuptools-42.0.2-py2.py3-none-any.whl (583 kB)
  Downloading setuptools-42.0.1-py2.py3-none-any.whl (582 kB)
  Downloading setuptools-42.0.0-py2.py3-none-any.whl (582 kB)
  Downloading setuptools-41.6.0-py2.py3-none-any.whl (582 kB)
  Downloading setuptools-41.5.1-py2.py3-none-any.whl (581 kB)
  Downloading setuptools-41.5.0-py2.py3-none-any.whl (581 kB)
  Downloading setuptools-41.4.0-py2.py3-none-any.whl (580 kB)
  Downloading setuptools-41.3.0-py2.py3-none-any.whl (580 kB)
  Downloading setuptools-41.2.0-py2.py3-none-any.whl (576 kB)
  Downloading setuptools-41.1.0-py2.py3-none-any.whl (576 kB)
  Downloading setuptools-41.0.1-py2.py3-none-any.whl (575 kB)
  Downloading setuptools-41.0.0-py2.py3-none-any.whl (575 kB)
  Downloading setuptools-40.9.0-py2.py3-none-any.whl (575 kB)
  Downloading setuptools-40.8.0-py2.py3-none-any.whl (575 kB)
  Downloading setuptools-40.7.3-py2.py3-none-any.whl (574 kB)
  Downloading setuptools-40.7.2-py2.py3-none-any.whl (574 kB)
  Downloading setuptools-40.7.1-py2.py3-none-any.whl (574 kB)
  Downloading setuptools-40.7.0-py2.py3-none-any.whl (573 kB)
  Downloading setuptools-40.6.3-py2.py3-none-any.whl (573 kB)
  Downloading setuptools-40.6.2-py2.py3-none-any.whl (573 kB)
  Downloading setuptools-40.6.1-py2.py3-none-any.whl (573 kB)
  Downloading setuptools-40.6.0-py2.py3-none-any.whl (573 kB)
  Downloading setuptools-40.5.0-py2.py3-none-any.whl (569 kB)
  Downloading setuptools-40.4.3-py2.py3-none-any.whl (569 kB)
  Downloading setuptools-40.4.2-py2.py3-none-any.whl (569 kB)
  Downloading setuptools-40.4.1-py2.py3-none-any.whl (569 kB)
  Downloading setuptools-40.4.0-py2.py3-none-any.whl (568 kB)
  Downloading setuptools-40.3.0-py2.py3-none-any.whl (568 kB)
Run Code Online (Sandbox Code Playgroud)

我很困惑我们是否正确使用了新的 pip 解析器,尤其是因为

- Substantial improvements in new resolver for performance, output and error messages, avoiding infinite loops, and support for constraints files.
Run Code Online (Sandbox Code Playgroud)

所看到的行为在发行说明中被描述为回溯。我明白它为什么在那里。它指定我可以使用一个约束文件(看起来像一个 requirements.txt)来修复依赖项的版本以减少使用 pip install -c constraints.txt setup.py.

生成此约束文件的最佳方法是什么?目前,我能想到的最好方法是pip install setup.py在新的虚拟环境中本地运行,然后使用pip freeze > constraints.txt. 但是,这对于本地安装仍然需要很多时间(现在已经卡住了大约 10 分钟)。笔记确实提到This means the “work” is done once during development process, and so will save users this work during deployment.

使用旧的依赖解析器,我能够在不到一分钟的时间内在本地安装这个包。

这里推荐的流程是什么?

编辑:我刚刚发现一些依赖项直接指向内部 gitlab 服务器。如果我直接从我们的内部包注册表安装,它会在几分钟内再次运行。

Ner*_*xis 51

由于我遇到了类似的问题,我同意这很烦人。回溯可能是有用的功能,但您不想等待数小时以不确定的成功完成。

我发现了几个可能有帮助的选项:

  • 使用@Daniel Davee--use-deprecated=legacy-resolver在答案中提出的旧解析器 ( ),但这更像是临时解决方案而不是适当的解决方案。
  • 跳过使用--no-deps选项解决依赖项。我一般不建议这样做,但在某些情况下,尽管存在一些冲突,但您可以拥有一组工作包版本。
  • 减少 pip 将尝试回溯的版本数量,并对包依赖项更加严格。这意味着numpy我可以尝试numpy >= 1.18.0或者更严格地使用numpy == 1.18.0. 严格可能有很大帮助。

检查以下来源:

我仍然没有一个总是有帮助的正确答案,但 requirements.txt 的最佳实践似乎“固定”了包版本。我找到了pip 工具即使使用 constrains.txt 也可以帮助你管理这个(但我处于实验阶段,所以我不能告诉你更多)。

更新 (2021-04):

似乎问题的作者能够解决这个问题(使用自定义 gitlab 服务器的问题),但我想扩展这个答案,因为它可能对其他人有用。

在阅读并尝试之后,我最终将我的所有软件包版本固定到一个特定的版本。这确实应该是正确的方法。虽然没有它一切都可以正常工作,但在某些情况下,如果你不固定你的依赖项,你的包管理器会默默地安装一个新版本(当它发布时)可能有错误或不兼容(这发生在我身上,dask今年)。

有几种工具可能会对您有所帮助,我会推荐以下方法之一:

最简单的一种 pipreqs

  • pipreqs是一个库,它根据任何项目的导入生成 pip requirements.txt 文件
  • 您可以通过以下方式启动pip install pipreqs,只是捉迷藏pipreqs(有或最终在你的项目根--force标志,如果你的要求已经存在)
  • 它会很容易地创建requirements.txt寄托根据您的环境采取项目进口版本版本
  • 然后您可以随时基于此创建新环境 requirements.txt

这是一个非常简单的工具(你甚至不需要编写你的requirements.txt)。它不允许您创建一些复杂的东西(对于更大的项目来说可能不是一个好的选择),上周我发现了一个奇怪的行为(参见这个),但总的来说我对这个工具很满意,因为它通常可以完美地工作。

使用 pip-tools

还有其他几种常用的工具,如pip-toolsPipenvPoetry。您可以在 2018 年使用 pipenv、诗歌或 pip-toolsPython 应用程序依赖管理的更快的 Docker 构建中阅读更多内容(较旧,但对我来说似乎仍然有效)。在我看来,最好的选择(尽管这取决于您的项目/用例)是pip-tools.

您可以(这是一种选择,请参阅文档中的更多信息):

  • 创建requirements.in(与 相同的格式requirements.txt,取决于您是否固定某些包依赖项)
  • 然后你可以使用它pip install pip-tools并运行pip-compile requirements.in
  • 这将生成固定requirements.txt所有版本的新文件,很明显,来源是什么
  • (可选)您可以使用--generate-hashes选项运行它
  • 然后您可以(与pipreqs)随时基于此创建新环境requirements.txt
  • pip-tools为您提供--upgrade升级最终要求的选项
  • 支持分层需求(例如具有开发和生产版本)
  • 预提交集成
  • 提供pip-sync基于 requirements.txt 更新您的环境的工具

你可以用它做更多的事情,我真的很喜欢与pre-commit. 这允许您使用与以前相同的要求(仅带有.in后缀)并添加自动更新的预提交挂钩requirements.txt(因此您永远不会遇到与生成的本地环境不同的requirements.txt情况,这在您手动运行时很容易发生)。

  • 我已经将所有内容固定到确切的版本,但我仍然收到永恒的“pip 正在查看多个版本”消息。:( (6认同)
  • 仍然只是挂起。尝试了很多次。每个依赖项都被精确固定。 (2认同)

小智 23

所以他们正在改变解析器,这似乎是一个错误。有效的是使用旧的解析器,通过使用标志

--use-deprecated=legacy-resolver
Run Code Online (Sandbox Code Playgroud)

这显然会一直工作到 pip 21.0。

来源 https://github.com/pypa/pip/issues/9215

  • 我特别要求不使用旧解析器的解决方案 (6认同)
  • @Bromide,消息和错误跟踪已经由OP提供。你还需要什么?不仅仅是他,包括我自己在内的很多人都遇到了同样的错误,我们正在寻找解决方案来解决这个问题。 (5认同)
  • 仅供参考,pip 21.1.2 中仍然支持 `--use-deprecated=legacy-resolver` (4认同)

ant*_*puz 12

有类似的问题,想报告对我有用的解决方案。我必须使用更新 pip 版本

pip install --upgrade pip
Run Code Online (Sandbox Code Playgroud)

实际上我正在构建一个 docker 镜像,所以我添加了这一行

RUN pip install --upgrade pip
Run Code Online (Sandbox Code Playgroud)

就在安装要求之前。在撰写本答案时,安装的 pip 版本是22.0.3。这样做解决了问题。