できない.dev

pyenv で Python のバージョンが切り替わらない

pyenv local や pyenv global を実行しても python --version が変わらない時は、shim より前にシステム Python が PATH 解決されているか、shell の rc に pyenv init が書かれていないことが多い。
rc と PATH を見直す。

公開: 更新:

症状できない
pyenv versions
* system (set by /root/.pyenv/version)
  3.11.16

2026-09-16 に python:3.12(Python 3.12.14 / Git 2.47.3) で実際に打って取った出力。検証環境の詳細

要約

pyenv は $PYENV_ROOT/shims 配下に python などのラッパースクリプトを置き、それを PATH の先頭に挿入することで python 呼び出しを横取りする。
shim パスが PATH に入っていない、または OS の python が先に解決されていると、pyenv local を打っても効かない。pyenv init を rc に書いて shell を再起動するのが基本対応。

実行例

python:3.12 のコンテナに pyenv を入れて 3.11 をビルドし、rc に pyenv init を書く前と後で挙動を比べてみる。pyenv local 3.11 を打って .python-version が作られていても、shim が PATH に入っていなければ python --version はイメージ同梱の 3.12.14 のままで、pyenv init を追記した後のシェルで初めて 3.11.16 に変わる。

$ pyenv versions
* system (set by /root/.pyenv/version)
  3.11.16
$ pyenv local 3.11; cat .python-version; python --version; which python
3.11
Python 3.12.14
/usr/local/bin/python
$ tail -n 3 ~/.bashrc
export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init - bash)"
$ which python; python --version
/root/.pyenv/shims/python
Python 3.11.16
$ echo $PATH | tr ':' '\n' | head -3
/root/.pyenv/shims
/root/.pyenv/bin
/usr/local/bin
$ echo "3.10.14" > .python-version; python --version; pyenv version
Python 3.12.14
pyenv: version `3.10.14' is not installed (set by /tmp/tmp.gxvclYI2VU/.python-version)
$ pyenv versions --bare; pyenv local 3.11; python --version
3.11.16
Python 3.11.16
$ export PYENV_VERSION=system; python --version; pyenv version
Python 3.12.14
system (set by PYENV_VERSION environment variable)
$ export PYENV_VERSION=system; echo "PYENV_VERSION=$PYENV_VERSION"; unset PYENV_VERSION; python --version; pyenv version
PYENV_VERSION=system
Python 3.11.16
3.11.16 (set by /tmp/tmp.gxvclYI2VU/.python-version)

— 2026-09-16 時点の出力

検証環境Python 3.12.14 / Git 2.47.3 / 2026-09-16 検証
検証日
実行環境
python:3.12 Debian GNU/Linux 13 (trixie)
バージョン
  • Python 3.12.14
  • Git 2.47.3

この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。

解決策

1. shell 初期化を確認

~/.bashrc または ~/.zshrc に次を追加する(pyenv 公式 README(新しいタブで開く) の手順)。

export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init - bash)"

zsh は pyenv init - zsh に置き換える。
書いたら新しいターミナルを開く。

2. PATH の順序を確認

which python
# 期待: /Users/you/.pyenv/shims/python
echo $PATH | tr ':' '\n' | head -5

shim パスが上位に来ているか確認する。/usr/local/bin や /opt/homebrew/bin が先にある場合は rc 内で PATH を組み直して shim を先頭に置く。

3. バージョンの存在を確認

pyenv versions
# 不足していれば
pyenv install 3.12.3
pyenv local 3.12.3
python --version

pyenv local は .python-version を作るだけで、対象バージョンが入っていないと反映されない。
リポジトリの README は pyenv/pyenv(新しいタブで開く) にある。

4. PYENV_VERSION の解除

echo $PYENV_VERSION
unset PYENV_VERSION

環境変数が設定されていると、.python-version より優先される。
CI スクリプトでは終わったら unset しておく。

5. shim の再生成

pyenv rehash

新しいパッケージをインストールしたのに pip install の実行ファイルが見つからない時は rehash で shim を作り直す。

よくある原因

  1. eval "$(pyenv init - bash)" を rc に書き忘れている、または zsh に乗り換えた際に .zshrc 側に転記していない
  2. which python が /usr/bin/python3 や /opt/homebrew/bin/python3 を返しており、shim が PATH の後ろに居る
  3. .python-version が書き込まれたディレクトリでも pyenv versions に該当版が無く、グローバルバージョンにフォールバックしている
  4. CI で PYENV_VERSION を設定したまま消し忘れている
  5. macOS で Terminal がログインシェルでない設定になっており、.bash_profile だけに書いた pyenv 初期化が読まれていない

この手順で直った?