ファイルの検索と選択(index
とPackageFinder
)¶
pipのpip._internal.index
サブパッケージは、プロジェクトの要件に基づいて、ダウンロードするファイルとその場所を決定する役割を担っています。このパッケージの機能は、主にパッケージのPackageFinder
クラスを通じて公開され、調整されます。
概要¶
パッケージの要件に基づいて、pipがダウンロードするファイルを選択するために使用するプロセスの大まかな説明を以下に示します。
プロジェクトパッケージファイルを含むさまざまなネットワークおよびファイルシステムの場所を収集します。これらの場所は、たとえば、pipの--index-url(デフォルトはhttps://pypi.org/simple/)設定、および構成された--extra-index-urlの場所から派生します。各プロジェクトページのURLは、PEP 503の「Simple Repository API」で定義されているように、アンカーリンクのHTMLページです。
各プロジェクトページのURLについて、HTMLをフェッチし、アンカーリンクを解析して、それぞれから
Link
オブジェクトを作成します。LinkCollectorクラスは、前のステップとネットワーク経由でのHTMLのフェッチの両方を担当します。どのリンクが最小限に関連しているかをLinkEvaluatorクラスを使用して判断します。これらの関連するリンクごとに
InstallationCandidate
オブジェクト(インストール候補とも呼ばれる)を作成します。InstallationCandidate
オブジェクトのコレクションを(CandidateEvaluatorクラスを使用して)さらにフィルタリングして、「適用可能な」候補のコレクションにします。適用可能な候補がある場合は、それらをソートすることにより最適な候補を選択します(これもCandidateEvaluatorクラスを使用)。
このセクションの残りの部分は、index
パッケージ内のクラスを次の順序でドキュメント化することによって構成されています。
メインのPackageFinderクラス。
LinkCollectorクラス。
LinkEvaluatorクラス。
CandidatePreferencesクラス。そして
PackageFinder
クラス¶
PackageFinder
クラスは、pipのコードがindex
パッケージと対話するための主要な方法です。これは、さまざまなパッケージ検索機能をカプセル化およびグループ化する包括的なクラスです。
PackageFinder
クラスは、ネットワークとファイルシステムを検索して、pipがインストールできるパッケージのバージョンを検索し、ユーザーの好みや対象のPython環境などに基づいて、どのバージョンが最も優先されるかを決定する役割も担っています。
PackageFinder
クラスを使用するpipコマンドは次のとおりです。
PackageFinder
クラスの使用を必要とするpipコマンドは、通常、pipの呼び出し全体でPackageFinder
を1回だけインスタンス化します。実際、pipはこのPackageFinder
インスタンスを、コマンドオプションが最初に解析されたときに作成します。
pip listを除いて、上記の各コマンドはRequirementCommand
から継承するCommand
クラスとして実装されています(たとえば、pip downloadはDownloadCommand
によって実装されています)。そして、PackageFinder
インスタンスはRequirementCommand
クラスの_build_package_finder()
メソッドを呼び出すことによって作成されます。一方、pip list
は、ListCommand
クラスの_build_package_finder()
を呼び出すことによって、PackageFinder
インスタンスを構築します。(この違いは単に歴史的なものであり、実際には必ずしも必要ではない可能性があります。)
これらの各コマンドは、pipの「自己チェック」(つまり、pipのアップグレードが利用可能かどうかを確認するため)にもPackageFinder
クラスを使用します。この場合、PackageFinder
インスタンスはself_outdated_check.py
モジュールのpip_self_version_check()
関数によって作成されます。
PackageFinder
クラスは、概要セクションにリストされているすべての操作(PEP 503のシンプルリポジトリHTMLページのフェッチと解析、シンプルリポジトリページのどのリンクが各要件に関連しているかの評価、関連するリンクから来るインストールの候補をさらにフィルタリングして優先順位付けする)を行う役割を担っています。
PackageFinder
のメインのトップレベルメソッドの1つは、find_best_candidate()
です。このメソッドは、次の2つのことを行います。
ユーザーが提供したインデックスURLと場所を読み取って解析することによって、可能なすべてのパッケージリンクを収集する
find_all_candidates()
メソッドを呼び出し(LinkCollectorクラスのcollect_sources()
メソッド)、それらのリンクの一部をフィルタリングするLinkEvaluatorオブジェクトを構築し、InstallationCandidates
(インストール候補とも呼ばれる)のリストを返します。これは、上記の概要のステップ1〜3に対応します。CandidateEvaluator
オブジェクトを構築し、それを使用して最適な候補を決定します。これは、find_all_candidates()
の戻り値に対してCandidateEvaluator
クラスのcompute_best_candidate()
メソッドを呼び出すことによって行います。これは、概要のステップ4〜5に対応します。
PackageFinder
には、PEP 503の「シンプルリポジトリ」プロジェクトページを処理するためのprocess_project_url()
メソッド(find_best_candidate()
によって呼び出される)もあります。このメソッドは、PEP 503プロジェクトページのURLからHTMLをフェッチして解析し、アンカー要素を抽出してそれらからLink
オブジェクトを作成し、それらのリンクを評価します。
LinkCollector
クラス¶
LinkCollectorクラスは、ファイルシステムの位置からのパッケージファイルへの「リンク」(Link
オブジェクトとして表される)の生のリストと、PackageFinder
がアクセスする必要があるPEP 503プロジェクトページのURLを収集する役割を担うクラスです。
LinkCollector
クラスは、リンクを収集する場所を決定する際に、ユーザーの --find-links、--extra-index-url、および関連オプションを考慮します。このクラスの主なメソッドは、collect_sources()
メソッドです。PackageFinder クラスは、その find_all_candidates()
メソッドの最初のステップとして、このメソッドを呼び出します。
LinkCollector
は、プロジェクトページの URL から HTML を取得するための fetch_page()
メソッドも持っています。このメソッドは HTML を解析しないという点で「非インテリジェント」です。
LinkCollector
クラスは、index
サブパッケージ内でネットワークリクエストを行う唯一のクラスであり、リクエストを行うための pip の設定オプションと状態を格納する PipSession
に直接依存する唯一のクラスです。
LinkEvaluator
クラス¶
LinkEvaluator
クラスには、リンク(たとえば、シンプルなリポジトリページ内)がインストール候補となるための最低限の条件を満たしているかどうかを判断するビジネスロジックが含まれています(結果として InstallationCandidate
オブジェクトが生成されます)。この決定を行う際、LinkEvaluator
インスタンスは、ターゲットの Python インタープリターや、バイナリファイルが許可されているか優先されているかなどのユーザー設定などの情報を使用します。
具体的には、LinkEvaluator
クラスには、リンクがインストールの候補であるかどうかを返す evaluate_link()
メソッドがあります。
このクラスのインスタンスは、PackageFinder
クラスの make_link_evaluator()
によって要件ごとに作成されます。
CandidateEvaluator
クラス¶
CandidateEvaluator
クラスには、どの InstallationCandidate
オブジェクトを優先すべきかを評価するビジネスロジックが含まれています。これは、LinkEvaluator
クラスによって実行されるものよりもきめ細かい判断と見なすことができます。
特に、CandidateEvaluator
クラスは、LinkEvaluator
が行うように各候補を個別に評価するのではなく、決定を行う際に InstallationCandidate
オブジェクトの全体セットを使用します。たとえば、プレリリース版が選択の対象となるかどうか、またはハッシュが一致しないファイルが対象となるかどうかは、コレクション全体のプロパティに依存します。
CandidateEvaluator
クラスは、ターゲットの Python インタープリターと互換性のあるプラットフォームタグのリスト、ユーザーが提供したハッシュ、その他のユーザー設定などの情報を使用します。
具体的には、クラスには get_applicable_candidates()
メソッドがあります。これは、LinkEvaluator
クラスの evaluate_link()
メソッドによって受け入れられたリンクから生じた InstallationCandidate
オブジェクトを受け入れ、「適用可能な」候補のリストにフィルタリングし、優先順位で並べ替えます。
CandidateEvaluator
クラスには、最適な(つまり、最も優先度の高い)候補を返す sort_best_candidate()
メソッドもあります。
最後に、クラスには get_applicable_candidates()
を呼び出した後、sort_best_candidate()
を呼び出し、決定の中間結果と最終結果の両方をカプセル化する BestCandidateResult オブジェクトを返す compute_best_candidate()
メソッドがあります。
CandidateEvaluator
のインスタンスは、PackageFinder
クラスの make_candidate_evaluator()
メソッドによって要件ごとに作成されます。
CandidatePreferences
クラス¶
CandidatePreferences
クラスは、PackageFinder
が CandidateEvaluator
オブジェクトを構築する際に使用するユーザー設定の一部(PackageFinder
クラスの make_candidate_evaluator()
メソッドを介して)をまとめるシンプルなコンテナクラスです。
PackageFinder
インスタンスには、値が CandidatePreferences
インスタンスである _candidate_prefs
属性があります。PackageFinder
には、その動作を制御する多くの責任とオプションがあるため、CandidateEvaluator
に固有の設定をグループ化すると、メンテナーは CandidateEvaluator
にのみ必要な属性を知ることができます。
BestCandidateResult
クラス¶
BestCandidateResult
クラスは、要件に最適な候補を見つける結果をカプセル化する便利な「コンテナ」クラスです。(「コンテナ」とは、単にデータを含み、独自のビジネスロジックや状態変化メソッドを持たないオブジェクトを意味します。)最終結果だけでなく、結果を決定するために使用された中間値も格納します。
このクラスは、CandidateEvaluator
クラスの compute_best_candidate()
メソッドと PackageFinder
クラスの find_best_candidate()
メソッドの両方の戻り値の型です。