Skip to content
Published on

Python 型チェッカー 2026 — Mypy・Pyright・Pylance・Pyre・Pyrefly・ty 徹底比較ガイド

Authors

プロローグ — 2026 年、Python に静的型チェッカーが多すぎる

Python は動的言語として始まった。しかし 2026 年現在、産業の現場で Python を書くということは事実上 型アノテーションを書くということ だ。FastAPI は型ヒントでルーティングを定義し、Pydantic は型でデータ検証し、SQLAlchemy 2.0 ORM は Mapped[int] でカラムを宣言する。型がなければ現代の Python ライブラリは使いづらい。

問題は その型を誰がチェックするのか だ。そして 2025-2026 年の間に、この問いの答えが急に複雑になった。

  • Mypy — 2012 年からある標準実装。Dropbox 時代の Jukka Lehtosalo と Guido van Rossum が作った。
  • Pyright — 2019 年 Microsoft 発表。VS Code の Pylance エンジン。IDE フィードバック最強。
  • Pyre — Meta が Instagram モノレポのために作った OCaml 製チェッカー。徐々に衰退。
  • Pyrefly — 2025 年 Meta が Pyre を Rust で書き直した後継。モノレポで速い。
  • ty — 2025 年 Astral(uv・ruff 会社)が公開した Rust 製チェッカー。アルファだが速い。
  • Pytype — Google が作った推論型チェッカー。使用量減少中。

この記事は 2026 年 5 月時点でのこれらの道具の地図を描く。誰が何を作っていて、soundness・speed・ergonomics がどう違って、PEP 695・742 のような最新文法をどこまで追っていて、段階的導入をどう始めるかまで。


1 章 · 2026 年 Python 型チェッカーの地図

まず全体像。各チェッカーは作った場所・実装言語・主用途が違う。

チェッカー出所実装主用途2026 年の状態
MypyDropbox / Python 財団Python(mypyc で C にコンパイル)OSS 標準、ライブラリ著者安定、標準リファレンス
PyrightMicrosoftTypeScript / NodeIDE(Pylance)、CI非常に活発
PylanceMicrosoft(Pyright ベース)TypeScript / NodeVS Code 専用Pyright の IDE ラッパー
PyreMetaOCamlInstagram モノレポ保守モード
PyreflyMetaRustMeta モノレポ・OSS2025 年 OSS 公開、急成長
tyAstralRustuv エコシステム2025 年アルファ、加速中
PytypeGooglePythonGoogle 内部使用量減少、保守のみ

地図から見える 2 つの大きなトレンド。

第一に Rust への書き直しの波。 Python ツールチェーンはこの 3 年で Rust に移った。Ruff(リンタ)・uv(パッケージマネージャ)が Astral の代名詞になり、いま型チェッカーも Rust に向かっている。ty と Pyrefly がその代表。Mypy はすでに mypyc(Python から C へのコンパイラ)で自身をコンパイルしているが、Rust ネイティブには及ばない。

第二に IDE と CLI の分離。 Pyright と Pylance は LSP・incremental・watch モードに強い。Mypy はバッチ CI チェックに強い。両方を使うチームが増えた。ty と Pyrefly はこの 2 つの市場を同時に狙う。


2 章 · Python typing PEP 年表 — 大きな変更

型チェッカーを比較するには、まず 何をチェックすべきか を決めた PEP を知らなければならない。大きいものだけ。

PEP内容Python バージョン
4842014型ヒント導入3.5
5262016変数アノテーション3.6
5442017Protocol(構造的部分型)3.8
5612017配布時の型情報(py.typed)3.7
5852019builtin ジェネリック(list[int])3.9
5912019Final 修飾子3.8
5932019Annotated3.9
6042019X パイプ Y ユニオン表記3.10
6122019ParamSpec3.10
6462020TypeVarTuple3.11
6472021TypeGuard3.10
6732022Self 型3.11
6752022LiteralString3.11
6812022dataclass_transform3.11
6922023TypedDict で kwargs 型付け3.12
6952022新ジェネリック文法(class Box[T]:)3.12
6962022TypeVar デフォルト3.13
6982022@override デコレータ3.12
7022023@deprecated デコレータ3.13
7052023TypedDict readonly3.13
7122023dataclass フィールド変換(提案中)
7282023TypedDict closed/extra_items(提案中)
7422024TypeIs(改良された narrowing)3.13
7492024アノテーション遅延評価仕様(議論中)
7502024t-string(型付き文字列リテラル)(提案中)

要点。

  • PEP 695(3.12): 新ジェネリック文法。class Box[T]: のようにクラス名の横に型パラメータを書く。TypeScript に近づいた。
  • PEP 696(3.13): TypeVar のデフォルト。Box[T = int] のような記法が可能。
  • PEP 742(3.13): TypeGuard の弱点を補った TypeIs。narrowing が双方向で機能する。
  • PEP 698(3.12): @override デコレータ。メソッドオーバーライドの検証。
  • PEP 749: アノテーション評価方式の整理。from __future__ import annotations の次を定義する。

各チェッカーはこの PEP リストを追いつくスピードが違う。Pyright が最も速く、Mypy が最も遅い。 ty と Pyrefly は新 PEP を最初から実装する。


3 章 · Mypy — 標準リファレンス実装

Mypy は 2012 年に始まった。Jukka Lehtosalo の博士論文から出発し、Guido van Rossum が Dropbox で合流して本格化した。2026 年現在 PEP 484 の事実上のリファレンス実装だ。

# mypy のチェック例
from typing import Optional

def find_user(user_id: int) -> Optional[str]:
    if user_id < 0:
        return None
    return "alice"

name = find_user(42)
print(name.upper())  # mypy エラー: name は None の可能性

mypy を回すと上のコードは次のように指摘される。

example.py:9: error: Item "None" of "Optional[str]" has no attribute "upper"
Found 1 error in 1 file (checked 1 source file)

Mypy の長所。

  1. 標準動作。 typing モジュール PEP のリファレンス実装。他のチェッカーは Mypy の挙動を基準に比較される。
  2. 豊富なプラグイン。 Django・SQLAlchemy・attrs など動的動作の多いライブラリ向けプラグインシステムが確立。
  3. incremental cache。 .mypy_cache/ に結果を保存し、2 回目以降が速くなる。
  4. mypyc で自己コンパイル。 Mypy 自身を mypyc で C 拡張化し、速度を引き上げた。

Mypy の短所。

  1. 速度。 モノレポで cold start が遅い。50 万行コードベースで 3-5 分は普通。
  2. 新 PEP の追いつき。 PEP 695 を受け入れるまで時間がかかった。PEP 742(TypeIs)も遅かった。
  3. エラーメッセージ。 "Argument 2 to ... has incompatible type" のような表現が長く難解なことがある。

典型的な mypy.ini 設定。

[mypy]
python_version = 3.13
strict = True
plugins = pydantic.mypy, sqlalchemy.ext.mypy.plugin

[mypy-tests.*]
disallow_untyped_defs = False

strict = True は事実上「全ての厳格化フラグをオンにする」意味だ。新コードは strict から始め、レガシーコードはモジュール単位で緩めるのが定石。


4 章 · Pyright + Pylance — Microsoft、IDE フィードバック最強

Pyright は 2019 年 Microsoft が発表した。TypeScript で書かれ、Node.js で動く。VS Code の Python 拡張に Pylance という名前で組み込まれている。

Pyright の設計目標は incremental・即時・正確 だ。ファイル一つを保存したら 0.1 秒以内に結果が出る。そのために Pyright は次のことをする。

  • AST キャッシュ。 変更されていないファイルは再パースしない。
  • シンボル単位の incremental。 関数 1 個が変わったらその関数の依存だけを再チェック。
  • 積極的な推論。 Mypy より積極的に型を推論する(特に type narrowing)。
# Pyright の narrowing 例
from typing import Union

def process(x: Union[int, str]) -> str:
    if isinstance(x, int):
        # ここで x は int に narrowing(Mypy もできる)
        return str(x * 2)
    # ここで x は str(Mypy もできる)
    return x.upper()

基本 narrowing は Mypy でもできる。違いはもっと微妙なケースに出る。

# Pyright は narrowing するが Mypy はできない場合
from typing import Literal

def get_status() -> Literal["ok", "error"]:
    ...

s = get_status()
if s == "ok":
    # Pyright: s は Literal["ok"]
    # Mypy: 最近のバージョンでは同じ
    handle_ok()

Pylance と Pyright の違い。

  • Pyright: オープンソース。CLI・LSP・CI どこでも使える。
  • Pylance: VS Code 専用、クローズドソース。Pyright エンジン + VS Code 統合(オート import・docstring inlay・セッションキャッシュ等)。

Pyright は npm で取る。

npm install -g pyright
pyright src/

設定は pyrightconfig.json または pyproject.toml[tool.pyright] セクション。

{
  "include": ["src"],
  "exclude": ["**/node_modules", "**/__pycache__"],
  "typeCheckingMode": "strict",
  "pythonVersion": "3.13",
  "reportMissingImports": "error",
  "reportUnknownArgumentType": "warning"
}

typeCheckingModeoffbasicstandardstrict の 4 段階。strict は Mypy の --strict よりも厳しい傾向。


5 章 · Astral の ty — Rust 製、ruff・uv のチーム

Astral は 2024-2025 年の間に Python ツールチェーンを書き直した。Ruff(リンタ)・uv(パッケージマネージャ)が圧倒的に速いと実証された後、2025 年に同じチームが ty という型チェッカーをアルファ公開した。

ty の設計原則。

  1. Rust ネイティブ。 Mypy の 30-100 倍速い cold start が目標。
  2. incremental DB。 Salsa(rust-analyzer が使う incremental computation フレームワーク)ベース。
  3. LSP と CLI 両方。 Pyright のように IDE 統合が一級市民。
  4. ruff と統合。 同じワークスペース設定・同じキャッシュディレクトリ。

2026 年 5 月現在、ty はアルファ段階だが、新 PEP の実装が速い。PEP 695 はリリース時点でサポート、PEP 742・749 もすでに入っている。

# インストール
uv tool install ty

# チェック
ty check src/

# LSP サーバを起動
ty server

設定は pyproject.toml[tool.ty] セクション。

[tool.ty]
python-version = "3.13"
strict = true
exclude = ["tests/"]

[tool.ty.rules]
unresolved-import = "error"
unused-ignore-comment = "warning"

ty が投げる脅威。

  • 速度が圧倒的。50 万行モノレポで Mypy 3 分 → ty 5 秒のような報告がアルファ段階ですでに出ている。
  • ruff・uv ユーザにはツールチェーン統一の魅力。3 つとも同じ会社・同じキャッシュ・同じ設定。
  • ただし プラグインシステムがまだない。SQLAlchemy 2.0・Pydantic 2 のような動的ライブラリは静的解析だけでは捕まえにくい部分がある。

2026 年 5 月の現実。 ty は新規プロジェクトや小さなライブラリに良い。5 万行以上の SQLAlchemy 1.x コードベースを ty で検査すると false positive が大量に出る。1 年以内に安定化するというのが一般的な観測。


6 章 · Meta Pyrefly — Pyre の Rust 書き直し

Meta は Instagram・Facebook バックエンドに 1 億行単位の Python モノレポを運用する。Pyre はそのモノレポのために作った OCaml 製チェッカーだった。OCaml エコシステムが縮小し、モノレポの incremental・distributed 要求が拡大すると、Meta は 2024-2025 年に Pyrefly という Rust 書き直し後継を作った。

Pyrefly の強み。

  1. モノレポ向き。 分散インデックス・増分検査・シンボル DB がモノレポスケールで検証済み。
  2. type at scale。 1 億行で回ることが Meta 社内で実証。
  3. OSS 公開。 2025 年に OSS で公開された。Meta 外部でも使える。
# インストール
cargo install pyrefly
# または
pip install pyrefly

# チェック
pyrefly check src/

Pyrefly の設定は pyrefly.toml または pyproject.toml[tool.pyrefly]

[tool.pyrefly]
python_version = "3.13"
project_root = "."
search_path = ["src", "lib"]
strict = true

Pyrefly と ty のポジショニングの違い。

  • Pyrefly: モノレポスケールが先。Meta 社内検証が強み。
  • ty: 一般 OSS・中小規模プロジェクトが先。ruff・uv エコシステム統合が強み。

両方とも Rust だがターゲット市場が違う。小さなライブラリ著者は ty、Meta のようなモノレポ運用者は Pyrefly を好むパターンが見える。


7 章 · Google Pytype — 使用量減少だが残存

Pytype は Google が作った。2015-2017 年の間活発で、Python 2/3 推論に強みがあった。型アノテーションなしでも型を推論する ことが差別点だった。

# Pytype はアノテーションなしでも推論する
def add(x, y):
    return x + y

# Pytype: 使用箇所を追跡して int・str・float などの可能性を推定
add(1, 2)     # int + int -> int
add("a", "b") # str + str -> str

Pytype の強み。

  1. アノテーションのないレガシーコードに対する推論能力。
  2. .pyi スタブファイルの自動生成。
  3. Google 社内で長期に検証。

Pytype の弱み。

  1. 使用量減少。 Google 社内でも Pyright・Pyrefly に移るチームが出ている。
  2. 新 PEP の追いつき。 PEP 695・742 のような新文法サポートが遅い。
  3. 速度。 モノレポで Mypy より遅いという報告もある。

2026 年現在 Pytype は 新規導入の推奨対象ではない。ただし Google・Apache Beam のような一部の大規模プロジェクトが依然使っており、完全に消えはしない。


8 章 · Soundness vs Speed vs Ergonomics — 4 種比較表

型チェッカーを選ぶ際の 3 軸。

  • Soundness: 捕まえられるバグの幅。「Mypy が通してランタイムで壊れるコード」がどれだけ少ないか。
  • Speed: cold start と incremental の両方。
  • Ergonomics: エラーメッセージ・プラグイン・LSP・ドキュメント。

2026 年 5 月時点の主観評価。

チェッカーSoundnessCold Start 速度Incremental 速度LSPエラーメッセージPlugin
Mypy標準遅い普通別途デーモン要長く難解豊富
Pyright非常に強い速い非常に速い一級市民短く明確限定的
Pyrefly強い非常に速い非常に速い一級市民明確未完成
ty未完成非常に速い非常に速い一級市民明確なし

理論的 soundness は Mypy が標準で、他のチェッカーはそれをリファレンスにする。実戦の soundness は narrowing・overload・protocol のような微妙なケースで分かれる。

速度 は Pyrefly・ty が圧勝。100 万行コードベースで Mypy 5 分 → Pyright 30 秒 → Pyrefly・ty 5 秒。

エラーメッセージ は Pyright が最高。Mypy は長く、Pyrefly・ty は明確だが初期段階。

Plugin は Mypy が圧倒。ただし、新しい道具が Pydantic 2・SQLAlchemy 2.0 のような新しいライブラリを最初からよくサポートする点は興味深い。


9 章 · PEP 695・TypeIs・Self・Never — 実戦でよく出会うもの

2026 年の Python コードを見ると PEP 484 時代と文法がかなり違う。よく出会うもの。

PEP 695 — 新ジェネリック文法(3.12+)

旧文法(まだ動く):

from typing import TypeVar, Generic

T = TypeVar("T")

class Box(Generic[T]):
    def __init__(self, item: T) -> None:
        self.item = item

新文法(3.12+):

class Box[T]:
    def __init__(self, item: T) -> None:
        self.item = item

# 関数も可能
def first[T](items: list[T]) -> T:
    return items[0]

# 型エイリアスも
type StringList = list[str]

TypeScript に近い見た目になった。Pyright は最初からサポート。Mypy 1.4 で部分サポート、1.7 で安定。ty・Pyrefly はリリース時点でサポート。

PEP 742 — TypeIs(3.13+)

TypeGuard の弱点を補った narrowing。

from typing import TypeIs

def is_str_list(val: list[object]) -> TypeIs[list[str]]:
    return all(isinstance(x, str) for x in val)

def process(items: list[object]) -> None:
    if is_str_list(items):
        # items は list[str] に narrowing
        print(",".join(items))
    else:
        # items は依然 list[object](TypeGuard ではできなかった)
        print("not strings")

TypeIsTypeGuard の違い: TypeIs双方向 に narrowing する。else 分岐でも「それでない型」が生き残る。

Self 型(PEP 673、3.11+)

from typing import Self

class Builder:
    def with_name(self, name: str) -> Self:
        self.name = name
        return self

    def with_age(self, age: int) -> Self:
        self.age = age
        return self

class FancyBuilder(Builder):
    def with_color(self, color: str) -> Self:
        self.color = color
        return self

# Self のおかげでチェーンがサブクラス型を維持
b = FancyBuilder().with_name("alice").with_color("red")
# b: FancyBuilder(Self のおかげで Builder ではない)

以前は TypeVar のトリックで解決していたことが Self 一語で解決。

Never 型

from typing import Never

def fail(msg: str) -> Never:
    raise RuntimeError(msg)

def process(x: int | str) -> str:
    if isinstance(x, int):
        return str(x)
    if isinstance(x, str):
        return x
    fail("unreachable")  # この後のコードは dead code として表示

Never は「この関数は返らない」の明示。コンパイラが dead code 解析に活用する。

@override デコレータ(PEP 698、3.12+)

from typing import override

class Base:
    def greet(self) -> str:
        return "hello"

class Child(Base):
    @override
    def greet(self) -> str:
        return "hi"

    @override
    def greeet(self) -> str:  # タイポ — 親にない、チェッカーが指摘
        return "hi"

TypeScript の override キーワードと同じ役割。親クラスに同名メソッドがなければエラー。


10 章 · strict モードと段階的型導入戦略

最初から strict で始められれば良いが、既存コードベースではそれができない。段階的導入の定石パターン。

ステップ 1 — baseline を取る

まず現在の状態でどんなエラーがあるかを見る。

mypy --ignore-missing-imports src/ > baseline.txt
wc -l baseline.txt

これが出発点。新しい PR はこれ以上増やさないルールで開始。

ステップ 2 — 新規コードは strict

mypy.ini で新モジュールにだけ strict を適用。

[mypy]
python_version = 3.13

[mypy-myapp.new_module.*]
strict = True

[mypy-myapp.legacy.*]
ignore_errors = True

新規コードは最初からタイトに。レガシーはひとまず無視。

ステップ 3 — --strict-optional だけ先に

Optional[X]X を区別することが最大の価値を持つ。他の strict フラグより先にオン。

[mypy]
strict_optional = True
no_implicit_optional = True

この 2 つだけオンにしても NPE のような None 関連バグの 80% は捕まる。

ステップ 4 — disallow_untyped_defs

型のない関数定義を禁止。

[mypy]
disallow_untyped_defs = True
disallow_incomplete_defs = True

新しい関数は必ず型を書かせる。既存関数は段階的に追加。

ステップ 5 — strict = True

全ての strict フラグを一度に。最終段階。

[mypy]
strict = True

strict = True がオンにするフラグ。

  • disallow_untyped_defs
  • disallow_any_generics
  • disallow_untyped_calls
  • disallow_incomplete_defs
  • disallow_untyped_decorators
  • check_untyped_defs
  • no_implicit_optional
  • warn_redundant_casts
  • warn_return_any
  • warn_unused_ignores
  • strict_equality

11 章 · 実戦セットアップ — pre-commit・CI・pytest 統合

pre-commit フック

.pre-commit-config.yaml:

repos:
  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v1.13.0
    hooks:
      - id: mypy
        additional_dependencies:
          - "pydantic>=2.0"
          - "sqlalchemy>=2.0"
        args: ["--strict"]

  - repo: https://github.com/RobertCraigie/pyright-python
    rev: v1.1.380
    hooks:
      - id: pyright

2 つのチェッカーを一緒に回すパターンは一般的。Mypy は深さ、Pyright は速度。

GitHub Actions CI

.github/workflows/typecheck.yml:

name: typecheck
on: [pull_request]
jobs:
  mypy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.13"
      - run: pip install -e ".[dev]"
      - run: mypy --strict src/

  pyright:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.13"
      - run: pip install -e ".[dev]"
      - run: pip install pyright
      - run: pyright src/

pytest-mypy-plugins — 型自体をテスト

型自体が意図通りに動くかをテストする道具。

# tests/typing/test_types.yml
- case: dict_lookup
  main: |
    from typing import TypedDict

    class User(TypedDict):
        name: str
        age: int

    user: User = {"name": "alice", "age": 30}
    reveal_type(user["name"])  # N: Revealed type is "builtins.str"
    reveal_type(user["age"])   # N: Revealed type is "builtins.int"

こんな yaml を置けば pytest が mypy を回し、reveal_type の出力が期待値と同じかを検証する。

inline_snapshot — 型出力の snapshot テスト

reveal_type の出力を snapshot で比較。

from inline_snapshot import snapshot

def test_types():
    from mymodule import process
    result = process(42)
    assert type(result) == snapshot(int)

型変更が意図したものか意図しないものかが PR diff で見える。

mypy デーモン(dmypy)

大型コードベースで incremental 速度を上げる方法。

# デーモン起動
dmypy start -- --strict

# チェック(キャッシュ生存)
dmypy check src/

# 状態確認
dmypy status

# 停止
dmypy stop

VS Code で mypy を使うと自動で dmypy を立ち上げる拡張もある。Pyright の LSP に比べると依然遅いが、バッチ mypy よりはずっと速い。


12 章 · 意思決定ガイド — どれを選ぶか

状況別のおすすめ。

ケース 1 — 新規 OSS ライブラリ。

  • メイン: Pyright(CI で)
  • 補助: Mypy(配布時のプラグイン互換性検証)
  • 理由: Pyright は速く強いが、OSS の利用者は Mypy で検査するので両方通る必要がある。

ケース 2 — Pydantic・FastAPI バックエンド。

  • メイン: Pyright + Pylance(VS Code)
  • 補助: Mypy with pydantic.mypy プラグイン
  • 理由: Pydantic 2 は Pyright と相性が良い。Mypy はプラグインが必要。

ケース 3 — SQLAlchemy 2.0 + Django モノレポ。

  • メイン: Mypy with sqlalchemy.ext.mypy.plugin、django-stubs
  • 補助: Pyright(IDE のみ)
  • 理由: SQLAlchemy 1.x から 2.0 へのマイグレーションは Mypy プラグインが核。Pyright は一部の ORM パターンを捕まえられない。

ケース 4 — 新規プロジェクト、Astral ツールチェーン。

  • メイン: ty
  • 補助: Pyright(CI 補強)
  • 理由: ruff・uv をすでに使っているなら ty との統合が自然。アルファだが新規プロジェクトなら false positive が少ない。

ケース 5 — 1 億行モノレポ。

  • メイン: Pyrefly
  • 補助: なし
  • 理由: Meta がこのスケールで検証済み。他のチェッカーは OOM する。

ケース 6 — レガシー Python 2/3 混在コード。

  • メイン: Pytype(当分のみ)
  • マイグレーション後 Mypy か Pyright に移動
  • 理由: Pytype はアノテーションなしコードの推論が強い。新規導入の推奨ではない。

13 章 · 2026 年の予測 — 1 年後に誰が生き残るか

最後に 1 年後を予測する。

  1. Pyright は IDE で標準を維持する。 Pylance の VS Code シェアはすでに圧倒的。敵がいない。
  2. Mypy はリファレンスとして生き残る。 プラグインエコシステムが大きすぎる。死なない。
  3. ty が最も速く成長する。 Astral のトラックレコード(ruff・uv)が信頼を与え、アルファ → ベータ → 安定が 1 年以内に起こる可能性が高い。
  4. Pyrefly はモノレポ専用ツールに定着する。 OSS で公開されたが、ty と一般市場は重ならない。
  5. Pytype は保守モードに留まる。 新規導入はほぼなし。
  6. Pyre は事実上終了する。 Pyrefly への完全移行発表が 1 年以内に出る可能性。

最大のワイルドカードは ty のプラグインシステム だ。SQLAlchemy 2.0・Django のような動的ライブラリを ty が最初からよく捕まえれば Mypy の最後の堀が崩れる。あるいは ty と Mypy がプラグイン互換レイヤを共有することもあり得る。どちらにせよ 2027 年 5 月には風景がまた変わるだろう。


14 章 · 参考 / References

公式ドキュメント

Typing PEP

実戦ツール

背景