こちらのツイート解題です
#技書博 で頒布する内容、「ASTを扱えば実装できる(書籍とは別に、ライブラリとしても表現できる)よな」と思い、https://t.co/1drZAcpfXZ
— nikkie / にっきー 技書博 け-04 Python型ヒント本 (@ftnext) 2024年5月11日
アイデア検証は完了(gistのコード)https://t.co/3izj81T8Ez
結論:琴葉ちゃんは、作れる!🙌 https://t.co/TaHgtqGU48
目次
技書博で頒布した『引数の型ヒントをlistにしてはいけません』
公式ドキュメントに「引数の型ヒントをlistにしてはいけません」(※意訳)って書いてあるのですが、どうも浸透していないように見受けられるので、このたび頒布しました。
私は、ドキュメントに沿って書かれたPythonを世界に増やしたいんです!
本エントリはおまけです。
田中琴葉ちゃん
重いことで知られます1
サンライズ立ちで注目の琴葉がどんな子かと言うとゲーム内の重い発言で打線組める子です pic.twitter.com/20HKAc8Gsk
— メイオウ (@kmproject59) 2023年11月19日
ミリシタを遊んでいると「控え室で野球をしてはいけません」という貼り紙が目につきます。
これは琴葉ちゃんによるもの
「引数の型ヒントをlistにしてはいけません」って「控え室で野球をしてはいけません」っぽくないですか?2
ぽいですよね3
書籍で著したのでコードでも著していきましょう
Pythonスクリプト化した琴葉ちゃん「引数の型ヒントをlistにしてはいけません」
Pythonの見た目(構文)って面白いと興味を持った経験4が活きました。
NodeVisitor
を継承して、「引数の型ヒントをlistにしてはいけません」を検出するVisitorを定義しています5。
https://docs.python.org/ja/3/library/ast.html#ast.NodeVisitor
関数定義を見たところ、関数の引数はarg
らしいことが分かります。
https://docs.python.org/ja/3/library/ast.html#ast.FunctionDef
そこで、visit_arg
を定義しました。
https://docs.python.org/ja/3/library/ast.html#ast.arg
arg
is a raw string of the argument name;annotation
is its annotation
ast.arg
のannotation
属性に型ヒントが入っているようなので、そこがlist
(をはじめとする具象コレクション)になっているかを確認しています(なっていたら「いけません」と通知します)。
以下のコードを渡したときに
from collections.abc import Iterable print("Hello, world!") def plus_one_ng(numbers: list[int]) -> list[int]: return [n + 1 for n in numbers] def plus_one_ok(numbers: Iterable[int]) -> list[int]: return [n + 1 for n in numbers]
Fix at 6:16 arg(arg='numbers', annotation=Subscript(value=Name(id='list', ctx=Load()), slice=Name(id='int', ctx=Load()), ctx=Load()))
はああ、「引数の型ヒントをlistにしてはいけません」、できた〜🙌
終わりに
「引数の型ヒントをlistにしてはいけません」を、ASTを操作して実装してみました。
気が向いたら琴葉ちゃんをGitHubやPyPIに置いちゃうかもしれません。
探せばもっとうまい実装がある気もします。
70億人いて私しか考えつかないというはずはないですから。
静的解析をするツールを覗いてみて、機能追加しやすくなるような実装も考えてみたいです。
このあたりにピンとくる方からのタレコミ、お待ちしています!
念のためですが、タイトルから、琴葉ちゃんが退屈なことって主張するつもりはこれっぽっちもないですからね!
O'Reilly Japan - 退屈なことはPythonにやらせよう 第2版