Skip to content

pipおよびpip-toolsとの互換性

uvは、一般的なpipおよびpip-toolsのワークフローのドロップイン置換として設計されています。

非公式には、既存のpipおよびpip-toolsユーザーが、パッケージングワークフローに意味のある変更を加えることなくuvに切り替えることができるようにすることを意図しています。ほとんどの場合、pip installuv pip installに置き換えるだけで「うまくいく」べきです。

ただし、uvはpipの完全なクローンを目指しているわけではなく、一般的なpipワークフローから離れるほど、動作の違いに遭遇する可能性が高くなります。場合によっては、その違いは既知で意図的なものであるかもしれません。他の場合では、実装の詳細によるものであるかもしれません。また、バグである場合もあります。

このドキュメントでは、uvとpipの間の既知の違い、理由、回避策、および将来の互換性に関する意図について説明します。

設定ファイルと環境変数

uvは、pip.confPIP_INDEX_URLなど、pipに特有の設定ファイルや環境変数を読み取りません。

他のツール用の設定ファイルや環境変数を読み取ることにはいくつかの欠点があります:

  1. ユーザーがフォーマットやパーサーのバグに依存するため、ターゲットツールとのバグ互換性が必要です。
  2. ターゲットツールがフォーマットを変更した場合、uvも同様に変更する必要があります。
  3. その設定がバージョン管理されている場合、uvはユーザーが使用するターゲットツールのバージョンを知る必要があります。
  4. ターゲットツールに存在しない設定や構成をuvが導入することを妨げます。そうでなければ、pip.conf(または類似のもの)はpipと互換性がなくなります。
  5. uvが他のツール用の設定ファイルを読み取ることを期待しない多くのユーザーにとって、uvが実際にはその動作に影響を与えない設定を読み取ることは混乱を招く可能性があります。

代わりに、uvはUV_INDEX_URLのような独自の環境変数をサポートしています。uvはまた、uv.tomlファイルやpyproject.toml[tool.uv.pip]セクションでの永続的な設定もサポートしています。詳細については、設定ファイルを参照してください。

プレリリースの互換性

デフォルトでは、uvは次の2つの場合に依存関係の解決中にプレリリースバージョンを受け入れます:

  1. パッケージが直接の依存関係であり、そのバージョンマーカーにプレリリース指定子が含まれている場合(例:flask>=2.0.0rc1)。
  2. パッケージのすべての公開バージョンがプレリリースである場合。

依存関係の解決が推移的なプレリリースのために失敗した場合、uvはすべての依存関係に対してプレリリースを許可するために--prerelease allowで再実行するようにユーザーに促します。

または、推移的な依存関係をプレリリース指定子(例:flask>=2.0.0rc1)でrequirements.inファイルに追加して、その特定の依存関係に対するプレリリースサポートをオプトインすることもできます。

要するに、uvは特定のパッケージに対してリゾルバがプレリリースを受け入れるかどうかを事前に知る必要があります。一方、pipはリゾルバが関連する指定子に遭遇する順序に応じて推移的な依存関係のプレリリース識別子を尊重する場合があります(#1641)。

プレリリースはモデル化が非常に難しいものであり、パッケージングツールのバグの頻繁な原因です。リファレンス実装と見なされるpipでさえ、プレリリースの処理に関して多くの未解決の問題があります(#12469#12470#40505など)。uvのプレリリース処理は意図的に制限されており、プレリリースの正確性を確保するためにユーザーのオプトインを必要とします。

将来的には、uvは推移的な依存関係におけるプレリリース識別子をサポートするかもしれません。ただし、それはPythonパッケージング仕様の進化に依存する可能性があります。既存のPEPは「依存関係の解決」をカバーしていないため、単一のバージョン指定子の動作に焦点を当てています。そのため、パッケージングエコシステム全体でプレリリースの正しいおよび意図された動作に関する未解決の問題があります。

複数のインデックスに存在するパッケージ

uvとpipの両方で、ユーザーは特定のパッケージの利用可能なバージョンを検索するために複数のパッケージインデックスを指定できます。ただし、uvとpipは複数のインデックスに存在するパッケージの処理方法が異なります。

たとえば、会社がプライベートインデックス(--extra-index-url)に内部バージョンのrequestsを公開し、デフォルトでPyPIからのパッケージのインストールも許可しているとします。この場合、プライベートなrequestsは公開されているrequestsと競合します。

uvが複数のインデックスでパッケージを検索する場合、インデックスを順番に反復し(--extra-index-urlをデフォルトインデックスより優先)、一致するものが見つかると検索を停止します。つまり、パッケージが複数のインデックスに存在する場合、uvはパッケージを含む最初のインデックスに存在する候補バージョンに制限します。

一方、pipはすべてのインデックスから候補バージョンを組み合わせ、結合セットから最適なバージョンを選択しますが、インデックスを検索する順序については保証しませんし、インデックス間で名前とバージョンが一意であることを期待します。

uvの動作は、パッケージが内部インデックスに存在する場合、常に内部インデックスからインストールされ、PyPIからはインストールされないようにすることです。これは、攻撃者が内部パッケージと同じ名前の悪意のあるパッケージをPyPIに公開し、内部パッケージの代わりに悪意のあるパッケージがインストールされる「依存関係の混乱」攻撃を防ぐことを意図しています。たとえば、2022年12月のtorchtriton攻撃を参照してください。

バージョン0.1.39以降、ユーザーは--index-strategyコマンドラインオプションまたはUV_INDEX_STRATEGY環境変数を使用して、複数のインデックスに対するpipスタイルの動作をオプトインできます。サポートされている値は次のとおりです:

  • first-match(デフォルト):すべてのインデックスで各パッケージを検索し、パッケージを含む最初のインデックスに存在する候補バージョンに制限します。--extra-index-urlインデックスをデフォルトインデックスURLより優先します。
  • unsafe-first-match:すべてのインデックスで各パッケージを検索しますが、他のインデックスに新しいバージョンが存在しても、互換性のあるバージョンを含む最初のインデックスを優先します。
  • unsafe-best-match:すべてのインデックスで各パッケージを検索し、候補バージョンの結合セットから最適なバージョンを選択します。

unsafe-best-matchpipの動作に最も近いですが、「依存関係の混乱」攻撃のリスクにさらされます。

uvはまた、特定のインデックスにパッケージを固定することもサポートしています(例:Indexesを参照)。これにより、特定のパッケージが常に特定のインデックスからインストールされます。

PEP 517ビルドの分離

uvはデフォルトでPEP 517ビルドの分離を使用します(pip install --use-pep517に類似)。これはpypa/buildに従い、将来的にpipがPEP 517ビルドをデフォルトにすることを見越しています(pypa/pip#9175)。

パッケージがビルド時の依存関係の欠如によりインストールに失敗する場合は、新しいバージョンのパッケージを使用してみてください。問題が解決しない場合は、パッケージメンテナに問題を報告し、正しいPEP 517ビルド時の依存関係を宣言するように依頼してください。

エスケープハッチとして、パッケージのビルド依存関係を事前にインストールし、--no-build-isolationオプションを使用してuv pip installを実行できます。例:

uv pip install wheel && uv pip install --no-build-isolation biopython==1.77

PEP 517ビルドの分離で失敗することが知られているパッケージのリストについては、#2252を参照してください。

推移的なURL依存関係

uvはURL依存関係(例:ruff @ https://...)を一級市民としてサポートしていますが、推移的なURL依存関係の処理方法がpipとは異なります。

まず、uvは非URL依存関係が解決中にURL依存関係を導入しないと仮定します。つまり、レジストリから取得された依存関係はURLに依存しないと仮定します。非URL依存関係がURL依存関係を導入する場合、uvは解決中にそのURL依存関係を拒否します(PyPIは公開パッケージがURL依存関係に依存することを許可していません。他のレジストリはより寛容かもしれません)。

第二に、制約(--constraint)またはオーバーライド(--override)が直接URL依存関係を使用して定義されており、制約されたパッケージが独自の直接URL依存関係を持っている場合、uvはその推移的な直接URL依存関係を解決中に拒否することがあります。URLが入力要件セットの他の場所で参照されていない場合です。

uvが推移的なURL依存関係を拒否する場合、最善の方法は、関連するpyproject.tomlまたはrequirement.inファイルにURL依存関係を直接依存関係として提供することです。上記の制約は直接依存関係には適用されません。

デフォルトで仮想環境

uv pip installおよびuv pip syncは、デフォルトで仮想環境と連携するように設計されています。

具体的には、uvは常に現在アクティブな仮想環境にパッケージをインストールするか、現在のディレクトリまたは親ディレクトリに.venvという名前の仮想環境を検索します(アクティブでなくても)。

これは、仮想環境がアクティブでない場合にグローバル環境にパッケージをインストールし、非アクティブな仮想環境を検索しないpipとは異なります。

uvでは、--python /path/to/pythonオプションを使用してPython実行ファイルへのパスを提供するか、--systemフラグを使用して最初に見つかったPythonインタープリタにインストールすることで、非仮想環境にインストールできます。これはpipと同様です。

言い換えれば、uvはデフォルトを反転させ、システムPythonへのインストールには明示的なオプトインを必要とします。これは破損やその他の複雑な問題を引き起こす可能性があり、限られた状況でのみ行うべきです。

詳細については、「任意のPython環境の使用」を参照してください。

解決戦略

特定の依存関係指定子のセットに対して、インストールする「正しい」パッケージのセットが存在しないことがよくあります。代わりに、指定子を満たす有効なパッケージのセットが多数存在します。

pipもuvも、インストールされるパッケージの正確なセットについて保証しません。解決が一貫性があり、決定論的であり、指定子に準拠していることのみを保証します。そのため、場合によっては、pipとuvが異なる解決をもたらすことがあります。ただし、両方の解決は同様に有効であるべきです。

たとえば、次のように考えてみましょう:

requirements.in
starlette
fastapi

執筆時点で、最新のstarletteバージョンは0.37.2であり、最新のfastapiバージョンは0.110.0です。ただし、fastapi==0.110.0starletteにも依存しており、上限を導入しています:starlette>=0.36.3,<0.37.0

リゾルバが最新バージョンのstarletteを優先する場合、fastapiの古いバージョンを使用する必要があります。実際には、fastapi==0.1.17に戻る必要があります:

requirements.txt
# このファイルは次のコマンドを使用してuvによって自動生成されました:
#    uv pip compile requirements.in
annotated-types==0.6.0
    # via pydantic
anyio==4.3.0
    # via starlette
fastapi==0.1.17
idna==3.6
    # via anyio
pydantic==2.6.3
    # via fastapi
pydantic-core==2.16.3
    # via pydantic
sniffio==1.3.1
    # via anyio
starlette==0.37.2
    # via fastapi
typing-extensions==4.10.0
    # via
    #   pydantic
    #   pydantic-core

または、リゾルバが最新バージョンのfastapiを優先する場合、上限を満たす古いバージョンのstarletteを使用する必要があります。実際には、starlette==0.36.3に戻る必要があります:

requirements.txt
# このファイルは次のコマンドを使用してuvによって自動生成されました:
#    uv pip compile requirements.in
annotated-types==0.6.0
    # via pydantic
anyio==4.3.0
    # via starlette
fastapi==0.110.0
idna==3.6
    # via anyio
pydantic==2.6.3
    # via fastapi
pydantic-core==2.16.3
    # via pydantic
sniffio==1.3.1
    # via anyio
starlette==0.36.3
    # via fastapi
typing-extensions==4.10.0
    # via
    #   fastapi
    #   pydantic
    #   pydantic-core

uvの解決がpipと異なる望ましくない方法で異なる場合、それは指定子が緩すぎる兆候であり、ユーザーがそれらを厳密にすることを検討するべきです。たとえば、starlettefastapiの場合、ユーザーはfastapi>=0.110.0を要求することができます。

pip check

現在、uv pip checkは次の診断を表示します:

  • パッケージにMETADATAファイルがない、またはMETADATAファイルを解析できない。
  • パッケージのRequires-Pythonが実行中のインタープリタのPythonバージョンと一致しない。
  • パッケージがインストールされていないパッケージに依存している。
  • パッケージがインストールされているが、互換性のないバージョンのパッケージに依存している。
  • 仮想環境に複数のバージョンのパッケージがインストールされている。

場合によっては、uv pip checkpip checkが表示しない診断を表示し、その逆もあります。たとえば、uv pip checkとは異なり、pip checkは現在の環境に複数のバージョンのパッケージがインストールされている場合に警告しません。

--userおよびuserインストールスキーム

uvはuserインストールスキームに基づいてパッケージをインストールする--userフラグをサポートしていません。代わりに、パッケージインストールを分離するために仮想環境の使用を推奨します。

さらに、pipはターゲットディレクトリへの書き込み権限がないことを検出した場合、システムPythonにインストールする場合など、一部のシステムでuserインストールスキームにフォールバックします。uvはそのようなフォールバックを実装していません。

詳細については、#2077を参照してください。

--only-binaryの強制

--only-binary引数は、事前にビルドされたバイナリディストリビューションにインストールを制限するために使用されます。--only-binary :all:が提供されると、pipとuvの両方がPyPIおよび他のレジストリからソースディストリビューションをビルドすることを拒否します。

ただし、依存関係が直接URLとして提供される場合(例:uv pip install https://...)、pipは--only-binaryを強制せず、すべてのそのようなパッケージのソースディストリビューションをビルドします。

一方、uvは直接URL依存関係に対して--only-binaryを強制しますが、1つの例外があります:uv pip install https://... --only-binary flaskが提供される場合、uvはパッケージ名を事前に推測できない場合、指定されたURLでソースディストリビューションをビルドします。uvはそのような場合にパッケージが「許可されている」かどうかを判断できないためです。

pipとuvの両方は、--only-binaryが提供されている場合でも、編集可能な要件をビルドしてインストールすることを許可します。たとえば、uv pip install -e . --only-binary :all:は許可されます。

--no-binaryの強制

--no-binary引数は、インストールをソースディストリビューションに制限するために使用されます。--no-binaryが提供される場合、uvは事前にビルドされたバイナリディストリビューションをインストールすることを拒否しますが、ローカルキャッシュに既に存在するバイナリディストリビューションを再利用します。

さらに、pipとは対照的に、uvのリゾルバは--no-binaryが提供されている場合でも事前にビルドされたバイナリディストリビューションからメタデータを読み取ります。

manylinux_compatibleの強制

PEP 600は、Pythonディストリビュータが_manylinux標準ライブラリモジュールにmanylinux_compatible関数を定義することでmanylinux互換性をオプトアウトするメカニズムを説明しています。

uvはmanylinux_compatibleを尊重しますが、現在のglibcバージョンに対してのみテストし、manylinux_compatibleの戻り値をグローバルに適用します。

言い換えれば、manylinux_compatibleTrueを返す場合、uvはシステムをmanylinux互換と見なし、Falseを返す場合、uvはシステムをmanylinux非互換と見なし、すべてのglibcバージョンに対してmanylinux_compatibleを呼び出しません。

このアプローチは仕様の完全な実装ではありませんが、no-manylinuxのような一般的なブランケットmanylinux_compatible実装と互換性があります:

from __future__ import annotations
manylinux1_compatible = False
manylinux2010_compatible = False
manylinux2014_compatible = False


def manylinux_compatible(*_, **__):  # PEP 600
    return False

バイトコードのコンパイル

pipとは異なり、uvはデフォルトでインストール中に.pyファイルを.pycファイルにコンパイルしません(つまり、uvは__pycache__ディレクトリを作成またはポピュレートしません)。インストール中にバイトコードのコンパイルを有効にするには、uv pip installまたはuv pip sync--compile-bytecodeフラグを渡します。

厳格さと仕様の強制

uv は pip よりも厳格であり、pip がインストールするパッケージを拒否することがよくあります。たとえば、uv は無効な URL フラグメントを含む HTML インデックスを拒否します(参照:PEP 503)、一方 pip はそのようなフラグメントを無視します。

場合によっては、uvは特定の仕様準拠の問題がある人気のあるパッケージに対して寛容な動作を実装します。

uvが仕様違反のためにpipがインストールするパッケージを拒否する場合、最善の方法は、まずパッケージの新しいバージョンをインストールしようとし、それが失敗した場合はパッケージメンテナに問題を報告することです。

pipコマンドラインオプションとサブコマンド

uvはpipのコマンドラインオプションとサブコマンドの完全なセットをサポートしていませんが、大部分をサポートしています。

欠落しているオプションとサブコマンドは、ユーザーの需要と実装の複雑さに基づいて優先され、個別の問題で追跡される傾向があります。たとえば:

欠落しているオプションやサブコマンドに遭遇した場合は、既に報告されているかどうかを確認し、報告されていない場合は新しい問題を開くことを検討してください。既存の問題に投票して関心を伝えることもできます。

レジストリ認証

uvはpip--keyring-providerautoまたはimportオプションをサポートしていません。現在、subprocessオプションのみがサポートされています。

pipとは異なり、uvはデフォルトでキーチェーン認証を有効にしません。

pipとは異なり、uvはHTTP 401が返されるまで認証を検索しません。uvは資格情報が利用可能なホストのすべてのリクエストに認証を添付します。

eggサポート

uvはpipでレガシーまたは非推奨と見なされる機能をサポートしていません。たとえば、uvは.eggスタイルのディストリビューションをサポートしていません。

ただし、uvは(1).egg-infoスタイルのディストリビューション(DockerイメージやConda環境で見られることがある)および(2)レガシー編集可能な.egg-linkスタイルのディストリビューションの部分的なサポートを提供します。

具体的には、uvは新しい.egg-infoまたは.egg-linkスタイルのディストリビューションのインストールをサポートしていませんが、解決中にそのような既存のディストリビューションを尊重し、uv pip listおよびuv pip freezeでそれらをリストし、uv pip uninstallでアンインストールします。

ビルド制約

制約が--constraint(またはUV_CONSTRAINT)を介して提供される場合、uvはビルド依存関係を解決する際に制約を適用しません(つまり、ソースディストリビューションをビルドするために)。代わりに、ビルド制約は専用の--build-constraint(またはUV_BUILD_CONSTRAINT)設定を介して提供する必要があります。

一方、pipはPIP_CONSTRAINTを介して指定された場合にビルド依存関係に制約を適用しますが、コマンドラインで--constraintが提供された場合には適用しません。

たとえば、setuptoolsにビルド依存関係があるパッケージをビルドするためにsetuptools 60.0.0を使用することを確実にするには、--constraintではなく--build-constraintを使用します。

pip compileのデフォルト

pip compilepip-toolsのデフォルトの動作にはいくつかの小さな違いがあります。

デフォルトでは、uvはコンパイルされた要件を出力ファイルに書き込みません。代わりに、uvはユーザーが-oまたは--output-fileオプションを使用して出力ファイルを明示的に指定することを要求します。

デフォルトでは、uvはコンパイルされた要件を出力する際にエクストラを削除します。言い換えれば、uvはデフォルトで--strip-extrasを使用し、pip-compileはデフォルトで--no-strip-extrasを使用します。pip-compileは次のメジャーリリース(v8.0.0)でこのデフォルトを変更する予定であり、その時点で両方のツールはデフォルトで--strip-extrasを使用します。uvでエクストラを保持するには、uv pip compile--no-strip-extrasフラグを渡します。

デフォルトでは、uvは出力ファイルにインデックスURLを一切書き込みませんが、pip-compileはデフォルト(PyPI)と一致しない--index-urlまたは--extra-index-urlを出力します。出力ファイルにインデックスURLを含めるには、uv pip compile--emit-index-urlフラグを渡します。pip-compileとは異なり、uvは--emit-index-urlが渡された場合、デフォルトのインデックスURLを含むすべてのインデックスURLを含めます。

requires-pythonの強制

Pythonバージョンをrequires-python指定子と比較する際、uvは候補バージョンをメジャー、マイナー、およびパッチコンポーネントに切り捨て、プレリリースおよびポストリリース識別子を無視します。

たとえば、requires-python: >=3.13を宣言するプロジェクトはPython 3.13.0b1を受け入れます。3.13.0b1は厳密には3.13よりも大きくありませんが、プレリリース識別子が省略されると3.13よりも大きくなります。

これはPEP 440に厳密には準拠していませんが、pipと一致しています。

パッケージの優先順位

要件のセットが与えられた場合、通常、解決策が多数存在し、リゾルバはそれらの中から選択する必要があります。uvのリゾルバとpipのリゾルバは異なるパッケージの優先順位を持っています。両方のリゾルバはユーザー提供の順序を優先順位の1つとして使用しますが、pipにはuvにはない追加の優先順位があります。そのため、uvはユーザーの順序の変更によってpipよりも影響を受けやすいです。

たとえば、uv pip install foo barfooの新しいバージョンをbarよりも優先し、uv pip install bar fooとは異なる解決をもたらす可能性があります。同様に、この動作はuv pip compileの入力ファイルの要件の順序にも適用されます。