mypy on Ubuntu — Python静的型チェックの導入とCI組み込み

開発環境

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 のゲートとしてそのまま使える

目次

  1. 前提環境
  2. mypy のインストール
  3. 型エラーを検出してみる
  4. pyproject.toml で設定をカスタマイズ
  5. CI(GitHub Actions)への組み込み
  6. よくあるエラーと解決策
  7. まとめ

前提環境

本記事のコマンドはすべて 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 を使うのが正しい方法です。




ubuntu@linuxlab: ~
$ sudo apt-get update
$ 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 をインストールする




ubuntu@linuxlab: ~
$ python3 -m venv ~/mypy_env
$ 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)
mypy インストールと型チェック実行(Ubuntu 24.04 実測)
mypy インストールと型チェック実行(Ubuntu 24.04 実測)
Ubuntu 24.04 での mypy インストールログ(実測)
Ubuntu 24.04 での mypy インストールログ(実測)

実測で確認した出力です。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 にかけます。




sample_basic.py
def greet(name: str) -> str:
return “Hello, ” + name

def add(a: int, b: int) -> int:
return a + b

result: str = add(1, 2) # ← int を str 型変数に代入
greet(42) # ← str 引数に int を渡す



ubuntu@linuxlab: ~
(mypy_env) $ mypy sample_basic.py
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 はそれを事前に検出します。




sample_optional.py
from typing import Optional

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 かもしれない



ubuntu@linuxlab: ~
(mypy_env) $ mypy sample_optional.py
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 が返ることを実測で確認しました。

mypy による型エラー検出の実測例(3種)
mypy による型エラー検出の実測例(3種)

pyproject.toml で設定をカスタマイズ

pyproject.toml[tool.mypy] セクションに設定を書くと、プロジェクトごとにチェックの厳しさを調整できます。

基本設定ファイルの例




pyproject.toml
[tool.mypy]
python_version = “3.12”
strict = true
ignore_missing_imports = true

strict = true にすると、型注釈がない関数を全て指摘するようになります。




ubuntu@linuxlab: ~/myproject
(mypy_env) $ mypy –config-file pyproject.toml main.py
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)
pyproject.toml strict モードでの mypy 実行(実測)
pyproject.toml strict モードでの mypy 実行(実測)

既存コードに strict を当てると大量のエラーが出ることがあります。そのときは disallow_untyped_defs = true だけを有効にして少しずつ締めていくのが現実的です。

よく使う mypy 設定オプション

strict = true は以下を全て有効にするショートカットです。個別に制御したい場合はそれぞれを設定します。

  • disallow_untyped_defs = true:型注釈なしの関数を禁止
  • warn_return_any = trueAny 型の返却を警告
  • no_implicit_optional = true:デフォルト None を自動で Optional にしない
  • ignore_missing_imports = true:型スタブのないサードパーティ製ライブラリのエラーを抑制

CI(GitHub Actions)への組み込み

mypy の終了コードを使う

mypy はエラーがあると exit code 1 を返し、問題なければ 0 を返します。CI システムは終了コードを見て pass/fail を判定するので、mypy をそのままゲートとして使えます




ubuntu@linuxlab: ~/ciproject
(mypy_env) $ mypy src/
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
mypy CI 統合・終了コード確認(Ubuntu 24.04 実測)
mypy CI 統合・終了コード確認(Ubuntu 24.04 実測)
mypy CI 統合・複数ファイル一括チェック(実測)
mypy CI 統合・複数ファイル一括チェック(実測)

GitHub Actions ワークフロー例




.github/workflows/typecheck.yml
name: Type Check
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(モジュールが見つからない)




ubuntu@linuxlab: ~
error: Cannot find implementation or library stub for module named “requests” [import-untyped]

requests など型スタブ(*.pyi ファイル)を持たないライブラリで出ます。解決策は2つあります。

  • pip install types-requests で公式スタブパッケージを入れる(requestsboto3 など多数存在)
  • 出ても構わなければ pyproject.tomlignore_missing_imports = true を追加

Incompatible types in assignment — 代入先の型と合わない

変数に型注釈をつけているのに、違う型を代入しようとすると出ます。注釈を外すか、代入する値の型を合わせます。




ubuntu@linuxlab: ~
error: Incompatible types in assignment (expression has type “int”, variable has type “str”) [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.tomlstrict = true で注釈なし関数も全て検出できる
  • mypy はエラー時に exit code 1 を返す → GitHub Actions など CI のゲートにそのまま使える
  • 型スタブがないライブラリは types-* パッケージを入れるか ignore_missing_imports = true で抑制
Ubuntu 22.04 vs 24.04 の Python・mypy バージョン比較(実測)
Ubuntu 22.04 vs 24.04 の Python・mypy バージョン比較(実測)

コードの規模が小さいうちから mypy を入れておくと、後で型を追加するコストが大幅に下がります。まず mypy src/ を走らせて何本エラーが出るか確認してみてください。

次のステップ

  • 型チェックを覚えたら、テストも整備したい → pytest の導入は
  • VPS 上で開発環境を整えたい方には (Vultr / DigitalOcean 比較)もどうぞ

コメント

タイトルとURLをコピーしました