プロンプトと適用範囲
Python 3.14では、評価が遅延された際のアノテーション取得用としてannotationlibが追加されています。ローダーは前方参照をサポートし、検出中に任意のアノテーション式が実行されるのを防ぎ、古いバージョンのPythonに対する互換性パスを提供する必要があります。中心となるスキルはランタイムのイントロスペクションと副作用の制御であるため、これはcodingに関する質問です。
面接官が評価するポイント
優れた回答では、アノテーションの取得とその評価を明確に区別します。コンシューマーに応じてVALUE、FORWARDREF、またはSTRINGを選択し、失敗を隔離し、信頼できるコードを評価してよいタイミングを定義します。また、インタープリタのプライベート属性に依存するのではなく、キャッシュの無効化、モジュールのリロード、ネストされた型エイリアス、およびバージョンごとのフォールバックに対処します。
最初に確認すべき明確化のための質問
- ローダーが検査しているのは信頼できるアプリケーションコードですか、それともサードパーティのプラグインですか?
- スキーマジェネレーターが必要としているのは、ランタイムオブジェクト、文字列、未解決の参照のどれですか?
- サポートを継続する必要があるPythonのバージョンは何ですか?
- アノテーション式がモジュールをインポートしたり関数を呼び出したりすることは許可されていますか?
- プラグインがリロードされた後、失敗はどのように報告され、キャッシュされ、再試行されますか?
- アノテーションデータは公開互換性規約の一部ですか?
30秒の回答フレームワーク
「アノテーションを常に評価してしまうヘルパーの呼び出しを中止します。Python 3.14では、信頼できない検出にはannotationlib.get_annotations()をFormat.FORWARDREFまたはFormat.STRINGとともに使用し、明示的な信頼済みフェーズのためにFormat.VALUEを残しておきます。結果を内部スキーマに正規化し、オブジェクトごとの失敗を隔離し、古いPython用のバージョン判定付きフォールバックを維持します。テストでは前方参照、オプショナルインポート、ネストされたエイリアス、リロード、および決定論的なエラー報告をカバーします。」
ステップ別の回答
ステップ 1: 検出と評価の分離
2つのフェーズを定義します。検出では名前またはForwardRefオブジェクトを解決せずに記録し、解決は承認されたモジュールおよびシンボルに対してのみ実行します。これにより、スキーマ検出が単にアノテーションされているという理由だけでオプショナルな依存関係をインポートしたり式を実行したりするのを防ぎます。
ステップ 2: アノテーションフォーマットの選択
スキーマがソースのようなテキストを必要とする場合はFormat.STRING、未解決の名前を構造化された状態のままにする必要がある場合はFormat.FORWARDREF、ランタイムオブジェクトが必要で評価が信頼できる場合のみFormat.VALUEを使用します。フォーマットの選択は、ローダーのAPI規約の一部として扱います。
ステップ 3: 失敗と副作用の封じ込め
呼び出し可能オブジェクトまたはクラスごとに解決エラーをキャッチし、オブジェクトパスとフォーマットを診断情報に添付して、独立したプラグインの検出を継続します。未解決の参照を暗黙的にAnyに変換しないでください。互換性の欠陥が隠蔽されてしまいます。インポートやシンボルを評価する前にアローリストを適用します。
ステップ 4: バージョン管理された互換性の追加
Python 3.14以降では、文書化されているannotationlib APIを使用します。古いバージョンでは、プロジェクトの既存の互換性レイヤーを使用し、その保証が弱いことを文書化します。長期的なインターフェースとしてプライベートな__annotate__やインタープリタの内部構造に依存することは避けます。
ステップ 5: 決定論とライフサイクルのテスト
後方で定義される定義、不足しているモジュール、ネストされたジェネリックエイリアス、文字列、およびモジュールのリロードを参照するアノテーションをテストします。検出によってブロックされたモジュールがインポートされないこと、繰り返しの読み取りが同じ正規化されたスキーマを生成すること、およびプラグインの同一性やソースが変更されたときにキャッシュが無効化されることを検証します。
模範回答
「このバグはフェーズ違反です。スキーマを記述するだけであるべきデータを、検出フェーズで評価してしまっています。Python 3.14の文書化されたannotationlib APIを使用し、信頼できない検査にはSTRINGまたはFORWARDREFを選択し、VALUEは明示的な信頼済みリゾルバーでのみ使用します。各オブジェクトは独立した診断情報を取得し、未解決の参照は可視のまま維持され、アローリストによって評価が制御されます。バージョンアダプターによって古いPythonの動作が維持されます。テストでは、前方参照、不足しているオプショナルモジュール、エイリアス、リロード、副作用を伴うインポート、および安定した正規化出力をカバーします。」
よくある間違い
- アノテーションを常に評価する → 検出中にオプショナルなインポートや式が実行される → フォーマットとフェーズを分離する。
- 失敗を
Anyに変換する → スキーマのドリフトが見過ごされる → 未解決の参照と診断情報を保持する。 - インタープリタのプライベートフィールドを使用する → アップグレードによってローダーが破損する → 文書化された
annotationlibに依存する。 - 単一のグローバルキャッシュを共有する → リロード時に古いスキーマが返される → プラグインの同一性とソースによってキーを設定して無効化する。
- 完全な権限ですべてのプラグインを解決する → 信頼できないコードに副作用が発生する → アローリストと信頼済みフェーズを使用する。
- 単純な組み込み型のみをテストする → 本番環境で前方参照が失敗する → 不足している名前やネストされたエイリアスを含める。
フォローアップの質問
フォローアップ 1: VALUEが適切なのはどのような場合ですか?
コンシューマーがランタイム型オブジェクトを必要とし、モジュールおよびアノテーション式が信頼できる場合です。デフォルトの検出動作ではなく、明示的な解決フェーズである必要があります。
フォローアップ 2: 文字列ではなくFORWARDREFを保持する理由は何ですか?
未解決の参照が構造化された値として保持されるため、後続のリゾルバーが不足している名前と通常の文字列アノテーションを区別できるようになります。
フォローアップ 3: Python 3.14は何を変更しますか?
アノテーションはデフォルトで遅延評価され、annotationlibがそれらを取得するための文書化されたフォーマットを提供します。即時評価を想定していたコードは、希望するフォーマットを定義する必要があります。
フォローアップ 4: 古いバージョンをどのようにサポートしますか?
プロジェクトの既存のフォールバックに対して小さなバージョン判定アダプターを使用し、差異を文書化し、サポートされているすべてのインタープリタで同じ規約テストを実行します。