8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

mypy + numpy で静的型チェックするメモ

Last updated at Posted at 2021-01-28

背景

機械学習とか画像処理とか, numpy を使う場合型はだいたい既知(e.g. 画像データだと dtype np.uint8 とか)なので, 静的型チェックしたい.

Python3.5 以降の型アノテーション + mypy + nptyping(完全ではない) を使います.
(numpy v1.12 かそれ以降では numpy.typing が使えるようだが現状 2021/01/28 時点では v1.12 はベータリリース段階で stable release は v1.19)

Python 3.8 以降あたりを使うのがよさそうです.

ただ, 現状(2021/01/28 時点), 完全にうまく行く方法はありません.

(追記) 2021/01/30 に numpy.typing 対応した numpy v1.20 がリリースされました.

今後はこちらを mypy と共に使うのが主流になっていくことでしょう.

静的型チェック

  • 型アノテーションと実行時型チェックをコードに記述
  • mypy でチェック
  • OK になったら普通に python で実行

のステップになります.

mypy とは...?

Pythonではじまる、型のある世界
https://qiita.com/icoxfog417/items/c17eb042f4735b7924a3

ありがとうございます.

ただ, そのまま mypy 実行だと numpy module の型情報取得できないっぽいので,

Type hint for NumPy ndarray dtype?
https://stackoverflow.com/questions/54503964/type-hint-for-numpy-ndarray-dtype

にあるように, data-science-types を入れておきます(ついでに pandas とかでも使えてよい)

他に使っている module があり型ヒントがなくてエラーになる場合は, 適当に --ignore-missing-imports をつけるなりしてひとまず suppress しておきます.

nptyping で型アノテーション

numpyでも型ヒントチェックしたいと思った
https://qiita.com/qython/items/1f7416bbb29f48a153bb

ありがとうございます.

nptyping なしで文字列指定もできますが, dtype のチェックはうまくしてくれないようで

import numpy as np


def proc_numpy(a: "np.ndarray[np.float64]"):
    print(a)


a = "bora"
proc_numpy(a) # error

b = np.random.rand(4, 5).astype(np.int32)
proc_numpy(b) # ok :thinking: 

文字列渡す場合は

error: Argument 1 to "proc_numpy" has incompatible type "str"; expected "ndarray[float64]"

とエラーレポートしてくれますが,

と int 配列を渡す場合は mypy は OK をレポートしてしまいます.

nptyping を使って型アノテーションを書くと, size や dtype もチェックできまます.

nptyping は mypy でチェックできない

しかし, 現状 nptyping は残念ながら mypy でサポートしていないため,

def proc_numpy(a: NDArray[(typing.Any, ...), Float[64]]) -> None:
    print(a)

のように書いても mypy チェックでは無視されます :cry:

関数の引数の型指定の場合, ひとまずは文字列指定などで最低限のチェックを mpypy で行い,
残りは isinstance で実行時型チェックするかありません.

実行時型チェック

上記のようなケースや, コードの書き方によっては実行時にチェックする必要も出てくるかと思います.

実行時に型チェックしたい場合は今までどおり assert isinstance(...) あたりを記載することになるかと思います.

(将来) numpy.typing で型アノテーション

v1.12 では numpy 自体に取り込まれるっぽい.

まとめ

numpy.typing にいずれは統合されて mypy でよろしく型チェックできると思われますが, python 自体の型サポートとあいまり, 現状は過渡期という感じです.

python 3.10+ + numpy v1.12+ あたりでいい感じになるかもしれません.

8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?