pip
およびpip-tools
との互換性
uvは、一般的なpip
およびpip-tools
のワークフローのドロップイン置換として設計されています。
非公式には、既存のpip
およびpip-tools
ユーザーが、パッケージングワークフローに意味のある変更を加えることなくuvに切り替えることができるようにすることを意図しています。ほとんどの場合、pip install
をuv pip install
に置き換えるだけで「うまくいく」べきです。
ただし、uvはpip
の完全なクローンを目指しているわけではなく、一般的なpip
ワークフローから離れるほど、動作の違いに遭遇する可能性が高くなります。場合によっては、その違いは既知で意図的なものであるかもしれません。他の場合では、実装の詳細によるものであるかもしれません。また、バグである場合もあります。
このドキュメントでは、uvとpip
の間の既知の違い、理由、回避策、および将来の互換性に関する意図について説明します。
設定ファイルと環境変数
uvは、pip.conf
やPIP_INDEX_URL
など、pip
に特有の設定ファイルや環境変数を読み取りません。
他のツール用の設定ファイルや環境変数を読み取ることにはいくつかの欠点があります:
- ユーザーがフォーマットやパーサーのバグに依存するため、ターゲットツールとのバグ互換性が必要です。
- ターゲットツールがフォーマットを変更した場合、uvも同様に変更する必要があります。
- その設定がバージョン管理されている場合、uvはユーザーが使用するターゲットツールのバージョンを知る必要があります。
- ターゲットツールに存在しない設定や構成をuvが導入することを妨げます。そうでなければ、
pip.conf
(または類似のもの)はpip
と互換性がなくなります。 - uvが他のツール用の設定ファイルを読み取ることを期待しない多くのユーザーにとって、uvが実際にはその動作に影響を与えない設定を読み取ることは混乱を招く可能性があります。
代わりに、uvはUV_INDEX_URL
のような独自の環境変数をサポートしています。uvはまた、uv.toml
ファイルやpyproject.toml
の[tool.uv.pip]
セクションでの永続的な設定もサポートしています。詳細については、設定ファイルを参照してください。
プレリリースの互換性
デフォルトでは、uvは次の2つの場合に依存関係の解決中にプレリリースバージョンを受け入れます:
- パッケージが直接の依存関係であり、そのバージョンマーカーにプレリリース指定子が含まれている場合(例:
flask>=2.0.0rc1
)。 - パッケージのすべての公開バージョンがプレリリースである場合。
依存関係の解決が推移的なプレリリースのために失敗した場合、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-match
はpip
の動作に最も近いですが、「依存関係の混乱」攻撃のリスクにさらされます。
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
を実行できます。例:
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が異なる解決をもたらすことがあります。ただし、両方の解決は同様に有効であるべきです。
たとえば、次のように考えてみましょう:
執筆時点で、最新のstarlette
バージョンは0.37.2
であり、最新のfastapi
バージョンは0.110.0
です。ただし、fastapi==0.110.0
はstarlette
にも依存しており、上限を導入しています:starlette>=0.36.3,<0.37.0
。
リゾルバが最新バージョンのstarlette
を優先する場合、fastapi
の古いバージョンを使用する必要があります。実際には、fastapi==0.1.17
に戻る必要があります:
# このファイルは次のコマンドを使用して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
に戻る必要があります:
# このファイルは次のコマンドを使用して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
と異なる望ましくない方法で異なる場合、それは指定子が緩すぎる兆候であり、ユーザーがそれらを厳密にすることを検討するべきです。たとえば、starlette
とfastapi
の場合、ユーザーはfastapi>=0.110.0
を要求することができます。
pip check
現在、uv pip check
は次の診断を表示します:
- パッケージに
METADATA
ファイルがない、またはMETADATA
ファイルを解析できない。 - パッケージの
Requires-Python
が実行中のインタープリタのPythonバージョンと一致しない。 - パッケージがインストールされていないパッケージに依存している。
- パッケージがインストールされているが、互換性のないバージョンのパッケージに依存している。
- 仮想環境に複数のバージョンのパッケージがインストールされている。
場合によっては、uv pip check
はpip 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_compatible
がTrue
を返す場合、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-provider
のauto
または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 compile
とpip-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 bar
はfoo
の新しいバージョンをbar
よりも優先し、uv pip install bar foo
とは異なる解決をもたらす可能性があります。同様に、この動作はuv pip compile
の入力ファイルの要件の順序にも適用されます。