pipのキャッシュの管理

MySQL 8.4がリリースされて、定番の「mysqlclient をインストールしたんだけど動かない」という報告が来た。これはpipが以前にビルドしたバイナリをキャッシュして再利用しているためで、前のバージョンのlibmysqlclientにリンクしたバイナリなのでバージョンアップしたら当然動かなくなる。

この解決方法と合わせて、pipのキャッシュについて簡単に説明していこうと思う。

pip.pypa.io

2種類のキャッシュ

pipのキャッシュには2種類ある。HTTPレスポンスを保存するHTTPキャッシュと、ソースパッケージをビルドした結果を保存するwheelキャッシュだ。

wheelが提供されていたらHTTPキャッシュのみが使われる。wheelキャッシュはソースパッケージからインストールするときしか使われない。

最近はpure PythonパッケージでもWheelを提供することが増えたのでwheelキャッシュの数は増えにくくなった。

一方でmysqlclientのようにユーザーの環境にあるライブラリとリンクするC拡張を含むパッケージはバイナリを提供できないのでwheelキャッシュが使われるが、最初に紹介したような問題の発生源にもなる。

wheelキャッシュを無効化する方法

pipのキャッシュを無効化する方法として --no-cache-dir が有名だけれども、これは問題のあるwheelキャッシュだけでなくHTTPキャッシュまで無効化するのであまり推奨されていない。バイナリのキャッシュを使わないために公式に推奨されているのは次の方法だ。

python -m pip download sampleproject==1.0.0 --no-binary :all:
python -m pip install sampleproject-1.0.0.tar.gz

It is also a good idea to remove the offending cached wheel using the pip cache command.

Avoiding caching

1つ目の方法は pip download --no-binary :all: してソースパッケージをダウンロードしてから、pip installでそのソースパッケージをインストールする。ローカルのパッケージのインストールではバイナリキャッシュを使わないので問題が起こらない。

2つ目の方法は pip cache コマンドを使って wheel を消すことだ。 mysqlclient の例で言えば、 pip install mysqlclient する前に pip cache remove mysqlclient で mysqlclient の wheel キャッシュを削除してしまう。パッケージ名はglobパターンを使えるので、 pip cache remove '*' (*はシェルによる置換を避けるためにクォートが必要) で全パッケージのwheelを削除してもいい。

pip cache コマンド

pip cache dir, pip cache info

pip cache dir コマンドはキャッシュディレクトリを表示する。この中に http, http-v2, wheels ディレクトリがある。ちなみに http ディレクトリは古いフォーマットのキャッシュなので、古いpipを使ってないのであれば消していい。

pip cache info コマンドを使うともっと詳細な情報を取得できる。httpキャッシュとwheelsキャッシュそれぞれのパスはもちろん、キャッシュの容量や数も表示してくれる。

pip cache list, pip cache remove

list と remove は wheel キャッシュのためのコマンドだ。

list を引数なしで実行したら全てのキャッシュを表示するし、引数に glob パターンを渡すとそれにマッチするキャッシュだけを表示する。

remove コマンドはglobパターンで指定されたキャッシュを削除する。

pip cache purge

httpキャッシュとwheelキャッシュ両方を削除する。

httpキャッシュはwheelキャッシュと違って容量を使う以外のデメリットがないので、容量を気にする時以外は purge よりも pip cache remove '*' の方が良い。

このブログに乗せているコードは引用を除き CC0 1.0 で提供します。