meta前回の記事の続き前回の記事で、以下のようなことを言っていた。わかりやすさを考えると、「どのクラスのどのメソッドの中のどの箇所か?」という形で表現したい(今回の場合は「WebSocketEndpointのdecode()メソッドのjson.loads()部分」という形)。しても誰かに伝えたい場合や説明したい場合、丁寧に言及したい場合には、丁寧に整形するのだけれど、元々が備忘録という関係上なるべくコストを抑えたい。有り体に言えば整形のコストを払いたくない。これをどうにかしたいねという話。具体的には、こういうリンクをこういう感じで出力したい。received.")これは手動で整形したものだけれど。これを良い感じにそれこそgithubでpemalinkを生成するのと同じ程度のコストでできたりしないものかという試行錯誤。やったら良い感じに出力できそうか考えてみる雰囲気でほしい情報を列挙とりあえずコードを書く前にどういう表現で出力したかったのかを雑に考えてみる。手動での整形が面倒ということなので自動で整形された形で出力されて欲しいということだった。頭の中で思い描いていたのは以下のような事柄。ような)大雑把な方針を考える次にどうやって実装するかを雑に考えてみる。ある特定のライブラリのある特定の箇所と言っているけれど、引数として渡すのは何かということを考えてみると、これは昨日の記事でも言及していたような気がする。エディタから利用する場合には物理的な行番号を指定して利用することができたら便利なんじゃないかとふわっと思っていたりしている(エディタは物理行の指定、CLIでは何らかのパスのような形で指定がやりやすそう)まぁそうかな。少なくとも引用対象のコードが手元にあること前提になってはしまうけれど。エディタから指定できるというのが嬉しい形かもしれない。starllette.endpoints:WebSocketEndpoint)できるけれどその特定の箇所をとなるとむずかしい。物理的行番号で指定するのが無難。以下の様な感じになりそう。Tree)を取り出すAST上の指定した行に対応するnodeを見つける対応するnodeの親要素になりそうなnodeを集めるそして取り出したASTの情報を元にテキトウにコードを出力すれば良さそう。実際に色々やってみる実際に色々やってみる。lib2to3でASTを取り出してあれこれする方法は色々ある。標準ライブラリのastを使う方法(これは本当にASTなので情報に欠損が出がち)。familyを使う方法(redbaronとbaron。Tree)なのでコードの情報は全部取れる)。コードの補完などでお世話になるjediで使われているパーサーを使ってみてもよいかもしれない(parsoというパーサーを自分で書いて使っている)。今回は標準ライブラリの範囲でやりたいという気持ちがあるのでlib2to3を使ってみようと思う。これは元々はpython2.xからpython3.xへの変換を担うツールを提供するためのライブラリなのだけれど、それなりにpythonのコードをtreeに変換してのあれこれを行える。その辺りについては昔記事を書いたりした。pythonのastモジュールに不満がでたらlib2to3のコードを使ってみよう行番号に対応するnodeを取り出すとりあえず行番号に対応したnodeを取り出そうとしてみる。今回はまだ試行錯誤の段階なので横着をして過去に自分が作ったpycommentの持つモジュール(pycomment.parse)を拝借して使うことにする。これはlib2to3の薄いwrapper。以下の様なテキトーなコード片を用意しておく。このコード片をしばらくは実行結果の確認に使うことにする。f"[{x}]"visitorをてきとうに実装して呼んであげる。lineno=4)まぁ何か取れていそう(実装はこちら)。'\n')])性能を考えるなら行に対応するnodeの選択にひと手間加えると良さそうだけれど。get_lineno()で指定した行番号と一致したnodeが見つかれば良しと言うことにする。取得したnodeの親的なnodeたちを集める次は取得したnodeの親的なnodeを集めたい。親的なnodeってなんだろう?と考えて見るとまぁ以下があれば良さそうなきがする。関数定義のdef部分の行クラス定義のclass部分の行それらを集めたい。テキトウに調べたりするとclassdefとfuncdefが定義に対応するnodeということが分かる。これはこういう感じのコードを書いてあげると調べられる。specification)からあたりをつけても良い。何はともあれ、親階層も含めたnodeを集めてこれる。対応する行のコードを取ってくるのにはlinecacheモジュールを使うと便利。"[]"テキトウに良い感じに整形して出力するあとはテキトウに良い感じに整形して出力すると良い。この整形の部分はもうちょっと調整が必要そう。