【Python】mypyで型チェックする方法!インストールから使い方まで解説!

Pythonでプログラミングをしていると、「mypy」というツールを目にすることがあります。

Pythonでは、変数や関数の引数に型を指定する「型ヒント」を記述できます。しかし、型ヒントを書いただけでは、Pythonが型の間違いを自動的にエラーとして検出してくれるわけではありません。

そこで役立つのがmypyです。

この記事では、mypyの基本的な意味から、型ヒントとの関係、インストール方法、基本的な使い方まで、初心者向けにわかりやすく解説します。

mypyとは?

mypyとは?

mypyとは、Pythonのコードから型の情報を解析し、型の間違いがないかチェックする「静的型チェッカー」です。

Pythonは「動的型付け言語」と呼ばれるプログラミング言語で、変数を作成するときに型を厳密に指定する必要はありません。

例えば、次のコードはPythonでは実行できます。

value = 10
value = "Hello"

最初はint型の10が入っていますが、そのあとstr型の"Hello"を代入しています。

この柔軟さはPythonの特徴の1つですが、プログラムが大きくなると、「この変数や関数ではどの型を使用するのか」が分かりにくくなり、型の違いによるミスが発生することがあります。

そこでPythonでは、「型ヒント」を記述できます。

例えば、次のコードを見てみましょう。

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

result = add("10", 20)

add()の引数abには、どちらもintが指定されています。また、-> intは戻り値がintであることを示しています。

しかし、add("10", 20)では、第1引数にstr型の"10"を渡しています。

Pythonの型ヒントは、実行時に型を強制するものではないため、型ヒントを書いただけでこのような間違いを自動的に検出してくれるわけではありません。

そこでmypyを使用します。

mypyでこのコードをチェックすると、intを受け取る場所にstrが渡されていることを検出できます。

つまり、型ヒントで「どの型を使用するのか」を記述し、mypyで「型の使い方が正しいか」をチェックします。

簡単に整理すると、型ヒントとmypyには次のような違いがあります。

項目型ヒントmypy
主な役割変数や引数などで想定する型を記述する型ヒントをもとに型をチェックする
Python標準の機能×
型の間違いをチェック型ヒントだけでは行わない
プログラムの実行不要不要

mypyはPythonプログラムを実際に実行するのではなく、コードと型ヒントを解析して問題を検出します。このように、プログラムを実行せずにコードを調べることを「静的解析」と呼びます。

Pythonの型ヒントの基本

mypyは型ヒントをもとにチェックするため、Pythonの型ヒントについても簡単に確認しておきましょう。

# 変数の型を指定
name: str = "Taro"
age: int = 30

# int型の値を持つリスト
scores: list[int] = [80, 90, 100]

# キーがstr型、値がint型の辞書
user: dict[str, int] = {
    "age": 30
}

# intまたはstr
value: int | str = 10

# strまたはNone
user_name: str | None = None

このように、型ヒントを使用すると、変数やリスト、辞書などにどの型の値が入るのかをコード上で示せます。

mypyは、これらの型ヒントをもとに型の使い方が正しいかをチェックします。

mypyをインストールする

mypyはPythonとは別のツールなので、使用するにはインストールが必要です。

Pythonの仮想環境などで、次のコマンドを実行します。

python -m pip install mypy

インストールできたか確認する場合は、次のコマンドを実行します。

mypy --version

mypyのバージョンが表示されれば、インストールは完了です。

mypyの基本的な使い方

mypyでは、チェックしたいPythonファイルを指定して実行します。

例えば、sample.pyをチェックする場合は、次のコマンドを実行します。

mypy sample.py

sample.pyの内容が次のコードだったとします。

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

result = add("10", 20)

mypyを実行すると、次のように型が一致していないことを示すエラーが表示されます。

error: Argument 1 to "add" has incompatible type "str"; expected "int"  [arg-type]
Found 1 error in 1 file (checked 1 source file)

これは、add()の第1引数にはintが必要なのに、strが渡されているという意味です。

次のように修正します。

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

result = add(10, 20)

もう一度mypyを実行します。

mypy sample.py

型に問題がなければ、次のように表示されます。

Success: no issues found in 1 source file

戻り値の型もチェックできる

mypyでは、関数に渡す引数だけでなく、関数が返す値の型もチェックできます。

例えば、次のコードを見てみましょう。

def get_price() -> int:
    return "1000"

get_price()の戻り値にはintを指定していますが、実際にはstr型の"1000"を返しています。

mypyでチェックすると、戻り値の型が一致していないことを検出できます。

error: Incompatible return value type (got "str", expected "int")  [return-value]
Found 1 error in 1 file (checked 1 source file)

このように、関数の引数だけでなく戻り値についても型のミスを確認できます。

Noneになる可能性もチェックできる

mypyは、値がNoneになる可能性を見落としている場合にも役立ちます。

例えば、次のコードを見てみましょう。

def get_name(data: dict[str, str]) -> str:
    return data.get("name")

dict.get()は、指定したキーが存在しない場合にNoneを返します。

そのため、このコードではstrだけでなくNoneが返される可能性があります。

しかし、関数の戻り値には-> strと指定されています。

mypyでチェックすると、次のようなエラーを検出できます。

error: Incompatible return value type (got "str | None", expected "str")  [return-value]
Found 1 error in 1 file (checked 1 source file)

str | Noneは、「strまたはNoneになる可能性がある」という意味です。

Noneをそのまま返す仕様であれば、次のように戻り値の型を修正できます。

def get_name(data: dict[str, str]) -> str | None:
    return data.get("name")

実際のプログラムでは、「値が必ず存在すると思っていたのに、実際にはNoneだった」というエラーが発生することがあります。

mypyを利用すると、このような問題にもプログラムを実行する前に気付きやすくなります。

ディレクトリ全体をmypyでチェックする

mypyでは、1つのPythonファイルだけでなく、ディレクトリを指定して複数のPythonファイルをまとめてチェックすることもできます。

例えば、srcディレクトリ内のPythonコードをチェックする場合は、次のコマンドを実行します。

mypy src

これにより、srcディレクトリ内を対象に型チェックできます。

複数のPythonファイルで構成されたプロジェクトでは、ファイルを1つずつ指定するよりも、ディレクトリ単位でチェックすると便利です。

型ヒントがないコードはすべてチェックされるわけではない

mypyを使用するときに注意したいのが、型ヒントがないPythonコードです。

例えば、次の関数には型ヒントがありません。

def add(a, b):
    return a + b

mypyは段階的に型チェックを導入できるように設計されているため、デフォルトでは、このような型ヒントのない関数の内部を厳しくチェックしない場合があります。

一方、次のように型ヒントを記述すると、mypyが型をチェックしやすくなります。

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

そのため、mypyは「Pythonコードをすべて自動的にチェックしてくれるツール」というよりも、「型ヒントを利用して型の問題を見つけるツール」と考えるとわかりやすいでしょう。

--strictでより厳しくチェックする

mypyには、通常よりも厳しく型をチェックする--strictオプションがあります。

例えば、次のコマンドを実行します。

mypy --strict sample.py

--strictを使用すると、型ヒントが不足している関数などについても、通常より厳しいルールでチェックされます。

ただし、既存の大きなPythonプロジェクトにいきなり--strictを適用すると、大量のエラーが表示される場合があります。

初めてmypyを使用する場合は、まず通常の型チェックから始め、必要に応じてチェックを厳しくしていくとよいでしょう。

VS Codeでもmypyを利用できる

mypyはコマンドラインから実行するだけでなく、VS Codeなどのエディタと組み合わせて使用することもできます。

VS Codeでは、「Mypy Type Checker」という拡張機能を利用できます。

拡張機能をインストールすると、Pythonコードを書いているときに型の問題をエディタ上で確認できるため、毎回mypyコマンドを実行しなくても型エラーに気付きやすくなります。

普段VS Codeを使用してPythonを開発している場合は、コマンドラインからのmypyとあわせて利用すると便利です。

VS Codeでもmypyを利用できる

mypyを使用するメリット

mypyを使用する主なメリットは、型に関するミスをプログラムの実行前に見つけやすくなることです。

また、型ヒントを記述しておくことで、「この関数には何を渡すのか」「何が返ってくるのか」がコードから分かりやすくなります。

VS Codeなどのエディタでは、型情報を利用してコード補完などを行える場合もあるため、コードを書くときだけでなく、読むときにも役立ちます。

小さなプログラムでは型の間違いに気付きやすいですが、プログラムが大きくなり、関数やクラスが増えてくると型の関係も複雑になります。

mypyを利用すると、このような型の問題を早い段階で見つけやすくなります。

本記事のまとめ

この記事では「mypy」について、以下の内容を説明しました。

  • mypyはPythonのコードを実行する前に型をチェックできる静的型チェッカー
  • Pythonは動的型付け言語で、型ヒントを書いても実行時に型が強制されるわけではない
  • mypy sample.pyのようにファイルを指定して型チェックできる
  • 引数だけでなく、戻り値やNoneになる可能性もチェックできる
  • list[int]str | Noneなどの型ヒントを利用できる
  • --strictを使用すると、より厳しい型チェックができる
  • VS Codeの拡張機能を利用してエディタ上でも型を確認できる

Pythonでは型ヒントを書いても、その型が実行時に自動的に強制されるわけではありません。

mypyを利用することで、型ヒントを活用して型の間違いを早い段階で発見しやすくなります。

お読みいただきありがとうございました。

スポンサーリンク