mypy vs ty — Python型チェッカー移行ガイド【互換性・速度・移行手順】
Python開発において、型ヒントと型チェックはコードの品質と保守性を高める上で不可欠な要素です。長らくmypyがPythonの型チェッカーのデファクトスタンダードとして君臨してきました。しかし、近年、Rustで書かれた超高速な型チェッカーtyが登場し、注目を集めています。
「どちらのツールを使えば良いのか?」 「既存のmypyプロジェクトをtyに移行できるのか?」
このような疑問を持つ開発者も多いでしょう。本記事では、mypyとtyの徹底的な比較を行います。そして、mypyからtyへの具体的な移行手順を詳述します。非互換な設定への対処法や、tyがまだ未対応なケースについても解説します。プロジェクトに最適な型チェッカー選びの一助となれば幸いです。
一言で言うと
- mypy: 高機能・安定
- ty: 超高速・新鋭
比較表
| 項目 | mypy | ty |
|---|---|---|
| 開発言語 | Python | Rust |
| 実行速度 | 中程度(大規模プロジェクトで遅延あり) | 非常に高速(mypyの10倍〜100倍) |
| 機能 | 広範、プラグインシステム、詳細設定 | 主要機能網羅、高精度診断、言語サーバー内蔵 |
| 設定 | .ini または pyproject.toml | pyproject.toml |
| 学習コスト | 中〜高(多くの設定項目と概念) | 低(Ruffに似たシンプルな思想) |
| コミュニティ | 非常に大きい、成熟、デファクト | 成長中、Astral社が強力に推進 |
| 言語サーバー | 単体では提供しない(LSP対応エディタで利用可能) | 内蔵(高速なLSP、きめ細やかな差分解析) |
| 開発元 | Python Software Foundation (コミュニティ主導) | Astral (uv, Ruffの生みの親) |
| 安定性 | 非常に高い、実績豊富 | ベータ版(急速に進化中) |
| 拡張性 | プラグイン機構、カスタム型チェック | 現時点では限定的(今後の発展に期待) |
実際のコマンド比較
ここでは、Pythonプロジェクトで型チェックを行う際の基本的なコマンドを比較します。
インストール
両ツールともpipで簡単にインストールできます。
mypyのインストール
pip install mypytyのインストール
uvを利用している場合は、uv経由でのインストールも推奨されます。
pip install ty # または uv pip install ty
型チェックの実行
プロジェクトルートディレクトリで実行する際のコマンドです。
mypyの実行
特定のディレクトリやファイルを指定して型チェックを実行します。
mypy your_project/ # 特定のファイルをチェックする場合 mypy your_project/module_a.pytyの実行
tyも同様に、ディレクトリやファイルを指定して型チェックを実行します。
ty your_project/ # 特定のファイルをチェックする場合 ty your_project/module_a.py
設定ファイル
両ツールは pyproject.toml を利用した設定をサポートします。mypyは mypy.ini も利用できますが、pyproject.toml が主流です。
mypyの設定例 (
pyproject.toml)pyproject.tomlファイル内に[tool.mypy]セクションを記述します。# pyproject.toml [tool.mypy] python_version = "3.11" strict = true # 厳密な型チェックを有効にする ignore_missing_imports = true # 型ヒントのない外部ライブラリのインポートエラーを無視 disallow_untyped_defs = true # 型ヒントのない関数定義を許可しない warn_unused_ignores = true # 不要な ignore コメントを警告する # ファイルごとのオーバーライド設定例 [[tool.mypy.overrides]] module = "tests.*" # tests/ ディレクトリ以下のモジュールに適用 ignore_errors = true # そのモジュールでは型エラーを無視するtyの設定例 (
pyproject.toml)tyの設定は、Ruffと似たシンプルな構造を目指しています。具体的なルールや設定項目はtyの公式ドキュメントで確認してください。
# pyproject.toml [tool.ty] # デフォルトでは厳しめの設定が適用されます # 必要に応じてルールを無効化したり、レベルを変更したりできます target-version = "py311" # 対象とするPythonのバージョン # 例えば、特定のルールを無効化する場合 # tyのルールコードは TYPxxx の形式です # ignore = ["TYP001", "TYP002"] # 例: 未定義のルールコードを無視する # ファイルごとのオーバーライド [[tool.ty.overrides]] path = "tests/**" # tests/ ディレクトリ以下のファイルに適用 ignore = ["ALL"] # テストファイルでは全ての型チェックを無視するtyのルールコードは
TYPxxxの形式です。selectやignoreオプションでルールを細かく制御できます。
エラーの抑制
コード内で特定のエラーを一時的に抑制する方法です。
mypyのエラー抑制
行末に
# type: ignoreまたは特定のコードを指示します。# mypyのエラー抑制例 def foo(x: int) -> str: return x # type: ignore # 戻り値の型がintだがstrを期待されているため無視 # 特定のエラーコードを抑制 def bar(x: int) -> str: return x # mypy: disable-error-code="return-value" # return-valueエラーを抑制tyのエラー抑制
tyでは
# ty: ignoreや# ty: disable-error-codeを使用します。Ruffと同様の記法が採用されていることが多いです。# tyのエラー抑制例 def foo(x: int) -> str: return x # ty: ignore # 戻り値の型がintだがstrを期待されているため無視 # 特定のエラーコードを抑制 def bar(x: int) -> str: return x # ty: disable-error-code="TYP001" # TYP001エラーを抑制エラーコードはtyのドキュメントで確認できます。
こんな人にはmypyがおすすめ / こんな人にはtyがおすすめ
mypyがおすすめな人
- 既存の大規模プロジェクトで安定性を最優先する開発者
- mypyは長年の実績があり、非常に安定しています。
- 大規模なコードベースでの運用経験が豊富です。
- 特定のmypyプラグインや、高度な型システム機能が必須なプロジェクト
- DjangoやSQLAlchemyなど、特定のフレームワーク特有の型チェックを強化するプラグインがあります。
- 非常に複雑な型ヒントを駆使している場合、mypyの成熟したサポートが役立ちます。
- Pythonエコシステムとの深い統合を重視する開発者
- mypyはPythonで書かれており、Pythonの他のツールとの連携がスムーズです。
- コミュニティで培われた知見や情報が豊富です。
- 型チェックに時間をかけても良い、またはCI/CDでキャッシュが効いている場合
- mypyの実行速度がボトルネックになっていないプロジェクトに適しています。
tyがおすすめな人
- 型チェックの速度がボトルネックになっていると感じる開発者
- CI/CDの実行時間が長い、ローカルでの型チェックが遅い場合に劇的な改善が見込めます。
- 特に大規模なプロジェクトでその効果を実感しやすいでしょう。
- CI/CDの時間を短縮し、開発サイクルを高速化したいチーム
- Rust製であるため、型チェックの実行が非常に高速です。
- ビルドパイプライン全体の時間を大幅に削減できます。
- Ruffやuvなど、Astral製品のエコシステムを好む開発者
- tyはAstral社が開発しており、Ruffやuvとの連携も考慮されています。
- 統一された開発体験を求める場合に最適です。
- 新しいプロジェクトで、最初から高速なツールを使いたい場合
- 新規開発プロジェクトであれば、tyを導入する障壁が低いです。
- 最初から高速なフィードバックサイクルを享受できます。
- 言語サーバーの高速なフィードバックを重視する開発者
- tyは内蔵の言語サーバーが非常に高速です。
- IDEでのリアルタイムな型チェックやコード補完が快適になります。
- 段階的な型チェックの導入を検討しているプロジェクト
- tyは「部分的に型付けされたコード」をサポートします。
- 既存のコードベースに徐々に型ヒントを追加していく際に役立ちます。
移行する場合の手順 — mypyからtyへの乗り換え方
mypyからtyへの移行は、主に設定ファイルの変換とエラーの調整が中心になります。ここでは、具体的なステップを解説します。
ステップ1: tyのインストール
まず、プロジェクトにtyを追加します。
pip install ty
ステップ2: tyの実行と初期診断
既存のプロジェクトでtyを実行し、どのようなエラーが報告されるかを確認します。
ty your_project/
この段階で、mypyでは検出されなかったエラーや、異なるエラーメッセージが表示されることがあります。tyはmypyよりも厳密なチェックを行う場合や、異なるアプローチで型を推論する場合があります。出力されたエラーメッセージとtyのドキュメントを照らし合わせ、tyの挙動を把握しましょう。
ステップ3: 設定ファイルの移行
mypy.ini や pyproject.toml の [tool.mypy] セクションを [tool.ty] セクションに移行します。mypyのすべての設定項目がtyに直接対応しているわけではありません。tyはRuffと同様に、よりシンプルな設定を目指しています。
非互換な設定の対処法
主要な設定項目について、mypyとtyでの対応を考えます。
python_version/target-version- mypyで
python_version = "3.11"と設定していた場合、tyではtarget-version = "py311"となります。 - これは比較的簡単に移行できます。
- mypyで
strict = true- mypyの
strict = trueは、多くの厳密な型チェックオプションを一括で有効にします。 - tyでは、デフォルトで厳しめのチェックが適用される傾向にあります。
- mypyの
strictに相当するtyのルール群は、tyのドキュメントで確認し、selectやignoreで個別に制御します。 - tyの
pyproject.tomlで、mypyのstrictが有効にしていた特定のルールコードをignoreから除外することで、厳密性を高めることができます。
- mypyの
ignore_missing_imports = true- mypyで型ヒントのない外部ライブラリのインポートエラーを無視する設定です。
- tyにも同様の機能があるかドキュメントで確認します。
- 通常は
pyproject.tomlの[tool.ty]セクションで、特定のルールコードをignoreに追加することで対応します。 - 例えば、tyが未解決のインポートを検出するルールコードが
TYPxxxの場合、ignore = ["TYPxxx"]と設定します。
disallow_untyped_defs = true- mypyで型ヒントのない関数定義を許可しない設定です。
- tyでは、これに相当するルールコードを
selectに含めるか、デフォルトで有効になっているか確認します。 - tyのドキュメントで「untpyed definitions」に関連するルールを探し、適切に設定します。
warn_unused_ignores = true- mypyで不要な
# type: ignoreコメントを警告する設定です。 - tyにも同様のルールコードがあるか確認します。
- Ruffの思想からすると、このような警告は標準で提供される可能性が高いです。
- mypyで不要な
plugins- mypyのプラグインシステムは、カスタムロジックや特定のフレームワーク対応を可能にする強力な機能です。
- tyは現時点ではmypyのような汎用的なプラグインシステムは提供していません。
- この点が、mypyからtyへの移行における最大の障壁となる可能性があります。
- もしプロジェクトがmypyの特定のプラグイン(例えば、Django REST Frameworkのシリアライザ型チェック)に強く依存している場合、tyへの移行は難しいかもしれません。
- 代替策として、tyのルールや設定でカバーできないか検討するか、当該部分のみmypyを残す「ハイブリッド運用」も一時的な選択肢となり得ます。
ファイルごとのオーバーライド (
[[tool.mypy.overrides]])- mypyで特定のファイルやモジュールに対して、設定を上書きする機能です。
- tyは
[[tool.ty.overrides]]セクションで同様の機能を提供します。 pathを指定して、特定のファイルやディレクトリに異なるルールを適用できます。- 例えば、テストファイルでは型チェックを完全に無効にするなどの設定が可能です。
# pyproject.toml [tool.ty] # ... グローバル設定 ... [[tool.ty.overrides]] path = "tests/**" # tests/ ディレクトリ以下のファイルに適用 ignore = ["ALL"] # テストファイルは全ての型チェックを無視する
ステップ4: エラーの調整と抑制
tyを実行して報告されるエラーを一つずつ確認し、対処します。
既存の
# type: ignoreコメント- tyは
# type: ignoreを認識しない可能性があります。 - 必要に応じて
# ty: ignoreまたは# ty: disable-error-code="TYPxxx"に変換します。 - tyの診断機能は非常にリッチです。エラーメッセージをよく読み、コードのどこに問題があるか理解しましょう。
- tyは
tyが報告する新しいエラー
- tyはmypyよりも厳密なチェックや、異なる型推論を行うことがあります。
- 新しいエラーは、実際のバグを示している可能性もあるため、慎重にレビューします。
- コードを修正して型エラーを解消するのが理想的です。
- どうしても修正が難しい場合は、
# ty: ignoreやpyproject.tomlのignoreリストでルールを一時的に抑制します。
ステップ5: CI/CDの統合
tyでの型チェックが安定したら、CI/CDパイプラインのmypyコマンドをtyに置き換えます。
CIスクリプトの例 (GitHub Actions)
# .github/workflows/ci.yml name: CI on: [push, pull_request] jobs: type-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install dependencies run: | pip install ty pip install -e . # プロジェクトの依存関係をインストール - name: Run type checker run: | ty your_project/
tyは実行速度が非常に速いため、CI/CDのビルド時間が大幅に短縮されるはずです。この効果を測定し、チームに共有することで移行のメリットを可視化できます。
mypyのみ対応でtyが未対応なケース
移行を検討する上で、tyがまだmypyの全ての機能をカバーしていない可能性も考慮する必要があります。
特定のmypyプラグインへの依存
- 前述の通り、mypyのプラグインシステムは強力です。
- 例えば、DjangoやFastAPIのORMモデル、Pydanticモデルなど、特定のライブラリの型チェックを強化するプラグインに依存している場合、tyには同等の機能がないかもしれません。
- この場合、手動でより詳細な型ヒントを追加するか、その部分のみmypyを併用するなどの対策が必要です。
- tyの今後の発展に期待しつつ、現時点での機能差を把握しておくことが重要です。
非常にニッチな型システムの利用
- mypyはPythonの高度な型ヒント(Protocol, TypeVarTuple, ParamSpecなど)に対して、長年の開発で培われた堅牢なサポートを持っています。
- tyも主要なPEPをサポートしていますが、非常に複雑でニッチな型システムの解釈において、mypyと異なる挙動を示す可能性はあります。
- これは、tyがまだベータ版であることによるものです。
- もし、このような特殊な型ヒントを多用している場合は、tyの挙動を慎重に検証する必要があります。
コミュニティと情報の成熟度
- mypyはPythonコミュニティで長年利用されており、Stack Overflowやブログ記事など、問題解決のための情報が非常に豊富です。
- tyはまだ新しいため、特定のニッチな問題に直面した際に、解決策を見つけるのが難しい場合があります。
- しかし、Astral社が強力にバックアップしており、ドキュメントは充実しつつあります。
- Discordコミュニティなども活用し、情報収集に努めましょう。
移行は段階的に進めるのが賢明です。まずはtyを並行して導入し、既存のmypyチェックとtyチェックの両方を実行してみるのも良いでしょう。そして、tyで問題がないことを確認しながら、徐々にmypyへの依存を減らしていくのが理想的なアプローチです。