nikkie-ftnextの日記

イベントレポートや読書メモを発信

琴葉ちゃん「引数の型ヒントをlistにしてはいけません」をflake8のプラグインとして実装しました( #imas_hack でflake8-kotoha 0.1.0を開発!)

はじめに

伊藤美来さん、お誕生日おめでとうございます!1 nikkieです

アイマスハッカソン2024成果報告です。
1日ありがとうございました!

目次

琴葉ちゃんを、実装する!

こちらが琴葉ちゃんです。かわいいですね

今回突然思いついたというよりは温めていたアイデアです。

このスクリプト版琴葉ちゃんをflake8のプラグインに転生させました(琴葉ちゃん as flake8 plugin💚)。

後付けですけど、Kaizen Type Hintです!

使い方

pipxの方はこちら

$ pipx install flake8
$ pipx inject flake8 flake8-kotoha
$ flake8

仮想環境を作ってインストールする場合

$ python -m venv .venv --upgrade-deps
$ .venv/bin/python -m pip install flake8-kotoha
$ .venv/bin/flake8

型ヒントに伸びしろのあるPythonコードを渡すと

def plus_one(numbers: list[int]) -> list[int]:
    return [n + 1 for n in numbers]

「引数の型ヒントは具体な型listよりも抽象な型Iterable(またはSequence)がよいですよ」と教えてくれます。

% flake8 example.py
example.py:1:14: KTH101 Type hint with abstract type `collections.abc.Iterable` or `collections.abc.Sequence`, instead of concrete type `list`

「引数の型ヒントをlistにしてはいけません」以外も検出できます。
関数の引数の型ヒントが

  • tuple
  • set
  • dict

の場合も検出します2
抽象構文木操作を頑張りました(この学びは別記事にしたい)

裏話

flake8 plugin開発の参考情報

参考にしたのは以下です。

Writing Plugins for Flake8 — flake8 7.1.0 documentationにあるビデオチュートリアル

(得たノウハウは別の記事にまとめるかも)

同人誌「引数の型ヒントをlistにしてはいけません」のツール版

5月の技書博で同人誌を頒布しました。

公式ドキュメントで裏を取ったうえで、listを引数の型ヒントに使わない書き方を示しています。

from collections.abc import Iterable


def plus_one(numbers: Iterable[int]) -> list[int]:
    return [n + 1 for n in numbers]

これをflake8と連携して検出できるようにしたわけです。

「引数の型ヒントをlistにしてはいけません」、これ琴葉ちゃんの「控え室で野球をしてはいけません」3とかなり近い動きと思われてならないんですよね(琴葉ちゃんスクリプト版の記事も合わせてどうぞ)。
というわけで「もう琴葉ちゃんを実装している」と思い込んで、より効果的と期待されたflake8のplugin版を実装しました4
これで毎日の開発でもずっと一緒だね...

なお、本当はRuffとも連携させたいのですが、Ruffはまだplugin機構をサポートしていないようでした。

(Ruffは追い切れていないので、pluginができることをご存じの方は教えていただけると助かります)

終わりに

アイマスハッカソン2024にて、flake8のpluginとして田中琴葉ちゃんを実装しました。
引数の型ヒントをlistにしてはいけません」(KTH101)

2018年ぶりに参加しましたが、めちゃめちゃ楽しかったです。
1日ありがとうございました & お疲れさまでした〜

復帰のきっかけのミリアニには、本当にもう感謝しかないです。
私、「"(RE)ST@RT"」したんだなあ

P.S. ミリオンライブ!シリーズ

仕掛け人活動が現実世界に展開されています。


  1. 代表的な役の1つが七尾百合子ちゃんです。私、Python界の七尾百合子目指してるんで!(しかし、この記事は田中琴葉をやっているので、外れていっている気もする)
  2. 書いてて気づきましたが、dictはちょっと微妙かもな〜(Iterableにすべきところをdictにすることはほとんどないのでは)
  3. たぶん私だけだと思いますが、リンターっぽいと思ってました
  4. リリースノートならぬこのブログをまずざっと書いて、開発に取り組んでいます。公開にあたっては裏話部分を加筆しました