There are several subtle differences in managing versions of Python on older distributions of Ubuntu. If you're running Ubuntu 18.04 or older, go here.
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 boot camps 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.
Ubuntu 20.04 is the first LTS version of Ubuntu to drop Python2, coming fresh out of the box with Python 3.8.5. But what if you've written apps intended for a newer version of Python? If you're like me, you might have tried to replace your system's default installation and destroyed your machine. If nobody has warned you, I'll do the honors: don't do that.
The risk of unintended destruction is only one of many unintuitive details that complicate the seemingly simple task of using an updated version of Python:
apt upgrade
does not apply to versions of Python. In fact...- Newer Python distributions aren't even visible to
apt
; thus, we can't even useapt update
to find a more recent version of Python without the help of a third party. - Versions of Python installed on the same machine do not share the same core features (such as pip), leading to confusion.
What do we do?
Using Ubuntu's built-in alternative install
is optimal for several reasons:
- We can install a new version of Python in parallel to the version of Python Ubuntu depends on so we don't ruin our machine.
- It's best to avoid messing around with your Python PATH whenever possible.
- We can easily switch the active version of Python on our machine via a convenient CLI.
We will walk through how to install the latest version of Python alongside Ubuntu's system Python versions safely and (relatively) easily.
Python via Deadsnakes
Deadsnakes PPA is an actively maintained repository of Python distributions available to Ubuntu. Deadsnakes carries the burden of hosting versions of Python that have been tried and tested to work on Ubuntu (their Github organization is essentially a collection of Ubuntu-friendly Python versions).
By adding the Deadsnakes PPA, we're making these Python versions visible to our Ubuntu machines:
Upon adding this repository, you'll immediately receive a prompt explaining this verbosely. Press enter to move on.
To pick up the versions of Python that Deadsnakes makes visible to us, we still need to run a quick update:
Now check to see if the version of Python you're looking for is available for download like so:
If available, you'll see an output like so:
That's our green light! Go on and proceed to install Python:
Managing Alternative Python Installations
We now have two versions of Python installed on our machine: the system default Python 3.8.5, and our newly added Python 3.10.12. We want to leave our system's default Python installation alone, but we want to run our apps written in Python 3.10.12... so how do we manage this?
Recognizing Multiple Versions of a Package via update-alternatives
update-alternatives is a native feature of Debian-based Linux distributions and conveniently handles these scenarios. update-alternatives
is a CLI interface for installing and switching between alternative versions of packages. This applies to programming languages (like python
), text editors (like vim
), and really anything else apt
can install.
We makeupdate-alternatives
is aware of parallel versions via the --install
flag, which accepts three parameters:
- The file path to the default system location of the package we're adding alternatives for. On Ubuntu 20.04, the default location for Python3 is
/usr/bin/python3
. - Name of the package we're adding alternatives for (
python3
). - File path to an existing or newly installed version of the package. We add the existing version of a package to give ourselves the option to fall back if necessary. Adding the newly installed version allows us to switch to an alternative (likely newer) version.
- An integer used to "prioritize" our list of managed versions for human-readability purposes (for example, it is a good idea to mark the existing default version as
1
, and label subsequent versions incrementally).
Begin by adding the system's default version of Python to update-alternatives
:
Next, our newly installed version:
update-alternatives --list python3
should now list the alternative installations of python3
we've installed and added to update-alternatives
:
Swapping Between Versions
Now we can swap between versions of Python! Run the following --config
command to change the active version of Python you'd like to use:
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:
Respond to the above prompt with the selection number representing the Python version you want to use.
We've done the "hard" part, but there's a bit of housekeeping to take care of.
Finishing Touches
Now that we've switched to a freshly installed version of Python, we must install a few Python-related Ubuntu packages to ensure Python runs properly. These include pip (obviously), python-apt (necessary for Debian Python), distutils (supposedly-deprecated-but-kinda-not, and venv (to manage Python virtual environments).
First, we need to reinstall python3-apt
with our new version of Python active:
Next, we'll install distutils
, python-dev
, and python-venv
:
...And, of course pip3
:
You Did It
As absurd as it sounds, successfully updating Python on Ubuntu is a legitimate accomplishment. I've witnessed software developers of all backgrounds struggle with dumb things like "setting up Python." Some tasks are unintuitive and lack any conventional patterns or logic. Updating Python on Ubuntu is one of those tasks.
You've managed to prevail, so congratulations are in order. If you're new to Python, please don't be discouraged by how weirdly complicated this was. The miserable journey we've just embarked on is no indication of what software development is like... or any related profession, for that matter. From here on out, it's sunshine, rainbows, and snakes 🐍.