IronPython と Python 標準ライブラリについての注意
2006.11.7 (鈴)本文書は Python & IronPython 入門 の補足である。
背景
IronPython http://www.codeplex.com/ironpython は Python 標準ライブラリの Python 実装モジュールを前提に作られている。 しかし,IronPython の配布物自身には Python 標準ライブラリは含まれていないから,各自で補う必要がある。
たとえば,IronPython 1.0.1 をインストールしたばかりの素の状態では,乱数発生器モジュール random を利用することはできない。
>>> import random Traceback (most recent call last): File , line 0, in <stdin>##3 File , line 0, in __import__##7 ImportError: No module named random >>>
しかし, IronPython は random モジュールの下請けモジュール _random をもっている。 普通の Python では _random は高速化のため C 言語で実装されているが, IronPython では C# で実装されている。 ソース・ファイルでは下記の _random.cs が該当する。
$ ls IronPython-1.0.1/Src/IronPython/Modules/ Builtin.Generated.cs _weakref.cs datetime.cs nt.cs Builtin.cs binascii.cs errno.cs operator.cs Exceptions.Generated.cs cPickle.cs gc.cs re.cs Exceptions.cs cStringIO.cs imp.cs socket.cs IterTools.cs clr.cs locale.cs struct.cs _random.cs codecs.cs marshal.cs thread.cs _sre.cs collections.cs math.Generated.cs time.cs _weakref.Generated.cs copy_reg.cs math.cs $
したがって,もしも Windows に Cygwin http://www.cygwin.com の python パッケージがインストールされているならば, IronPython-1.0.1/Lib/site.py に
sys.path.append(r'C:\cygwin\lib\python2.4')
を追記して,sys.path に Cygwin の Python 2.4.3 の標準ライブラリのディレクトリを加えることにより, random モジュールを import して,実際に乱数を発生させることができる。
>>> import random >>> random.random() 0.990227685771 >>> random.random() 0.702135360195 >>> random.__file__ 'C:\\cygwin\\lib\\python2.4\\random.py' >>>
ここで Cygwin の Python 実装モジュールが使われていることは, 上記のように random.__file__ 属性で確認できる。
標準ライブラリの random モジュールは http://docs.python.org/lib/module-random.html のように陽に文書化されている一方,_random はその内部実装にすぎず, random の下請けとしてだけ存在する。 標準ライブラリがなければ意味をもたない下請けモジュールをもっていることから, IronPython は標準ライブラリの存在を前提にしていることがわかる。
問題
Python 2.4.3 の標準ライブラリの実装は Python 2.4.3 の仕様を仮定しており, Python 2.5 の標準ライブラリの実装は Python 2.5 の仕様を仮定している。 IronPython 1.0.1 は Python 2.4.3 の仕様に準じている。 今のところ Cygwin の標準パッケージの Python のバージョンも 2.4.3 であり,IronPython はその標準ライブラリを利用できる。 Unix 類である Cygwin は Windows と改行コードが異なっているが, Python と同じく IronPython もまた両者をともに受理するから問題はない。 前節で示したとおり機能する。
一方,www.python.org で一次配布されている,旧版のバグ修正版でない最新のバージョンは Python 2.5 である。性能,機能,安定性 (IDE の日本語パス名への対応等も含めて) いずれの点でも Python 2.5 の使用が望ましいが, IronPython 1.0.1 からその標準ライブラリを使うことには問題がある。 Windows 用 Python 2.5 をインストールして, その標準ライブラリを IronPython から
sys.path.append(r'C:\Python25\Lib')
と参照した場合,os モジュールなどは利用できるが,random モジュールについては下記のようにエラーが発生して import に失敗する。 random モジュールから import される warnings モジュールが, Python 2.5 で新しく導入された ImportWarning を参照しようとするからである。
>>> import random Traceback (most recent call last): File , line 0, in <stdin>##11 File , line 0, in __import__##4 File C:\Python25\Lib\random.py, line 41, in Initialize File , line 0, in __import__##4 File C:\Python25\Lib\warnings.py, line 264, in Initialize NameError: name 'ImportWarning' not defined >>>
random モジュールに依存している tempfile モジュール等も同様に失敗する。
解決策
この問題を解決するにはいくつかの方法がある。
- Cygwin の python パッケージを導入し,その標準ライブラリを利用する。
- Python 2.4.3 ないし Python 2.4.4 を導入し,その標準ライブラリを利用する。
- Python 2.4.3 ないし Python 2.4.4 のソースを展開し, その標準ライブラリのファイルを参照する。
Cygwin の python パッケージは間もなくバージョンアップする可能性がある。 古いバージョンをわざわざ導入することは,いささかナンセンスと言える。 正攻法といえるのは,おそらく 3. の方法である。 (Python 2.4.3 のバグ修正版として 10月 18日に Python 2.4.4 がリリースされた。予期しない非互換性が導入されていない限り, 後者を使うのが妥当であろう)
www.python.org では tgz と tar.bz2 の形式でソースを配布している。 これを展開し,その Lib ディレクトリのパスを sys.path に追加するか, あるいは内容を (site.py を上書きしないように気をつけて) IronPython-1.0.1/Lib 以下にコピーすればよい。
必要なのは Python 実装のモジュールだから,ソースをコンパイルする必要はない。 ソースの改行コードは Unix の '\n' だが, Cygwin の python パッケージを利用する場合と同じく,これも問題ない。 そのまま利用できる。
下記のいずれかを行うとよい。
展開したソースをそのまま参照する例
下記では Cygwin 上でソースを取得し,C ドライブ直下に展開している。
$ wget http://www.python.org/ftp/python/2.4.4/Python-2.4.4.tgz --11:54:53-- http://www.python.org/ftp/python/2.4.4/Python-2.4.4.tgz (...略...) Length: 9,531,474 (9.1M) [application/x-tar] 100%[====================================>] 9,531,474 138.33K/s ETA 00:00 11:56:07 (149.12 KB/s) - `Python-2.4.4.tgz' saved [9531474/9531474] $ cd c: $ tar xf ~/Python-2.4.4.tgz
IronPython-1.0.1/Lib/site.py に下記を書く。
sys.path.append(r'C:\Python-2.4.4\Lib')
もちろん,必ずしも Cygwin を使う必要も,C ドライブ直下に展開する必要もない。 任意のツールを使って任意の場所に展開してよい。 パス名に空白文字や日本語文字を含めてもよい。 ただし,日本語文字を含める場合,site.py の中に日本語文字を書くことになるから, site.py の先頭で下記のようにエンコーディングを指定する (あるいは site.py を BOM 付き UTF-8 にする)。
# -*- coding: shift_jis -*-
ソースの内容を Lib にコピーする例
下記では Cygwin 上でソースを取得・展開し,その Lib 以下の内容を IronPython-1.0.1/Lib に置いている。ただし site.py を除く。 もともとの IronPython-1.0.1/Lib/site.py を上書きしないように注意する。
$ wget http://www.python.org/ftp/python/2.4.4/Python-2.4.4.tgz (...略...) $ cd c: $ cd IronPython-1.0.1/Lib $ ls sie.py $ tar xf ~/Python-2.4.4.tgz $ cd Python-2.4.4/Lib $ rm site.py $ mv * ../.. $ cd ../.. $ rm -rf Python-2.4.4
IronPython-1.0.1/Lib ははじめから sys.path に含まれているから, この場合は site.py での sys.path への追記は必要ない。 ちなみに,この構成方法は jython-2.1 http://www.jython.org と同じである。