7 minutes
Pyenv: Install and manage different Python versions

Why Do You Need Different Python Versions?
Why would you want to install another Python version than the one your system already ships with?
Well, the default Python version that is bundled with your system is usually way too old and might not have what you need. For instance, Python 3.11 is now 10~60% faster than 3.10 which is a huge improvement and can improve your applications and scripts runtime.
In this post, I will explain how to install Pyenv and then optionally, integrate it with my favorite shell, fish on an Ubuntu machine.
What is Pyenv?
pyenv is a tool that allows you to easily manage and switch between multiple versions of Python on a single machine. It allows you to specify the version of Python that you want to use for a particular project, and it will automatically modify your environment so that the desired version of Python is used when you run your scripts or use the Python interpreter.
Pyenv Installation
- Get the installer:
cd /tmp/
curl -s -S -L -o pyenvInstaller.sh https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer
- Install it:
bash pyenvInstaller.sh
Pyenv installer depends on Git. If you do not have it installed, you can do so by running “sudo apt install -y git”
Right after the installation is done, we are presented with this message:
# Load pyenv automatically by appending
# the following to
~/.bash_profile if it exists, otherwise ~/.profile (for login shells)
and ~/.bashrc (for interactive shells) :
export PYENV_ROOT="$HOME/.pyenv"
command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
# Restart your shell for the changes to take effect.
# Load pyenv-virtualenv automatically by adding
# the following to ~/.bashrc:
eval "$(pyenv virtualenv-init -)"
- so, let’s modify the
.bashrcfile and add the required commands.
cat <<EOF>> ~/.bashrc
export PYENV_ROOT="\$HOME/.pyenv"
command -v pyenv >/dev/null || export PATH="\$PYENV_ROOT/bin:\$PATH"
eval "\$(pyenv init -)"
eval "\$(pyenv virtualenv-init -)"
EOF
- All good! Next,
sourcethe.bashrcfile for our changes to take effect:
source ~/.bashrc
Running pyenv --version should give you an output similar to the result below:
$ pyenv --version
pyenv 2.3.9
Exploring the Available Python Versions
It is time to explore the plethora of the available Python versions at our fingertips. Say, you want to install the CPython (default and mainstream Python) implementation of Python version 3.11.
The command below lists all the available Python versions and I just narrow down the list to what I actually look for:
pyenv install --list | grep "^ 3.11"
3.11.0
3.11-dev
3.11.1
Install a Custom Version of Python
Some dependencies are required for pyenv to successfully build and install your desired Python version. Chances are that you already have them. Although it is better to make sure they are installed by running:
sudo apt update
sudo apt install -y gcc build-essential libffi-dev python3-pip
With all that our of the way, let’s install Python 3.11.1:
pyenv install 3.11.1
pyenvputs the Python binaries inside~/.pyenv/versionsdirectory.
After the installation, run the interpreter to make sure everything is fine:
~/.pyenv/versions/3.11.1/bin/python3
Using the New Python Version
There are a few ways to utilize the new Python version:
- Invoke the executable directly on your apps,
~/.pyenv/versions/3.11.1/bin/python3 app.py - Add
~/.pyenv/versions/3.11.1/bin/to your$PATH - Leverage
pyenv local 3.11.1 - Use
virtualenvs
The first two options are just not convenient and spiral out of control once you have a few different versions installed.
The third option is quite clever; it generates a .python-version file in the current directory and runs python 3.11.1 when you use the Python command inside that directory and its sub-directories.
The fourth option, virtual environment is my favorite way of managing different Python versions.
Let’s see how to use them.
Python Virtual Environments
A Python virtual environment or venv is a tool used to isolate specific Python environments on a single machine, allowing you to work on multiple projects with different software requirements concurrently and in a safe manner.
To give a simplified example, it enables you to have:
- Project A with
Python 3.8andrequestslibrary version 1 - Project B with
Python 3.11.1andrequestslibrary version 2
While for instance your system’s default Python version is 3.6.
Virtual environments will keep your Python versions and your project’s dependencies in a safe and fluffy place, ensuring that you don’t accidentally break your system (in case of Linux/Mac OS) and that there are no interference between different projects.
Creating a venv is pretty straightforward:
python3 -m venv /tmp/test
Now, we need to activate the virtual environment:
source /tmp/test/bin/activate
This will slightly change your Bash prompt, indicating that we are in a venv:
(test) pouriya@dev:/tmp$ python -V
Python 3.6
Notice the
(test); name of thevenvwe just created in the Bash prompt and the Python version which is my system’s default.
Exit from the venv by issuing:
deactivate
This will again change your Bash prompt by removing
(test), indicating that we are no longer in avenv.
At this point, you might wonder what happened to version 3.11.1 and why do we see version 3.6 instead?
It all lies withing the fact that we just ran python3 -m venv /tmp/test which uses my default system’s Python installation. In order to make a specific venv version, we need to explicitly specify it:
~/.pyenv/versions/3.11.1/bin/python3 -m venv /tmp/3.11
Activate it and check the version:
$ source /tmp/3.11/bin/activate
(3.11) pouriya@3dc918f6bff8:/tmp$ python -V
Python 3.11.1
Better Virtual Environment Management with virtualenvwrapper
virtualenvwrapper is a set of shell scripts that provide additional functionality for managing Python virtual environments which works on top of virtualenv. It provides several features that can make it easier to work with virtual environments, such as:
- A set of commands for creating, deleting, and managing virtual environments.
- A centralized location for storing all of your virtual environments, making it easier to organize and manage them.
- The ability to specify a default Python interpreter for each virtual environment.
- The ability to set
environment variablesfor each virtual environment.
Install virtualenvwrapper
- Let’s start off by installing the
virtualenvwrapper:
pip3 install virtualenvwrapper
Take a note of where virtualenvwrapper.sh will be placed according to the output. Mine was placed in ~/.local/bin/
Most modern text editors and IDEs can automatically detect and activate a venv if:
- The
venvis in the same directory as your project - There’s a directory called
.virtualenvsin your$HOME
- I prefer to have all of my
venvs in one location, so I’ll create a new directory under the$HOMEdirectory:
mkdir -p ~/.virtualenvs
- Modify the
~.bashrcto specify the location of yourvenvs and to initializevirtualenvwrapperwhenever you open a new shell:
cat <<EOF>> ~/.bashrc
export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
export WORKON_HOME=~/.virtualenvs
source ~/.local/bin/virtualenvwrapper.sh
EOF
sourcethe file for the changes to take effect:
source ~/.bashrc
Now, we will have some new commands such as:
mkvirtualenv: Creates a new virtual environmentrmvirtualenv: Deletes a virtual environmentworkon: Activates a virtual environment
Create Python venvs using virtualenvwrapper
Let’s create a new venv called p3.11 using Python 3.11.1:
mkvirtualenv p3.11 -p ~/.pyenv/versions/3.11.1/bin/python3
The venv also gets activated by the command above.
Take note of the argument -p For this environment, it instructs the virtualenvwrapper to use Python 3.11.1. Otherwise, the system’s built-in Python would be utilized.
If you have multiple venvs, you can easily switch between them using the workon command:
workon p3.11
workon p3.10
workon dev
workon test
Exiting from a venv is similar to what I previously showed, just type deactivate and done.
Deleting a venv is achieved by running:
rmvirtualenv p3.11
Make sure you deactivate the venv before deleting it.
In case you faced errors complaining about command not found or PATH, just add the $HOME directory to the system PATH:
export PATH=~/.local/bin:$PATH
Optionally, make it consistent by adding it to the ~/.bashrc file.
export PATH=~/.local/bin:$PATH
Fish Shell Integration
I assume you already have fish installed on your system. Otherwise you can follow the steps mentioned here.
- Install the VirtualFish which is a Python virtual environment manager for the Fish shell. I am going to shorten the steps mentioned in the official documentation.
python3 -m pip install --user virtualfish
This will place the files under ~/.local/bin/ directory. Make sure it is included in the
$PATHas depicted in the previous section.
- Install the
VirtualFishloader by running:
vf install
- Install the plugins:
vf install compat_aliases projects environment
- Add the plugins:
vf addplugins compat_aliases projects environment
- Customize your
fish_promptby editing~/.config/fish/functions/fish_prompt.fishand adding the following lines somewhere in the middle of the file:
if set -q VIRTUAL_ENV
echo -n -s (set_color -b blue white) "(" (basename "$VIRTUAL_ENV") ")" (set_color normal) " "
end
- Apply the changes:
exec fish
Now, you should be able to use the virtualenvwrapper with the fish shell.
Summary
In this post I demonstrated how to utilize pyenv and virtualenvwrapper to manage and maintain multiple Python versions on your system in an organized way and gradually, we worked our way towards integrating it all with the fish shell.
I hope this post helps you and improve your development experience.
Python Python_3.11 Pyenv Manage Python versions virtual_env Linux Ubuntu fish_shell
1484 Words
2023-01-01 09:15