・今まで使えていたpillow,PILが使えなくなる
以下のようにエラーが出る。
ライブラリはインストールできていて、特にPIL,Pillowを使ったプログラムは今まで動いていたのに動作しなくなった。
Traceback (most recent call last):
File "/Users/user/Dropbox/python/source_code/fileope.py", line 5, in <module>
from PIL import Image
File "/Users/user/Library/Python/3.10/lib/python/site-packages/PIL/Image.py", line 82, in <module>
from . import _imaging as core
ImportError: cannot import name '_imaging' from 'PIL' (/Users/user/Library/Python/3.10/lib/python/site-packages/PIL/__init__.py)
chatGPTに聞くと、アンインストールして再度インストールせよという回答でした。
しかしアンインストールしようとして、以下のコマンドを入力しても、やはり動きませんでした。
・ライブラリの削除
rm -rf /Users/user/Library/Python/3.10/lib/python/site-packages/PIL
rm -rf /Users/user/Library/Python/3.10/lib/python/site-packages/Pillow*
・再インストール
pip3 install --upgrade Pillow -t /Users/user/Library/Python/3.10/lib/python/site-packages
pip3 install --upgrade PIL -t /Users/user/Library/Python/3.10/lib/python/site-packages
この途中でもどこにインストールされているか間違って認識していました。
print(PIL.__file__)
で確認すると、以下になっています。
/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/PIL/__init__.py
デフォルトのインストール先はpython3.11であり、今使っているのはpython3.10.8です。
以下のアンインストールのコマンドではディレクトリの指定ができませんでした。
pip3 uninstall
そこで、python3.11を削除することにしました。
pyenvのコマンドで以下のように表示されます。
$ pyenv versions
system
3.10.7
* 3.10.8 (set by /Users/user/.python-version)
3.11-dev
3.11.0rc2
こちらのコマンドでアンインストールします。
pyenv uninstall 3.11-dev
pyenv uninstall 3.11.0rc2
pyenv global system
しかし、以下のようにライブラリのインストール先がpython3.10のディレクトリになっているのに、
$ python3
Python 3.10.8 (v3.10.8:aaaf517424, Oct 11 2022, 10:14:40) [Clang 13.0.0 (clang-1300.0.29.30)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sysconfig
>>> print(sysconfig.get_path("purelib"))
/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages
>>> quit
以下のコマンドで、Pillowがpython3.11のディレクトリにインストールされてしまいます。
pip3 install Pillow
/usr/local/lib/python3.11/site-packages
pip3に関連付けられているpythonが3.11なので、ライブラリのインストール先デフォルトディレクトリが3.11になっているらしいです。
以下のコマンドでpip3がpython3.11に関連づけられていることがわかります。
$ pip3 --version
pip 23.2.1 from /usr/local/lib/python3.11/site-packages/pip (python 3.11)
これをpython3.10に変更します。
pyenvを3.10に変更すればpip3のデフォルトインストール先も変わります。
ただ、グローバルの設定はすでにできています。
pyenv global 3.10.8
グローバルよりローカルのほうが優先されるので、ローカルの設定をします。
以下のコマンドでpythonのバージョンを変更しようとしたが以下のエラーが出ました。
pyenv local 3.10.8
/usr/local/Cellar/pyenv/2.3.5/libexec/pyenv-version-file-write: line 21: .python-version: Operation not permitted
どうやらDropbox配下のディレクトリで作業していたため、同期関連でディレクトリの権限がなかったらしいです。
echo "3.10.8" > .python-version
上記で.python-versionを手動で作成し、再び
pyenv local 3.10.8
を実行したらエラーは出ませんでした。
以下のコマンドで以下の表示がされます。
$ pyenv version
3.10.8 (set by /Users/user/Dropbox/python/source_code/.python-version)
ところが、以下のように表示されてしまいます。
$pip3 --version
pip 23.2.1 from /usr/local/lib/python3.11/site-packages/pip (python 3.11)
シンボリックリンクの変更が必要のようです。
以下、chatGPTの回答。
Python と pip のバイナリは通常、特定のバージョンのディレクトリに保存されています。シンボリックリンクを使って、pip3 が特定のバージョンを指すように変更することができます。
以下のステップでシンボリックリンクを変更します:
which pip3
/usr/local/bin/pip3
上記をバックアップとしてリネームします
sudo mv /usr/local/bin/pip3 /usr/local/bin/pip3_backup
次に、Python 3.10 の pip バイナリへのシンボリックリンクを作成します。まず、Python 3.10 の pip の正確なパスを探す必要があります。一般的な場所は /usr/local/Cellar/python@3.10/3.10.x/bin/pip3 などです(Homebrewを使っている場合)。
このパスを探すために以下のコマンドを試してみることができます:
find /usr/local -name pip3
上記コマンドで、Python 3.10 に関連する pip3 のパスを見つけたら、それを使って新しいシンボリックリンクを作成します。
sudo ln -s /usr/local/Cellar/python@3.10/3.10.12_1/Frameworks/Python.framework/Versions/3.10/bin/pip3 /usr/local/bin/pip3
$ pip3 --version
pip 23.0.1 from /usr/local/lib/python3.10/site-packages/pip (python 3.10
実行し、変更されたか確認します。
$ pip3 --version
pip 23.0.1 from /usr/local/lib/python3.10/site-packages/pip (python 3.10
ようやく、pip3のインストール先を変更できました。
ここから、以下のコマンドを実行してPillowのインストールをやり直します。
pip3 uninstall Pillow
pip3 install Pillow
そして、元のプログラムを起動したが、また、以下のエラーが出ました。
Traceback (most recent call last):
File "/Users/user/Dropbox/python/source_code/fileope.py", line 5, in <module>
from PIL import Image
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/PIL/Image.py", line 82, in <module>
from . import _imaging as core
ImportError: cannot import name '_imaging' from 'PIL' (/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/PIL/__init__.py)
わけがわからないので、Pillowのプログラムがきちんと動作しているパソコンと、問題が起きているパソコンの両方で以下のコマンドを試しました。
pip3 show Pillow
すると、以下のRequired-byの箇所がそれぞれ違っていました。
・動作するパソコン:Required-by: image
・動作しないパソコン。問題あり:Required-by: PyScreeze
$ pip3 show Pillow
Name: Pillow
Version: 10.0.0
Summary: Python Imaging Library (Fork)
Home-page: https://python-pillow.org
Author: Jeffrey A. Clark (Alex)
Author-email: aclark@aclark.net
License: HPND
Location: /usr/local/lib/python3.10/site-packages
Requires:
Required-by: PyScreeze
だが、これも違うようです。
ネット上のフォーラムで同じ質問をしていた人がいたので、その回答に沿って試します。
PILもPillowもアンインストールし、pythonプログラムより、import PIL(Pillow)ができないことを確認します。
pip3 uninstall Pillow
pip3 uninstall PIL
そしてインストールしてPillowを使うpythonプログラムを実行します。
pip3 install --upgrade Pillow
そうしたらエラーがなく実行できました。
–upgradeオプションのせいでアンインストールしてインストールするときうまくできていなかったのかもしれません。
–upgradeは最新に更新するに加え、すでにライブラリが存在していても上書きされます。
それですでに存在していたものが上書きされたから出来たのでしょうか?
以下はchatGPTの回答
`ImportError: cannot import name ‘_imaging’ from ‘PIL’` は、Pillowのインストールに問題があった場合によく見られるエラーです。具体的には、バイナリコンポーネント(`_imaging`)のコンパイルやリンクに失敗した場合や、異なるバージョンのPillowが混在している場合などにこのエラーが発生します。
以下は、このエラーが解消された可能性のある原因を示しています:
1. **環境のクリーンアップ**:
`pip3 uninstall Pillow` および `pip3 uninstall PIL` により、システムから古い、または壊れたPillowのインストールが削除されました。この操作により、環境がクリーンアップされ、新しいインストールが正しく行われる可能性が高まります。2. **最新のバージョンのインストール**:
`pip3 install –upgrade Pillow` により、Pillowの最新のバージョンがインストールされました。この最新のバージョンは、あなたの環境との互換性が高かったり、以前のバージョンに存在していたバグが修正されている可能性があります。3. **バイナリの再コンパイル**:
以前のインストール時に何らかの理由で `_imaging` モジュールのコンパイルやリンクが正しく行われなかった場合、新しいインストール時にこれが修正された可能性があります。結論として、`–upgrade` オプションを使用して最新のPillowをインストールすることで、以前のインストールの問題や互換性の問題が解決され、エラーが解消されたと考えられます。
パッケージとライブラリの区別: 一つのパッケージは複数のライブラリを含むことがあります。pip3 show はパッケージ全体の情報を表示しますが、import ライブラリ名 は特定のライブラリを指します。したがって、大きなパッケージの中の特定のライブラリの場所と、パッケージ全体の場所が異なることがあります。
インストールの違い: pip3 でインストールしたものと、システムや他の方法でインストールしたものとで、インストールされる場所が異なることがあります。
原因の1つとして、python3とpip3で異なる環境を参照していました。
以下のコマンドで両者がどこを参照しているか確認できます。
which python3
which pip3