M12i.

学術書・マンガ・アニメ・映画の消費活動とプログラミングについて

Python初心者、モジュール検索パスではまる

Pyramidフレームワークをためしてみよう、ということで、以下の手順で作業したらはまった(作業環境はMac OS X MervericksでデフォルトのPythonインタープリタのバージョンは2.7)。

  1. リファレンスにしたがい、パッケージ管理ツールpipをインストール(sudo python .../get-pip.py)。
  2. pipを使ってPyramidをインストール(sudo pip install pyramid)。
  3. リファレンスにしたがい、PyramidでHello World

pipのインストール自体は何事もなく完了した。Pyramidのインストールも同様。
問題はPyramidでHello Worldアプリを作成するところ。

起動すると、下記のように「zope.interfaceなんてモジュールは見つからない」と怒られた:

Traceback (most recent call last):
File "/Users/.../hello.py", line 7, in
from pyramid.config import Configurator
File "/Library/Python/2.7/site-packages/pyramid/config/__init__.py", line 11, in
from pyramid.interfaces import (
File "/Library/Python/2.7/site-packages/pyramid/interfaces.py", line 3, in
from zope.interface import (
ImportError: No module named interface

それではとpipでzope.interfaceをインストールしようとすると「もうあるよ」と言われる:

$ sudo pip install zope.interface
Password:
Requirement already satisfied (use --upgrade to upgrade): zope.interface in /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python
Requirement already satisfied (use --upgrade to upgrade): setuptools in /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python (from zope.interface)
Cleaning up...

そこで今度はsys.pathを調べてみると以下のようになっていた:

  1. (エントリーポイントのスクリプトが格納されたディレクトリ)
  2. '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7'
  3. '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin'
  4. '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac'
  5. '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages'
  6. '/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python'
  7. '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk'
  8. '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload'
  9. '/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC'
  10. '/Library/Python/2.7/site-packages'
  11. '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python27.zip'
  12. '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-old'

「ふーむ、pathに格納された検索パス通りなら "/System/Library/Frameworks/ Python.framework/Versions/2.7/Extras/lib/ python/zope/interface" がヒットしそうなものなのだけど」と考えていたのだが・・・。

実際には "/Library/Python/2.7/site-packages" の配下のzopeパッケージが先に探知されてしまい、ここを起点としてサブ・パッケージが検索されるため、"/System/Library/Frameworks/..." 側のzopeの配下のinterfaceが検索されないかたちになっている。

原因は結局のところよくわからなかった。気になるところと言ったらやはりsiteモジュールの仕様でありこれが "/System/Library/Frameworks/..." 側のzopeを隠蔽してしまっている感じである。

ともかく以下のようにして "/System/Library/Frameworks/..." の側へとシンボリック・リンクを設定してやって解決してしまった:

ln -s /Library/Python/2.7/site-packages/zope/interface 
/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/zope/interface

なんとも納得のいかない結果である・・・。

[2014/09/08追記]この件の教訓としては(それが可能なら)ライブラリの管理場所は一元的であるべしということだろう。ちなみに、MarvericksではPythin2.7が標準なので、Python3.x系が必要な場合はMacPorts等を使用して各ユーザがインストールすることになるわけだが、こちらの場合結果的にライブラリ格納ディレクトリに統一がとれ、この記事で取り上げた問題は起こらなかった。