2026年10月1日、Pythonの型チェッカーmypyの2.4.0が公開されました。型チェッカーとは、型ヒントをもとに、プログラムを動かす前に型の間違いを見つけてくれる道具です。
今回の2.4では、10月9日に正式版が出たPython 3.15への対応が入りました。さらに、チェックの土台となるパーサーが新しくなり、複数のCPUで並列にチェックする機能も正式な機能になっています。
型ヒントを書き始めたばかりの方にとっても、嬉しい変更が含まれています。今回は、実際に動かしながら順番に見ていきます。
まずは何が変わったのかを整理しよう¶
最初に、今回取り上げる変更を表にまとめます。内容は、mypyの公式リポジトリにある変更履歴にもとづいています。
| 変更 | 中身 |
|---|---|
| Python 3.15への対応 | 3.15上で動き、sentinelやlazy import、内包表記のアンパックをチェックできる |
| 新しいパーサーが標準に | Ruffのパーサーをもとにした、高速なネイティブパーサーを既定で使う |
| 並列チェックの正式化 | 複数のプロセスでチェックする機能が実験段階を卒業 |
| sentinelの型チェック | isで判定したあとに、正しく型を絞り込む |
PyPIの記録によると、2.4.0が必要とするPythonは3.10以上です。インストールは、変更履歴にあるとおりpython3 -m pip install -U mypyで行えます。
mypyそのものがまだよくわからない方は、先にこちらを読んでおくと話がつながります。【関連記事】Pythonのmypyとは?
Python 3.15の新機能をチェックできるように¶
変更履歴によると、mypy 2.4はPython 3.15の上で動き、3.15の新機能のほとんどをチェックできます。対応した主な機能は、次のとおりです。
| 3.15の新機能 | mypy 2.4での対応 |
|---|---|
| sentinel(PEP 661) | 対応 |
| lazy import(PEP 810) | 対応 |
| 内包表記でのアンパック(PEP 798) | 対応 |
| TypedDictのextra_items(PEP 728) | まだ未対応。今後のリリースで対応予定 |
すべてではないものの、正式版の公開前に主要な機能への対応を済ませていたことになります。Python 3.15で何が変わったかは、こちらで実際に動かしながら紹介しました。【関連記事】Python 3.15が正式リリース
sentinelの型チェックを試してみた¶
今回の目玉の1つが、3.15で加わったsentinelへの対応です。sentinelは、値が渡されなかったことのような、特別な状態を表す目印の値を作るための仕組みです。
変更履歴によると、mypyはsentinelを型ヒントの中で直接使えるようにし、isやis notで判定したあとに型を絞り込みます。Python 3.11でも、typing_extensionsというライブラリから同じsentinelを使えます。
実際に、引数が渡されなかった場合と、Noneが渡された場合を区別する関数を書いてみました。わざと、Noneのチェックを忘れたままにしています。
from typing_extensions import sentinel
MISSING = sentinel("MISSING")
def greet(name: str | None | MISSING = MISSING) -> str:
if name is MISSING:
return "名前が渡されていません"
reveal_type(name)
return f"こんにちは、{name.upper()}さん"
mypy 2.4.0でチェックした結果です。reveal_type()は、mypyがその時点でどんな型だと考えているかを表示させるための特別な関数です。
sentinel_demo.py:9: note: Revealed type is "str | None"
sentinel_demo.py:10: error: Item "None" of "str | None" has no attribute "upper" [union-attr]
Found 1 error in 1 file (checked 1 source file)
1行目を見ると、name is MISSINGの判定のあとで、型からMISSINGが正しく取り除かれ、strかNoneに絞り込まれています。そのうえで、Noneのときに.upper()を呼んでしまう間違いを、動かす前に見つけてくれました。
直したあとの結果¶
Noneの場合の分岐を加えて、もう一度チェックしてみます。reveal_type()の行は取り除きました。
def greet(name: str | None | MISSING = MISSING) -> str:
if name is MISSING:
return "名前が渡されていません"
if name is None:
return "名前が空です"
return f"こんにちは、{name.upper()}さん"
今度はSuccess: no issues found in 1 source fileと表示されました。実際に呼び出してみると、引数なし、None、文字列の3つの場合で、それぞれ別のメッセージが返ってきます。
greet()、greet(None)、greet("taro")の順に呼び出して表示した結果です。
名前が渡されていません
名前が空です
こんにちは、TAROさん
型チェックでは、3つの場合をきちんと分けて書けているかを確かめてくれます。実行してみて初めて気づく、という事態を減らせるのが型チェッカーの強みです。
この、値がないことと値が空であることを区別する考え方は、Pydantic 2.14で正式になったMISSINGと同じものです。【関連記事】Pydantic 2.14がリリース
新しいパーサーが標準になった¶
2つ目の大きな変更が、パーサーの入れ替えです。パーサーとは、ソースコードを読み取って、プログラムが扱える形に組み立てる部品のことです。
変更履歴によると、mypy 2.4では、Ruffのパーサーをもとにしたネイティブパーサーが既定で使われます。これまでの、標準ライブラリのastモジュールを使うパーサーより、かなり速いと説明されています。
新しいパーサーで嬉しいこと¶
速さのほかにも、利点があると書かれています。代表的なものを表にまとめます。
| 利点 | 中身 |
|---|---|
| 新しい文法を古いPythonでチェックできる | 3.14でmypyを動かしながら、--python-version 3.15を指定できる |
| スタブファイルで新しい文法を使える | 対象のバージョンより新しい文法でも書ける |
| 並列チェックの前提になる | 並列チェックには新しいパーサーが必要 |
古いパーサーも、--no-native-parserを付ければ当面は使えます。ただし、変更履歴では2027年の早い時期に古いパーサーを削除する予定だと書かれています。
気をつけたい小さな違い¶
1つだけ注意があります。新しいパーサーは、forやwithで作る変数に付けた型コメントを、黙って無視します。
型コメントとは、# type: intのように、コメントで型を書く古い書き方です。変更履歴では、代わりに変数の型ヒントを前の行に書く方法が案内されています。
# これまでの書き方(新しいパーサーでは無視される)
for i in x: # type: int
...
# これからの書き方
i: int
for i in x:
...
Python 3.6で変数の型ヒントが入る前の書き方なので、今から学ぶ方はまず使わないはずです。古いコードを引き継いだときにだけ、思い出してください。
型ヒントの基本的な書き方は、こちらで紹介しています。【関連記事】Pythonの型ヒントとは?
並列チェックが実験段階を卒業¶
3つ目の変更が、並列チェックの正式化です。並列チェックとは、複数のプロセスで手分けして型チェックを進める機能です。
変更履歴によると、-n 8や--num-workers 8のようにして、作業するプロセスの数を指定できます。2.4では、新たに-n autoも使えるようになり、使えるCPUのコア数をもとに自動で決めてくれます。
autoで選ばれる数は、最大で8に抑えられています。大きなプロジェクトでプロセスを増やしすぎると、メモリを多く使ってしまうためです。
変更履歴には、8つのプロセスを使って最大で5倍速くなった例があったと書かれています。将来のリリースでは、並列チェックを既定で有効にする予定だそうです。
私は10年ほどエンジニアとして開発に関わってきましたが、型チェックが遅いと、CIの待ち時間が延びて、結局だれもローカルで型チェックをしなくなりがちでした。チェックが速いことは、それだけで使われ続ける理由になると感じます。
設定ファイルで並列チェックを有効にする¶
毎回コマンドに-n autoを付けるのは面倒ですよね。変更履歴によると、並列チェックの設定はpyproject.tomlやmypy.iniにも書けます。
pyproject.tomlなら、[tool.mypy]の下に次のように書きます。
[tool.mypy]
num_workers = "auto"
strict = true
実際に、先ほどのsentinelのコードがあるフォルダにこのファイルを置き、オプションを付けずにmypy sentinel_fixed.pyを実行しました。結果はSuccess: no issues found in 1 source fileで、設定ファイルの内容がそのまま使われています。
古いパーサーに戻したいとき¶
もし新しいパーサーで問題が起きた場合は、設定ファイルでも古いパーサーに戻せます。pyproject.tomlなら、[tool.mypy]の下にnative_parser = falseと書きます。
変更履歴では、問題を見つけたら課題管理のページで報告してほしいと呼びかけています。古いパーサーは2027年の早い時期に削除される予定なので、戻すのはあくまで一時しのぎと考えておきましょう。
Intel Macを使っている方へ¶
配布の面でも1つ変更があります。変更履歴によると、Intel版のMac向けには、mypycという仕組みで高速化したホイールの提供が終わりました。
ホイールとは、インストールするだけで使えるビルド済みのファイルのことです。Intel版のMacでは、これまでより型チェックが遅く感じられるかもしれません。
学習者が押さえておきたいこと¶
最後に、学習者や実務で使い始めた人が押さえておきたいことを整理します。
まず、新しい型ヒントの書き方を学ぶなら、mypyも最新版にそろえておくのがおすすめです。古いmypyでは、3.15の新しい書き方を正しくチェックできないことがあります。
次に、sentinelのように、Noneとは別の目印を使う考え方は、これからのPythonでよく見かけるようになりそうです。値が渡されなかったのか、空なのかを区別したい場面で、ぜひ思い出してみてください。
以前、関数の引数の既定値にNoneを使ったせいで、利用者が明示的にNoneを渡したのか、何も渡さなかったのかが区別できず、仕様の打ち合わせが長引いたことがあります。型チェッカーがこの区別を手伝ってくれるのは、とても心強い進歩です。
まとめ¶
mypy 2.4.0が2026年10月1日に公開されました。Python 3.15のsentinelやlazy importに対応し、Ruffのパーサーをもとにした高速な新パーサーが標準になり、並列チェックも正式な機能になりました。
型ヒントは、書いただけでは何も起きません。mypyのような型チェッカーと組み合わせてこそ、動かす前に間違いを見つける力を発揮します。
ここまでお読みいただきありがとうございました。