Compatibility with pip and pip-tools#
uvは、一般的なpipおよびpip-toolsワークフローのドロップイン置換として設計されています。
非公式には、既存のpipとpip-toolsのユーザがパッケージワークフローに意味のある変更を加えることなくuvに切り替えることができるようにすることを目的としています。そして、ほとんどの場合、pip installをuv pip installに置き換えることは"うまくいく"はずです。
しかし、uvはpipの正確なクローンを意図したものではなく、一般的なpipワークフローから離れるほど、動作の違いに遭遇する可能性が高くなります。これらの違いは、既知で意図的な場合もあれば、実装の詳細の結果である場合もあれば、バグである場合もあります。
この文書では、uvとpipの既知の違いを、理論的根拠、回避策、および将来の互換性に関する意図とともに概説します。
Configuration files and environment variables#
uvは、pip.confやPIP_INDEX_URLのようなpip固有の設定ファイルや環境変数を読み込みません。
他のツール用の設定ファイルと環境変数を読み込むことには、いくつかの欠点があります。
- ユーザがフォーマットやパーサなどのバグに依存することになるため、ターゲットツールとのバグ対バグの互換性が必要です。
- ターゲットツールが何らかの方法でフォーマットを変更すると、uvは同じ方法でフォーマットを変更するようにロックされます。
- その設定が何らかの方法でバージョン管理されている場合、uvは、ユーザが使用する予定のターゲットツールのバージョンを知る必要があります。
- これは、uvがターゲットツールに存在しない設定や構成を導入するのを防ぎます。そうでなければ、
pip.conf(または同様のもの)はpipで使用できなくなるからです。
- これはユーザの混乱を招く可能性があります。なぜなら、uvは実際には動作に影響しない設定を読み込むことになり、多くのユーザはuvが他のツール用の設定ファイルを読み込むことを_期待しない_可能性があるからです。
代わりに、uvはUV_INDEX_URLのような独自の環境変数をサポートします。将来、uvは独自の構成ファイル形式(例えばpyproject.tomlやuv.tomlなど)での永続的な構成もサポートする予定です。詳細については、#651を参照してください。
Pre-release compatibility#
デフォルトでは、uvは次の2つの場合に、依存関係の解決中にプレリリースバージョンを受け入れます。:
- パッケージが直接の依存関係であり、そのバージョンマーカーにプレリリース指定子が含まれている場合(例:
flask>=2.0.0rc1)。
- パッケージの_すべての_公開バージョンがプレリリースである場合。
推移的なプレリリースが原因で依存関係の解決に失敗した場合、uvはユーザに対して、すべての依存関係に対してプレリリースを許可するために、--prerelease allowで再実行するように促します。
あるいは、リリース前の指定子(例えばflask>=2.0.0rc1)でrequirements.inファイルに推移的な依存関係を追加して、その特定の依存関係のリリース前のサポートを選択することもできます。
要約すると、uvは、リゾルバが特定のパッケージのプレリリースを受け入れるべきかどうかを事前に知る必要があります。一方、pipは、リゾルバが関連する指定子(#1641)に遭遇する順序に応じて、推移的な依存関係にあるプレリリース識別子を尊重する可能性があります。
プレリリースはモデル化がnotoriously difficultであり、パッケージングツールのバグの原因となることが多くあります。参照実装と見なされているpipでさえ、プレリリースの処理に関して多くの未解決の問題があり(#12469、#12470、#40505など)。uvのプレリリースの処理は_意図的に_制限されており、_意図的に_正確さを保証するために、プレリリースに対してユーザのオプトインを必要とします。
将来、uv_may_は、推移的な依存関係でプレリリース識別子をサポートするようになります。ただし、これはPythonパッケージング仕様の進化に左右される可能性が高いです。既存のPEPs[do not cover "dependency resolution"]](https://discuss.python.org/t/handling-of-pre-releases-when-backtracking/40505/17)は、代わりに_single_version指定子の動作に焦点を当てています。そのため、より広範なパッケージングエコシステムでは、プレリリースの正しい意図された動作に関して未解決の問題があります。
Local version identifiers#
uvは、ローカルバージョン識別子(例えば1.2.3+local)の仕様に準拠した処理を実装していません。これは既知の制限と考えられています。ローカルバージョン識別子は公開されたパッケージでは稀ですが(例えばPyPIでは禁止されています)、PyTorchエコシステムでは一般的であり、uvのローカルバージョンへのアプローチは、標準のPyTorchワークフローをサポートしており、すぐに成功します。
PEP 440は、バージョン指定子を評価するときに、いくつかの例外を除いて、ローカルバージョンセグメントは通常無視されるべきであると指定しています。たとえば、foo==1.2.3は1.2.3+localを受け入れるべきですが、foo==1.2.3+localは1.2.3を受け入れるべきではありません。これらの非対称性は、解決アルゴリズムでモデル化するのは困難です。そのため、uvは1.2.3と1.2.3+localを完全に別々のバージョンとして扱いますが、解決全体を通じて直接の依存関係として提供されたローカルバージョンを尊重します。たとえば、foo==1.2.3+localを直接の依存関係として提供すると、foo==1.2.3を要求する推移的な依存関係に対して1.2.3+local_が受け入れられます。
PyTorchエコシステムから例を挙げると、torch==2.0.0+cu118とtorchvision==0.15.1+cu118を直接の依存関係として指定するのが一般的です。torchvision@0.15.1+cu118はtorch==2.0.0への依存関係を宣言します。この場合、torch==2.0.0+cu118は直接の依存関係として提供されているため、uvはこの指定子を満たすと認識します。
pipと比較して、観察された挙動の主な違いは以下のとおりです。:
- 一般に、ローカルバージョンは直接の依存関係として提供される必要があります。ローカル以外のバージョンを要求する推移的な依存関係の解決は成功する可能性がありますが、これは保証されていません。
- 指定されたバージョンのパッケージ
fooに_only_localバージョンが存在する場合(例えば、1.2.3+localは存在しますが、1.2.3は存在しません)、uv pip install foo==1.2.3は失敗し、pip install foo==1.2.3は任意のローカルバージョンに解決されます。
Packages that exist on multiple indexes#
uvとpipの両方で、ユーザは特定のパッケージの利用可能なバージョンを検索する複数のパッケージインデックスを指定できます。ただし、uvとpipでは、複数のインデックスに存在するパッケージの処理方法が異なります。
たとえば、ある会社がプライベートインデックス(--extra-index-url)にrequestsの内部バージョンを公開しているが、デフォルトでPyPIからパッケージをインストールすることも許可しているとします。この場合、プライベートrequestsはPyPI上のパブリックrequestsと競合します。
uvが複数のインデックスにまたがってパッケージを検索する場合、(デフォルトのインデックスよりも--extra-index-urlを優先して)インデックスを順番に繰り返し、一致するものが見つかるとすぐに検索を停止します。つまり、パッケージが複数のインデックスに存在する場合、uvはその候補バージョンを、そのパッケージを含む最初のインデックスに存在するバージョンに制限します。
一方、pipは、すべてのインデックスから候補となるバージョンを結合し、結合されたセットから最適なバージョンを選択しますが、インデックスを検索するno guarantees around the orderので、パッケージは名前とバージョンまで、インデックス間でも一意であることが期待されます。
uvの動作では、パッケージが内部インデックスに存在する場合、パッケージは常に内部インデックスからインストールされ、PyPIからはインストールされません。その目的は、攻撃者が内部パッケージと同じ名前で悪意のあるパッケージをPyPIに公開し、内部パッケージの代わりに悪意のあるパッケージがインストールされる「依存関係の混乱」攻撃を防ぐことです。たとえば、2022年12月のthe torchtriton attackを参照してください。
v0.1.39では、ユーザは--index-strategyコマンドラインオプション、または以下の値をサポートするUV_INDEX_STRATEGY環境変数を使用して、複数のインデックスに対してpipスタイルの動作を選択できます。
first-match(デフォルト):すべてのインデックスにわたって各パッケージを検索し、候補バージョンをパッケージを含む最初のインデックスに存在するバージョンに制限し、デフォルトのインデックスURLよりも--extra-index-urlインデックスを優先します。
unsafe-first-match:すべてのインデックスにわたって各パッケージを検索しますが、他のインデックスで新しいバージョンが利用可能であっても、互換性のあるバージョンの最初のインデックスを優先します。
unsafe-best-match:すべてのインデックスにわたって各パッケージを検索し、候補バージョンの組み合わせから最適なバージョンを選択します。
unsafe-best-matchはpipの動作に最も近いものですが、ユーザを"dependency confusion"のリスクにさらします。
将来、uvはパッケージを専用インデックスに固定することをサポートするようになります(参照:#171)。さらに、PEP 708は、パッケージレジストリとインストーラ間の"依存関係の混乱"の問題に対処することを目的とした暫定標準です。
Transitive direct URL dependencies for constraints and overrides#
uvはURLの依存関係(例えばblack @ https://...)をサポートしていますが、制約やオーバーライドのための_transitive_(すなわち"ネストされた")直接的なURLの依存関係はサポートしていません。
具体的には、制約またはオーバーライドが直接的なURL依存関係を使用して定義され、制約されたパッケージがそれ自体の直接的なURL依存関係を持つ場合、uv_may_rejectは解決中にその推移的な直接的なURL依存関係を拒否します。
また、uvは、非URL依存関係がURL依存関係を導入しない(つまり、レジストリからフェッチされた依存関係自体が直接的なURL依存関係を持たない)ことを前提としています。非URL依存関係がURL依存関係を導入する場合、uvは解決中にURL依存関係を拒否します。
どちらの場合でも、uvが推移的なURL依存関係を拒否する場合、最善の方法は、制約、オーバーライド、または推移的な依存関係としてではなく、requirements.inファイル内の直接的な依存関係としてURL依存関係を提供することです。
Virtual environments by default#
uv pip installとuv pip syncは、デフォルトで仮想環境で動作するように設計されています。
具体的には、uvは常に現在アクティブな仮想環境にパッケージをインストールするか、現在のディレクトリまたは任意の親ディレクトリ(アクティブ化されていない場合でも)で.venvという名前の仮想環境を検索します。
これはpipとは異なります。pipでは、アクティブな仮想環境がない場合にパッケージをグローバル環境にインストールし、非アクティブな仮想環境を検索しません。
uvでは、--python /path/to/pythonオプションまたは--systemフラグを使用してPython実行可能ファイルへのパスを指定することで、非仮想環境にインストールできます。--systemフラグは、pipのようにPATHにある最初のPythonインタプリタにインストールされます。
言い換えれば、uvはデフォルトを反転させ、システムPythonへのインストールに明示的なオプトインを要求します。これは、破損やその他の複雑さにつながる可能性があり、限られた状況でのみ実行する必要があります。
詳細については、"Using arbitrary Python environments"を参照してください。
Resolution strategy#
指定された依存関係指定子のセットに対して、インストールする"正しい"パッケージのセットが1つもない場合がよくあります。その代わりに、指定子を満たす有効なパッケージのセットが多数存在します。
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の最新バージョンを含めることを優先する場合、starletteの上限を除外した古いバージョンのfastapiを使用する必要があります。実際には、これはfastapi==0.1.17に戻す必要があります。
# This file was autogenerated by uv via the following command:
# uv pip compile -
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 pip compile -
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ファイルを解析できません。
- パッケージに実行中のインタプリタのPythonバージョンと一致しない
Requires-Pythonがあります。
- パッケージは、インストールされていないパッケージに依存しています。
- パッケージは、インストールされているが互換性のないバージョンのパッケージに依存しています。
- 仮想環境に複数のバージョンのパッケージがインストールされています。
場合によっては、uv pip checkはpip checkが表示しない診断を表示したり、その逆の場合もあります。たとえば、uv pip checkとは異なり、pip checkは現在の環境に複数のバージョンのパッケージがインストールされている場合には警告しません。
--user and the user install scheme#
uvは、userインストールスキームに基づいてパッケージをインストールする--userフラグをサポートしていません。代わりに、仮想環境を使用してパッケージのインストールを分離することをお勧めします。
さらに、pipは、ユーザがターゲットディレクトリへの書き込み権限を持っていないことを検出した場合、userインストールスキームに戻ります。これは、一部のシステムでシステムにインストールする場合と同様です。Python. uvはそのようなフォールバックを実装していません。
詳細については、#2077を参照してください。
--only-binary enforcement#
--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-binaryflaskが与えられた場合、uvは事前にパッケージ名を推測できなければ、与えられたURLでソースディストリビューションを構築します。なぜなら、uvはメタデータを構築しなければ、そのような場合にパッケージが「許可されている」かどうかを判断できないからです。
pipとuvの両方で、--only-binaryが提供されている場合でも、編集可能な要件を構築してインストールすることができます。たとえば、uv pip install -e . --only-binary :all:が許可されています。
Bytecode compilation#
pipとは異なり、uvはデフォルトではインストール時に.pyファイルを.pycファイルにコンパイルしません(つまり、uvは__pycache__ディレクトリを作成または生成しません)。インストール時にバイトコードのコンパイルを有効にするには、--compile-bytecodeフラグをuv pip installまたはuv pip syncに渡してください。
Strictness and spec enforcement#
uvはpipよりも厳密な傾向があり、pipがインストールするパッケージを拒否することがよくあります。たとえば、uvはメタデータ内に無効なバージョン指定子を持つパッケージを省略しますが、pipも同様に[future release]で除外する予定です(https://github.com/pypa/pip/issues/12063)。
場合によっては、uvは、特定の仕様準拠の問題があることがわかっている一般的なパッケージに対して、緩やかな動作を実装します。
仕様違反のためにpipがインストールするパッケージをuvが拒否した場合、最善の対処方法は、まず新しいバージョンのパッケージをインストールしようとすることです。それが失敗した場合は、パッケージのメンテナに問題を報告します。
pip command-line options and subcommands#
uvはpipのコマンドラインオプションとサブコマンドの完全なセットをサポートしていませんが、大きなサブセットはサポートしています。
不足しているオプションとサブコマンドは、ユーザーの要求と実装の複雑さに基づいて優先順位が付けられ、個々の問題で追跡される傾向があります。次に例を示します。
オプションまたはサブコマンドが見つからない場合は、問題追跡ツールを検索して、すでに報告されているかどうかを確認してください。報告されていない場合は、新しい問題を開くことを検討してください。関心を伝えるために、既存の問題に自由に賛成票を投じてください。
Registry authentication#
uvは、--keyring-providerに対するpipのautoまたはimportオプションをサポートしていません。現在、subprocesオプションのみがサポートされています。
pipとは異なり、uvはデフォルトでキーリング認証を有効にしません。
pipとは異なり、uvはリクエストがHTTP 401を返すまで認証を検索しません。uvは、利用可能な資格情報を持つホストに対するすべてのリクエストに認証を付加します。
egg support#
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でアンインストールします。
pip compile defaults#
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でエクストラを保持するには、--no-strip-extrasフラグをuv pip compileに渡します。
デフォルトでは、uvはインデックスURLを出力ファイルに書き込みませんが、pip-compileはデフォルト(PyPI)に一致しない--index-urlまたは--extra-index-urlを出力します。出力ファイルにインデックスURLを含めるには、--emit-index-urlフラグをuv pip compileに渡します。pip-compileとは異なり、uvは--emit-index-urlが渡されると、デフォルトのインデックスURLを含むすべてのインデックスURLを含みます。
デフォルトでは、uvはpip-compileとは異なり、--no-buildまたは--only-binaryオプションを出力ファイルに書き込みません。これらのオプションを出力ファイルに含めるには、--emit-build-optionsフラグをuv pip compileに渡します。