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

标签 python pip

new pip dependency resolver与版本 20.3 一起发布的安装包需要很长时间。
昨天在我们的 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)
我很困惑我们是否正确使用了新的 pip 解析器,尤其是因为
- Substantial improvements in new resolver for performance, output and error messages, avoiding infinite loops, and support for constraints files.
看到的行为被描述为 backtracking在发行说明中。我明白它为什么在那里。
它指定我可以使用一个约束文件(看起来像一个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 服务器。如果我直接从我们的内部包注册表安装,它会在几分钟内再次运行。

最佳答案

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

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

  • 检查以下来源:
  • Fixing conflicts
  • Github pip discussion
  • Reducing backtracking

  • 我仍然没有一个总是有帮助的正确答案,但 requirements.txt 的最佳实践似乎“固定”了包版本。我找到了 pip-tools即使使用 constrains.txt 也可以帮助你管理这个(但我处于实验阶段,所以我不能告诉你更多)。
    更新 (2021-04):
    似乎问题的作者能够解决这个问题(使用自定义 gitlab 服务器的问题),但我想扩展这个答案,因为它可能对其他人有用。
    在阅读并尝试之后,我最终将我的所有软件包版本固定到一个特定的版本。这确实应该是正确的方法。虽然没有它一切都可以工作,但在某些情况下,如果你不固定你的依赖项,你的包管理器会默默地安装一个可能有错误或不兼容的新版本(当它发布时)(这发生在我身上 dask)今年最后一次)。
    有几种工具可能会对您有所帮助,我会推荐以下方法之一:
    最简单的一个 pipreqs
  • pipreqs是一个基于任何项目的导入生成 pip requirements.txt 文件的库
  • 您可以从 pip install pipreqs 开始并且正在运行 pipreqs在您的项目根目录中(如果您的要求已经存在,则最终使用 --force 标志)
  • 它将轻松创建 requirements.txt固定 基于项目中导入的版本以及从您的环境中获取的版本
  • 那么您可以随时基于此创建新环境 requirements.txt

  • 这是一个非常简单的工具(你甚至不需要编写你的requirements.txt)。它不允许你创建一些复杂的东西(对于更大的项目来说可能不是一个好的选择),上周我发现了一个奇怪的行为(见 this )但总的来说我对这个工具很满意,因为它通常工作得很好。
    使用 pip-tools还有其他几个常用的工具,如 pip-tools , PipenvPoetry .您可以在 Faster Docker builds with pipenv, poetry, or pip-tools 中阅读更多信息或 Python Application Dependency Management in 2018 (较旧但对我来说似乎仍然有效)。在我看来,最好的选择(尽管这取决于您的项目/用例)是 pip-tools .
    您可以(这是一种选择,更多信息请参见 docs ):
  • 创建 requirements.in (与 requirements.txt 格式相同,是否固定某些包依赖取决于您)
  • 那么您可以通过 pip install pip-tools 使用它正在运行 pip-compile requirements.in
  • 这将生成新的 requirements.txt所有版本都是的文件固定 ,一目了然,是什么起源
  • (可选)您可以使用 --generate-hashes 运行它选项
  • 然后您可以(与 pipreqs 一样)随时基于此 requirements.txt 创建新环境
  • pip-tools为您报价 --upgrade升级最终要求的选项
  • 支持分层需求(例如具有开发和生产版本)
  • pre-commit 集成
  • 提供 pip-sync基于requirements.txt更新环境的工具

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

    关于python - 解决新的 pip 回溯运行时问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65122957/

    相关文章:

    python - 如何将不同值的行连接成新列的单行?

    python - 使用本地依赖项用诗歌构建可安装的 tar.gz/whl

    cmake - CMake 安装出现问题,正在中止构建。 CMake 可执行文件是 cmake

    python - 当我在 virtualenv 中时无法 pip 安装包

    python - Keras错误: Error when checking model target: the list of Numpy arrays that you are passing to your model is not the size the model expected

    python - 在 Python 中导入 .意思是?

    python - 构建成功后 pip 不删除源

    python - 获取虚拟环境python包安装日期的方法

    python - 我可以在 PyTorch 中指定内核权重特定学习率吗?

    python - Numpy:从二维数组中获取随机行集