型ヒントが提供されていないpythonライブラリにmypy用に型ヒントを入れる
最近mypyを趣味で使い始めたのでいろいろ書こうと思います。 @tk0miiyka さんの記事を読んでとりあえず自分の仕事でmypy使えそうなところをいろいろ考えてみた
対象バージョン
version | |
---|---|
python | 3.5.2 |
mypy | 0.4.6 |
last update | 2017.01.08 |
TL;DR
pyiファイルをつくれば世の中の型ヒントが提供されていないプロジェクトに型ヒントをつけられる。 まーでも結構めんどいので、みんなでtypeshedを育てていくのがよさそうです。
GitHub - python/typeshed: Collection of library stubs for Python, with static types
mypyって?
こちらの素晴らしい記事を読んだほうがいいですね。
要はPython3.4以降で使える静的型チェッカーらしい。個人的にはコメントをツールで拡張できるところがいいと思ってます。 コメントだからスクリプトの邪魔をしないんですよね。また、あとから書き足すことも可能です。 世界樹の迷宮風に言うと「君は型を書いてもいいし、書かなくてもいい」ってところです。
ちなみに僕はある程度使い回す&&インターフェースがほぼもう変更されない段階のpythonスクリプトとかに書いてます。 たまにコード読むとこのコードなんだったか忘れますよねー。(ものぐさ
インストール
pipで一発です。python 3.4以降で動くのでvenvとか使うと手元の環境が汚れないので良いかと。
pip install mypy-lang
venvについてはこちら http://docs.python.jp/3.5/library/venv.htmldocs.python.jp
mypyかるく使い方説明
といいつつ、この辺見るのがよさ気。割とちゃんとドキュメントが書かれてるのが良い感じ。
http://mypy.readthedocs.io/en/latest/basics.htmlmypy.readthedocs.io
python2でも使えるよ
type hintってpython3から入ったからpython2のスクリプト使えないっぽく見えるんですが、実際には使えますです。 こんな感じ。
http://mypy.readthedocs.io/en/latest/python2.html?highlight=py2mypy.readthedocs.io
でもtypeshedが対応してないといろいろ怒られる
残念ながらtypeshedに登録されていないライブラリを実行するとmypyさんに怒られてしまう。 例えばfabric用のファイルとかにmypyを実行するとこんな感じで怒られてしまいます。
from fabric.api import run def test(): "() -> None" run("ls")
$ mypy --py2 fabfile.py fabfile.py:1: error: No library stub file for module 'fabric.api' fabfile.py:1: note: (Stub files are from https://github.com/python/typeshed)
typeshedにstub登録されてないっすよって言われてしまいました。 軽い気持ちでmypy使いたい勢としては辛い。。。。
pyiファイルってのがある
やっとここからが話したかったことです。 そんなどうしようもない人たち向けにpyiってファイルがありまして、これを用意するとなんとかなる。
out/ └── fabric ├── __init__.py └── api.pyi
api.pyi
def run(command: str): ...
MYPYPATH=./mypy-stub/fabric/ mypy --py2 fabfile.py
こんな感じで実行しても怒られなくなります。 でも毎回自分でpyiファイルを用意するのはめんどいよね。
stubgen
という声のために、mypyはpyiを作ってくれるコマンドを用意してくれてます。 こんなのをつかうとメソッドリストは簡単につくれる
mypy/stubgen.py
@methane さんが作ってるpymysql用のstubもあって、これもstubgenつかってるらしい。
使い方はmypyとstubを作りたいライブラリをインストールして、実行するだけ!!
詳しくはコードを読んでね
https://github.com/python/mypy/blob/master/mypy/stubgen.py
mkdir out stubgen fabric stubgen fabric.api stubgen fabric.operations
これで無事作られる...やったー、というわけには行かなくてですね。。。
残念ながら今のstubgenはメソッドとimportを抜き出してくれるだけで、ライブラリ内でimportしてるところをうまく抜き出してくれないんですよね。。。 まー自力でメソッドリストつくらなくてもいいのは助かります。
とかとかで対象になるライブラリのコードを読んで対処します。
というわけで頑張ってある程度実行できるやつを作りました。
$ git clone https://github.com/masahitojp/fabric-mypy.git $ MYPYPATH=./fabric-mypy/ mypy --py2 learn_mypy/fabfile.py
ふーやっと怒られなくなりました。お疲れ様でした。
まーこんな感じで型情報が提供されてないライブラリを使ってmypyできるところまでこれました。 mypyを使いやすくするためになるべくtypeshedに上げるように頑張りたいところですねー
気になってるもの
- ライブラリ側のバージョンアップでインターフェース変わったらどうするよ
- pyiのテスト