LoginSignup
12
10

More than 5 years have passed since last update.

Homebrew で pip が DistributionError を出す場合の対処

Last updated at Posted at 2014-06-06

現象

pip コマンドを実行すると、 pkg_resources.DistributionNotFound: pip==1.5.4 のようなエラーが表示されて何もできない。

再現手順

  1. Homebrew で Python をインストールする
  2. 新しい pip がある状態で pip install --upgrade pip する

brew install python すると、

==> Caveats
Setuptools and Pip have been installed. To update them
  pip install --upgrade setuptools
  pip install --upgrade pip

のように表示されるのですが、この通りに pip をアップグレードすると pip が動かなくなります。
pip がアップグレードされたのに /usr/local/bin/pip が古いままになっている状態です。

対処

python -m pip で pip を起動できます。 /usr/local/bin/pip を削除して

$ rm /usr/local/bin/pip /usr/local/bin/pip2 /usr/local/bin/pip2.7
$ python -m pip install --upgrade --force-reinstall pip

もしくは

$ python -m pip install --upgrade --force-reinstall pip --no-use-wheel

をします。
後者の方法を利用する場合は、今後 pip や setuptools を upgrade する際は常に

$ pip install --upgrade --no-use-wheel pip setuptools

する必要があります。

原因

Homebrew と wheel の相性問題です。

Homebrew は Python をインストールする際に、 pip と setuptools を

/usr/local/Cellar/python/<version>/

配下にインストールし、 /usr/local/bin/ に pip コマンドなどへの symlink を設置します。

そして、 distutils.cfgprefix=/usr/local という設定を書き、通常 pip install などでインストールされるパッケージが /usr/local/bin/ 配下にスクリプトが、 /usr/local/lib/pytthon2.7/ 配下にライブラリがインストールされるようにします。

この状態で pip install --upgrade pip すると、 /usr/local/bin/pip スクリプトをインストールしたいのですが、そこにはすでに Homebrew が勝手に作った pip が感知しない symlink が存在します。

スクリプトをインストールしたい場所にすでに symlink があったときの振る舞いですが、 wheel からのインストールと tar.gz からのインストールで違っていて、 wheel の場合はインストールできずにスキップされ、 tar.gz からの場合は symlink のリンク先 (つまり Cellar の中身) を書き換えてしまいます。

最近の pip はデフォルトで wheel があるとそれを使うので、 Cellar 配下の古いバージョンの pip を使おうとするスクリプトに対する symlink がそのまま残ってしまい、起動できなくなってしまうのです。

wheel を使う場合と使わない場合で振る舞いが違うのは良くないとは思いますが、そもそも外部で勝手に作られた symlink に上書きインストールする場合の挙動に正解なんて無いので、 Homebrew は pip install --upgrade pip を許すなら最初から普通に pip をインストールするべきだと思います。

追記

pip と setuptools を Cellar 内にインストールするのをやめるように修正する Pull request を出しました。 https://github.com/Homebrew/homebrew/pull/29926

追記2

上記の PR は Homebrew の基本方針とあわないので却下されました。
そこで、 wheel を使ったインストール時にも wheel を使わない場合と同じように、スクリプトのインストール先にすでにシンボリックリンクが合っても(リンク先を)上書きするようにする修正を pip 側に PR し、先ほど取り込まれました。

次の pip (1.6.0) がリリースされて、 Homebrew の Python にバンドルされるようになったら、その次のバージョンからは普通に pip install --upgrade pip でアップグレードできるようになるはずです。

とは言え、 Celler の中と外で2つの pip があり、外にインストールするときに中のスクリプトを書き換えるという、到底スマートとは言えない状態です。
特に困ってるのでなければ、 pip のアップグレードは行わず、 Homebrew がアップデートされるのを待つことをお勧めします。

また、 Python のヘビーな開発者は、独自の方式のために無理やりなことをしている Homebrew よりも MacPorts や、 pyenv を使った自前ビルドの方がいいかもしれません。
pip install --upgrade pip は直りましたが、 pip install --user ipython とかは動かないままですし、パッケージング周りで他にどんな副作用があるかも解りません。

12
10
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
10