ブログ、Python、型付け
2020/05/28
Python SDKにおける型付けの変更
Beam Pythonは、コードの明確さと型の正確性チェックを向上させるために、Python 3の型アノテーションのサポートと統合を強化しました。何が新しくなったのかをご覧ください。
Pythonは関数に型アノテーションをサポートしています(PEP 484)。mypyなどの静的型チェッカーは、これらの型への準拠を検証するために使用されます。例えば
def f(v: int) -> int: return v[0]
上記のコードでmypyを実行すると、次のエラーが発生します:"int"型の値はインデックス化できません
。
私たちは最近、Beamに2つの領域で変更を加えました
Beam全体に型アノテーションを追加しました。型アノテーションにより、Beamのような大規模で洗練されたコードベースを、お気に入りのIDEで理解しやすくなりました。
次に、Python 3の型アノテーションのサポートを追加しました。これにより、SDKユーザーはDoFnの型ヒントを1か所で指定できます。また、Beamの`typing`モジュール型のサポートも拡張しました。
詳細な背景については、Pythonの型安全性の確保を参照してください。
Beamは型付けされています
DoFn内の新しい型アノテーションのサポートと並行して、Beam Pythonコード自体に型アノテーションを追加するために多くの時間を費やしました。これにより、静的型チェッカーであるmypyをBeamのコードレビュープロセスの一部として使用し始めました。これにより、貢献の質が向上し、バグが減少します。Beam全体に追加されたコンテキストと洞察は、すべてのBeam開発者、貢献者、エンドユーザーにとって役立ちますが、特にプロジェクトに不慣れな開発者にとって有益です。型アノテーションを理解するIDEを使用している場合、以前よりも豊富な型補完と警告が提供されます。また、IDEを使用してBeam関数と変換の型を調べて、それらがどのように機能するかをより深く理解できるようになり、独自の開発が容易になります。最後に、Beamの注釈が完全に付けられると、エンドユーザーは独自のパイプラインとカスタム変換に静的型分析を使用できるようになります。
アノテーションの新しい方法
Python 3構文アノテーション
Beam 2.21(BEAM-8280)では、Pythonアノテーション構文を使用して入力型と出力型を指定できるようになります。
例えば、この新しい形式
class MyDoFn(beam.DoFn): def process(self, element: int) -> typing.Text: yield str(element)
はこれと同等です
@apache_beam.typehints.with_input_types(int) @apache_beam.typehints.with_output_types(typing.Text) class MyDoFn(beam.DoFn): def process(self, element): yield str(element)
新しい形式の利点の1つは、mypyなどの静的型チェッカーと組み合わせて既に使用している可能性があり、追加のランタイム型チェックを無料で取得できることです。
この機能はデフォルトで有効になり、無効にするための2つのメカニズムがあります
- パイプラインの構築前に`apache_beam.typehints.disable_type_annotations()`を呼び出すと、新しい機能が完全に無効になります。
- 関数を`@apache_beam.typehints.no_annotations`でデコレートすると、Beamはその関数の注釈を無視するように指示されます。
Beamの`with_input_type`、`with_output_type`メソッドとデコレータの使用は引き続き機能し、アノテーションよりも優先されます。
サイドバー
あなたは尋ねるかもしれません:mypyを使用してBeamパイプラインの型チェックを行うことはできないでしょうか?これが当てはまらない理由はいくつかあります。
- パイプラインは実行時に構築され、設定ファイルやデータベーステーブルスキーマなど、その時点でしかわからない情報に依存する場合があります。
- PCollectionには必要な型情報がないため、mypyはそれらを事実上あらゆる要素型を含むものと見なします。これは将来的に変更される可能性があります。
- ラムダを使用する変換(例:`beam.Map(lambda x: (1, x)`)は、PEP 484を使用して適切に注釈を付けることができません。ただし、Beamはバイトコードから出力型を分析するために最善を尽くします。
typingモジュールのサポート
Pythonのtypingモジュールは、型アノテーションで使用される型を定義します。これは「ネイティブ」型と呼ぶものです。Beamには独自の型指定型がありますが、ネイティブ型もサポートしています。Beam型とネイティブ型の両方がサポートされていますが、新しいコードではネイティブのtyping型を使用することをお勧めします。ネイティブ型は、追加のツールでサポートされているためです。
Python 3アノテーション構文のサポートに取り組んでいる間、ネイティブ型のサポートに関する問題も発見して修正しました。まだバグやサポートされていないネイティブ型が存在する可能性があります。問題が発生した場合は、お知らせください。