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.
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:
sudo apt-get update
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:
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:
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
After updating your shell configuration, restart your terminal or source the configuration file:
source ~/.bashrc
To verify that pyenv
has been installed successfully, run:
pyenv --version
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:
pyenv install --list
This will display a comprehensive list of Python versions that pyenv
can install.
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:
pyenv install 3.13.2
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:
pyenv install 3.12.9
To see which Python versions you have installed:
pyenv versions
* 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:
pyenv global 3.12.9
This sets Python 3.12.2 as your default Python interpreter. Verify the change:
python3 --version
Python 3.12.9
which python
/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:
import sys
print(f"Using Python {sys.version}")
print(f"Located at {sys.executable}")
Run it to confirm the active Python version:
python test.py
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:
mkdir pyenv-demo && cd pyenv-demo
Set the local Python version for this project:
pyenv local 3.13.2
This creates a .python-version
file in your project directory:
cat .python-version
3.13.2
Now, whenever you enter this directory, pyenv
automatically switches to Python 3.13.2:
python --version
Python 3.13.2
Let's create another project that requires a different Python version.
Move out of the current directory:
cd ..
Create a new project directory and navigate into it:
mkdir legacy-project && cd legacy-project
Set a different Python version for this project:
pyenv local 3.12.9
Verify the Python version:
python --version
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:
pyenv shell 3.13.2
python --version
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:
pyenv shell --unset
python --version
Python 3.12.9
Understanding pyenv
's version precedence is essential:
shell
- Highest priority, set bypyenv shell
local
- Project-specific, set bypyenv local
global
- System-wide default, set bypyenv 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:
cd ~
Now, install the plugin:
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:
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
source ~/.bashrc
Now you can create virtual environments tied to specific Python versions:
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:
mkdir enhanced-project && cd enhanced-project
Set the virtual environment for this project:
pyenv local my-project-env
Your shell prompt will update to show the active virtual environment. Install packages as usual:
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:
pyenv virtualenvs
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:
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:
mkdir dev-dir && cd dev-dir
Now create a new virtual environment:
pyenv virtualenv 3.13.2 dev-tools
Then activate this environment:
pyenv activate dev-tools
Install commonly used development tools in this environment:
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:
pyenv shell dev-tools
Verify that the tools are available by checking their version:
black --version
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:
cd ..
Create another project:
mkdir tool-test-project && cd tool-test-project
For project-specific tools, create a separate requirements file for development dependencies:
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:
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.
Thanks for reading!
Make your mark
Join the writer's program
Are you a developer and love writing and sharing your knowledge with the world? Join our guest writing program and get paid for writing amazing technical guides. We'll get them to the right readers that will appreciate them.
Write for us
Build on top of Better Stack
Write a script, app or project on top of Better Stack and share it with the world. Make a public repository and share it with us at our email.
community@betterstack.comor submit a pull request and help us build better products for everyone.
See the full list of amazing projects on github