# How to Manage Multiple Python Versions With pyenv

[`pyenv`](https://github.com/pyenv/pyenv) is a powerful tool for managing multiple Python versions on a single machine. 

It allows you to easily switch between Python interpreters, ensuring compatibility across projects with varying requirements. 

This article provides a detailed walkthrough of `pyenv`, demonstrating how to use it effectively to simplify your Python development workflow.

[ad-logs]

## Prerequisites

Before exploring `pyenv`, you should be familiar with command-line operations. While you don't need to have Python pre-installed—`pyenv` can handle that for you—having some experience working with Python development environments will be beneficial.


## Why use `pyenv`?

Before diving into `pyenv`, let's understand why managing multiple Python versions is essential for modern development workflows. Here's what makes `pyenv` particularly valuable:

- Version isolation: Different projects often require different Python versions. While one might depend on Python 3.8 features, another might require Python 3.11's performance improvements.

- Global vs. local interpreters: `pyenv` allows you to set both system-wide default Python versions and project-specific versions, providing flexibility without conflicts.

- Seamless switching: Instead of manually installing and configuring multiple Python versions, `pyenv` handles the complexity of switching between interpreters with simple commands.

- No sudo required: Unlike system-wide Python installations, `pyenv` installs versions in your user directory, eliminating permission issues and system conflicts.

Think of `pyenv` as a specialized tool that gives you complete control over your Python environment, making it easy to manage multiple projects with different requirements simultaneously.

## Installing `pyenv`

In this section, you will install `pyenv`, the Python version manager that will allow you to easily switch between different Python interpreters.

Before installing `pyenv`, ensure you have the necessary build dependencies for compiling Python.

For Ubuntu/Debian:

```command
sudo apt-get update
```
```command
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev wget curl llvm libncurses-dev \
xz-utils tk-dev libffi-dev liblzma-dev python3-openssl git
```

The most straightforward way to install `pyenv` is using the official installer script:

```command
curl https://pyenv.run | bash
```

This will clone the `pyenv` repository to `~/.pyenv` and set up the necessary shell integration. After installation, you must add `pyenv` to your shell configuration file.

For bash:

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


After updating your shell configuration, restart your terminal or source the configuration file:

```command
source ~/.bashrc
```

To verify that `pyenv` has been installed successfully, run:

```command
pyenv --version
```

```text
[output]
pyenv 2.5.3
```

This output confirms that `pyenv` has been installed successfully and is ready to use.

## Getting started with `pyenv`

Now that `pyenv` is installed, let's explore its core functionality. At its heart, `pyenv` manages multiple Python versions by manipulating your shell's PATH environment variable, ensuring the correct Python interpreter is used when you run python commands.

To see which Python versions are available for installation, run:

```command
pyenv install --list
```

This will display a comprehensive list of Python versions that `pyenv` can install.

```text
[output]
Available versions:
  2.1.3
  2.2.3
  ...
  3.12.6
  3.12.7
  3.12.8
  3.12.9
  3.13.0
  3.13.0t
  3.13-dev
  3.13t-dev
  3.13.1
  3.13.1t
  3.13.2
  3.13.2t
  3.14.0a5
  3.14.0a5t
  3.14-dev
  3.14t-dev
  ...
 ```


 To install a specific version, use:

```command
pyenv install 3.13.2
```

```text
[output]
Downloading Python-3.13.2.tar.xz...
-> https://www.python.org/ftp/python/3.13.2/Python-3.13.2.tar.xz
Installing Python-3.13.2...

Installed Python-3.13.2 to /home/stanley/.pyenv/versions/3.13.2
```

You can install multiple Python versions:

```command
pyenv install 3.12.9
```

To see which Python versions you have installed:

```command
pyenv versions
```

```text
[output]
* system (set by /home/stanley/.pyenv/version)
  3.12.9
  3.13.2
```

The asterisk indicates the currently active Python version. By default, this is your system Python.

To switch to a different Python version globally:

```command
pyenv global 3.12.9
```

This sets Python 3.12.2 as your default Python interpreter. Verify the change:

```command
python3 --version
```

```text
[output]
Python 3.12.9
```

```command
which python
```

```text
[output]
/home/stanley/.pyenv/shims/python
```

Notice that `pyenv` doesn't move Python binaries—instead, it creates shims that direct commands to the appropriate Python installation.

Let's create a simple script to verify our Python environment:

```python
[label test.py]
import sys
print(f"Using Python {sys.version}")
print(f"Located at {sys.executable}")
```

Run it to confirm the active Python version:

```command
python test.py
```

```text
[output]
Using Python 3.12.9 (main, Mar 11 2025, 13:51:04) [GCC 13.3.0]
Located at /home/stanley/.pyenv/versions/3.12.9/bin/python
```

You've seen how `pyenv` simplifies Python version management by providing an interface to install, select, and manage multiple Python interpreters.

 Instead of wrestling with system paths and package conflicts, `pyenv` gives you a clean, isolated environment for each Python version.


## Working with project-specific Python versions

In the previous section, you learned how to install and set global Python versions with `pyenv`. While this works for system-wide settings, modern Python development often requires different Python versions for specific projects.

One of `pyenv`'s most powerful features is its ability to set project-specific Python versions using the `local` command. This ensures that each project automatically uses the correct Python interpreter, without requiring manual switching.

To create a project directory with a specific Python version:

```command
mkdir pyenv-demo && cd pyenv-demo
```

Set the local Python version for this project:

```command
pyenv local  3.13.2
```

This creates a `.python-version` file in your project directory:

```command
cat .python-version
```

```text
[output]
3.13.2
```

Now, whenever you enter this directory, `pyenv` automatically switches to Python 3.13.2:

```command
python --version
```

```text
[output]
Python 3.13.2
```

Let's create another project that requires a different Python version.

Move out of the current directory:

```command
cd ..
```

Create a new project directory and navigate into it:

```command
mkdir legacy-project && cd legacy-project
```
Set a different Python version for this project:

```command
pyenv local 3.12.9
```
Verify the Python version:

```command
python --version
```

```text
[output]
Python 3.12.9
```

This project-level control ensures consistent environments across your team and prevents version conflicts between projects.

For temporary usage of a specific Python version, use the `shell` command:

```command
pyenv shell 3.13.2
```

```command
python --version
```

```text
[output]
Python 3.13.2
```

This sets the Python version only for your current shell session and precedes local and global settings.

To revert to the Python version specified by local or global settings:

```command
pyenv shell --unset
```
```command
python --version
```

```text
[output]
Python 3.12.9
```

Understanding `pyenv`'s version precedence is essential:

1. `shell` - Highest priority, set by `pyenv shell`
2. `local` - Project-specific, set by `pyenv local`
3. `global` - System-wide default, set by `pyenv global`

This hierarchy gives you granular control over which Python version is used in different contexts.


## Integrating `pyenv` with virtual environments

While `pyenv` manages Python versions, virtual environments manage project dependencies. Combining these tools creates a great development workflow that ensures both interpreter and package consistency.

The `pyenv-virtualenv` plugin extends `pyenv` with virtual environment capabilities, bridging the gap between version management and dependency isolation.

First, let's return to our home directory from the `legacy-project` directory we were in:

```command
cd ~
```

Now, install the plugin:

```command
git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv
```

If you see an error indicating the directory already exists, that's fine—it means the plugin is already installed. 

Update your shell configuration to enable the plugin:


```command
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
```
```command
source ~/.bashrc
```

Now you can create virtual environments tied to specific Python versions:

```command
pyenv virtualenv 3.13.2 my-project-env
```

This creates a virtual environment named `my-project-env` using Python 3.13.2.

To activate this environment for a project. Create a new project directory and move into it:

```command
mkdir enhanced-project && cd enhanced-project
```
Set the virtual environment for this project:

```command
pyenv local my-project-env
```

Your shell prompt will update to show the active virtual environment. Install packages as usual:

```command
pip install requests numpy pandas
```

These packages are installed only in the `my-project-env` environment, isolating your project dependencies.

To list your virtual environments:

```command
pyenv virtualenvs
```

```text
[output]
  3.13.2/envs/my-project-env (created from /home/stanley/.pyenv/versions/3.13.2)
* my-project-env (created from /home/stanley/.pyenv/versions/3.13.2)
```

You can now move out of the directory:

``` command
cd ..
```

Combining `pyenv` with virtual environments creates a comprehensive solution for managing Python versions and project dependencies.

## Managing development tools with `pyenv`

As your Python projects grow in complexity, you'll likely use various development tools like formatters, linters, and testing frameworks. `pyenv` can help manage these tools effectively, ensuring they're consistently available across projects.

One approach is to create a dedicated virtual environment for development tools. 


First, create another directory and move into it:

```command
mkdir dev-dir && cd dev-dir
```
Now create a new virtual environment:

```command
pyenv virtualenv 3.13.2 dev-tools
```

Then activate this environment:

```command
pyenv activate dev-tools
```

Install commonly used development tools in this environment:

```command
pip install black pytest mypy flake8 isort
```

Now you can access these tools from any project by activating this environment. Set the shell to use this environment:

```command
pyenv shell dev-tools
```

Verify that the tools are available by checking their version:

```command
black --version
```

```text
[output]
black, 25.1.0 (compiled: yes)
Python (CPython) 3.13.2
```

Let's create a test directory to demonstrate project-specific tool configurations. First move out of the current directory:

```command
cd ..
```

Create another project:

```command
mkdir tool-test-project && cd tool-test-project
```

For project-specific tools, create a separate requirements file for development dependencies:

```command
pip freeze > dev-requirements.txt
```

This approach keeps development tools separate from runtime dependencies, creating a cleaner and more organized workflow.

Another powerful feature of `pyenv` is the ability to use specific Python versions for individual commands with the `pyenv exec` command:

```command
pyenv exec python -m pytest
```

This runs pytest using the currently active Python version, ensuring consistency between your development and testing environments.

This flexibility allows you to maintain consistent development practices across multiple projects, even when they require different Python versions.



## Final thoughts

This article explored the key features of `pyenv` to help you manage multiple Python versions effectively. With `pyenv`, you can ensure consistent development environments across projects, teams, and deployment targets.

To explore the tool more thoroughly, check out the [official documentation](https://github.com/pyenv/pyenv#readme).

Thanks for reading!