開拓馬の厩

いろいろやる

Pythonを改造してみた はじめに

Pythonは実行時にソースコードから機械語を生成するインタプリタ型言語の一種です。この記事ではPythonがコードを実行する際に、内部でどのような処理を行っているのかを調査した結果を紹介します。

しかし、ただソースコードやドキュメントを読むだけでは面白くありません。また、Pythonオープンソースで誰でも自由にソースコードをいじることができます。なので「Pythonを改造して新しい予約語を追加する」という方法でインタプリタの仕組を追ってみることにしました。

このページではソースコードをダウンロードしてビルドする所までの様子をお伝えします。 実際に改造を行った部分の説明は以下の記事からご覧いただけます。

これらの記事は大規模ソフトウェアを手探るという大学の講義のレポートを兼ねています。

また、ソースコードをいじる作業やブログ記事の作成はブログ主(id:pf_siedler)ともう一名の学生の二人組で行いました。

環境

ビルド

Pythonの公式サイトからソースコード(tarball形式)をダウンロードして適当なディレクトリに展開します。 ターミナルでソースコードを展開したディレクトリに移動しconfigureを叩きます。ここで、デバッグを行いやすいように、CFLAGS-g -O0オプションを与えます((-gデバッグシンボルを付けるオプション。これを付けないとデバッガを使うことができない。-O0は最適化を行わないオプション。デバッグ時にソースコードがそのままの状態で読める。))。また、--prefixオプションでインストール先のディレクトリをホーム直下のmypythonディレクトリに指定します。

その後、makemake installを行いインストールを行いました。makeには-jオプションで複数のプロセッサを割り当て高速化しました。

% tar zxvf Python3.5.2

% cd Python3.5.2

% CFLAGS="-g -O0" ./configure --prefix=/home/(username)/mypython/

% make -j8

% make install

ビルドは問題なく完了しました。~/mypython/bin/python3を実行することでPythonを起動できます。

% ~/mypython/bin/python3
Python 3.5.2 (<<>>)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

ドキュメントを読む

とりあえずビルドはできましたが、どこから手をつければいいかわかりません。そこでネットの記事を漁って情報を仕入れることにしました。 すると、昨年度の「大規模ソフトウェア」受講者にPythonを改造した方がいたので記事を読んでみると、Changing CPython’s Grammarなるガイドラインが紹介されていました。
この講義は「同じことをしようとしている誰かの役に立つため」に最終レポートをブログ形式で一般公開することを要求されているのですが、早速後輩の役に立つとは……

ガイドによると新しい予約語を追加する場合、おおよそ以下のような変更を加えればよいそうです。

  1. Grammar/Grammarをいじる(文法をの規定)
  2. Parser/Python.asdlをいじる(構文解析部分の自動生成に使うらしい?)
  3. Python/ast.cをいじる(AST生成)
  4. Python/symtable.c(をいじるASTに意味付けを行いコンパイラに渡す)
  5. Python/compile.cをいじる(コードに従ってバイトコードを生成)

後ろ3つはC言語のコードですが、GrammarPython.asdlは独特な記法で書かれていて大きな変更しづらそうです。また、C言語のファイル3つもマクロを使用して関数を呼び出しているので、既存のコードから大幅に外れた変更は難しそうです。

なので 既存の構文とほとんど同じ動きをする構文を追加する

慣れたら少し変わったことをする
という順序で開発を行っていくことにしました。

参考資料

Python公式ページ
Developer's Guideの23. Changing CPython’s Grammarに文法を変更する手順が記載されています。

大規模ソフトウェアを手探る
この記事を書くきっかけとなった大学の講義ページです。

CPythonに後置インクリメントを加えてみた
昨年度の大規模ソフトウェアを手探る受講者の方が書いたページです。Pythonのディベロッパーズガイドはこの記事を読んで知りました。

Python internals: adding a new statement to Python
「Pythonにuntil文を追加してみた」という内容の記事です。とても参考になりました。

dis/inspect モジュールを使った Python のハッキング
disassembleモジュール等を使ってPythonの言語仕様を解析する内容の記事です