Fixing pyenv version system not installed
If you're using pyenv
to manage Python versions, you might encounter a frustrating issue where the system
version doesn't seem to work as expected. For instance, even when pyenv shell system
is set, running python
results in an error like this:
$ python --version
pyenv: python: command not found
In this post, I’ll walk you through the steps to understand and resolve this issue. By the end, you’ll have a working pyenv
configuration that properly recognizes the system Python.
The Problem
Here’s an example of the issue in action:
#
# Check available pyenv install version:
#
$ pyenv versions
system
2.7.18
* 3.12.8 (set by PYENV_VERSION environment variable)
#
# Switch shell's python to pyenv system:
#
$ pyenv shell system
$ pyenv versions
* system (set by PYENV_VERSION environment variable)
2.7.18
3.12.8
#
# Confirm python version
#
$ python --version
pyenv: python: command not found
The `python` command exists in these Python versions:
2.7.18
3.12.8
Note: See 'pyenv help global' for tips on allowing both
python2 and python3 to be found.
After some investigation, I found Issue #1301 on the pyenv
GitHub repository, which discusses this exact problem. However, that issue was closed and marked as fixed in May 2021. Fast forward to December 2024, and I’m still facing this issue using:
$ pyenv --version
pyenv 2.5.0
What the Documentation Says
The documentation explains the behavior of pyenv system
as follows:
A special version name "system" means to use whatever Python is found on PATH after the shims PATH entry (in other words, whatever would be run if Pyenv shims weren't on PATH). Note that Pyenv considers those installations outside its control and does not attempt to inspect or distinguish them in any way. So e.g. if you are on macOS and have OS-bundled Python 3.8.9 and Homebrew-installed Python 3.9.12 and 3.10.2 — for Pyenv, this is still a single "system" version, and whichever of those is first on PATH under the executable name you specified will be run.
To investigate available python
commands in my PATH
, I temporarily deactivated Homebrew and pyenv by commenting out the related lines in my .bashrc
:
# =============
# PATH
# =============
#eval "$(/opt/homebrew/bin/brew shellenv)" # Homebrew PATH and environment
...
...
# =============
# PYENV
# =============
#export PYENV_ROOT="$HOME/.pyenv"
#[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
#eval "$(pyenv init -)"
With pyenv and Homebrew deactivated, the system should fall back to the default Python available on macOS. However, the following command:
which python
returns nothing, meaning the python
command is not present in my PATH
:
$ echo "$PATH" | sed $'s/:/\\\n/g'
/Users/apollotang/.local/bin
/Users/apollotang/_x_conf/bin
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
/Applications/iTerm.app/Contents/Resources/utilities
The Default Python on macOS
What is the default "system" Python that comes with macOS? According to the macOS Monterey 12.3 Release Notes:
Python 2.7 was removed from macOS in this update. Developers should use Python 3 or an alternative language instead. (39795874)
This suggests that the available default Python command should be python3
:
$ which python3
/usr/bin/python3
An intuitive solution is to create a symlink from /usr/bin/python
to /usr/bin/python3
. However, doing so triggers the macOS developer tools installation prompt. For more details, see this post.
Using Homebrew’s Python
If I can’t symlink /usr/bin/python
to /usr/bin/python3
, I can use the Python installed via Homebrew. To do this, I reactivated Homebrew:
eval "$(/opt/homebrew/bin/brew shellenv)" # Homebrew PATH and environment
Adding Homebrew to my PATH
yields:
$ echo "$PATH" | sed $'s/:/\\\n/g'
....
/opt/homebrew/bin
/opt/homebrew/sbin
....
Investigating the Python installation by Homebrew reveals:
$ brew info python
==> python@3.13: stable 3.13.1 (bottled)
....
Installed
/opt/homebrew/Cellar/python@3.13/3.13.1 (3,299 files, 65.6MB) *
....
Python is installed as
/opt/homebrew/bin/python3
Unversioned symlinks `python`, `python-config`, `pip` etc., pointing to
`python3`, `python3-config`, `pip3` etc., respectively, are installed into
/opt/homebrew/opt/python@3.13/libexec/bin
The response of brew info python
tell us that the python
command is installed at:
$ /opt/homebrew/opt/python@3.13/libexec/bin/python --version
Python 3.13.1
Since this location is not in my PATH
, I created a symlink for this python
command in homebrew/bin
:
$ ln -s /opt/homebrew/opt/python@3.13/libexec/bin/python /opt/homebrew/bin/python
$ python --version
Python 3.13.1
Reactivating pyenv
Finally, I reactivated pyenv
:
# =============
# PYENV
# =============
export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
Verifying the setup:
$ pyenv versions
* system (set by /Users/apollotang/.pyenv/version)
2.7.18
3.12.8
$ python --version
Python 3.13.1
$ which python
/Users/apollotang/.pyenv/shims/python
With this configuration, pyenv
now correctly recognizes the system Python.