iimon TECH BLOG

iimonエンジニアが得られた経験や知識を共有して世の中をイイモンにしていくためのブログです

Pythonの型チェッカについてまとめる

はじめに


こんにちは!

株式会社iimonでエンジニアをしている遠藤です。

以前「ロバストPython 型チェックを効果的に導入するための考え方」という記事を書かせていただきました。この時に知った「Pytype」というツールについて気になっていたので、今回は、型チェッカを自分なりにまとめてみることにしました。

ここでは、以下の型チェッカについて取り上げます。

  • mypy
  • Pyre
  • Pyright
  • Pytype

そもそもPythonの型ヒントとは何か


Pythonの型ヒントは、変数、クラス属性、関数のパラメータや返り値がどのデータ型を期待するかを明確にするためのものです。

Pythonは動的型付け言語なので強制はされませんが、オプションで以下のように型アノテーションをつけることができます。

def sum (a: int, b: int) -> int:
    return a + b

アノテーションを使用することで、コードの意図が開発メンバーに伝わりやすくなり、コードの保守性が高まります。また、IDEによるコードの自動補完の恩恵も受けられます。

なぜ型チェッカが必要なのか


Pythonランタイムは型アノテーションを参照しないため、実行時に以下のように型が変更されてもエラーになりません。

>>> hoge: string = 'hoge' # string
>>> hoge = 1 # int
>>> hoge
1

そのため、Pythonの型ヒントを活用してよりロバストなコードを書くためには、静的型チェックツール(型チェッカ)を使用するのが有効になります。 型チェッカは、静的解析ツールとして、実行前にコード内の型の不整合を検出し、潜在的なバグを防ぐためのツールです。これにより、コードが意図した通りに動作するか、実行前に確認できます。

mypy


mypyは、Pythonの定番な型チェッカで、Pythonの型アノテーションを利用して、プログラムに対して静的な型チェックを行うツールです。

mypyの特徴は、既存のコードに少しずつ型ヒントを追加し、型チェックを行えることです。型アノテーションがない関数は、mypyは動的型付けされたものとみなすため、厳格に型チェックを行わず、エラーを報告しません。これにより、大規模なプロジェクトでも、段階的に型ヒントを導入していくことが可能です

関数外の変数については、最初に定義した値に基づいて型推論が働くため、明示的な型注釈がなくても基本的な型検証が可能です。また、mypyは外部ライブラリの型サポートが充実しており、django-stubsのようなDjangoフレームワーク向けの拡張もあります。様々なIDEやエディタと統合されており、リアルタイムに型チェックを行うことができます。

基本的な使い方

・インストール:

$ pip install mypy

・型チェックのコマンドを実行:

$ mypy <file_or_directory>

これにより、指定されたファイルやディレクトリ内の型エラーが表示されます。エラーが検出されると、問題のある行と期待される型と実際の型が詳細に表示されます。

大規模プロジェクトでのパフォーマンス向上

mypyでは、大規模なコードベースでパフォーマンスが低下することがありますが、mypyデーモン(dmypy)を使うことで高速化が可能です。

・デーモンを起動し、最初のチェックを実行:

$ dmypy run -- <flags> <files>

・以降は、既に起動されているデーモンを使用してチェック:

$ dmypy check <files>

デーモンを使用することで、メモリにキャッシュされたプログラム状態を保持し、次回以降のチェックが高速化されます。リモートキャッシュを使うことでさらに高速化を図ることも可能です。

設定のカスタマイズ

mypyでは、プロジェクトに合わせた細かい設定が可能です。以下は主なオプションの例です。

・disallow_any_explicit: Any型の使用を禁止します。

・disallow_untyped_calls: 型アノテーションを持つ関数から、型アノテーションを持たない関数を呼び出すことを禁止します。

・ignore_missing_imports: 解決できないインポートに関するエラーメッセージを抑制します。

・check-untyped-defs: 型注釈があるかどうかに関係なく、すべての関数の本体の型をチェックします。

これらの設定を使うことで、コードベースに最適な型チェックポリシーを適用することができます。

詳細については、公式ドキュメントを参照してください。

The mypy configuration file - mypy 1.12.1 documentation

所感

広いコミュニティと機能のサポートがあり安定な選択ですが、大規模な既存プロジェクトに導入する場合は、段階的に型をつけていくとしてもコストがかかるので、型を自動生成するツール(Monkey Typeなど)の使用も併せて検討できると良さそうだと思いました。

Pyre


PyreはMeta社(旧Facebook)が開発した、OCamlで書かれたパフォーマンス最適化された型チェッカーです。特に大規模なコードベース向けに設計されています。mypyデーモンと似た形で、Pyreもバックグラウンドで実行されることが多く、型チェックを高速化できます。

Pyreも段階的な型ヒントの導入をサポートしています。明示的な戻り値またはパラメータに型アノテーションを持つ関数はエラーを返し、全ての型が指定されていない関数はAnyを返すと仮定します。

また、Pysaというセキュリティに重点を置いた静的解析ツールが付属しており、データフロー解析を通じてセキュリティ上の脆弱性を検出します。

静的型推論ツールとしても機能し、既存のコードベースに型注釈を推論で追加することができます

pyre infer -i

使い方

・依存ツールのインストール(macOSの場合):

$ brew install watchman

Watchmanはファイルシステムの変更を監視するツールで、macOSではPyreと一緒に使用されます。

・Pyreのインストール:

$ pip install pyre-check

・Pyreのセットアップ:

$ pyre-check init

これにより、pyre_configurationファイルが作成され、プロジェクトの設定が行われます。

・型チェックの実行:

$ pyre check

このコマンドで、コード内の型エラーが検出され、結果が表示されます。

所感

学習コストがやや高い印象。大規模のプロジェクトで、高速な型チェックが求められる時とかに良さそうだと感じました。

Pyright


PyrightはMicrosoftが作った速度を重視した型チェッカで、mypyよりも高速です。 Python 3.0以降のみサポートしているため、古いPythonバージョンを使用しているプロジェクトでは利用できません。

Pythonの型システム全体に対応しており、非常に正確な型チェックが可能です。(リファレンス: GitHub & BitBucket HTML Preview) 型ガードもサポートしています。

デフォルトで型アノテーションの有無に関わらず、すべてのコードに対して型チェックが実行されます。型アノテーションがない場合、Pyrightは型を推測して型チェックを実行します。厳密度は、モードの選択や設定の上書きによって調整できます。

また、PylanceというVS Code拡張機能があり、リアルタイムで型チェックや補完が可能です。これはPyrightの機能を強化した形で、VS Codeユーザーにとって非常に便利なツールです。

使い方

$ pip install pyright
$ pyright <options>

pyrightを使うことで、コマンドラインから手軽に型チェックを実行することができます。プロジェクト全体や特定のファイルを対象にチェックすることが可能です。

所感

VS Code拡張機能によるリアルタイムでの型チェックが便利なので、VS Codeを利用する開発においては有効な選択肢だと思いました。 また、パフォーマンスが非常に高く、大規模なプロジェクトでもスムーズに動作するため、大規模開発で採用しても良さそうです。

Pytype


特徴

PytypeはGoogleが作った型チェッカです。 Pythonのコードから型を推論するため、型ヒントが付けられていないコードでも型チェックが可能です。これは、型ヒントが少ない既存コードベースへの導入を容易にします。 また、実行時に型アノテーションと矛盾しない操作は許容されるため、型チェックの厳密さは他の型チェッカと比較してやや柔軟です。

また、静的型推論ツールとしても機能し、コードの解析結果を基に.pyiファイルが自動生成されます。これにより、型情報をコードに補完することができ、型安全性を向上させることができます。

 $ merge-pyi -i <filepath>.py .pytype/pyi/<filename>.pyi

使い方

$ pip install pytype
$ pytype <file_or_directory>

Pytypeはプロジェクト全体の型チェックを行い、型推論を通じて型エラーを検出します。

所感

既存の型ヒントがないプロジェクトでも、型推論を用いて型チェックが可能である点と、.pyiファイルを自動生成することで、型ヒントを明示的に補完することができることから、既存プロジェクトへの型チェック導入に適している印象です。

まとめ

簡単にPythonの型チェッカについてまとめてみました。
ざっとまとめた感じになってしまったので、もし記載に間違い、不備がありましたらご指摘いただけると幸いです。
本当は比較のような形にしたかったので、今後この記事はブラッシュアップしていきたい気持ちです。。。
新規プロダクトへの導入か既存プロダクトへの導入かによっても適切な設定が変わってくると思うので、それぞれのツールでどういった設定ができるのかももう少し調べてみようと思います。 それぞれのツールの特性をより理解して、状況に応じた選定をしていきたいと思いました。

最後まで読んでくださりありがとうございます! 弊社ではエンジニアを募集しております。 ご興味がありましたらカジュアル面談も可能ですので、是非ご応募ください!

Wantedly / Green

参考文献

Patrick Viafore著,鈴木駿監修,長尾高弘訳 (2023)「ロバストPython ―クリーンで保守しやすいコードを書く」オライリー・ジャパン https://docs.python.org/ja/3/library/typing.html

https://mypy.readthedocs.io/en/stable/

https://microsoft.github.io/pyright/#/ https://pyre-check.org/

https://google.github.io/pytype/

https://qiita.com/NSS_FS_ENG/items/1f4243f83e5a7fa8cf37

https://htmlpreview.github.io/?https://github.com/python/typing/blob/main/conformance/results/results.html