Pip: `pip install -U`は、すでに満たされた依存関係をアップグレードします

作成日 2011年06月09日  ·  23コメント  ·  ソース: pypa/pip

pip install -U foo場合、最新バージョンのfooがインストールされ、 fooの依存関係は、まだ満たされていない場合にのみ再インストールされると思います。 しかし実際には、同じバージョンがすでにインストールされている場合でも、依存関係はすべて再インストールされます。


$ pip install -U django-supervisor
Downloading/unpacking django-supervisor
  Downloading django-supervisor-0.2.0.tar.gz
  Running setup.py egg_info for package django-supervisor
Downloading/unpacking supervisor (from django-supervisor)
  Downloading supervisor-3.0a10.tar.gz (438Kb): 438Kb downloaded
  Running setup.py egg_info for package supervisor
    no previously-included directories found matching 'docs/*.pyc'
    no previously-included directories found matching 'docs/.build'
Downloading/unpacking meld3>=0.6.5 (from supervisor->django-supervisor)
  Downloading meld3-0.6.7.tar.gz
  Running setup.py egg_info for package meld3
Installing collected packages: django-supervisor, supervisor, meld3
  Found existing installation: django-supervisor 0.1.1
    Uninstalling django-supervisor:
      Successfully uninstalled django-supervisor
  Running setup.py install for django-supervisor
  Found existing installation: supervisor 3.0a10
    Uninstalling supervisor:
      Successfully uninstalled supervisor
  Running setup.py install for supervisor
    no previously-included directories found matching 'docs/*.pyc'
    no previously-included directories found matching 'docs/.build'
    Skipping installation of /usr/local/ejucovy/django/lib/python2.6/site-packages/supervisor/__init__.py (namespace package)
    Installing /usr/local/ejucovy/django/lib/python2.6/site-packages/supervisor-3.0a10-py2.6-nspkg.pth
    Installing echo_supervisord_conf script to /usr/local/ejucovy/django/bin
    Installing pidproxy script to /usr/local/ejucovy/django/bin
    Installing supervisorctl script to /usr/local/ejucovy/django/bin
    Installing supervisord script to /usr/local/ejucovy/django/bin
  Found existing installation: meld3 0.6.7
    Uninstalling meld3:
      Successfully uninstalled meld3
  Running setup.py install for meld3
Successfully installed django-supervisor supervisor meld3
Cleaning up...

supervisor-3.0a10meld3-0.6.7 「既存のインストール」は両方とも「正常にアンインストール」され、同じバージョンがインストールされます。

upgrade auto-locked bug

最も参考になるコメント

#49の複製ではないと思います。 #49を読んだところ、 install -U fooは、すでに最新バージョンになっている場合は_ foo自体_を再インストールしないでください。これは、 foo再インストールする必要があるかどうかとは異なります。のすでに満たされた依存関係。

この区別は、リリースが頻繁であるがAPIがかなり安定しているビルドが難しいライブラリにとって重要です-ほとんどの場合、1回のインストールで十分です-依存関係がそれらの新しい機能を使用し始めた場合にのみ再インストールしたいと思いますネストされた依存関係(つまり、要件が満たされなくなった場合)-例:

  • foo 0.1lxml>=2.3.0依存します
  • foo 0.2がリリースされ、 lxml>=2.3.0依存します(同じ依存関係)
  • lxml 2.4.0がリリースされました

すでにfoo 0.1lxml 2.3.0をインストールしていて、 pip install -U foo場合、 lxml 2.4.0をインストールしたくありません。 foolxml>=2.4.0に依存し始めた場合にのみ、 lxml 2.4.0インストールする必要があります。

全てのコメント23件

私の判断では、これは既知の動作です。本当にバグかどうかはわかりません。 easy_installも同じ動作をしていると思います。

他の人の意見を聞きたいです。

PS:これに関連するStackOverflowに質問がありました: http

第49号に関連

これはバグであり、#49の複製です。

#49の複製ではないと思います。 #49を読んだところ、 install -U fooは、すでに最新バージョンになっている場合は_ foo自体_を再インストールしないでください。これは、 foo再インストールする必要があるかどうかとは異なります。のすでに満たされた依存関係。

この区別は、リリースが頻繁であるがAPIがかなり安定しているビルドが難しいライブラリにとって重要です-ほとんどの場合、1回のインストールで十分です-依存関係がそれらの新しい機能を使用し始めた場合にのみ再インストールしたいと思いますネストされた依存関係(つまり、要件が満たされなくなった場合)-例:

  • foo 0.1lxml>=2.3.0依存します
  • foo 0.2がリリースされ、 lxml>=2.3.0依存します(同じ依存関係)
  • lxml 2.4.0がリリースされました

すでにfoo 0.1lxml 2.3.0をインストールしていて、 pip install -U foo場合、 lxml 2.4.0をインストールしたくありません。 foolxml>=2.4.0に依存し始めた場合にのみ、 lxml 2.4.0インストールする必要があります。

ああ、はい、それは少し異なります。 #49が修正されたとしても、依存関係が最新バージョンではないが、依存関係の要件を満たしている場合に、必要な動作を実現するために必要な追加のコードがいくつかあります。

この変更を加えると、意外な人もいると思います。 特定の場合にそれが望ましい理由はわかりますが、現在の動作(マイナス#49)が望ましい場合もわかります。 だから私はこれのフェンスにいます。

追加のコマンドラインオプションが適切でしょうか? pip install foo --upgrade vs pip install foo --upgrade-recursive ? (または、現在の動作を逆方向に保持する場合は--upgrade-nonrecursive -互換性が重要です)

デフォルトでアップグレードを非再帰的にすると、APTやPortageなどの他のパッケージマネージャーとの一貫性が得られます。 そして、そのような動作には正当な理由があると思います。それは、意図しない副作用を回避することです。パッケージPをアップグレードする場合は、 upgrade P行に沿ってコマンドを入力します。 upgrade P --but-not-other-thingsはありません。

一方、「all」はデフォルトで「all」を意味するはずなので、「upgradeall」コマンド(#59を参照)はデフォルトで再帰的である必要があると思います。 この場合、非再帰的な動作は、「直接インストールされたすべてのパッケージをアップグレードしますが、直接インストールされなかった依存関係はアップグレードしません」(Portageのemerge --update @world--deep )を意味します。

関連する問題は、アップグレードされるパッケージが、すでにインストールされているがリポジトリから利用できない別のパッケージに依存している場合、依存関係が満たされているにもかかわらず、Pipが失敗し、要求されたパッケージをアップグレードできないことです。

これは、-Iと-Uで発生するようです。

-I--ignore-installed -I表し、pipを現在何もインストールされていないかのように動作させることを目的としているため、すべてを再インストールすることは-Iの正しい動作です。 したがって、ここでの動作は-Uバグであり、 -Iバグではありません。

easy_installの動作は同じではありません。 easy_installは、依存関係がすでに満たされている場合、依存関係を再インストールしません。

これは機能や動作ではなく、バグです。

これも非常に面倒です。フレームワークのパッケージのPIP配布をテストしたり、単一のフレームワークアドオンを更新したりすると、フレームワーク全体とそのすべての依存関係を再インストールする必要があります。 これらの不要なダウンロードとインストールは、時間とリソースの無駄です。

動作/コードを「-U」に変更する以外に、これを_今_行う方法が必要な場合

これで望ましい結果が得られると思いますよね?

トップレベルの要件のみをアップグレードします。

  • pip install -U --no-deps REQS //トップレベルのみをアップグレードします
  • pip install REQS //この2番目のパスは、アップグレードからの_new_依存関係をインストールします

最も単純なケースで十分ですが、requirements.txtファイルでは機能しないと思います。または、install_requiresに更新がある依存関係がある場合。 私たちはrequirements.txtの差分を実行し、多かれ少なかれあなたが説明したことを実行する複雑なスクリプトを持っていますが、それはアップグレードの深さ> 1を処理しません。

ある程度問題を複雑にしているのは、このバグのために、多くのdjangoパッケージがinstall_requires行をコメントアウトまたは削除していることです。 そうしないと、djangoのアルファ版がインストールされてしまいます(これは私たちの経験であり、多くの著名なdjangoパッケージのgithubの問題で見ました。

ねえ@fdintino 、私は要件、-U、および--no-depsを使用して基本的なテストを装備しましたが、それは機能しているように見えました。つまり、要件ファイルの項目はアップグレードされましたが、依存関係はありません。 これは、コードが何をしているのかについての私の理解と一致しています。 しかし、そこは退屈なので、このアイデアは失敗する可能性があります。

トップレベルの要件に新しい「install_requires」依存関係がある場合は、それらをインストールするための2番目のパスコマンドについて説明しました。

「install_requiresが更新された依存関係がある」場合は、私があなたをフォローしているのかわかりません。 完全な再帰的アップグレードを実行したい場合は、それを発見してそれに基づいて行動したいだけですよね?

要件を満たさなくなった場合のみ。 したがって、たとえば、django-sentryを更新し、django-sentryがdjango-celery>=2.5.4,django-celery<3.0必要としていた場合、以前はdjango-celery>=2.5.3,django-celery<3.0必要django-celery==2.5.3場合、パッチと同じように、要件を満たすようにdjango-celeryを更新することを期待します。 しかし、たまたまdjango-celery==2.5.4を持っていたら、セロリが更新されるとは思いませんでした。 セロリの場合、それは大したことではありませんが、パッケージにDjango>1.2,Django<=1.4があり、プロジェクトがDjango 1.2、1.3、または1.4をターゲットとして作成されることが多い場合、djangoの予期しないアップグレードは大きな頭痛の種になる可能性があります。

ありがとう@fdintino 。 私は今フォローしています。 すべての再帰的な動作を遮断するのではなく(要件を満たすために必要なアップグレードを実行します)、再帰的な「強制」アップグレードを停止するだけです。

ところで、あなたのコメントはフォーマットのためにトリミングされています。 他の人のためにそれを修正したいかもしれません。

上記の2つのコマンドを順番に使用して、目的の動作を達成するための内訳の要点を投稿しました。
このチケットやプルの欲求が無効になるわけではありませんが、その方法を確認するのに役立ちました
それは現在機能し、現在何が可能か。
(ヒント:この例では、「b」は懸念事項として言及されたdjangoと類似しています)

https://gist.github.com/3088149

これがシナリオでない場合は、要点についてコメントをいただければ幸いです。

私はこれが長い間開かれていることに気づきました。

私のバージョンのpipには、実行するオプションがあることがわかりました

pip install --upgrade --upgrade-strategy=only-if-needed package

かなり冗長ですが、これは望ましい動作のようです。 個人的には、これがデフォルトだったら良かったと思いますが、今は変更するには遅すぎるかもしれません。

デフォルトを変更するには遅すぎる場合は、これを閉じることができると思いますか?

https://github.com/pypa/pip/issues/3871#issuecomment -247789343で、私がこれを前進させる方法であると私が信じていることを述べ、ここで再現します。

今これに戻って回る。 これが私たちがすべきだと思うことです:

  1. デフォルトがeagerであるpipvXに--upgrade-strategy = [eager / non-eager]を追加し、人々が非熱心な戦略にオプトインできるようにします。 これにより、一度に全員に変更を加えることなく、実際のテストを人々から受けることができます。
  2. 1.からのフィードバックに対処したら、pip vX + 1でデフォルトの--upgrade-strategynon-eagerに切り替えます。 これにより、すべての人に変更を強制することで、実際に多くの使用を得ることができますが、何らかの理由で変更によって壊れた人々に脱出用ハッチを提供します。
  3. 2.からのフィードバックに対処したら、pip vx + 2での--upgrade-strategy非推奨を検討してください(通常の非推奨ポリシーに従って削除されます)。

これにより、非熱心なものがデフォルトになるまでのリードタイムが長くなりますが、段階的にゆっくりと段階的に進めて、そこから混乱するユースケースがないことを確認できます。 理想的には、最終的に--upgrade-strategyフラグを削除したいと思います。 この種のフラグは、実際に完全にテストするためにアップグレードテストを複製する必要があるため、問題が発生した場合に問題が発生したように感じます。 ただし、フェーズインと破損への対処を可能にするために、今のところ追加するのは良いフラグだと思います。

いいですね。ステップ2が完了するのを待ちます。 他の問題は重複しているようですが、すでにクローズされています。

@xavfernandez @dstufftこれを閉じることはできますか、それともデフォルトが切り替わるまで待ちますか?

デフォルトが切り替わるまで待つでしょう。

#4500が統合されて以来、締めくくり

このページは役に立ちましたか?
0 / 5 - 0 評価