pyenv Cheatsheet
pyenv Cheatsheet
What is pyenv?
pyenv lets you switch between multiple Python versions on a per-user basis. It modifies your PATH at shell startup so that calls to python are intercepted and routed to the version you’ve selected — no sudo, no system-wide changes.
How pyenv resolves a Python version
pyenv checks the following sources in order, using the first match:
PYENV_VERSIONenvironment variable (if set).python-versionfile in the current directory (walk up to/)~/.pyenv/version(the global default)- System Python as final fallback
Quick reference
| Task | Command |
|---|---|
| List installable versions | pyenv install --list |
| Install a version | pyenv install 3.12.8 |
| Set global default | pyenv global 3.12.8 |
| Set version for a project | pyenv local 3.11.10 |
| Set version for current shell | pyenv shell 3.13.1 |
| Show active version | pyenv version |
| List installed versions | pyenv versions |
| Uninstall a version | pyenv uninstall 3.10.15 |
| Rehash shims | pyenv rehash |
Installation
1. Install build dependencies (openSUSE Tumbleweed)
Python versions are compiled from source, so you need a C toolchain and several libraries:
sudo zypper install -y \
gcc make automake \
zlib-devel bzip2 libbz2-devel \
readline-devel libffi-devel \
libopenssl-devel libopenssl-1_1-devel \
sqlite3-devel xz-devel lzma-sdk-devel \
tk-devel ncurses-devel \
patch git curlTip: If a
zypper installfails for a specific package name, search withzypper se <keyword>. Tumbleweed renames packages occasionally during rolling updates.
2. Install pyenv via the official installer
curl -fsSL https://pyenv.run | bashThis clones pyenv and useful plugins (pyenv-virtualenv, pyenv-update, pyenv-doctor) into ~/.pyenv.
Alternative: install via Git manually
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
cd ~/.pyenv && src/configure && make -C src # optional, speeds up pyenv3. Configure your shell
Add these lines to the end of your shell’s rc file.
Bash (~/.bashrc)
export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init - bash)"
eval "$(pyenv virtualenv-init -)" # optional, for pyenv-virtualenvZsh (~/.zshrc)
export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init - zsh)"
eval "$(pyenv virtualenv-init -)"Fish (~/.config/fish/config.fish)
set -gx PYENV_ROOT $HOME/.pyenv
fish_add_path $PYENV_ROOT/bin
pyenv init - fish | source
pyenv virtualenv-init - | sourceAfter editing, restart your shell or exec $SHELL.
4. Verify the installation
pyenv --version # e.g. pyenv 2.5.x
pyenv doctor # checks build deps5. Updating pyenv
pyenv update # if installed via pyenv-installer
# or
cd ~/.pyenv && git pull # if installed via git6. Uninstalling pyenv
Remove the directory and the shell lines you added:
rm -rf ~/.pyenv
# then delete the pyenv lines from ~/.bashrc / ~/.zshrc / config.fishCore Commands
Installing Python versions
# List every installable version (CPython, PyPy, Anaconda, etc.)
pyenv install --list
# Filter the list
pyenv install --list | grep '^\s*3\.12'
# Install a specific version
pyenv install 3.12.8
# Install with verbose output (useful for debugging build failures)
pyenv install -v 3.12.8
# Install with a custom build configuration
PYTHON_CONFIGURE_OPTS="--enable-optimizations --with-lto" pyenv install 3.12.8Optimised builds: Adding
--enable-optimizations --with-ltomakes the build slower but produces a noticeably faster Python binary. Recommended for versions you use daily.
Selecting versions
pyenv global — user-wide default
pyenv global 3.12.8 # single version
pyenv global 3.12.8 3.11.10 # fallback chain: try 3.12.8 first, then 3.11.10
pyenv global system # revert to the system PythonWrites to ~/.pyenv/version.
pyenv local — per-project
cd ~/projects/myapp
pyenv local 3.11.10Creates a .python-version file in the current directory. Commit this file to your repo so collaborators get the same version.
pyenv shell — current terminal session only
pyenv shell 3.13.1 # set
pyenv shell --unset # clearSets the PYENV_VERSION env var. Highest priority, overrides local and global.
Inspecting state
pyenv version # active version + where it was set
pyenv versions # all installed versions (* marks active)
pyenv which python # full path to the active python binary
pyenv whence pip # which installed versions provide 'pip'
pyenv root # prints PYENV_ROOT (usually ~/.pyenv)
pyenv prefix 3.12.8 # prints the install prefix for a versionUninstalling versions
pyenv uninstall 3.10.15
pyenv uninstall -f 3.10.15 # skip confirmation promptRehashing shims
pyenv uses shim executables in ~/.pyenv/shims/. If you install a new package that adds a CLI tool (e.g. pip install black), run:
pyenv rehashWith
pyenv initin your shell config, rehashing happens automatically most of the time. You only need this manually if a newly installed command is not found.
Multiple simultaneous versions
You can activate several versions at once. The first one listed becomes the default python, but executables unique to other versions remain accessible:
pyenv global 3.12.8 3.11.10 3.10.15
python --version # 3.12.8
python3.11 --version # 3.11.10
python3.10 --version # 3.10.15This is handy for running tox or nox across multiple Python versions.
Virtual Environments
pyenv-virtualenv plugin
pyenv-virtualenv is installed automatically by the pyenv-installer. It lets you manage virtual environments as first-class pyenv versions.
Creating virtual environments
# Create a virtualenv named "myproject" based on Python 3.12.8
pyenv virtualenv 3.12.8 myproject
# Create using the currently active Python version
pyenv virtualenv myprojectVirtual environments live inside ~/.pyenv/versions/ alongside regular Python installs.
Listing virtual environments
pyenv virtualenvsThey also appear in pyenv versions — marked with the base version they were created from.
Activating / deactivating
Manual activation
pyenv activate myproject
pyenv deactivateAutomatic activation (recommended)
Tie a virtualenv to a project directory with pyenv local:
cd ~/projects/myapp
pyenv local myprojectIf you added eval "$(pyenv virtualenv-init -)" to your shell config, the virtualenv activates and deactivates automatically when you cd in and out.
Deleting virtual environments
pyenv virtualenv-delete myproject
# or equivalently
pyenv uninstall myprojectpyenv-virtualenv vs. plain venv
| Feature | pyenv-virtualenv | python -m venv |
|---|---|---|
| Managed by pyenv shims | Yes | No |
Auto-activate on cd | Yes (with virtualenv-init) | No (needs manual source) |
Lives in ~/.pyenv/versions/ | Yes | Wherever you create it |
Works with pyenv local | Yes | No |
You can use both approaches. If you prefer python -m venv, pyenv still manages which Python version you’re calling — you just won’t get auto-activation via pyenv.
Typical project setup workflow
# 1. Install the Python version you need
pyenv install 3.12.8
# 2. Create a virtualenv for your project
pyenv virtualenv 3.12.8 myapp-3.12
# 3. Bind it to your project folder
cd ~/projects/myapp
pyenv local myapp-3.12
# 4. Verify
python --version # 3.12.8
which python # ~/.pyenv/shims/python
pip install -r requirements.txtConfiguration & Environment Variables
Environment variables
| Variable | Purpose | Default |
|---|---|---|
PYENV_ROOT | Where pyenv stores versions and shims | ~/.pyenv |
PYENV_VERSION | Override the active Python version | (unset) |
PYENV_SHELL | Shell type pyenv was initialized for | auto-detected |
PYENV_VIRTUALENV_DISABLE_PROMPT | Set to 1 to stop virtualenv from modifying your prompt | 0 |
PYTHON_BUILD_MIRROR_URL | Custom mirror for downloading source tarballs | (python.org) |
PYTHON_BUILD_CACHE_PATH | Cache directory for downloaded tarballs | ~/.pyenv/cache |
PYTHON_BUILD_SKIP_MIRROR | Set to 1 to skip mirrors entirely | 0 |
Build configuration flags
Pass these before pyenv install to customise the CPython build:
# Optimised build (PGO + LTO)
PYTHON_CONFIGURE_OPTS="--enable-optimizations --with-lto" \
pyenv install 3.12.8
# Enable shared library (needed by some embedding use-cases)
PYTHON_CONFIGURE_OPTS="--enable-shared" \
pyenv install 3.12.8
# Custom OpenSSL path (useful if system OpenSSL is too old)
CPPFLAGS="-I/usr/local/opt/openssl/include" \
LDFLAGS="-L/usr/local/opt/openssl/lib" \
pyenv install 3.12.8
# Parallel build (speed up compilation)
MAKE_OPTS="-j$(nproc)" pyenv install 3.12.8Editor integration
VS Code
In .vscode/settings.json:
{
"python.defaultInterpreterPath": "~/.pyenv/versions/<version>/bin/python"
}Or let the Python extension detect pyenv automatically — it reads .python-version.
Neovim / LSP (pyright, pylsp)
Most LSP servers respect .python-version. Set pythonPath in your LSP config if auto-detection fails:
require('lspconfig').pyright.setup {
settings = {
python = {
pythonPath = vim.fn.expand("~/.pyenv/shims/python"),
},
},
}CI integration
In GitHub Actions or similar, you usually don’t need pyenv — use the setup-python action instead. But if you do want pyenv in CI:
- name: Install pyenv
run: |
curl -fsSL https://pyenv.run | bash
echo "$HOME/.pyenv/bin" >> $GITHUB_PATH
echo "$HOME/.pyenv/shims" >> $GITHUB_PATH
- name: Install Python
run: |
pyenv install 3.12.8
pyenv global 3.12.8Useful aliases
Add to your ~/.bashrc or ~/.zshrc:
alias pyls='pyenv versions'
alias pyuse='pyenv local'
alias pynew='pyenv virtualenv'
alias pydel='pyenv virtualenv-delete'Troubleshooting
Build fails immediately
Symptom: pyenv install errors out before compilation starts.
Fix: Install the full build dependency set. On openSUSE Tumbleweed:
sudo zypper install -y \
gcc make automake \
zlib-devel bzip2 libbz2-devel \
readline-devel libffi-devel \
libopenssl-devel sqlite3-devel \
xz-devel tk-devel ncurses-devel \
patch git curlRun pyenv doctor to check what’s missing.
WARNING: No module named _ssl
Symptom: Python installs but pip or https requests fail.
Cause: OpenSSL headers were missing at build time.
Fix (openSUSE Tumbleweed):
sudo zypper install libopenssl-devel libopenssl-1_1-devel
pyenv uninstall 3.12.8
pyenv install 3.12.8For older Python versions (< 3.10) that need OpenSSL 1.1:
sudo zypper install libopenssl-1_1-devel
CPPFLAGS="-I/usr/include/openssl-1_1" \
LDFLAGS="-L/usr/lib64/openssl-1_1" \
pyenv install 3.9.20ModuleNotFoundError: No module named '_lzma'
sudo zypper install xz-devel lzma-sdk-devel
pyenv uninstall <version> && pyenv install <version>ModuleNotFoundError: No module named '_sqlite3'
sudo zypper install sqlite3-devel
pyenv uninstall <version> && pyenv install <version>ModuleNotFoundError: No module named '_tkinter'
Only needed if you use tkinter (GUI):
sudo zypper install tk-devel
pyenv uninstall <version> && pyenv install <version>pyenv: command not found
Your shell config is missing the pyenv init lines, or you haven’t restarted the shell.
# Verify pyenv is on PATH
ls ~/.pyenv/bin/pyenv
# Re-add to shell config (see Installation section), then:
exec $SHELLNewly installed CLI tool not found (e.g. black, pytest)
After pip install <tool>, the shim may be stale:
pyenv rehashpython resolves to system Python instead of pyenv’s
Check the resolution order:
pyenv version # what pyenv thinks is active
which python # should be ~/.pyenv/shims/python
type python # check for shell aliases/functions shadowing itCommon causes: a conda init block in your shell rc overriding PATH, or pyenv init placed before a conflicting PATH export.
Builds are slow
Use parallel make and consider skipping tests:
MAKE_OPTS="-j$(nproc)" pyenv install 3.12.8General debugging
# Verbose install output — shows every compiler command
pyenv install -v 3.12.8
# Check pyenv health
pyenv doctor
# Print exact path to the active interpreter
pyenv which python
# Print the prefix directory
pyenv prefix