事の発端
pyenv
環境(正確にはpyenv-virtualenv
)でPythonを管理しています。
PyCharm
とかIntelliJ IDEA
とか、JetBrains社のIDEをしばらく使っていたんですが、IntelliJ IDEAの方で独自のPython仮想環境($HOME/pyenv4intelliJ
というディレクトリにインストールされていた)を導入したら、それがpyenv下のpython環境を汚したらしく、起動しなくなりました。
どうやら、Python起動時に読み込むモジュール(を指定するPath)がおかしいゾということのようです。
で、今回は、これを直してちゃんと正常に戻すまでの記事。
内容的には
- エラー内容詳細・原因究明
- Python起動時のモジュール読み込みの話(pyenvの仕組み)
- エラーの直し方(
homebrew.pth
の書き方)
ここらへんです。
基本的にはpythonの話なんだけど、Homebrewとpyenvの知識が少し入ってくる、みたいな。
同じようなエラーメッセージに対するissueを本家PythonやPyCharmのフォーラムでも見かけたので、このエラーで困ってる人も少なからずいるはず…?
ということで、参ります。
エラー内容詳細解明
エラーメッセージその1
まず、PyCharm内のPythonConsole及び、TerminalからPython3を呼び出した時のエラーメッセージを見てみます。
Failed to import the site module
Your PYTHONPATH points to a site-packages dir for Python 2.x bet you are running Python 3.x!
# PyCharmから実行したとき↓
PYTHONPATH is currently: "/Applications/PyCharm.app/Contents/helpers/pydev"
# Terminalから実行したとき↓
PYTHONPATH is currently: "$HOME/.pyenv/versions/3.5.1/bin/python"
You should `unset PYTHONPATH` to fix this.
※なお、Terminal上ではエラーメッセージは出たけど対話型インターフェースは起動する。
エラーメッセージその2
そのうち、なんか色々いじってたらエラーメッセージが次のように変わりました。
$python
Error in sitecustomize; set PYTHONVERBOSE for traceback:
KeyError: 'PYTHONPATH'
Python 3.5.1 (default, May 19 2016, 22:59:42)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> # 一応これで対話型インターフェースが立ち上がる
ちなみに、PYTHONVERBOSE
っていうのは、$python -v
でオプションつけて起動するのと同じらしいです。起動時のtracebackをしてくれます。
調査結果
最初のエラーメッセージを読むと、どうやら、3.xを走らせているのに2.xのsite-packages(モジュール?)を読み込んでるぞ、という警告っぽい。
2番目のエラーメッセージは、sitecustomize.py
でエラーが起きててPYTHONPATH
が変だぞ、ということっぽい。
(結論からいうと、これは同じ原因でした。)
とりあえず、site.pyについて
ではここで、さっきから出てきているsite.py
というモジュールやsitecustomize.py
、site-packages
とはなんなのかについて説明していきます。
(飛ばして読んでもOK)
- Pythonがモジュールをロードするときに見るパスは
sys.path
で設定している - Pythonは起動時に
site.py
を実行することでsys.path
を設定する - オプションっぽい?:プロジェクト毎のローカルなパス設定は
sitecustomize.py
またはusersitecustomize.py
を実行してパスに追加している
このあたりは、下記ページが詳しく説明してくれています。
brew doctor
で原因特定
でも、PYTHONPATH
なんて設定してないし、対話型インターフェースから>>> import site; site.USERSITE
とかを実行して、site.py
の中で設定しているパスを調べても別におかしくない。
ところが……
$ python
>>> import sys
>>> sys.path
>>> sys.path
['', '$HOME/.pyenv/versions/3.5.1/lib/python35.zip',
'$HOME/.pyenv/versions/3.5.1/lib/python3.5',
'$HOME/.pyenv/versions/3.5.1/lib/python3.5/plat-darwin',
'$HOME/.pyenv/versions/3.5.1/lib/python3.5/lib-dynload',
'$HOME/.local/lib/python3.5/site-packages',
'/usr/local/lib/python2.7/site-packages',
'$HOME/.pyenv/versions/3.5.1/lib/python3.5/site-packages']
お?おおお???
なぜかMac system defaultのpython2.xのパスを参照している!
原因はこれだ!!!でもなんで2.xのパスを参照しているんだろう…?
んで、次に何気なく$brew doctor
してみた。
Warning: python is symlinked to python3
This will confuse build scripts and in general lead to subtle breakage.
Warning: "config" scripts exist outside your system or Homebrew directories.
`./configure` scripts often look for *-config scripts to determine if
software packages are installed, and what additional flags to use when
compiling and linking.
Having additional scripts in your path can confuse software installed via
Homebrew if the config script overrides a system or Homebrew provided
script of the same name. We found the following "config" scripts:
$HOME/.pyenv/shims/python-config
$HOME/.pyenv/shims/python3-config
$HOME/.pyenv/shims/python3.5-config
$HOME/.pyenv/shims/python3.5m-config
Error in sitecustomize; set PYTHONVERBOSE for traceback:
KeyError: 'PYTHONPATH'
Warning: Your default Python does not recognize the Homebrew site-packages
directory as a special site-packages directory, which means that .pth
files will not be followed. This means you will not be able to import
some modules after installing them with Homebrew, like wxpython. To fix
this for the current user, you can run:
mkdir -p $HOME/.local/lib/python3.5/site-packages
echo 'import site; site.addsitedir("/usr/local/lib/python2.7/site-packages")' >> $HOME/.local/lib/python3.5/site-packages/homebrew.pth
ちょっと長いですが英文を読んでいくと、
Your default Python does not recognize the Homebrew site-packages directory
as a special site-packages directory, # ... ( 以下略 )
……デフォルトのPython(=pyenv下のpython3.5.1)は、homebrewで作成した(=おそらく$HOME/.pyenv下のディレクトリに作った、の意味)site-packagesを読み込めてないみたいだぜ、ということらしい。
でしょうね。
うん、知ってる。
原因究明のまとめと、直し方
import sys
して調べたパスと、brew doctor
して出てきたpython絡みのwarningとを合わせると、次のことがわかります。
- Pythonが呼び出している
site.py
から設定されているパス → 正常 - homebrewから設定した(
$HOME/.pyenv
下の)パス → 異常
おそらく、homebrewから設定しているパスが2.xのsite-packagesを呼び出しているはずです。
このhomebrew
で見るパスは、$HOME/.local/lib/python3.5/site-packages
の中のhomebrew.pth
というファイルに書かれています。(そしてsite.py
はこのhomebrew.pth
を読み込んでいるんでしょう。たぶん。)
中を開けてみると…
import site; site.addsitedir("/usr/local/lib/python2.7/site-packages")
ビンゴ!!!
やっぱりこれでした!!!!
この中身をコメントアウトするなり、削除するなりしてあげると…
Python復活!!!!
PyCharmも正常に認識して起動するようになりました!!!!
以上、もし同じようなエラーで困っている人がいたら参考にしてください。