Sphinx-2.4 で進化した型機能を使おう

先ほど Sphinx-2.4.0 をリリースしました。
Sphinx は 2ヶ月ごとの定期リリースを目指しているので、大体予定通りのリリースです。

2.4.0 では autodoc まわりの機能が大きく改善されました。この記事ではその改善点についてまとめたいと思います。

## 変数アノテーションへの対応

>* autodoc: Support type annotations for variables
>* #7051: autodoc: Support instance variables without defaults (PEP-526)

これまで、コード内の変数アノテーションはドキュメント化されていなかったのですが、2.4 からはドキュメントに出力されるようになりました。
いまや型情報は規模の大きいプログラムを書くのに欠かせない情報となっています。型情報をアノテーションすることは、あなたと開発チームだけではなく、ライブラリを利用する人の助けになるでしょう。

また、[PEP-526](https://www.python.org/dev/peps/pep-0526/)の初期値なしの型宣言にも対応しました。次のような定義をしたときに、 `Starship.captain` や `Starship.damage` は型アノテーション付きのインスタンス変数としてドキュメント化されます。

```
class Starship:
    captain: str
    damage: int
```

この変更によって、Python3.7 から導入された dataclasses もドキュメント化できるようになりました。

## type comment 形式の型アノテーションに対応しました

>* #2755: autodoc: Support type_comment style (ex. ``# type: (str) -> str``)
>  annotation (python3.8+ or `typed_ast <https://github.com/python/typed_ast>`_
>  is required)

古くから使われていた type comment 形式(例: `# type: (str) -> str`)の型アノテーションをサポートしました。長くメンテナンスされているプロジェクトでは、この機能が役に立つはずです。

なお、Python3.7 以前をご利用の場合は typed_ast をインストールしてください。

## 型ドキュメントを本文に表示させる機能が先行導入されました

>* #6418: autodoc: Add a new extension ``sphinx.ext.autodoc.typehints``. It shows
>  typehints as object description if ``autodoc_typehints = "description"`` set.
>  This is an experimental extension and it will be integrated into autodoc core
>  in Sphinx-3.0

3.0 以降で正式採用する機能のチラ見せとして `sphinx.ext.autodoc.typehints` という拡張を追加しました。
この拡張をロードすると `autodoc_typehints` という設定に `"description"` を指定できるようになります。

`autodoc_typehints` は関数やメソッドをドキュメント化するときに、型情報をどのように表示するのかを調整するものです。

今回の改修を理解するためにも、オリジナルの機能も含めてご紹介したいと思います。

`autodoc_typehints` には(新しい設定を含めて) 3つのモードがあります。次の関数のドキュメントを例に、それぞれのモードの変換結果を見てみましょう。

```
def hello(name: str, age: int) -> str:
    """Hello world!

    :param name: Your name
    :param age: Your age
    :returns: greeting message
    """
```

### signature モード

デフォルトの設定(`autodoc_typehints = "signature"`)では、関数ドキュメントの定義欄にそのまま型アノテーションが表示されます。
![スクリーンショット 2020-02-09 17.08.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57661/743eb349-0cdb-10d0-0933-369206d1767e.png)

シンプルな関数であれば、この状態で十分読みやすいのすが、引数が多い関数やメソッドではとても読みづらい表示となってしまいます。例えば、tornado プロジェクトでは[次のようなドキュメントが生成されてしまっています](https://www.tornadoweb.org/en/latest/httpclient.html#tornado.httpclient.HTTPRequest)。
![50543599-ce009000-0baa-11e9-991c-db1bb6fb846a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57661/ae50daa5-ba08-b8c1-252e-030420776cc3.png)

### none モード

もうひとつの設定(`autodoc_typehints = "none"`)は、関数ドキュメントの定義欄から型アノテーションを削除します。
![スクリーンショット 2020-02-09 17.13.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57661/bb6bf75b-42dd-a674-21ab-465728ea5f54.png)

随分スッキリしましたね。このオプションは、関数コメント(docstring)に自分で引数の説明を書く場合に役立ちます。プログラム中とコメント内の二箇所に型情報を書く必要が出てくるため冗長にはなりますが、読みやすいドキュメントを書くことができます。

Google 形式や Numpy 形式では、型アノテーションを関数コメントに記載する文化があるため、このオプションにマッチしていると言えます。

### description モード (新規追加)

そして、今回追加された設定(`autodoc_typehints = "description"`)は、関数ドキュメントの本文部分に型アノテーション情報を表示します。
![スクリーンショット 2020-02-09 17.18.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57661/657588ca-d6b3-63fa-d44b-007c0f88e5e2.png)

どの形式が読みやすいかは書いているプログラムの規模によっても差があると思いますが、個人的には今回追加された設定は読みやすさが上がると感じています。
experimental としていますが、特に深刻なバグなどが見つからなければ 3.0 で正式採用されます。
実際に試してもらい、おかしい所があればバグ報告してもらえるとありがたいです。

※ 新しい設定はいまのところ `sphinx.ext.autodoc.typehints` 拡張をロードしたときのみ有効となるのでご注意を。

## まとめ

* Sphinx-2.4.0 をリリースしました
* autodoc まわりの改善がんばりました
* `sphinx.ext.autodoc.typehints` が追加されました。フィードバック絶賛お待ちしております
* 他にもいろいろ機能追加したりバグ潰したりしたよ。
  詳しくは[CHANGES](https://github.com/sphinx-doc/sphinx/blob/v2.4.0/CHANGES) 見てね