Python.use(better, src=”PyPy”) # はじめの一歩、末の千里
|中級篇|
Python.use(better, src=”PyPy”) # ソースコードの歩き方《中級篇》
ソースコードの歩き方《PyPy1.2》
PyPy1.2 のリリースを機に、PyPy1.1 版を再構成したものです。
※ compiler の傘下にあるモジュールは、PyPy1.1.0 からの変更はありません。
はじめの一歩、末の千里
さあこれから、Python の深層(Inside Python)を探る旅に出掛けましょう。まずは旅支度から…と言いたいところですが、スーツケース一は必要ありません。自由気ままな旅をしたければ、手ぶらが一番です。それでも、ノートパソコンを小脇に抱え、ビューアーを開ければ、それに越したことはありません。Python の実行環境があれば申し分ないのですが、それは旅から戻った後でもかまいません。幸運にも、すでに iPad を手に入れたみなさんは、すぐに開けてみるとよいでしょう。
■ お宝(PyPy)はどこに
公式サイト《PyPy - Welcome to PyPy》から、PyPy1.2 を入手すると、
pypy-1.2-osx + bin - lib-python + 2.5.2 - conftest.py + modified-2.5.2 - win32-failures.txt + pypy
フォルダー lib-python の傘下に、宝物が埋もれているのが分かります。
■ プログラマーの嗜み(compiler)
まず、プログラマーの嗜みとして「コンパイラー」の中身から覗いてみます。
$ cd ../pypy-1.2-osx/lib-python/2.5.2 $ ls -l compiler/ total 408 -rw-r--r--@ 1 sketch staff 878 3 9 21:47 __init__.py -rw-r--r--@ 1 sketch staff 35526 3 9 21:47 ast.py -rw-r--r--@ 1 sketch staff 401 3 9 21:47 consts.py -rw-r--r--@ 1 sketch staff 1839 3 9 21:47 future.py -rw-r--r--@ 1 sketch staff 1806 3 9 21:47 misc.py -rw-r--r--@ 1 sketch staff 26163 3 9 21:47 pyassem.py -rw-r--r--@ 1 sketch staff 47208 3 9 21:47 pycodegen.py -rw-r--r--@ 1 sketch staff 14538 3 9 21:47 symbols.py -rw-r--r--@ 1 sketch staff 1444 3 9 21:47 syntax.py -rw-r--r--@ 1 sketch staff 51386 3 9 21:47 transformer.py -rw-r--r--@ 1 sketch staff 3902 3 9 21:47 visitor.py
《NOTE》パッケージ compiler:幸運(?)にも、compiler の傘下にあるモジュールは、PyPy1.1.0 と同じで、PyPy1.2 では変更されていませんでした。□
文字列 "__main__" を頼りに、それを含むモジュールを探ると、
$ cat compiler/pycodegen.py
...
if __name__ == "__main__":
for file in sys.argv[1:]:
compileFile(file)
はじめの一歩は、モジュール pycodegen.py にするのが良さそうです。そこでは、関数呼び出し compileFile が見つかります。
■ はじめに光(__init__.py)ありき
次に、関数 compileFile を頼りに、それを含むモジュール __init__.py の冒頭にあるコメントを見ると、Python のソースコードを構文解析(parsing)して、バイトコードに変換(compiling)するには、次のような
$ cat compiler/__init__.py ... """Package for parsing and compiling Python source code ... parse(buf, mode="exec") -> AST Converts a string containing Python source code to an abstract syntax tree (AST). The AST is defined in compiler.ast. parseFile(path) -> AST The same as parse(open(path)) walk(ast, visitor, verbose=None) Does a pre-order walk over the ast using the visitor instance. See compiler.visitor for details. compile(source, filename, mode, flags=None, dont_inherit=None) Returns a code object. A replacement for the builtin compile() function. compileFile(filename) Generates a .pyc file by compiling filename. """
5つの関数が重要だと分かります。
関数 compileFile は、ファイル filename をコンパイルして、バイトコードを含む .pyc ファイルを生成するとあります。また、関数 compile が、コードオブジェクトを返すことから、次の一歩はこれに決めました。道すがら、脇道に逸れるのも一興です。