もっと知りたいPython3000

第4回Python 2.xから3.0への移行方法

2008年中に正式リリースが予定されているPython 3.0ですが、それに先だって2.x系の最新版であるPython 2.6のリリースが計画されています。2.6には、除算機能の変更や as を使った例外の表記方法など、3.0に搭載される一部の機能が追加される予定です。また、3.0非互換のコードに対する「警告モード」が搭載されます。

まず2.6からはじめよう

Python 2.6はPython 3.0への橋渡し役となる、とても重要なリリースと位置づけられています。既存のPythonユーザはまず2.6を使うことで、ある程度Python 3.0に備えることができます。3.0で予定されている後方互換性を崩す仕様変更の「緩衝材」として、2.6が用意されているわけです。

Pythonには、言語のコアとなる実行バイナリの他に、膨大な標準ライブラリが搭載されています。標準ライブラリの多くはPythonで書かれています。Python 3.0で動かすために、標準ライブラリを3.0対応のコードに書き換える必要があります。3.0と並行して開発が進む2.6では、標準ライブラリの3.0対応が進められるのではないかと見ています。

移行の最適なタイミング

かつては使い捨てのツールを作るための道具だったスクリプト言語も、今日ではWeb開発をはじめ、よりライフスパンの長い開発で活用されています。高度な開発では、プロジェクトが言語や組み込みのモジュールだけに依存するということはほとんどないはずです。プログラミング言語の移行の問題は、言語だけの問題ではないわけです。

フレームワークを使っている方であれば、フレームワークが新しいPythonのバージョンに対応するまで、ひと世代前のバージョンを使い続ける、といった経験があるはずです。それと同じ意味で、開発に関わるすべてのモジュールやフレームワークが3.0に対応するまで、みなさんが本格的にPython 3.0を使う機会は訪れないかも知れません。GuidoがPEP 3000「Python 3000が広まるには、3.1や3.2のリリースを待つことになるかも知れない」と書いているのには、そういう意図が背後にあるのではないでしょうか。

標準モジュールの移植で蓄積された移行のノウハウが徐々に広がり、主要なモジュールやフレームワークがPytohn 3.0に対応してはじめて、多くの方がPython 3.0を使うようになるはずです。Guidoが10年ほど前に思い描いた「真にPythonicなPython」の世界が現実のものとなるためには、あと数年かかるのかも知れません。その数年の間は、3.x系の開発と平行して、2.x系の開発とリリースが続けられることが予告されています。

3.0に備えるための方法

とはいえ、変化は必ず訪れます。今から3.0に備えておけば、よりPythonicなPythonの世界に素早く移行できるはずです。

インデントでブロックを表記するなど、Pythonには「開発スタイル」を強要するためにあるような類の機能や文法が多く見受けられます。3.0の変更点のうちいくつかは、より良い開発スタイルを推奨するための変更です。

開発のスタイルを3.0で推奨されているスタイルに変更することで、そのような変更点には対応が可能です。⁠外部からのテキストは生成時にエンコードを指定してUnicode文字列にする」⁠map()のような関数の返り値がリストであることを期待しない」といった点が代表例でしょうか。また、除算機能の変更、例外で利用するキーワード as などPython 3.0の機能の一部は2.6に搭載される予定です。2.6を使うことで、言語コアに近い変更の一部に対応できます。

将来的に3.0で動かす可能性のあるコードには、かならずユニットテストを書くべきです。ユニットテストを書いておけば、3.0に移行するときに万が一非互換性が発生した場合にも、問題点を把握しやすくなります。

コードコンバータ

Python 3.0で行われる変更のうち、一部は2.xの段階でも対応可能であるとはいえ、すべての機能に対応することは不可能です。たとえば、Python 3.0では「u"~"」 というUnicode文字列のリテラルは利用できません。Unicodeリテラルを含むコードはエラーになってしまいます。

Python 3.0のαリリースには、 ⁠2to3」と呼ばれるコードコンバータが付属しています。2.xから3.0対応のコードにコンパートするツールの開発途上版で、Python 3.0に搭載される予定です。このコンバータを使うと、2.xのコードをある程度3.0対応のコードに変換することができます。

このコードコンバータは、正規表現などを使った文字列置換のような単純な作りにはなっていません。Pythonのバイトコードコンパイラから得たAST木を使った構文解析を行い、3.0対応コードの変換を行っています。

現状のコンバータの対応範囲を一言で言うと、「バイトコードレベルで判別できる範囲」となります。⁠u"~"」のようなリテラルは「"~"」に、⁠print "~"」「print("~")」のような関数呼び出しに変換されます。削除されたhas_key()メソッドを迂回したり、例外回りの文法の変更を吸収する、というような比較的高度な変換も行ってくれます。

逆に、バイトコードレベルで判別できない類の非互換性は、このコンバータでは吸収できません。たとえば、Pythonではコードを短く書くために以下のようなコードを書くことがあります。

k = some_dic.has_key
if k('some_key'):
    ....

このように、一度変数に代入したメソッドを呼び出すようなコードは、バイトコードレベルでは非互換性がわからず、実行時にならないと判別できません。また、setattr()、getattr()などを使ったコードも、同様にコンバータの守備範囲外となります。

PythonによるPython実装PyPyの持つ機能を活用すれば、動的なコードも含めてより広い範囲のコードを3.0対応にコンバートできるようになるかも知れません。PyCon 2007でPythonのコア開発チームの一員であるJeremy Hyltonこのコンバータに関する講演を行っています。このとき、PyPyの開発チームから、動的なコードを3.0対応に変換するための方法について提案を受けていたようです。

3.0に付属のコンバータにPyPyの機能が取り込まれるか、またはPyPy派生の独立したコンバータがリリースされるか、2つの可能性があるように思います。より守備範囲の広いコンバータがリリースされれば、Python 3.x系への移行がよりスムーズに進むようになることは間違いないでしょう。


Pythonはこれまで、表面的にはゆっくりと、しかし着実に進化を続けてきました。急速な変化を嫌う体質の背後には、Pythonを利用する開発者への配慮があったはずです。

後方互換性を崩す3.0への移行方法についても、緻密といえるほどの配慮が見て取れます。⁠作りっぱなし」ではない、開発者に対して真摯なアティチュードが、Pythonの魅力のひとつと言えると思います。

Pythonの次期バージョンであるPython 3000についてお伝えする連載も今回で最後となります。数ヶ月後に予定されているβリリース、そして2008年末に予定されている正式リリースを楽しみに待ちつつ、筆を置きたいと思います。

おすすめ記事

記事・ニュース一覧