Installing Python 3 via deadsnakes PPA - lmmx/devnotes GitHub Wiki

Python 3.9 was released today so I checked conda (anaconda and conda-forge channels) before remembering the deadsnakes PPA)

Anthony Sottile maintains this PPA and I'd previously waited around for a long time to installa via conda, but since I recently got comfy using LXD containers, I'm going to try it this way for 3.9 (I expect it could be months before 3.9 lands in conda!)

Anthony recorded a video describing his new favourite features, which were broadly:

Generic types, in-place bitwise OR |= dict updates, str.removeprefix/suffix, line-buffered STDERR, ast.unparse, PEG parsing, __file__ is an abs path in interactive mode, decorators can be any expression, zoneinfo & graphlib

See What's new for more details on these features!

Containerising a deadsnakes-packaged Python with LXD

  • I'm using LXD 4.6 in the demo that follows

Since conda is a lot like a container, using LXD is a natural alternative. For a system with LXD set up (see Installing lxd), this is:

lxc launch images:ubuntu/18.04/cloud py39ubu

Creating py39ubu
Starting py39ubu
  • This command has created and started a new container using the official Ubuntu remote repo image for Ubuntu 18.04 (from Canonical), and named that container "py39ubu"

Could you do this with a more lightweight container image than the Ubuntu one? Maybe, but since Python is being distributed as a PPA I think it's best to just stick with an operating system I know will support that package installation (it doesn't take long to install)

Next I want to step inside the container (as a login shell for the default user, "ubuntu")

lxc exec py39ubu -- sudo --user ubuntu --login

To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

ubuntu@py39ubu:~$ 
  • A command line shows up here showing the user name and container name

I can now proceed to use apt-get to add the deadsnakes PPA within the container, and the PPA of the host system won't be affected (so there's no danger of messing up my host system's Python installation)

As the deadsnakes PPA site page says,

sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt-get update
apt search python3.9

This brings up 20 results (whereas running it on my host system brings up none!), the exact match for which is:

python3.9/bionic,now 3.9.0-1+bionic1 amd64 [installed] Interactive high-level object-oriented language (version 3.9)

  • The other packages are development/debugging packages etc.

So now, within the container:

sudo apt install python3.9

We can run python3.9 now:

python3.9

Python 3.9.0 (default, Oct  5 2020, 19:47:55) 
[GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

and we're set.

Note that it's also possible to set up a profile for LXD to create this from scratch, or we can save the image and discard the container. I'll demo this now.

lxc snapshot py39ubu addedsnake
lxc publish py39ubu/addedsnake --alias ubu18_py39

This takes a little while but afterwards you can discard the container and just recreate it from this locally stored image. Its size can be found by running lxc image list (183.81MB). Not bad! For comparison, the Ubuntu image it's based on was 108MB and the image I installed Firefox and X11 capabilities in was almost 400MB.

  • the plain Ubuntu image can now be deleted with lxc image delete FINGERPRINT using the fingerprint shown next to it in the table output from lxc image list

I won't delete the container just yet while I try it out, but when I'm done with it I can remove it with

lxc delete -f py39ubu

which is a 'forced deletion', i.e. equivalent to:

lxc stop py39ubu
lxc delete py39ubu

Python 3.9 capabilities

To compare the two both within the same container I can open a new tmux pane (or another terminal if you don't use tmux terminal multiplexer) and again start a login shell for the container I called "py39ubu"

lxc exec py39ubu -- sudo --user ubuntu --login

Again this steps into the login shell, showing ubuntu@py39ubu

which python3

/usr/bin/python3

So this is the containerised system's python, and its version is...

python3 --version

Python 3.6.9

Passing the --version flag twice shows

python3 --version --version

Python 3.6.9 (default, Jul 17 2020, 12:50:27) 
[GCC 8.4.0]

which I presume indicates when the Ubuntu 18.04 package for python3 was last released on its default branch

Anyway, some examples of what we can do now

"Hello Python 3.9!!!".removesuffix("!!")

'Hello Python 3.9!'
  • notice how the command only removed 2 of the 3 exclamation marks

Whereas in ye olde Python 3.6.9 all we can have by way of suffix removing string methods is the 'greedy' rstrip:

"Hello Python 3???".rstrip("?")

'Hello Python 3'
  • notice how the command stripped off all 3 of the question marks

It's the little improvements that count, I'm looking forward to using this more but will probably have to wait for conda to package it up. In the meantime I can just spin up an LXD container to try it out with

lxc launch ubu18_py39 my-bleeding-edge-py39-proj
  • as I recall (and from what I can see on my system), container names can only contain hyphens and alphanumeric characters whereas image names (aliases to be precise) can also contain underscores
    • I remade the image and renamed my example code above to call the image ubu18_py39 in this guide to reflect this, so I'll be able to tell at a glance that underscores are for image aliases and hyphens are for container names
⚠️ **GitHub.com Fallback** ⚠️