MacでPythonをHomebrewの3.10へ切り替え

MacでPythonをHomebrewの3.10へ切り替え
  • URLをコピーしました!

Mac Python Homebrew 切り替えでつまずきやすいのは、brew install python@3.10 を実行したあとも python3 --version が 3.9 のままになるケースです。
インストール自体は成功しているのに、シェルが参照している実行ファイルが別物、という状態がよく起きます。

本記事では、Apple Silicon Mac(Homebrew の接頭辞が /opt/homebrew)を想定し、PATH・which・unlink・.zshrc の仕組みから、確実に Python 3.10 へ切り替える手順を説明します。

ポイント

brew install は「パッケージを入れる」操作です。

python3 がどの実行ファイルを呼ぶかは、シェルの PATH 優先順位で決まります。

目次

前提:いまの python3 が何を指しているか

切り替え作業の前に、現状を記録します。
次のコマンドを順に実行してください。

python3 --version
which python3
type -a python3
which -a python3
brew --prefix
echo $PATH

各コマンドの意味は次のとおりです。

コマンド分かること
python3 --version実際に起動したインタプリタのバージョン
which python3PATH 上で最初に見つかった python3 のパス
type -a python3エイリアス・関数・実行ファイルを含む候補一覧
which -a python3PATH 上に存在する python3 の全パス
brew --prefix自分の Homebrew ルート(Apple Silicon では多くが /opt/homebrew)

which は「最初の1つ」だけを返します。
which -a と type -a は、隠れている別の python3 を洗い出すために使います。
たとえば /usr/bin/python3 と /opt/homebrew/bin/python3 が両方あるとき、どちらが先に来るかを PATH が決めます。

brew install しても python3 が 3.10 にならない理由

Homebrew のバージョン付き配方 python@3.10 を入れると、通常は python3.10 という明示コマンドが使えるようになります。
一方で、シェルが呼ぶ短い名前 python3 は、必ずしも同時に 3.10 へ差し替わりません。

The default formula installs python3 and pip3 into Homebrew’s bin directory. Unversioned names such as python, python-config and pip are installed into $(brew --prefix python)/libexec/bin.

引用:Homebrew and Python – Homebrew Documentation

つまり次の3層が別物です。

  1. パッケージの実体(Cellar 内の Python 3.10)
  2. Homebrew が作るシンボリックリンク(bin や opt 配下)
  3. シェルが PATH の先頭から探す python3

brew install python@3.10 は主に 1 と 2 を整えます。

3 は「もともと PATH の前にあった別の python3」が勝ち続けると、バージョン表示は古いままです。
macOS 付属や Xcode Command Line Tools 由来の /usr/bin/python3、以前入れた python.org インストーラ、pyenv の shim などが先に来る典型例です。
確認の目安として、python3.10 --version は 3.10 なのに python3 --version だけ古い、という結果なら「インストール成功・参照先未切替」と判断できます。

PATH の優先順位がバージョンを決める仕組み

シェルは環境変数 PATH を左から右へ走査し、最初に見つかった実行ファイルを起動します。
後から出てくる同名コマンドは無視されます。

echo $PATH | tr ':' '\n'

上から順に優先度が高いディレクトリです。
たとえば次の並びなら、/usr/bin/python3(多くはシステム側)が /opt/homebrew/bin/python3 より先に選ばれます。

/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin

逆に Homebrew 側を先頭へ置けば、同じ python3 という名前でも Homebrew の実行ファイルが選ばれます。
Mac Python Homebrew 切り替えの本質は、パッケージの再インストールではなく、この探索順の制御です。

brew unlink は何をするコマンドか

brew unlink <formula> は、対象レシピが Homebrew の prefix(例: /opt/homebrew)へ張っているシンボリックリンクを外します。
Cellar 内の実ファイルは残ります。
「削除」ではなく「PATH 上から見えにくくする」操作に近いです。

対になるのが brew link で、リンクを付け直します。
複数バージョンの Python を Homebrew で入れているとき、unlink と link で bin 配下の代表リンクを入れ替える、という使い方が一般的です。

ただし、いま動いている python3 が Homebrew 管理外なら、unlink しても参照先は変わりません。
その切り分けが次のエラーです。

brew unlink python@3.9 が No such keg になる理由

次のエラーは、よく「古い Python を外せない」と感じる場面です。

brew unlink python@3.9
# Error: No such keg: /opt/homebrew/Cellar/python@3.9

No such keg は、「その名前の配方が、この Homebrew の Cellar に存在しない」という意味です。
Apple Silicon では Cellar が /opt/homebrew/Cellar 配下になります。
ここに python@3.9 が無いので、unlink するリンクもありません。
続けて次を実行します。

brew list | grep python@3.9

何も表示されない場合、Homebrew は python@3.9 をインストール済みとして管理していません。
それでも python3 --version が 3.9 なら、その 3.9 は Homebrew 由来ではない、と結論できます。
システム Python、別インストーラ、バージョンマネージャなど、Homebrew の外にある実行ファイルを見ている状態です。

切り分け

No such keg と brew list 空表示は失敗ではなく、「3.9 を Homebrew で外す必要がない」という診断結果です。
次にやるべきは unlink ではなく、PATH で Homebrew の 3.10 を前に出すことです。

Homebrew 管理外の python3 を特定する方法

which python3 の結果を見てください。

  • /usr/bin/python3 … macOS / Command Line Tools 側のことが多い
  • /Library/Frameworks/Python.framework/... … python.org 公式インストーラ系
  • ~/.pyenv/shims/python3 … pyenv の shim
  • /opt/homebrew/bin/python3 … Homebrew 経由(Intel なら /usr/local/bin/python3 のことも)

実体の確認には次も有効です。

ls -l "$(which python3)"
python3 -c 'import sys; print(sys.executable)'

シンボリックリンクの行き先と、インタプリタ自身が認識しているパスが分かります。
Homebrew 管理外なら、無理にシステム側を消さず、開発用シェルの PATH だけを Homebrew の 3.10 優先に変えるのが安全です。

Homebrew の場所を brew –prefix で確認する

パスをハードコードすると、Apple Silicon(/opt/homebrew)と Intel(/usr/local)で設定が壊れます。

brew --prefix
brew --prefix python@3.10

brew --prefix は Homebrew 全体のルートです。
brew --prefix python@3.10 は、その配方の opt リンク先(多くの場合 .../opt/python@3.10)を返します。
以降の PATH 設定では、この結果を使うと環境差に強くなります。

Python 3.10 のインストールと参照確認

まだ入れていなければインストールします。

brew update
brew install python@3.10
brew info python@3.10

インストール後の確認です。

ls "$(brew --prefix)/opt/python@3.10/bin"
"$(brew --prefix)/opt/python@3.10/bin/python3.10" --version
"$(brew --prefix)/opt/python@3.10/bin/python3" --version

フルパスで 3.10 と出れば、実体は揃っています。
あとはシェルの探索順だけです。

.zshrc に PATH を追加する意味

zsh は対話シェル起動時に ~/.zshrc を読みます。
ここに PATH の先頭へ Python 3.10 の bin を足すと、新しいターミナルでは python3 が 3.10 側を指しやすくなります。
より安全な書き方は、Homebrew の位置を固定せず brew --prefix を使う方法です。

# ~/.zshrc の末尾付近に追加(例)
export PATH="$(brew --prefix)/opt/python@3.10/bin:$PATH"

$PATH の左側に置くことで、既存の /usr/bin などより先に検索されます。
右側へ追記すると、古い python3 が勝ち続けます。
順序を間違えると「設定したのに変わらない」原因になります。

補足

Homebrew のドキュメントでは、バージョン無しの python / pip を使いたい場合に libexec/bin を PATH へ足す説明もあります。
python3 を 3.10 に寄せる目的なら、まず $(brew --prefix)/opt/python@3.10/bin で十分なことが多いです。

必要なら次も検討できます。

export PATH="$(brew --prefix)/opt/python@3.10/libexec/bin:$PATH"

プロジェクト依存は、可能なら venv やバージョンマネージャで固定し、グローバルの python3 は開発用の既定値、と考えると運用が安定します。
公式も、Homebrew のベース環境を直接汚さない方針を示しています。

Homebrew marks its current Python as externally managed according to PEP 668. Install project dependencies in a virtual environment instead of modifying Homebrew’s base environment.

引用:Homebrew and Python – Homebrew Documentation

source ~/.zshrc の意味と、なぜ切り替わるのか

~/.zshrc を保存しただけでは、すでに開いているターミナルの環境変数は自動更新されません。
設定ファイルは「起動時(または明示的に読んだとき)」に評価されるためです。

source ~/.zshrc

source(同等の .)は、指定ファイルを今のシェルプロセス内で実行します。
その結果、編集した export PATH=... が現在のセッションに適用され、which python3 の結果が変わります。
新しいタブやウィンドウを開けば、同じ .zshrc が読み込まれて同様に切り替わります。

逆に、GUI アプリから起動したツールは独自の環境を持つことがあり、ターミナルで直っても IDE 内蔵ターミナルが古い PATH のまま、という差も起こります。
その場合は IDE 側のシェル設定や再起動も確認してください。

切り替え後の最終確認チェックリスト

次がすべて整合していれば、Mac 上での Homebrew Python 3.10 切替は完了です。

source ~/.zshrc
which python3
type -a python3
which -a python3
python3 --version
python3 -c 'import sys; print(sys.version); print(sys.executable)'

期待する目安は次です。

  • which python3 が $(brew --prefix)/opt/python@3.10/bin/python3 配下、または Homebrew 配下を指す
  • python3 --version が 3.10.x
  • which -a python3 の先頭が Homebrew 側で、後ろに /usr/bin/python3 などが残っていても問題ない

まだ古い場合は、type -a python3 で alias が挟まっていないか、.zprofile や .zshenv で別 PATH を上書きしていないかを見ます。
pyenv を使っている場合は、shim が常に先頭に来るため、pyenv の local/global 設定側でバージョンを選ぶ方が適切です。

python3.10 は使えるのに python3 だけ古いのはなぜ?

名前付きコマンド python3.10 はインストール済みでも、短い名前 python3 は PATH 先頭の別実体を指しているためです。

システム Python を消すべきですか?

基本的に消さないでください。
開発用シェルの PATH で Homebrew を優先する方が安全です。

Intel Mac でも同じ手順ですか?

考え方は同じです。
brew --prefix が /usr/local になる点だけ異なり、記事の PATH 書き方はそのまま使えます。

まとめ

Mac Python Homebrew 切り替えで重要なのは、「入れる」と「シェルが選ぶ」を分けて考えることです。
brew install python@3.10 だけでは python3 は必ずしも 3.10 になりません。
brew unlink python@3.9 の No such keg や、brew list | grep python@3.9 が空なのは、3.9 が Homebrew 管理外であるサインです。

which / type -a / which -a で参照先を特定し、$(brew --prefix)/opt/python@3.10/bin を PATH 先頭へ置き、source ~/.zshrc で現在のシェルへ反映してください。
仕組みが分かれば、同じ症状はバージョンを問わず同じ手順で解けます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次