🐍

VSCode extension mypy-type-checker 使ってみた

2023/11/03に公開

💡 やったこと

  • ruff の採用と同時に Linter/Formatter/Type annotation の見直しをしました。
  • mypy はゆるく使う方針で --disallow-untyped-defs のみ採用しました。
  • mypy-type-checker を使うことで mypy の利用がより簡便になりました。

背景

ruff という Linter/Formatter が最近いい感じらしいです。

https://docs.astral.sh/ruff

  • flake8, isort, black とほぼ同等 (公式が言うには例えば black は 99% カバー) の機能を丸々カバーできる。
    • isortblack が conflict する問題などで頭を悩まさなくてよくなる
    • 複数のソフトウェアのバージョン管理の手間がなくなる
  • Rust で実装されているので爆速
  • VSCode extension も実装されているのでファイルセーブ時に自動で ruff を実行することができる
    • ちなみに black, isort も extension があるにはある
  • --fix, --add-noqa 機能が便利 (簡単に言うと自動で直せる範囲で violation を fix したりできる)

普段は flake8, isort, black, mypy を利用しているのですがこのようなメリットから
flake8, isort, black をやめて ruff に移行しようかなと思いました。

ただし、 mypy の Type annotation 機能は ruff にはありませんので、 mypy は引き続き併用しようかなと思います。

ただ、ついでに mypy の使い方を見直しました。

mypy

型をある程度チェックすることで開発が円滑に進むことができるので、チーム内では Type annotation として mypy を利用していています。

  • あまりきついルールにすると boto3 など厳密な型を定義できないライブラリを実装する時苦労したり、結局 type:ignore としてしまい意味がなくなってしまう
  • 一方、関数やメソッドの引数、返り値は自身やチームメンバーが実装したものを利用する時、非常に有益な情報である
  • よって、関数やメソッドの引数、返り値が書かれているかチェックする --disallow-untyped-defs のみ有効にして mypy を利用したい。

と、一旦落ち着きました。多分これぐらいのゆるさか、逆に型をきっちり全部の変数で書きましょうと固めるかのどっちかが良さそうで、今回は前者に落ち着いた感じです。

pylance

ちなみに調べていたら Type annotation には他に Pyright というのがライブラリがありこの Pyright をベースにしている VSCode extenstion として利用者が多い pylance があります。

https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance

ググって適当な記事を読むと何気なく使っている pylance もデフォルトは off になっていますが、実は型タイプのエラーを出す設定があるみたいです。試しに strict という設定にすると mypy 同様、関数やメソッドの引数、返り値が実装されていない場合エラーを出すようになりました。

ただし、軽く触ってみたら strict と言う文字通り他のエラーもビシバシ出してきてちょっと厳しすぎると言うことで今回は見送りました。(ちなみに bacic は出して欲しい --disallow-untyped-defs をエラーとして出してくれなかったです)

mypy-type-checker

mypy の設定は決まったけど、 pylance 同様 mypy コマンドをターミナルで実行しなくとも VSCode でコード編集時にエラーとして表示したいなと色々調べていると mypy-type-checker という Extension が pylance 同様リリースされていることに気づきました。リリース日が 2023/4/5 なので結構最近です。

https://marketplace.visualstudio.com/items?itemName=ms-python.mypy-type-checker

試しに入れてみると、コードを書いている途中ですでに設定していたレギュレーション違反をするとエラー表示してくれます。これぞまさに求めていたものだと感じです。

コマンド実行時のエラーと同じです。

> mypy --disallow-untyped-defs sample.py
sample.py:20: error: Function is missing a type annotation  [no-untyped-def]
Found 2 errors in 1 file (checked 1 source file)

引数、返り値の型を追加するとエラーが消えたので期待通りワークしてそうです。

--disallow-untyped-defs を有効にするために Extension の設定は以下のように設定しました。
mypy-type-checker はデフォルトでは Extension に bundle として含まれている mypy が利用されてしまい、 VSCode 上で開発するだけなら mypy もインストールする必要もなく便利ですが、 CI の実行時にバージョンが異なりエラーを出す可能性があるため今回は "mypy-type-checker.importStrategy": "fromEnvironment" と設定しました。

{
  "mypy-type-checker.args": ["--disallow-untyped-defs"],
  "mypy-type-checker.importStrategy": "fromEnvironment"
}

ruff の採用と同時に Linter/Formatter/Type annotation の見直しをしてみました。
たまに見直すといいですね。

💡 まとめ

  • ruff の採用と同時に Linter/Formatter/Type annotation の見直しをしました。
  • mypy はゆるく使う方針で --disallow-untyped-defs のみ採用しました。
  • mypy-type-checker を使うことで mypy の利用がより簡便になりました。

Discussion