プロジェクトごとに独立した Python インストール環境を作れる virtualenv は便利なのだけど、pip でのインストールに対応していないモジュールを使いたいとなるととたんに難しいことになる。Windows では標準で拡張モジュールをビルドできないこともあってインストーラーの配布形式(bdist_wininst)が長い間使われてきたので、古いパッケージだと pip でインストールできる wheel 形式での配布がなされていないものが多い。wxPython とか py2exe とかである。
しかし、一旦インストーラーでシステムの Python にインストールしたうえで、それらを virtualenv 環境のライブラリのディレクトリにリダイレクトしてやれば、virtualenv 環境からでもインポートできるようになる。リダイレクトといっても、ようは site-packages にハードリンクやジャンクションを張るだけだけど。
たとえば wxPython の場合、通常どおりインストーラーで導入してシステムの Python から使ってみると、
C:\Users\mshibata>python Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win 32 Type "help", "copyright", "credits" or "license" for more information. >>> import wx >>> wx.__file__ 'C:\\Python27\\lib\\site-packages\\wx-3.0-msw\\wx\\__init__.pyc' >>>
パッケージが C:\Python27\lib\site-packages\wx-3.0-msw\wx にあるということがわかる。そこで、virtualenv 環境があるディレクトリで、
C:\Users\mshibata\work>virtualenv venv New python executable in venv\Scripts\python.exe Installing setuptools, pip...done. C:\Users\mshibata\work>mklink /j venv\Lib\site-packages\wx C:\Python27\lib\site-packages\wx-3.0-msw\wx venv\Lib\site-packages\wx <<===>> C:\Python27\lib\site-packages\wx-3.0-msw\wx のジャンクションが作成されました
とすれば、
C:\Users\mshibata\work>venv\Scripts\activate.bat (venv) C:\Users\mshibata\work>python Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win 32 Type "help", "copyright", "credits" or "license" for more information. >>> import wx >>>
とこのようにインポートできる。パッケージではなく単体のモジュールの場合は、ジャンクションではなくモジュールの .py ファイルへのハードリンクを張ればよい(けど、そういうのはふつうに virtualenv 環境にインストールできるか)。
py2exe もこの方法で virtualenv 環境で使えるようにすることができる。しかしこれだと py2exe がさらに読みこんでいる別のモジュールまではリダイレクトされていないので、ImportError が発生することがある。その場合は適宜足りてないモジュールへのリンクを張ればよい(いいかげんだ)。
最初だけなので手作業でやってもいいのだけれど、いちいちインポートされてるモジュールのパスを調べてコピペするのは面倒なので、上記の作業をやってくれるスクリプトを作ってみた。
C:\Users\mshibata\work>redirect-package.py venv wx py2exe venv\Lib\site-packages\wx <<===>> C:\Python27\lib\site-packages\wx-3.0-msw\wx のジャンクションが作成されました venv\Lib\site-packages\py2exe <<===>> C:\Python27\lib\site-packages\py2exe のジャンクションが作成されました
と、こんなふうに使う。