code reading to pyftpdlib (with Toky No.1 Soul Set)

3月頃に書いていた記事を今頃Postします。 Tokyo No.1 Soul Setは今はあんまり聴いてません。 最近はART-SCHOOLかな。

ほんとのはじまり

以前書いたとおり asyncoreなftpデーモン実装であるところの pyftpdlib [1] のコードリーディングしてみました。

まずは試しにドキュメント通りに、FTPデーモンを立ち上げてみます。

import os
from pyftpdlib import ftpserver

if __name__ == '__main__':
    authorizer = ftpserver.DummyAuthorizer()
    authorizer.add_anonymous(os.getcwd())
    ftp_handler = ftpserver.FTPHandler
    ftp_handler.authorizer = authorizer
    address = ('', 21)
    ftpd = ftpserver.FTPServer(address, ftp_handler)
    ftpd.serve_forever()
$ python ftp.py         ## ftp localhost とかでアクセスしてみる
Serving FTP on 0.0.0.0:21
[]127.0.0.1:39173 Connected.
127.0.0.1:39173 ==> 220 pyftpdlib 0.5.1 ready.
127.0.0.1:39173 <== USER anonymous
127.0.0.1:39173 ==> 331 Username ok, send password.
127.0.0.1:39173 <== PASS ******
127.0.0.1:39173 ==> 230 Login successful.
[anonymous]@127.0.0.1:39173 User anonymous logged in.
127.0.0.1:39173 <== SYST
127.0.0.1:39173 ==> 215 UNIX Type: L8
127.0.0.1:39173 <== PORT 127,0,0,1,211,37
127.0.0.1:39173 ==> 200 Active data connection established.
127.0.0.1:39173 <== LIST
[anonymous]@127.0.0.1:39173 OK LIST "/". Transfer starting.
127.0.0.1:39173 ==> 125 Data connection already open. Transfer starting.
127.0.0.1:39173 ==> 226 Transfer complete.
127.0.0.1:39173 <== QUIT
127.0.0.1:39173 ==> 221 Goodbye.
[anonymous]@127.0.0.1:39173 Disconnected.

pyftpdlibの中身的なもの

pyftpdlibは比較的素直なモジュールで、モジュール自体は1ファイルしか ありません。(敬意を評して、「ワンファイルモジュール」って呼んだほうが いいね。「ワンライナー」みたいな感じで。) 3KLくらいのファイルなので初級者脱却を目指している人にはちょうどいいのでは ないでしょうか。かく言う私も未だに初級者脱却目指しています。

今回私が参考になったと感じたところは、以下です。

  • callable()
  • pwdモジュール、grpモジュールの存在に気付く
  • __all__ が意味があるのは from pyftpdlib.ftpserver import * のときだけ
  • ftp_CMD は BaseHTTPServer.pyとかのdo_METHOD に似たつくり
  • ベースはasyncore/asynchatなのでその辺のドキュメントかコードは先読み必要

その他(コードリーディングガイド?)

運用例等をまじえつつリリースへの道を確かにしてくれる書籍「 Release It! 」の 読書が3/4くらいまで進んでから、停滞。コード読むほうが今楽しいからなぁ。

コードリーディングのTIPSなどを少し。

私は今現在は、職場の休憩時間を使ってよくコードリーディングをしています。 家に帰ると他の誘惑に負けちゃうので。 休憩時間だとまとまった時間は30分くらいなのですが、 集中して1関数だけ見るとかでも結構読めるものです。 それを少しづつ続けていきます。継続は本当に力になります。 帰って時間があるときは、好きな音楽を聴きながらリーディングに 没頭するのも今のスタイルです。

やり方は人それぞれなので、 みんなで勉強 したり、 ガイドツアー を参考に新たなツアーを組むのもOKだと思います。

コードリーディングの対象は、Python標準ライブラリがおすすめです。 標準のライブラリ豊富なので、初級者から上級者まで幅広くカバーしてくれるはずです。 あとは、流行のソースを読んでみるとか。 Mercurial とか Twisted とか Django とかとか。

まぁ、結論をまとめると好きなソースをどんどん読めと。 すべてを理解する必要は無いし、私自身もそこまで理解力があるわけではないので、 わかるところ+ガンバッたらわかるところしか読めない。 でもせっかく読むのだから、何かプラスになることを ひとつでも得られるのがいいのではないかと。 で、それをどこかに書くと。ヒミツのノートでもいいし、Blogでもいい。 オチ無しでもいい。実装の話でも良いし、ソース内のドキュメントの書き方とかでも。 ライブラリ自体の構成でもいいし。

ツール的なところ

あとは pycallgraph とかが視覚的に流れを追えるので、便利かなと。 pycallgraphを使ったコード例とその出力画像は以下になります。

http://farm4.static.flickr.com/3609/3347271090_3831720ffa.jpg
import os
from pyftpdlib import ftpserver
import pycallgraph

def main():
    authorizer = ftpserver.DummyAuthorizer()
    authorizer.add_anonymous(os.getcwd())
    ftp_handler = ftpserver.FTPHandler
    ftp_handler.authorizer = authorizer
    address = ('', 21)
    ftpd = ftpserver.FTPServer(address, ftp_handler)
    pycallgraph.start_trace()
    ftpd.serve_forever()
    pycallgraph.make_dot_graph('test.png')

if __name__ == '__main__':
    main()

ex.本日のBGM

Tokyo No.1 Soul Set です。はじめは独特なボーカルで とっつきにくかったですが、はまるとヤミツキ、カッコイイです。 [2]

See you Next code reading time!!

footnote

[1]2009/03/10時点での最新バージョン0.5.1を対象にしています。
[2]ちなみに最初の出会いは「OUTSET」。最後の曲が最高。