How to Install and Manage Python Versions on WSL Ubuntu

4 min read

Different projects often need different Python versions. This guide covers two ways to manage Python versions on WSL Ubuntu: pyenv (recommended) for per-project version control, and update-alternatives for switching between system-installed versions.

The examples in this guide are run on WSL2 Ubuntu in Windows, but they work the same on any Ubuntu system.

Prerequisites

Both methods need build dependencies for compiling Python from source. Install them first:

sudo apt update && sudo apt install -y make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncursesw5-dev \
xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev git

Method 1: pyenv (Recommended)

pyenv lets you install any Python version and switch between them per project — without touching your system Python. It works like nvm does for Node.js.

Step 1: Install pyenv

Clone the pyenv repository and add it to your shell:

git clone https://github.com/pyenv/pyenv.git ~/.pyenv

Add pyenv to your ~/.bashrc:

echo '' >> ~/.bashrc
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init --path)"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc

Load the changes:

source ~/.bashrc

Verify pyenv is working:

pyenv --version

Step 2: Install a Python Version

See what’s available:

pyenv install --list | grep "^\s*3\."

Install a version (this compiles from source, so it takes a few minutes):

pyenv install 3.12.7

Install as many versions as you need:

pyenv install 3.11.10
pyenv install 3.13.1

Step 3: Set Your Default Python Version

Set a global default that applies to all new terminal sessions:

pyenv global 3.12.7

Verify:

python --version

Step 4: Set Per-Project Python Versions

This is where pyenv really helps. Set a specific Python version for a project directory:

cd ~/projects/my-app
pyenv local 3.11.10

This creates a .python-version file in the directory. Whenever you cd into this folder, pyenv automatically switches to that version. Commit this file to your repo so your team uses the same version.

List all installed versions:

pyenv versions

Create Virtual Environments with pyenv

pyenv manages Python versions. For isolated project dependencies, add the pyenv-virtualenv plugin.

Install pyenv-virtualenv

git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
source ~/.bashrc

Create and Use a Virtual Environment

Create a virtualenv tied to a specific Python version:

pyenv virtualenv 3.12.7 my-project-env

Activate it manually:

pyenv activate my-project-env

Or set it as the local version for a project directory so it activates automatically:

cd ~/projects/my-app
pyenv local my-project-env

Now every time you cd into ~/projects/my-app, the virtualenv activates. When you leave the directory, it deactivates.

Method 2: update-alternatives (System-Level)

If you only need to switch between Python versions installed through apt (not per-project), update-alternatives works. This is a system-level tool built into Ubuntu.

Step 1: Install Additional Python Versions

Ubuntu only ships with one Python version. To install others, add the deadsnakes PPA:

sudo apt install -y software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update

Install the versions you need:

sudo apt install -y python3.11 python3.12

Step 2: Register Versions with update-alternatives

Register each version. The number at the end is the priority — higher means it’s preferred by default:

sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 2

Step 3: Switch Between Versions

Choose which version python3 points to:

sudo update-alternatives --config python3

You’ll see a numbered list. Enter the number of the version you want, then verify:

python3 --version

pyenv vs update-alternatives

Feature pyenv update-alternatives
Per-project versions Yes (.python-version) No (system-wide only)
Any Python version Yes (compiles from source) Only what’s in apt/PPA
Virtual environments Yes (with pyenv-virtualenv) No (use venv separately)
Requires sudo No Yes
Best for Development across multiple projects Simple system-wide default

Useful pyenv Commands

Command What it does
pyenv install --list Lists all available Python versions
pyenv install 3.12.7 Installs a specific version
pyenv global 3.12.7 Sets the default version
pyenv local 3.11.10 Sets version for current directory
pyenv versions Lists all installed versions
pyenv uninstall 3.11.10 Removes a version
pyenv which python Shows path to the active Python binary

Conclusion

Use pyenv if you work on multiple projects with different Python requirements — it handles versions, per-directory switching, and virtual environments. Use update-alternatives if you just need to change the system-wide default.

For better code quality in your Python projects, check out How to Use Flake8 and Black for Python Code Quality or set up pre-commit hooks on Ubuntu WSL 2.