はじめに
プログラミングしてる花咲夜、むふふ。nikkieです。
Pythonで型を書いてきて少なくとも2年、初めて reveal_type()
を知りました
目次
- はじめに
- 目次
- reveal_type()、一見に如かず
- mypy以外の型チェッカもサポート
- Python 3.11からtyping.reveal_type()
- 意見:reveal_type()は残したくない
- 終わりに
reveal_type()
、一見に如かず
mypyのドキュメントの中の「Displaying the type of an expression」にある例です。
https://mypy.readthedocs.io/en/stable/common_issues.html#displaying-the-type-of-an-expression
You can use
reveal_type(expr)
to ask mypy to display the inferred static type of an expression.
reveal_type((1, "hello"))
型チェックを実行します。
% mypy --version mypy 1.11.0 (compiled: yes) % mypy example.py example.py:1: note: Revealed type is "tuple[Literal[1]?, Literal['hello']?]" Success: no issues found in 1 source file
- 型チェックは通った
reveal_type()
は組み込み関数ではないが、型チェッカはそれを怒らない
reveal_type()
の部分、noteが出力されている- 式の型をprintデバッグしたような状態
このスクリプトをPythonインタプリタで実行するとreveal_type()
のためにエラーが送出されます。
% python -V Python 3.11.8 % python example.py Traceback (most recent call last): File "/.../example.py", line 1, in <module> reveal_type((1, "hello")) ^^^^^^^^^^^ NameError: name 'reveal_type' is not defined
mypy以外の型チェッカもサポート
pyrightでもmypyと同様に使えるようです。
% pyright --version pyright 1.1.372 % pyright example.py /.../example.py /.../example.py:1:13 - information: Type of "(1, "hello")" is "tuple[Literal[1], Literal['hello']]" 0 errors, 0 warnings, 1 information
PylanceはVS Code上で表示してくれて、これはなかなか便利!
(青い波の下線にマウスカーソルを当てて表示しています)
"(1, "hello")" の型は "tuple[Literal[1], Literal['hello']]" です
Python 3.11からtyping.reveal_type()
https://docs.python.org/ja/3/library/typing.html#typing.reveal_type
Ask a static type checker to reveal the inferred type of an expression.
導入理由(python.jpより)
導入理由はpython.jpが分かりやすかったです。
https://www.python.jp/news/wnpython311/typing5.html#typing.reveal_type()
reveal_type()
は mypy などの型チェッカでのみ実行可能な関数で、reveal_type() が残ったPythonスクリプトを実行すると、エラーとなってしまいます。このため、開発中に型を確認しながらテストを実行する場合には reveal_type() を入れたり消したりしなければならず、とても面倒でした。
typing.reveal_type()
を使えば、削除しなくてもPythonインタプリタはエラーを送出しません
from typing import reveal_type reveal_type((1, "hello"))
% mypy example.py example.py:3: note: Revealed type is "tuple[Literal[1]?, Literal['hello']?]" Success: no issues found in 1 source file % python example.py Runtime type is 'tuple'
typing.reveal_type()
の実装を見る
What's New in Python 3.11も見てみます。
https://docs.python.org/ja/3.11/whatsnew/3.11.html#typing
issueにもありますが、実装はprint文のようです
# https://github.com/python/cpython/blob/v3.11.9/Lib/typing.py#L3440-L3456 def reveal_type(obj: T, /) -> T: print(f"Runtime type is {type(obj).__name__!r}", file=sys.stderr) return obj
意見:reveal_type()
は残したくない
typing.reveal_type()
であれば消さなくてもエラーが送出されないことが分かりましたが、私としては削除したほうがいいのではないかと考えます。
実体はprint()
関数で、プログラム実行中には不要な出力な気がします。
printデバッグも解決したら削除すると思いますし、型のprintデバッグの面があるので削除したいかなと思います。
迷ったポイントとして、Pylanceが型を示してくれるのが他の開発者とのコミュニケーションで便利かもと思いました。
しかしながら、以下の点から削除したいと考えています。
- 開発チーム規模によっては全員がVS Code + Pylanceを前提にできないことがある
- コードベースが大きくなったら実行時のprintがじゃまになるのでは
- 他の開発者に型を伝える役目は、コード中のコメントが負った方がよい気がする
終わりに
型ヒントを書き始めたときに知りたかったreveal_type()
でした。
- import不要で
reveal_type()
と書くと、型チェッカが型を表示してくれる - Python 3.11から
typing.reveal_type()
が導入された
typing.reveal_type()
はありますが、本質はprintデバッグだと思うので、デバッグが終わったら削除しましょう!