pyenv Python version switching

Version 2.8 · source

Start here

pyenv install -l
List installable versions
pyenv install <version>
Build a Python version
pyenv versions
Installed versions
pyenv global <version>
Set the default
pyenv local <version>
Pin this directory
pyenv shell <version>
Pin this shell only
pyenv version
Active version and why
pyenv which <command>
Real path of a command

Concepts

  1. python shim in PATH
  2. Resolve version env, file, global
  3. ~/.pyenv/versions <version>/bin/python
  4. Your command right interpreter
Version resolution (first hit wins)
Source Set by
PYENV_VERSION pyenv shell
.python-version here pyenv local
.python-version in a parent pyenv local
$(pyenv root)/version pyenv global
system Python fallback if none

Setup

export PYENV_ROOT="$HOME/.pyenv"
Root directory (default ~/.pyenv)
export PATH="$PYENV_ROOT/bin:$PATH"
Put the pyenv command on PATH
eval "$(pyenv init - bash)"
Enable shims in bash (~/.bashrc)
eval "$(pyenv init - zsh)"
Enable shims in zsh (~/.zshrc)
pyenv init - fish | source
Enable shims in fish (config.fish)
pyenv init --path
Print only the shims PATH setup
pyenv root
Print the pyenv root directory
pyenv commands
List all pyenv commands
pyenv help <command>
Help for one command

Install versions

pyenv install -l
List all installable versions
pyenv install <version>
Build and install a version
pyenv install 3.12
Prefix: newest 3.12.x known to pyenv
A partial version resolves to the latest matching patch release.
pyenv install
Install what .python-version names
pyenv install -s <version>
Skip if already installed
pyenv install -f <version>
Reinstall even if present
pyenv install -v <version>
Show the compile output
pyenv install -k <version>
Keep the source tree after build
pyenv install -g <version>
Build a debug version
pyenv install <version>:<alias>
Install under a custom name
pyenv uninstall <version>
Remove a version (asks first)
pyenv uninstall -f <version>
Remove without confirming
pyenv latest <prefix>
Latest installed match for a prefix
pyenv latest -k <prefix>
Latest known (installable) match

Choose a version

pyenv versions
List installed, active one marked *
pyenv version
Active version and where it came from
pyenv version --bare
Print only the version name
pyenv global <version>
Default for the user (~/.pyenv/version)
pyenv global <v1> <v2>
Several versions, searched in order
pyenv global system
Use the system Python
pyenv local <version>
Write .python-version here
pyenv local <v1> <v2>
Several versions in one file
pyenv local --unset
Remove .python-version
pyenv local -f <version>
Set even if not installed
pyenv shell <version>
Set PYENV_VERSION in this shell
pyenv shell --unset
Clear the shell-level version
PYENV_VERSION=<version> <command>
Override for a single command

Find and run

pyenv which <command>
Full path pyenv would run
pyenv which --nosystem <command>
Ignore the system Python
pyenv whence <command>
Which versions provide a command
pyenv prefix [<version>]
Install directory of a version
pyenv exec <command>
Run with the selected version first in PATH
pyenv exec -N <command>
Also set PYTHONHOME and library path
pyenv rehash
Regenerate shims
Needed after installing a package that adds a command; pip installs usually trigger it for you, other installers may not.
pyenv shims
List existing shims
pyenv hooks <command>
List hook scripts for a command
pyenv completions <command>
List completions for a command

Build and environment

PYENV_ROOT
Where versions and shims live
PYENV_VERSION
Version to use; beats files
PYENV_DIR
Directory to start the .python-version search
PYENV_DEBUG=1 pyenv <command>
Trace what pyenv does
PYENV_HOOK_PATH
Extra hook search paths, colon-separated
PYENV_BUILD_ROOT
Where -k keeps build sources
rm -rf $(pyenv root)
Uninstall pyenv and all versions
brew upgrade pyenv
Upgrade a Homebrew install
pyenv update
Upgrade a git install (needs pyenv-update)
git -C $(pyenv root) pull
Upgrade a plain git checkout

Build dependencies

Debian / Ubuntu
sudo apt updatesudo apt install make build-essential libssl-dev zlib1g-dev \  libbz2-dev libreadline-dev libsqlite3-dev curl git \  libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev \  libffi-dev liblzma-dev libzstd-dev
Fedora
sudo dnf install make gcc patch zlib-devel bzip2 bzip2-devel \  readline-devel sqlite sqlite-devel openssl-devel tk-devel \  libffi-devel xz-devel libuuid-devel gdbm-libs libnsl2
macOS (Homebrew)
brew install openssl@3 readline sqlite3 xz tcl-tk@8 zstd zlib pkgconfig

Recipes

Fresh machine, new project
pyenv install 3.12cd myprojpyenv local 3.12python -m venv .venvpyenv version
Test against several versions
pyenv install -s 3.11 && pyenv install -s 3.12pyenv local 3.12 3.11python3.11 -m pytestpython3.12 -m pytest
Debug a missing command
pyenv versionpyenv which <command>pyenv whence <command>pyenv rehash
Install the newest patch release
pyenv install -l | grep -E '^ *3\.12'pyenv install 3.12pyenv global $(pyenv latest 3.12)