2007年1月20日土曜日

IPCE r5のsocketモジュール

IronPythonでurllibモジュールのurlopen()関数やurlretrieve()関数が使えないかと考えて、FePyプロジェクトのIPCE r5を色々と調べました。結果と二つのことがわかりました。
  1. IPCE r5は標準では、IronPythonのsocketモジュールを使用している
  2. IPCE r5で、socketモジュールの独自実装が始まっている
というものです。この独自実装のsocket.pyを使うのはどうするのかと、fepyパッケージを調べていて使い方を発見しました。使うためには、以下のような文を使用します。
import fepy
fepy.override_builtin('socket')

早速、urllibをインポートしてurllib.urlopen()関数を呼んでみると、残念ながらエラーになってしまいました。どうも返ってくるはずのファイル風オブジェクトが、正しいオブジェクトを持っていないのが原因のようです。
そこで、色々とハックしてみました。ハックしていくとhttplibが、socketのmakefile()を呼んでいることを見つけ、このmakefileが正しい結果を返さないのが原因でした。これに対処するには、socket.pyのmakefileメソッドの実装を変更する必要があります。
変更前:
stream = NetworkStream(self.socket)
return file(stream, mode)
変更後:
return _fileobject(self, mode, bufsize)
つまり、NetworkStreamオブジェクトをファイルオブジェクトに変換できないというのが原因でした。変更した_fileobjectのインスタンスは、httplibやhttplib2が使用しているsocketモジュールのオブジェクトで、CPythonのドキュメントには記載されていません。このことをFePyプロジェクトでは知っていたから、socketモジュールの独自実装を行っているようです。

この変更が完了したら、IPCE r5からでもIronPython 1.0.1からでもurllibのurlopen()関数やurlretrieve()関数が正常に動作するようになりました。

0 件のコメント: