Pythonのバグを実行前に潰したい。そう思ったときに最初に入れるべきツールが mypy です。型ヒント(int/str/Optional など)をもとに「実行しなくても確実におかしい箇所」を指摘してくれます。Ubuntu 24.04 での実インストールから、CI(GitHub Actions)への組み込みまで、docker コンテナで実際に動かした結果を使って説明します。
この記事のポイント
- Ubuntu 24.04 では
pip install mypyは venv 経由が必須(PEP 668 制限) - 実測:mypy 2.1.0(Python 3.12.3)が ubuntu:24.04 にインストールできることを確認
[assignment]・[arg-type]・[union-attr]など、よく出るエラーコードの意味pyproject.tomlの[tool.mypy]セクションで strict モードを有効にする手順- mypy は終了コード 1 でエラーを返す → CI のゲートとしてそのまま使える
目次
前提環境
本記事のコマンドはすべて Docker 公式イメージ ubuntu:24.04 で実行し、実出力を確認しています。VPS や WSL の Ubuntu 24.04 でも同じ手順で動きます。
| 項目 | バージョン |
|---|---|
| OS | Ubuntu 24.04 LTS (Noble Numbat) |
| Python | 3.12.3(ubuntu:24.04 同梱) |
| mypy | 2.1.0(2026-06-22 実測) |
| 実行環境 | Docker 公式イメージ(ホスト汚染なし) |
mypy のインストール
手順1:python3-venv をインストールする
Ubuntu 24.04 は PEP 668 の制限により、pip install をシステム Python に対して直接実行するとエラーが出ます(externally-managed-environment)。venv を使うのが正しい方法です。
$ sudo apt-get install -y python3 python3-pip python3-venv
Reading package lists… Done
Building dependency tree… Done
The following NEW packages will be installed:
python3-venv python3-pip
手順2:仮想環境を作り mypy をインストールする
$ source ~/mypy_env/bin/activate
(mypy_env) $
(mypy_env) $ pip install mypy
Collecting mypy
Downloading mypy-2.1.0-cp312-cp312-linux_x86_64.whl (513.1 kB)
Successfully installed mypy-2.1.0 mypy_extensions-1.1.0 …
(mypy_env) $ mypy –version
mypy 2.1.0 (compiled: yes)


実測で確認した出力です。compiled: yes は mypy が C 拡張でビルドされていることを示し、チェックが速く動きます。
Ubuntu 22.04 の場合
22.04 は PEP 668 の制限がないため pip3 install mypy でそのまま入ります(Python 3.10.12 + mypy 2.1.0 を実測で確認)。ただし、将来の互換性を考えると venv 経由の習慣をつけておくと安心です。
型エラーを検出してみる
mypy は Python ファイルを静的に解析し、型の矛盾を実行前に報告します。まずは3種類の典型的なエラーを実際に見てみましょう。
①代入エラー(assignment)と引数エラー(arg-type)
以下の sample_basic.py を書いて mypy にかけます。
return “Hello, ” + name
def add(a: int, b: int) -> int:
return a + b
result: str = add(1, 2) # ← int を str 型変数に代入
greet(42) # ← str 引数に int を渡す
sample_basic.py:8: error: Incompatible types in assignment
(expression has type “int”, variable has type “str”) [assignment]
sample_basic.py:9: error: Argument 1 to “greet” has incompatible type “int”; expected “str” [arg-type]
Found 2 errors in 1 file (checked 1 source file)
ファイル名・行番号・エラーコードまで出ます。慣れてくると [assignment] を見ただけで「型の代入ミスだ」とわかるようになります。
②None の可能性を見逃すエラー(union-attr)
個人的にいちばん助かるのがこれです。Optional[str](= str | None)を返す関数の戻り値に .upper() を呼ぶと、実行時に AttributeError: 'NoneType' object has no attribute 'upper' になります。mypy はそれを事前に検出します。
def get_user_name(user_id: int) -> Optional[str]:
if user_id == 1:
return “Alice”
return None
name = get_user_name(99)
print(name.upper()) # ← None かもしれない
sample_optional.py:9: error: Item “None” of “str | None” has no attribute “upper” [union-attr]
Found 1 error in 1 file (checked 1 source file)
if name is not None: と書いてから呼べば mypy のエラーは消えます。実際にそう直すと Success: no issues found in 1 source file が返ることを実測で確認しました。

pyproject.toml で設定をカスタマイズ
pyproject.toml の [tool.mypy] セクションに設定を書くと、プロジェクトごとにチェックの厳しさを調整できます。
基本設定ファイルの例
python_version = “3.12”
strict = true
ignore_missing_imports = true
strict = true にすると、型注釈がない関数を全て指摘するようになります。
main.py:1: error: Function is missing a type annotation [no-untyped-def]
main.py:4: error: Function is missing a type annotation [no-untyped-def]
main.py:7: error: Call to untyped function “process” in typed context [no-untyped-call]
main.py:8: error: Call to untyped function “get_count” in typed context [no-untyped-call]
Found 4 errors in 1 file (checked 1 source file)

既存コードに strict を当てると大量のエラーが出ることがあります。そのときは disallow_untyped_defs = true だけを有効にして少しずつ締めていくのが現実的です。
よく使う mypy 設定オプション
strict = true は以下を全て有効にするショートカットです。個別に制御したい場合はそれぞれを設定します。
disallow_untyped_defs = true:型注釈なしの関数を禁止warn_return_any = true:Any型の返却を警告no_implicit_optional = true:デフォルトNoneを自動でOptionalにしないignore_missing_imports = true:型スタブのないサードパーティ製ライブラリのエラーを抑制
CI(GitHub Actions)への組み込み
mypy の終了コードを使う
mypy はエラーがあると exit code 1 を返し、問題なければ 0 を返します。CI システムは終了コードを見て pass/fail を判定するので、mypy をそのままゲートとして使えます。
src/service.py:11: error: Incompatible return value type (got “str”, expected “int”) [return-value]
Found 1 error in 1 file (checked 3 source files)
(mypy_env) $ echo “exit: $?”
exit: 1


GitHub Actions ワークフロー例
on: [push, pull_request]
jobs:
mypy:
runs-on: ubuntu-24.04
steps:
– uses: actions/checkout@v4
– uses: actions/setup-python@v5
with:
python-version: “3.12”
– name: Install mypy
run: pip install mypy
– name: Run mypy
run: mypy src/
これで PR ごとに型チェックが走り、エラーがあればマージをブロックできます。チームで Python を書くなら、テストの次に入れておきたいゲートです。
よくあるエラーと解決策
Module not found(モジュールが見つからない)
requests など型スタブ(*.pyi ファイル)を持たないライブラリで出ます。解決策は2つあります。
pip install types-requestsで公式スタブパッケージを入れる(requests・boto3など多数存在)- 出ても構わなければ
pyproject.tomlにignore_missing_imports = trueを追加
Incompatible types in assignment — 代入先の型と合わない
変数に型注釈をつけているのに、違う型を代入しようとすると出ます。注釈を外すか、代入する値の型を合わせます。
# 修正: count: int = add(1, 2) ← 型を int に合わせる
# または: count = add(1, 2) ← 注釈を削除して mypy に推論させる
Function is missing a type annotation — strict モードで注釈なし関数
strict = true の場合に出ます。引数と戻り値に型を書けば消えます。段階的に直すなら # type: ignore[no-untyped-def] をその行に付けて一時スキップも可能ですが、放置しすぎないようにしましょう。
まとめ
Ubuntu 24.04 での mypy 導入手順と実測結果をまとめます。
- mypy 2.1.0 を ubuntu:24.04(Python 3.12.3)に venv 経由でインストールを確認(2026-06-22 実測)
[assignment]・[arg-type]・[union-attr]・[return-value]など、エラーコードで何が問題かわかるpyproject.tomlのstrict = trueで注釈なし関数も全て検出できる- mypy はエラー時に exit code 1 を返す → GitHub Actions など CI のゲートにそのまま使える
- 型スタブがないライブラリは
types-*パッケージを入れるかignore_missing_imports = trueで抑制

コードの規模が小さいうちから mypy を入れておくと、後で型を追加するコストが大幅に下がります。まず mypy src/ を走らせて何本エラーが出るか確認してみてください。
次のステップ
- 型チェックを覚えたら、テストも整備したい → pytest の導入は
- VPS 上で開発環境を整えたい方には (Vultr / DigitalOcean 比較)もどうぞ


コメント