【Python】mypyで、実行時の例外発生を予防

参考 mypy公式
https://mypy.readthedocs.io/en/stable/config_file.html?highlight=mypy.ini#the-mypy-configuration-file

【Python】mypyで、実行時の例外発生を予防

Pythonは動的型付言語であるため、実行時に障害が発生したり、品質に不安を与えてしまうことがあります。

  • 朝に実行完了していると思ったら、就寝直後に例外終了
  • 自信を持って、人前で走らせたら、例外終了
  • 納品したソースコードの型付けが不明瞭で、クレームと再納品

Pycharmの機能で、型が原因のミスは防げます。下の図のfunc()は、戻り値がNoneにも関わらず、returnしています。IDEは親切なことに、func()の戻り値の設定を教えてくれるのです。

【Python】mypyで、実行時の例外発生を予防

ところが、Pycharmの親切な機能があっても、人は警告を見逃すものです。というよりも、何度も見逃しました。

型の誤りを見逃さないようにできるツールの1つが、mypyです。コンソールでソースを指定して、mypyを走らせると、厳密にPythonコードの型チェックをしてくれます。

静的型付言語に慣れていると、見落としが日常化してますので、私にとっては定番ツールです。

mypyのインストールと実行方法

pip install mypy

main.pyをチェックするには、コンソールに入って、コマンドを打ち込みます。

d> mypy main.py

デフォルトは型チェックが緩いです。そのため、私は設定ファイルmypy.iniによって、厳密にしています。コマンドを実行するフォルダにiniファイルをコピーしてします。(

mypyで実行例

後述するmypy.iniで、次のコードをチェックすると、3つのエラーが出てきます。

mypyがチェックするソースのサンプル

main.py

	from typing import List
	from typing import Dict
	import pandas as pd

	def func(item: str, num: int) -> None:
	    df = pd.DataFrame(
	        [[item, num, 'east'],
	         ['パン', 20, 'west']],
	        index=['100', '101'],
	        columns=['item', 'price', 'area']
	    )
	    return df

	if __name__ == '__main__':
	    func(20, "ご飯")
	

mypyの実行方法のサンプル

mypy.ini

d> mypy --config-file mypy.ini main.py

前出のソースのサンプルを実行すると、3つのエラーが表示されます。

main.py:12: error: Returning Any from function declared to return "None"
main.py:15: error: Argument 1 to "func" has incompatible type "int"; expected "str"
main.py:15: error: Argument 2 to "func" has incompatible type "str"; expected "int"

Pythonのソースコードに、エラーを無視する設定

せっかくエラーが表示されるようにしたのに、エラーが厳密過ぎて邪魔なことがあります。分かり切っている時に出されると型付けたくなります。

そんな時は、ソースコードにエラーを無視するように打ち込みます。

    func(20, "ご飯") # type: ignore

すると、エラーが1つになりました。やっちゃいけないですけど。

型チェックを厳密にするmypy.iniの設定例

構成ファイルであるmypy.iniの所在は、公式だと「the user home directory」とあります。場所が不明瞭ですが、pythonライブラリのあるディレクトリの下にあります。ない場合は、下のものをコマンドを打ち込むディレクトリにコピーすれば問題ありません。

warn_return_any = True
warn_unused_configs = True
warn_unreachable = True
strict_optional = True
ignore_missing_imports = True

disallow_any_generics = True
disallow_untyped_defs = True
check_untyped_defs = True
show_none_errors = True

デフォルトよりも厳密になっています。設定項目は公式を見れば分かるのですが、分かりづらいかと思うので部分的に補足しておきます。

項目 説明
warn_return_any 戻り値がanyの関数なのに、型付けで返すと警告
warn_unreachable 到達不可能なコードがあると警告
strict_optional 厳密オプションを有効にする
ignore_missing_imports 解決不可能なimportのエラーを抑制
disallow_any_generics ジェネリック型の使用を禁止
disallow_untyped_defs 注釈なしがある関数の定義を禁止
check_untyped_defs 型注釈なしで関数の内部をチェック

コメント

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