macOSでPythonパッケージ更新確認ができなくなった話
[主題]
Python本体のアップデートに伴い、pythonの外部ライブラリ(パッケージ)アップデートができなくなった問題について述べる。
[背景]
macOS12.3 Monterey以降でpythonを使うためには、何らかの方法で自分でインストールする必要がある。筆者の場合、本家からダウンロードして使ってきた。その際、python3.11からpython3.12へのアップデートがあったが、何も考えずに更新した。また、外部ライブラリ(パッケージ)も、特に考えることなくインストールしてきた。その結果、外部ライブラリ(パッケージ)にアップデートがあっても、更新されないという問題が発生した。
本稿では、上記問題が発生する経緯について述べ、問題を回避するための対策を提案する。
[環境]
参考までに、筆者の環境を記載しておく
MacBook Air 2023 15.3inch(Apple Silicon Mac, M2)
macOS Sonoma 14.5
Xcode 15.4
CommandLine Tools for Xcode 15.3.0.0.1
[状況の確認]
まずpython3.11をインストールし、外部ライブラリ(パッケージ)も普通にインストールする。その上でpython3.12を(更新)インストールすると、以下の略図のようなディレクトリ構成になると思う。
/Library/Frameworks/Python.framework/
└── Versions
├── 3.11
│ ├── bin
│ │ ├── meson
│ │ ├── pip3
│ │ ├── scons
│ │ └── vcsi
│ ├── include
│ └── lib
├── 3.12
│ ├── bin
│ │ └── pip3
│ ├── include
│ └── lib
└── Current -> 3.12
一方、ホームディレクトリの.bash_profileや.zprofileを確認すると、次のようになっている。
PATH="\
/usr/local/apache2/bin:\
/usr/local/mysql/bin:\
/usr/local/mysql/support-files:\
/usr/local/sbin:\
${HOME}/Library/Android/sdk/platform-tools:\
/Library/Frameworks/Python.framework/Versions/3.11/bin:\
/Library/Frameworks/Python.framework/Versions/3.12/bin:\
${PATH}"
export PATH
この状態では、python3.11とpython3.12双方のbinディレクトリにパスが通っている(python3.11系が先であることに注意されたい)
/Library/Frameworks/Python.framework/Versions/3.11/bin:\
/Library/Frameworks/Python.framework/Versions/3.12/bin:\
ので、python3.11配下のbinに入れたパッケージは実行可能である。だが、落とし穴がある。次のコマンドを実行して見る。
pip3 --version
実行結果は次の通り、pipは3.11系であることが分かる。
pip 24.0 from /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/pip (python 3.11)
インストールしたパッケージの更新を確認すると
pip3 list -o
Package Version Latest Type
---------- -------- -------- -----
certifi 2024.2.2 2024.6.2 wheel
Jinja2 3.1.3 3.1.4 wheel
meson 1.4.0 1.4.1 wheel
setuptools 69.5.1 70.0.0 wheel
正常に表示される。念のため、次のコマンドを叩くと
python3 --version
Python 3.11.9
Python3.12をインストールしてあるのに、3.11系が動いている!
ここで、ホームディレクトリの.bash_profileや.zprofileを次のように変更する(python3.12系が先になるようにする)と
/Library/Frameworks/Python.framework/Versions/3.12/bin:\
/Library/Frameworks/Python.framework/Versions/3.11/bin:\
PATH="\
/usr/local/apache2/bin:\
/usr/local/mysql/bin:\
/usr/local/mysql/support-files:\
/usr/local/sbin:\
${HOME}/Library/Android/sdk/platform-tools:\
/Library/Frameworks/Python.framework/Versions/3.12/bin:\
/Library/Frameworks/Python.framework/Versions/3.11/bin:\
${PATH}"
export PATH
python及びpipのバージョンは3.12系になる。しかし…。
pip3 list -o
の実行結果には、3.11系に入れたパッケージの更新情報は表示されなくなる。当たり前じゃないかと言わないで欲しい。筆者は、パッケージが実行可能であることと合わせ、原因が分かるまでは、本当に混乱したのだ。
[原因]
察しの良い人ならば既にお気付きかと思うが、これは、環境変数Pathの優先順位、すなわち同じ名前のコマンドが複数のディレクトリ中に存在する場合は、Path環境変数の先頭の方にあるディレクトリが優先される。
に起因する問題である。
ただ特殊なのは、Path環境変数に加え、pythonのパッケージマネージャーであるpipが絡んでいる点である。挙動から推定する限り、pipはフレームワーク直下のディレクトリ、すなわち3.11系と3.12系を超えて(またいで)パッケージを管理することはないと考えられる。(これも当たり前だと言わないで欲しい)
[対策]
3.11系に入れたパッケージを3.12系に移動する。具体的には、以下の手順を踏む。
-
ホームディレクトリの.bash_profile(.zprofile)で、3.11系のみをpathに設定
-
3.11系にインストールしていたパッケージをrequirements.txtに書き出し
pip3 freeze > requirements.txt
-
requirements.txtを使って3.11系からパッケージをアンインストール
pip3 uninstall -y -r requirements.txt
-
ホームディレクトリの.bash_profile(.zprofile)で、3.12系のみをpathに設定
-
requirements.txtを使って3.12系にパッケージをインストール
pip3 install -r requirements.txt
上記作業が、3.11から3.12のようなメジャーバージョンアップ(勝手にそう呼称している)毎に必要となることになる。
[参考記事]
- Python, pipでrequirements.txtを使ってパッケージ一括インストール | note.nkmk.me
- pipで一括アンインストール【Python】 – Liquids
- MacのPATH設定と優先順位について理解した-スケ郎のお話
以上。
この投稿へのトラックバック
トラックバックはありません。
- トラックバック URL
この投稿へのコメント