Managing Multiple Versions of Python on Ubuntu
Tags: devops, architecture, python
Published: 2019-12-06 21:00:58

---
title: Managing Multiple Versions of Python on Ubuntu
published: true
date: 2019-12-03 01:48:00 UTC
tags: DevOps,Architecture,Python
canonical_url: https://hackersandslackers.com/https://hackersandslackers.app/multiple-versions-python-ubuntu/
---

 ![Managing Multiple Versions of Python on Ubuntu](https://res-1.cloudinary.com/hackers/image/upload/q_auto:best/v1/2019/12/pythononubuntu.jpg)

One of my earliest frustrations with Python development had nothing to do with Python itself, but rather the needlessly esoteric _act of deploying a Python app._ Code bootcamps and tutorials do a fine job of teaching students how to run Python code locally, but the most meaningful applications don't run on local machines: they run on _servers_, on the _internet_, because that's the _point_, isn't it? Maybe I'm taking crazy pills here.

Depending  on which version of Ubuntu you're running, your VPS probably shipped with either **Python 2.7** , or both **Python 2.7** and **Python 3.6**. But what if you don't want to run either of those versions? If you're like me, you might have tried to replace your system's default installation and [destroyed your machine](https://hackersandslackers.com/so-youve-fucked-up-your-python-path/) in the process. In case nobody has told you not to do that, I'll do the honors: **don't do that**.

So what _do_ we do? There are a couple of options, including the popular solution of using [pyenv](https://github.com/pyenv/pyenv) to manage multiple Python installations. That's a totally acceptable solution, but won't be the one we explore today for various reasons because:

1. I hate the way pyenv/virtualenv handle virtual environments compared to [Pipenv](https://hackersandslackers.com/pipenv-python-environment-management/)/[Poetry](https://hackersandslackers.com/python-poetry/) (miss me with that `$ source venv/bin/activate` shit),
2. It's probably best to avoid messing around with your Python PATH where possible, and
3. Using Ubuntu's built-in "alternative install" manager is actually easier to implement.

We're going to walk through how to install the current latest version of Python ([Python 3.8](https://www.python.org/downloads/release/python-380/)) alongside Ubuntu's system Python versions safely and easily.

## Downloading the Latest Python Version

The first step should be familiar: we need to update Ubuntu's mirrors and packages to make sure we pull the latest packages when we install anything:

```
$ apt update && apt upgrade -y
```

Installing Python fresh on a Ubuntu machine requires us to install a whole bunch of prerequisite libraries that Python depends on. I'm honestly not even sure what half of these do, and neither of us will probably ever need to. Trust me, it' a required step:

```
$ sudo apt-get install build-essential checkinstall
$ sudo apt-get install libreadline-gplv2-dev libncursesw5-dev libssl-dev \
    libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev zlib1g-dev
```

This is where a lot of people might turn to installing Python via Ubuntu's package manager with `apt-get install python3.X`. Instead, we're going to download and build the latest Python version from _source_. There are a few reasons to do this; if a Python version is new enough, some Ubuntu machines might have updated mirrors to find the newest version of Python. More importantly, it's easier to manage multiple Python installations this way.

The lines below will download a compressed **Python 3.8** archive to your **/opt** folder and unzip it:

```
$ cd /opt
$ sudo wget https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tgz
$ sudo tar xzf Python-3.8.0.tgz
```

Cool. We have Python downloaded; now we just need to install it... correctly.

## Alt-Installing Python from Source

The frustration of installing Python with `apt-get install python3.X` is that it'll install Python just fine, but Ubuntu will still default to using whichever version of Python is the default. Luckily for us, Ubuntu allows us to install _additional_ (AKA: alternative) versions of Python by providing us with the `make altinstall` command:

```
$ cd Python-3.8.0
$ sudo ./configure --enable-optimizations
$ sudo make altinstall
```

This may take a moment to complete. Once finished, go ahead and verify that the version of Python 3 you wanted is installed on your box:

```
$ python3 --version
Python 3.8.0
```

And there it is! A shiny new Python: Python 3.8. Ubuntu conveniently makes this the default for us.

### Managing Alternative Python Installations

So, we now have a few versions of Python installed on our machine. There's a system default Python 2.7, A system default Python 3, and now our newly added Python 3.8. We want to leave our system default Python installations alone, but we want to develop in Python 3.8.... so how do we manage this?

Luckily, Linux has us covered in this scenario with the [update-alternatives](https://linux.die.net/man/8/update-alternatives) command. We can tell Ubuntu that we have a bunch of alternative versions of the same software on our machine, thus giving us the ability to switch between them easily. Here's how it works:

```
$ update-alternatives --install /usr/bin/python python /usr/bin/python3.6 1
$ update-alternatives --install /usr/bin/python python /usr/bin/python3.8 2

```

We ran `update-alternatives` twice: once for Python 3.6, and once for Python 3.8 (don't worry about Python 2.7, your system knows about it... trust me). Now we can use `update-alternatives --list` to list all the alternative installations we have of certain software:

```
$ update-alternatives --list python
/usr/bin/python3.6
/usr/local/bin/python3.8
```

Now we can swap between versions of Python! Run the following:

```
$ update-alternatives --config python
```

You should be hit with a prompt like the one below. This will list all the versions of Python your system recognizes. Select the version of Python you'd like to use by providing the "selection" number to the prompt:

```
There are 2 choices for the alternative python (providing /usr/bin/python).

  Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/local/bin/python3.8 2 auto mode
  1 /usr/bin/python3.6 1 manual mode
  2 /usr/local/bin/python3.8 2 manual mode

Press <enter> to keep the current choice[*], or type selection number: 
```

And you've done it! To switch Python versions, all you need to do is respond to the above prompt with the selection number representing the Python version you want to use.

It sounds absurd, but succeeding at changing Python versions in Ubuntu without breaking things is fairly impressive. I'd argue this is mostly the fault of those who teach Python. If "those who can't do, teach," it's fair to assume a lot of Python courses are taught by those who haven't launched meaningful software. That was harsh, but don't @ me regardless.

We've done the "hard" part, but there's a bit of housekeeping to take care of. We still need to install **pip** for our newly installed Python, as well as upgrade pip to the latest version:

```
$ apt install python3-pip
$ python3.8 -m pip install --upgrade pip
```

That's all there is to it!