依存関係内蔵戦略
Apothem が src/apothem/_vendor/ 配下にどのサードパーティパッケージを内蔵し、どれをシステム前提条件として残すか、そして内蔵されたコピーがどのようにリフレッシュされるか。
依存関係内蔵戦略
ポリシー
Apothem の自己完結型ランタイムは、 エンジンのサードパーティ依存関係がソースツリー自体からインポート可能であることを 要求します。そのため、各ランタイム依存関係は次の 3 つのいずれかの方法で扱われます。
- 純粋 Python ソースとして内蔵——
src/apothem/_vendor/配下に。ブートストラップ はそのディレクトリを site-packages より前にsys.pathの先頭へ前置するため、 内蔵されたコピーはシステムにインストールされたいかなるバージョンに対しても インポート解決の競争で勝ちます。 - 純粋 Python のシムで置換——上流の配布物が、ポータブルなソースとして携行できない コンパイル拡張を同梱している場合。
- 文書化されたシステム前提条件として保持——内蔵することが、それが節約する以上の 面を抱え込む場合。
配置のルールは厳格です。純粋 Python の配布物のみが _vendor/ に置かれます。
コンパイル拡張(C、Rust/PyO3、Cython)はプラットフォームと ABI に固有であり、
決してそこには属しません。各内蔵パッケージは、その上流のライセンスファイルを
ソースと並べて携行します。
何が内蔵されるか
| パッケージ | 注記 |
|---|---|
yaml | 純粋 Python のパーサー/エミッター。オプションの libyaml C 拡張は高速化であって決して必須ではなく、携行されません。インポートは import yaml のままです。 |
jsonschema | profile、設定、golden フィクスチャの検証に使われるスキーマバリデーター。 |
attrs(およびその attr エイリアス) | jsonschema に必要。 |
referencing | jsonschema に必要。 |
jsonschema_specifications | jsonschema に必要。 |
rpds | 純粋 Python のシムであり、上流の配布物ではありません——下記参照。 |
typing_extensions | 内蔵された検証チェーンに必要。 |
rpds シム
上流の jsonschema は rpds-py に依存します。これは Rust(PyO3)で実装された
永続データ構造ライブラリで、薄い .py ラッパーだけを伴うコンパイル済みの
.pyd/.so を同梱しています。コピーできるポータブルな純粋 Python ソースが存在
しないため、内蔵できません。
代わりに src/apothem/_vendor/rpds/ は純粋 Python のシムであり、jsonschema と
referencing が行使する API のサブセット——HashTrieMap、HashTrieSet、List
——を、組み込みの dict / frozenset / tuple をバックエンドとして、まさにその
とおりに再実装しています。このシムは上流の永続性契約を守ります。変更メソッドは
新しいインスタンスを返し、レシーバーを変更しないままにします。これは、消費者が
これらの構造を凍結クラスのフィールドのデフォルト値として格納する際に依拠する点
です。Apothem のスキーマは小さいため、Rust 実装に対する性能差は無関係です。
何が内蔵されないか
click——CLI フレームワーク。大きく、端末向けで、広く入手可能であるため、 インストーラーがチェックするシステム前提条件として残ります。rich——端末レンダリングライブラリ。同じ理由でシステム前提条件として保持 されます。rpds-py——コンパイル済み。上記のシムで置換されます。- libyaml C 拡張——オプション。内蔵された純粋 Python の
yamlパッケージは 決してそれを必要としません。
インストーラーは何かをする前に、選択されたインタープリターの下で click と
rich がインポート可能であることを検証します。いずれかが欠けている場合、その
名前を挙げて、それをあなたのためにインストールすることを提案します——あなたの
確認のもとで、または --yes / APOTHEM_AUTO_INSTALL_DEPS=1 によって自動的に。
内蔵パッケージのリフレッシュ
内蔵パッケージをより新しい上流バージョンへ更新するには:
- 目標バージョンの上流ソース配布物を取得します。
- 純粋 Python のパッケージディレクトリを
src/apothem/_vendor/へコピーし、 以前のコピーを置き換え、隣接するライセンスファイルをリフレッシュします。 src/apothem/_vendor/vendor.txt——固定されたクロージャ——を更新し、その パッケージのname==version行が新しい上流バージョンと一致するようにします。 そして、パッケージの上流ライセンスまたは著作権が変わった場合は、ルートのREUSE.toml内のそのパッケージの[[annotations]]ブロックを更新します。 どちらもコピーと同一の変更セットで必須です(生きた依存関係の強制)。 サプライチェーン監査員とreuse lintゲートはそれらを読み取ります。- インポートパスはそのままにします——消費者は正規名をインポートし、ブートストラップ
の
sys.path優先順位が残りを行います。 - テストスイートと一致性ゲートを実行します。検証スタックの挙動は profile と スキーマの検証テストでカバーされています。
rpds シムのリフレッシュは異なります。それは消費者が使用する API サブセットを
追跡するため、jsonschema/referencing の更新はシムの実装済み表面と照合して
チェックされ、シムは新しい呼び出し点が現れたときにのみ成長します。
推奨される次のステップ
自己完結型ランタイムのページを読んで、
内蔵ツリー、PYTHONPATH=src の呼び出しモデル、そしてプラグインツリーのブートストラップ
が実行時にどのように組み合わさるかを確認してください。