始めに
2023/10/2に約一年ぶりのメジャーアップデートであるPython3.12.0が公開されました。 昨日から使おうとインストールしたところ、pythonパッケージ管理用アプリのpipでエラーが発生し、 そのエラーの対応方法も発見しましたので、まとめておきます。
検証した環境
その1
OS: Windows10 CPU: core i5-11600KF MEM: DDR4-3200 32GB GPU: GTX1660Ti
その2
上記マシン上にインストールしたwsl OS: Ubuntu 20.04-LTS
仮想環境
共にvirtualenvを用いた仮想環境を用意して検証しています。
発生している現象
Python3.12.0の環境で、pipを使うとエラーが発生する。
pip list
や
pip install numpy
で
Traceback (most recent call last): File "/root/pythonproject/test/bin/pip", line 8, in <module> sys.exit(main()) ^^^^^^ File "/root/pythonproject/test/lib/python3.12/site-packages/pip/_internal/cli/main.py", line 70, in main return command.main(cmd_args) ^^^^^^^^^^^^^^^^^^^^^^ File "/root/pythonproject/test/lib/python3.12/site-packages/pip/_internal/cli/base_command.py", line 101, in main return self._main(args) ^^^^^^^^^^^^^^^^ File "/root/pythonproject/test/lib/python3.12/site-packages/pip/_internal/cli/base_command.py", line 216, in _main self.handle_pip_version_check(options) File "/root/pythonproject/test/lib/python3.12/site-packages/pip/_internal/cli/req_command.py", line 179, in handle_pip_version_check session = self._build_session( ^^^^^^^^^^^^^^^^^^^^ File "/root/pythonproject/test/lib/python3.12/site-packages/pip/_internal/cli/req_command.py", line 125, in _build_session session = PipSession( ^^^^^^^^^^^ File "/root/pythonproject/test/lib/python3.12/site-packages/pip/_internal/network/session.py", line 343, in __init__ self.headers["User-Agent"] = user_agent() ^^^^^^^^^^^^ File "/root/pythonproject/test/lib/python3.12/site-packages/pip/_internal/network/session.py", line 175, in user_agent setuptools_dist = get_default_environment().get_distribution("setuptools") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/root/pythonproject/test/lib/python3.12/site-packages/pip/_internal/metadata/importlib/_envs.py", line 188, in get_distribution return next(matches, None) ^^^^^^^^^^^^^^^^^^^ File "/root/pythonproject/test/lib/python3.12/site-packages/pip/_internal/metadata/importlib/_envs.py", line 183, in <genexpr> matches = ( ^ File "/root/pythonproject/test/lib/python3.12/site-packages/pip/_internal/metadata/base.py", line 612, in iter_all_distributions for dist in self._iter_distributions(): File "/root/pythonproject/test/lib/python3.12/site-packages/pip/_internal/metadata/importlib/_envs.py", line 176, in _iter_distributions for dist in finder.find_eggs(location): File "/root/pythonproject/test/lib/python3.12/site-packages/pip/_internal/metadata/importlib/_envs.py", line 144, in find_eggs yield from self._find_eggs_in_dir(location) File "/root/pythonproject/test/lib/python3.12/site-packages/pip/_internal/metadata/importlib/_envs.py", line 111, in _find_eggs_in_dir from pip._vendor.pkg_resources import find_distributions File "/root/pythonproject/test/lib/python3.12/site-packages/pip/_vendor/pkg_resources/__init__.py", line 2164, in <module> register_finder(pkgutil.ImpImporter, find_on_path) ^^^^^^^^^^^^^^^^^^^ AttributeError: module 'pkgutil' has no attribute 'ImpImporter'. Did you mean: 'zipimporter'?
のようなエラーが発生。
pip -V
は普通に動きました。
修正方法
この方法は正式な方法ではありません。利用する際には自己責任で実行してください。
一段階目
pipのコードを二種類編集します。 pipはpythonによって実装されており、pythonベースのエラーが出てくるため、それに従って修正すればOKです。 見るべきはエラー出力下4行です。
File "/root/pythonproject/test/lib/python3.12/site-packages/pip/_vendor/pkg_resources/__init__.py", line 2164, in <module> register_finder(pkgutil.ImpImporter, find_on_path) ^^^^^^^^^^^^^^^^^^^ AttributeError: module 'pkgutil' has no attribute 'ImpImporter'. Did you mean: 'zipimporter'?
VScodeでは、エラーが出ているファイル名にカーソルを合わせるとそこからファイルへアクセスできます。
pip/_vendor/pkg_resources/__init__.py
のファイルの
register_finder(pkgutil.ImpImporter, find_on_path)
を
register_finder(pkgutil.zipimporter, find_on_path)
に変更します。 その後、もう一度
pip list
でエラーを確認します。すると、少し出力が変化し、以下のようになっているはずです。
File "/root/pythonproject/test/lib/python3.12/site-packages/pip/_vendor/pkg_resources/__init__.py", line 2315, in <module> register_namespace_handler(pkgutil.ImpImporter, file_ns_handler) ^^^^^^^^^^^^^^^^^^^ AttributeError: module 'pkgutil' has no attribute 'ImpImporter'. Did you mean: 'zipimporter'?
下4行が以上のようになっていたら、pip/_vendor/pkg_resources/__init__.py
のファイルの
register_namespace_handler(pkgutil.ImpImporter, file_ns_handler)
を
register_namespace_handler(pkgutil.zipimporter, file_ns_handler)
に変更します。 この状態で、
pip list
を実行すると、エラーが出ずに正常に動くはずです。 これで第一段階目が完了です。 これでも一応動くのですが、正常なコードではないためpipをアップグレードすることを推奨します。
第二段階目
pip list
を実行すると、モジュールが並んだ後に
[notice] A new release of pip is available: 23.0.1 -> 23.3.1 [notice] To update, run: pip install --upgrade pip
といった表示が出ると思います。この二行目の指示通り、
pip install --upgrade pip
を実行することで、pipが最新版にアップグレードされ、正常に動くようになります。 また、windows環境の場合は、アップグレード用のコマンドは
python -m pip install --upgrade pip
のようになります。
想定されるバグの原因
python3.12でpkgutilに変更がかかったことが問題だと考えられます。
終わりに
最後までお読みいただきありがとうございました。 今回の手法で修正できなかった・もっと簡単な修正法が見つかったという方はぜひコメントをよろしくお願いします。