Python の型チェッカー 5 種 — pyrefly·ty·mypy·Pyright·Zuban の分裂は生態系の弱点か、多様性の回復か

五つの型チェッカーが同じ PEP を異なって解釈する時代、ライブラリメンテナは何を試験し、利用者は何を信頼すべきか。

導入 — Quansight の一つの問いが投げた波紋

2026 年 6 月 8 日、Quansight Labs の Marco Gorelli が pyrefly のブログに短い記事を投稿した。タイトルは 「もう五つの Python 型チェッカーを回さねばならないのか?」 だった。三日のうちに Hacker News のトップに上がり、152 件のコメントが付いた。Gorelli が列挙した五つは mypy、Pyright、pyrefly、ty、Zuban である。mypy は Python 型システムの出発点であり、Guido van Rossum 本人が率いたツールだ。Pyright は Microsoft が作った高速チェッカーであり、VS Code の Pylance のエンジンでもある。pyrefly は Meta が社内コードベース対応のために作り、2026 年に外部へ公開した Rust 製チェッカーだ。ty は ruff を作った Astral の新しいチェッカーで、同じ Rust インフラを共有する。Zuban は比較的最近登場したもう一つの新星である。

この五つを並べる風景それ自体が、何かが歪んでいるように見える。標準は一つであるべきなのに、なぜ五つのツールが同じ PEP を手に異なる結論に到達するのか。Gorelli の文章はその風景を正当化しない。むしろ正確な結論はその反対だ。「複数の型チェッカーをテストスイートの上で回せ。少なくとも一つはソースコードの上で回せ。優先度はその順だ」 。分裂は解くべき問題ではなく、生き抜くべき条件だ、という立場である。その立場をたどると一つの事実が浮かぶ。Python の型システムにおける真の利用者はライブラリメンテナであり、利用者にとって分裂は負担だが、メンテナにとっては資産でもある、という事実だ。

五つのチェッカーの風景 — 誰が、なぜ、どこに立っているか

五つのチェッカーは単に 「同じ仕事を五通りに分けてやっている」 のではない。各々が異なる場所に立っている。mypy は学術的正確さと PEP 仕様の一次参照実装を志向する。最も保守的で、最も深く検査し、最も遅い。Hacker News のユーザー KolmogorovComp は荒く整理した。「レガシーインフラ以外で mypy をいまだに使う理由が分からない。遅いうえに最も怠惰で、多くの間違いを取りこぼす」 。この批判は乱暴だが、産業現場の一つの隅を正確に指している。mypy は Django や SQLAlchemy のような動的メタプログラミングが強いライブラリでしばしば悲鳴をあげる。

Pyright はその反対側にいる。Microsoft が作り、TypeScript のコンパイラエンジニアたちが設計した。高速で、IDE 統合に親和的で、Pylance という商用製品の基盤だ。Hacker News のユーザー thr1owaway9621 の報告がその定着度をよく示している。「5 万行の Django REST API コードベースに pyright を使っている。django-types と djangorestframework-types を入れれば、ほとんど問題はない」 。pyright が産業標準として根を張った理由の一つだ。

pyrefly と ty は同じ家族だ。両者とも Rust で書かれ、両者とも 「mypy と pyright の間に空いた席」 を狙う。pyrefly は Meta が 2025 年に社内コードベース (数億行の Python インフラ) を検査するために作り、Pyrefly チームが自ら言う差別化は 「厳密でありつつ高速で、仕様への準拠も果たす」 という点だ。ty は Astral のツールである。ruff が linting 領域でやったこと — つまり Python の産業標準ツールを Rust で書き直し、二桁速くすること — を type checking で繰り返そうとする試みだ。Astral の賭けが正しければ、ty は ruff が flake8 を押しのけた方法で mypy を押しのけるだろう。

Zuban は最も最近現れた五つ目のチェッカーだ。採用率はまだ小さいが、その存在自体がこの分野が依然として新規参入に開かれていることを示す信号だ。五つすべてが同じ PEP 484、526、561、692、695 の仕様の上で動く。だが仕様は両刃の剣だ。Hacker News のユーザー leni536 の指摘が核心を突く。「型チェッカーは特定の文脈で式の型を絞り込むべきだ。だがその挙動は現在の仕様では大半が未規定のままだ」 。同じコード、同じ PEP、異なる結論。分裂は単なる NIH 症候群ではなく、仕様そのものが残した空白の上で発生する。

分裂の本当のコストはどこに落ちるのか

五つのチェッカーが同じ PEP を異なって解釈するという事実は、一般の利用者にとってはさして問題ではない。自分のコードが自分の選んだ一つのチェッカーで通れば十分だ。本当のコストはライブラリメンテナに落ちる。Gorelli が記事で挙げた例は Polars の一つのメソッドだった。そのメソッドが五つのチェッカーすべてを通るようにするため、コードには四つの異なる # type: ignore コメントが並んでいた。ライブラリ側の一つの公開 API が、五人の異なる審判の前で五通りに評価されているわけである。

この非対称が Gorelli の結論を作る。「複数のチェッカーをテストスイートの上で回せ」 という勧告はライブラリ利用者への勧告ではなく、ライブラリメンテナへの勧告である。Polars、NumPy、pandas、Django、SQLAlchemy — 名の知れたライブラリのメンテナたちは、自分の利用者がどのチェッカーを使うかを事前に決める権利を持たない。利用者が pyright を使おうが mypy を使おうが、ライブラリの公開 API の型ヒントは双方で通らねばならない。だから五つのチェッカーをすべて CI に組み込めるメンテナだけが、利用者側の分裂を自分側の負担として吸収できる。Gorelli が明示的に書いた一行がその立場だ。「複数のチェッカーを回すことは厳密さの問題ではない。ライブラリメンテナにとっての主たる利益は、自分の API が利用者の使うツールと互換であるかを確認することだ」 。

利用者側のコストは別の形で落ちる。Hacker News のユーザー stephbook の整理が本質を突く。「五種類の型チェッカー、そして型チェックのプロジェクト自体が、複数の # ignore を付けることが正しいコードだと考えている。たとえば TypeScript なら同じことを ignore なしの overload で処理するだろう」 。この比較は残酷である。TypeScript は一つの言語、一つのコンパイラ、一つの仕様で束ねられており、新機能が追加されるたびにコンパイラがそれを即座に吸収する。Python は五つのチェッカーがそれぞれ異なる速度、異なる優先順位で PEP を吸収する。PEP 695 (新しい generics 構文) が mypy で完全にサポートされるまで 18 か月かかり、同じ PEP が ty では試案段階にとどまり、Pyright では最も早く追加された。同じ PEP の同じコードが、どのチェッカーで検査するかによって異なるメッセージを出す。

別の角度では、ユーザー throwawayffffas の指摘がより本質的な不満を示す。「多くの場合、推論で十分に導ける型をいちいち手書きせねばならない。型チェッキングが結局のところ一種の linting 段階に成り下がっている。もはや duck typing のシステムを使っているとは言えない」 。この不満は五つのチェッカーの分裂よりも大きな問いを示している。Python が PEP 484 (2014) で型ヒントを導入してから 12 年が経った。その 12 年の間、動的 typing のアイデンティティと静的 typing の保証の間で均衡を探した結果が、いまの五つのチェッカーの風景である。分裂は結果であって原因ではない。

メンテナ負担の未来 — Astral·Meta·Microsoft のゲーム

問いを改めて投げよう。我々は五つの型チェッカーを回すべきか。答えは誰かによって異なる。

ライブラリメンテナには 「はい」 だ。 少なくとも mypy、pyright、新しく登場した Rust チェッカー一つ (pyrefly または ty) まで三つは CI に縛り付けるべきだ。利用者がどのチェッカーを使うかをメンテナは制御できないからだ。この負担は Polars のような人気ライブラリほど重い。だから次第にライブラリのコードベースに tests/typing/ のようなディレクトリが現れ、五つのチェッカーの出力の差が snapshot として捕捉される。これはライブラリメンテナの仕事を増やすが、Gorelli の主張通り、利用者側の負担を吸収する仕事である。

一般の利用者には 「いいえ」 だ。 自分のコードに一つのチェッカーをかければ十分だ。ただし、その一つが何であるべきかは今後 2 年で答えが変わり得る。現在の事実上の産業標準は pyright (VS Code の既定) である。だが Astral の ty が ruff と uv が作った勢いをそのまま持ち込めば、向こう 2 年で標準が ty へ移るシナリオがある。ruff が flake8 / isort / black の席を一つに飲み込んだ速度を思い出せば、ty の同じ進路は非現実的ではない。

ツールメンテナ同士のゲームはより興味深い。 Meta は pyrefly を社内コードベース対応に縛ったため、外部市場での優位は副次目標である。Microsoft の Pyright は Pylance という商用製品の基盤であり、安定性と互換性が第一優先だ。Astral だけが ty を 「産業標準になるべき新しいツール」 として位置づけ、同じ会社の作る ruff·uv とまとめて Python ツール全体の一貫した利用者体験を狙う。Astral のこの戦略はすでに ruff の成功で検証された。同じ会社が道具の風景全体を自社の Rust インフラの上に描き直そうとする試みが進行中だという事実は、五つのチェッカーの風景が 5 年以内に二つ (Pyright + ty) へ収斂する可能性を示唆する。

興味深いのは PEP 仕様そのものの未来だ。Python の typing 仕様は PEP 692 の dataclass_transform、PEP 695 の generics 構文、PEP 705 の ReadOnly TypedDict などで次第に豊かになっている。新しい PEP が追加されるたびに、五つのチェッカーのうち誰が最も早く実装するか、誰が最も正確に実装するかが、市場シェアの尺度になる。仕様は標準だが、標準の実装速度は競争である。typeshed という stub ライブラリは五つのチェッカーの共通基盤として残り、その運営をめぐる政治は五つの会社が一歩ずつ踏み込む共有領域である。

結論 — 分裂は解くべき問題ではなく、システムそれ自体だ

五つのチェッカーが風景を作るという事実は、Python の弱点ではなく、Python が動的言語として一つの時期を生き抜いた痕跡である。PEP 484 が 2014 年に導入されて以降、Python は静的検査の利点と動的表現の自由の間で合意を探してきた。その過程の道具五つが、いま舞台の上にいる。Marco Gorelli の勧告がその痕跡を単純化する。ライブラリメンテナは複数のチェッカーをテストスイートの上で回し、利用者は自分の一つのチェッカーに集中すればよい。分裂の負担は中間にいるメンテナが引き受ける。

本当の問いは別にある。五つのチェッカーの風景が今後 3 年で二つ — つまり Pyright と ty — へ収斂するのか、それとも五つすべてが生き残り、PEP の異なる隅を異なる速度で吸収する分業構造として定着するのか。Astral の ty が ruff·uv の勢いを携えて市場の半分を取れるかが第一の変曲点だ。Meta の pyrefly が外部市場で社内インフラの副産物以上の意味を持てるかが第二の変曲点だ。その二つの変曲点がどう解けるにせよ、Gorelli の勧告は変わらない。五つのチェッカーが存在する限り、ライブラリの公開 API は五人の異なる審判の前に立たねばならない。そしてその審判は、毎年新しい PEP を手に再び厳しくなる。


出典: