Managing multiple versions of Python using pyenv and virtualenvwrapper
Tags: python, ubuntu, productivity, tutorial
Published: 2021-11-05 16:50:28

Are you scared to use multiple versions of Python on your system? Don't worry this article will guide you towards the ultimate Python setup on Ubuntu.

Sometimes we need to work simultaneously on multiple different projects which require different versions of Python and upgrading one Python version may break another project. It's also very hard to manage package installations manually respective to each Python environment and to switch between them. This is where pyenv comes into play to make your life easier.

#### What is pyenv anyway?

The pyenv Readme describes it best:

pyenv lets you easily switch between multiple versions of Python. It's simple, unobtrusive, and follows the UNIX tradition of single-purpose tools that do one thing well. It makes managing different versions of Python very easy and user friendly.

#### How do I install it on Ubuntu?

- Let's update our local package index first:

```
sudo apt-get update
```

- Install most common Python interpreter and compile dependencies:

```
sudo apt-get install aria2 build-essential curl git libbz2-dev libffi-dev liblzma-dev libncurses5-dev libncursesw5-dev libreadline-dev libsqlite3-dev libssl-dev llvm make tk-dev wget xz-utils zlib1g-dev --yes;
```

- Install pyenv:

```
curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
```

- Install pyenv's virtualenvwrapper plugin:

```
git clone https://github.com/pyenv/pyenv-virtualenvwrapper.git "${HOME}/.pyenv/plugins/pyenv-virtualenvwrapper"
```

- Initialize and configure pyenv in your .bashrc file:

```
#### pyenv config
if [ -f "$HOME/.pyenv/bin/pyenv" ] && ! type -P pyenv &>/dev/null ; then
  export PYTHON_CONFIGURE_OPTS="--enable-shared"
  export CFLAGS="-O2"
  export PYTHON_BUILD_ARIA2_OPTS="-x 10 -k 1M"
  export PYENV_ROOT="${HOME}/.pyenv"
  export PATH="${PYENV_ROOT}/bin:${PATH}"
  eval "$(pyenv init --path)"
  eval "$(pyenv init -)"
  eval "$(pyenv virtualenv-init -)"
  if [[ ! "$(pyenv which python)" == "/usr/bin/python" ]] ; then
    pyenv virtualenvwrapper_lazy;
  fi
fi
```

- Close and reopen the terminal.

#### How do I install and use multiple versions of Python?

- To view Python versions available that pyenv can easily auto-download:

```
pyenv install -l
```

- You can check the current available and active versions of Python on your system by using the following command:

```
pyenv versions
```

- To install a new Python version:

```
pyenv install <version>
Eg:- pyenv install 3.9.6
```

- I recommend that you activate all Python versions
  that you have installed:

```
pyenv global 3.10.0 3.9.6 3.8.11 3.7.11 3.6.14 2.7.18
```

NOTE: The order of versions we put in the above command matters as the first version will be the default version.
In this case 3.10.0 will be the default version as it comes first.

- Download virtual environment tools for each corresponding Python version:

```
python3.9 -m pip install virtualenv virtualenvwrapper
```

#### Wait, but what is virtualenv and virtualenvwrapper?

As explained by [bogotobogo](https://www.bogotobogo.com/python/python_virtualenv_virtualenvwrapper.php):

> A Virtual Environment enables us to keep the dependencies required by different projects in separate places, by creating virtual Python environments.

> In other words, virtualenv is a tool to create isolated Python environments. The virtualenv creates a folder which contains all the necessary executables to use the packages that a Python project would need.

So, each project can have its own dependencies, regardless of what dependencies every other project has.

#### How to use virtualenvwrapper?

- Creating a virtual environment:

```
#Creates a virtual env with default Python version
mkvirtualenv myenv
```

```
#Creates a virtual env with specified Python version 3.8 for the below case:
mkvirtualenv -p python3.10 myenv
```

```
#Mark the current directory as the virtualenv-linked Project Directory to automatically go to the Project Directory when activating it.
mkvirtualenv -p python3.10 -a $(pwd) myenv2
```

- Deactivating the virtual env:

```
deactivate
```

- Start the virtualenv:

```
workon <name of virtual env>
E.g workon myenv
```

#### Credits

This blog post is based on:

- An informal tutorial that [Fábio C. Barrionuevo da Luz](https://github.com/luzfcb) gave me the other day in the Cookiecutter Discord. This blog post is just a glimpse of pyenv, virtualenv, virtualenvwrapper can do. A detailed and in-depth guide about these tools can be found [here](https://t.co/EwqifWLJH6?amp=1).
- I am very thankful to Fabio and [Audrey Roy Greenfeld](https://github.com/audreyfeldroy) for their patient and generous guidance. This article would not have been possible without them.