MySQL 8.4がリリースされて、定番の「mysqlclient
をインストールしたんだけど動かない」という報告が来た。これはpipが以前にビルドしたバイナリをキャッシュして再利用しているためで、前のバージョンのlibmysqlclientにリンクしたバイナリなのでバージョンアップしたら当然動かなくなる。
この解決方法と合わせて、pipのキャッシュについて簡単に説明していこうと思う。
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.
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 '*'
の方が良い。