はじめに
pip install <パッケージ名> でパッケージのインストールや更新を行う際、以下のように「アンインストールできない」という旨のエラーが表示される。
$ pip install paddlepaddle
Cannot uninstall 'blinker'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
環境
OS: Windows10
Dockerで以下の環境を作成。
Ubuntu: 22.04
Python: 3.7.1
原因
パッケージ依存のライブラリが対象となっていた、もしくはバージョンが古い。原因がどちらか特定することはできなかった。
エラー文の内容としては、「<package>をアンインストールできない。 これは distutils がインストールされているプロジェクトであるため、どのファイルがそれに属するかを正確に判断できず、部分的なアンインストールしかできない」という内容。
なお、pip check
というコマンドでパッケージ間の依存関係を確認できるため、チェックしてみるとよいかもしれない。
解決法 (It works for me)
今回、解決法が2つ見つかったため、どちらも紹介する。
- 強制インストール
パッケージを強制インストールする。-I / --ignore-installed オプションで、依存関係を無視してインストールする。--force-installed オプションとの違いは、前者は既存パッケージは上書きせず、不足分のみをインストール。後者は既存パッケージのものは上書きしてインストール。
ただし、今回は環境構築段階で Docker で順番に動かそうとしたところ、解決しなかった。ターミナルでコマンドを打つと解決したが、これだとコンテナをリビルドする度にこのコマンドとpip install <package>
が必要となるため、別手法を模索。
pip install <package> --ignore-installed
システムコマンドとして実行する(pip の前に ! をつける)と成功するかも?
!pip install <package> --ignore-installed
-
apt remove <package>
でパッケージを削除
重複する不要なパッケージを削除する。このコマンドをエラーが出たpip install <package>
コマンドの前に実行するよう Dockerfile を編集したところ、無事パッケージをインストールすることができた。
(なお、私の場合、パッケージ名は python3-blinker だった。各自
どのパッケージが不要なのかを確認してほしい。)
apt remove -y <package>
pip install <package>
コマンド実行後、pip list | grep <package>
でそのパッケージが削除されているかどうかを確認するとよいだろう。
解決しない場合
解決しない場合は、以下のことを行うと解決する可能性がある。なお、私が直接試したわけではないため、詳細な内容は各自でさらに調査してほしい。
- パッケージのアップグレード
最初のタイミングでインストールした際のパッケージが、時間が経って古くなり、新しく別パッケージをインストールする際にその古いバージョンに対応していない、ということが考えられる。-U、もしくは --upgrade オプションでアップグレードできる。
pip install <package> --upgrade
- pip のバージョンを更新してから再インストール
pip のバージョンを下げる、下げたバージョンの pip でパッケージをアンインストールする、pip のバージョンを上げる、パッケージを再インストールするという流れ。
pip install pip==(version)
pip uninstall <package>
pip install --upgrade pip
pip install <package>
blinker, distutils って結局なんだったの?
私の場合、OCRツールである PaddleOCR をインストールしようとして起こった。
blinker については、どうやらシグナルの送受信を行う、Flask などで使うパッケージだったらしい。Flask を使ったことがないため、どこからインストールしたか皆目見当がつかないこと以外は納得。
distutils については、Python の標準のパッケージ管理ツールだったようだ。どうやら、Python 3.12 で削除されていたらしい。
ということで、blinker というパッケージが distutils で既にインストールされていて、pip でインストールしようとしたから再インストールしようとしたけど、pip では distutils でインストールした blinker を追跡できないよ、ってことだった……のか?