新しい pip バックトラッキング ランタイム問題の解決 質問する

新しい pip バックトラッキング ランタイム問題の解決 質問する

新しい pip 依存関係リゾルバーバージョン 20.3 でリリースされたは、パッケージのインストールに不当に長い時間がかかります。昨日の CI パイプラインでは、以前は約 10 分かかっていた docker ビルドが、次のような pip インストール メッセージの 1 時間後にタイムアウトしました (依存関係によってインストールされるほぼすべてのライブラリに対して、同様のログ出力があります)。

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.

観察された行動は次のように説明される。バックトラックリリース ノートに、なぜそれが存在するのかがわかります。依存関係のバージョンを修正する制約ファイル (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.

古い依存関係リゾルバを使用すると、このパッケージを 1 分以内にローカルにインストールできました。

ここで推奨されるプロセスは何ですか?

編集: 依存関係の一部が内部の GitLab サーバーを直接指していることがわかりました。代わりに内部パッケージ レジストリから直接インストールすると、数分で再び動作します。

ベストアンサー1

最新更新(2022-02)

pip数日後にメジャーアップデートがあるようです(バージョン22.0リリースノート+githubの関連問題)。

詳しくテストしたわけではありませんが、複雑なケースでのインストール順序の計算が最適化され、これまで遭遇した多くの問題が解決されたように思えます。ただし、確認するにはさらに時間が必要です。

いずれにせよ、この回答の残りの部分は依然として有効であり、特定のプロジェクトに適したスマートな要件の固定は良い方法だと思います。


私も同様の問題に遭遇したので、これはかなり面倒だと思います。バックトラッキングは便利な機能かもしれませんが、成功するかどうかわからないまま完了するまで何時間も待つのは嫌ですよね。

役立つかもしれないオプションをいくつか見つけました:

  • Use the old resolver (--use-deprecated=legacy-resolver) proposed in the answer by @Daniel Davee, but this is more like temporary solution than a proper one.
  • Skip resolving dependencies with --no-deps option. I would not recommend this generally but in some cases you can have a working set of packages versions although there are some conflicts.
  • Reduce the number of versions pip will try to backtrack and be more strict on package dependencies. This means instead of putting e.g. numpy in my requirements.txt, I could try numpy >= 1.18.0 or be even more strict with numpy == 1.18.0. The strictness might help a lot.

Check the following sources:

I still do not have a proper answer that would always help but the best practice for requirements.txt seems to "pin" package versions. I found pip-tools that could help you manage this even with constrains.txt (but I am in an experimental phase so I can not tell you more).

Update (2021-04)

It seems author of the question was able to fix the issue (something with custom gitlab server) but I would like to extend this answer since it might be useful for others.

After reading and trying I ended up with pinning all my package versions to a specific one. This really should be the correct way. Although everything can still work without it, there might be cases where if you don't pin your dependencies, your package manager will silently install a new version (when it's released) with possible bugs or incompatibility (this happens to me with dask last this year).

There are several tools which might help you, I would recommend one of these approaches:

Easiest one with pipreqs

  • pipreqs is a library which generates pip requirements.txt file based on imports of any project
  • you can start by pip install pipreqs and runnning just pipreqs in your project root (or eventually with --force flag if your requirements already exists)
  • it will easily create requirements.txt with pinned versions based on imports in your project and versions taken from your environment
  • then you can at any time create new environment based on this requirements.txt

This is really simple tool (you even do not need to write your requirements.txt). It does not allow you to create something complex (might not be a good choice for bigger projects), last week I found one strange behavior (see this) but generally I'm happy with this tool as it usually works perfectly.

Using pip-tools

There are several other tools commonly used like pip-tools, Pipenv or Poetry. You can read more in Faster Docker builds with pipenv, poetry, or pip-tools or Python Application Dependency Management in 2018 (older but seems still valid to me). And it still seems to me that the best option (although it depends on your project/use case) is pip-tools.

You can (this is one option, see more in docs):

  • 作成しますrequirements.in( と同じ形式ですがrequirements.txt、パッケージ依存関係を固定するかどうかはあなた次第です)
  • pip install pip-toolsそれを走らせることで使うことができますpip-compile requirements.in
  • これにより、すべてのバージョンが含まれた新しいrequirements.txtファイルが生成されますピン留め、それは明らかです、起源は何ですか
  • --generate-hashes(オプション)オプションで実行できます
  • そうすればpipreqs、いつでもこれに基づいて新しい環境を作成することができます。requirements.txt
  • pip-tools--upgrade最終要件をアップグレードするオプションを提供します
  • 階層化された要件をサポートする(例:開発バージョンと本番バージョンを持つ)
  • 統合されている事前コミット
  • pip-syncrequirements.txtに基づいて環境を更新するためのツールを提供します

これを使ってできることは他にもいくつかありますが、私は との統合が本当に気に入っていますpre-commit。これにより、以前と同じ要件 (サフィックスのみ.in) を使用し、自動的に更新される事前コミット フックを追加できrequirements.txtます (そのため、手動で何かを実行するときに簡単に発生する可能性のある、生成された と異なるローカル環境になることは決してありませんrequirements.txt)。

おすすめ記事