Ultimate mega master compatibility table
OK let's do this:
Python 3.x
+-----------------+
| 13 12 11 10 9 8 |
+-------+-----------------+
| 24.10 | M D |
| 24.04 | D |
| 22.04 | M D |
| 20.04 | M D |
+-------+-----------------+
Search for official PPAs
https://askubuntu.com/questions/1398568/installing-python-who-is-deadsnakes-and-why-should-i-trust-them asks if the popular deadsnakes PPA is trustworthy. While it is not maintained by Canonical employees directly (huge missed opportunity!), at least one of the developers, Anthony Sottile, has a video of hiself presenting the project: https://www.youtube.com/watch?v=Xe40amojaXE So at least we know that if it is a SCAM we have at least one American head to go after which gives it some confidence.
pyenv
https://github.com/pyenv/pyenv
Pyenv allows you to manage multiple Python versions without sudo for a single user, much like Node.js NVM and Ruby RVM.
Install Pyenv:
curl https://pyenv.run | bash
Then add to your .bashrc:
export PATH="${HOME}/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
Find Python version to install:
pyenv install --list
Install the python version you want:
# Increase the chances that the build will have all dependencies.
# https://github.com/pyenv/pyenv/wiki/Common-build-problems
sudo apt build-dep python3
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
xz-utils tk-dev libffi-dev liblzma-dev python-openssl git
# Build and install a Python version from source.
pyenv install 3.8.0
List available Python versions:
pyenv versions
We now have:
* system (set by /home/cirsan01/.pyenv/version)
3.8.0
Select a different python version:
pyenv global 3.8.0
python --version
python3 --version
Both output:
Python 3.8.0
We can now proceed to install and use packages normally:
pip install cowsay
python -c 'import cowsay; cowsay.tux("Python is fun")'
cowsay 'hello'
We can confirm that everything is locally installed in our clean environemnt with:
python -c 'import cowsay; print(cowsay.__file__)'
gives:
/home/ciro/.pyenv/versions/3.8.0/lib/python3.8/site-packages/cowsay/__init__.py
and:
which cowsay
gives:
/home/ciro/.pyenv/shims/cowsay
and:
which python
gives:
/home/ciro/.pyenv/shims/python
Per project usage
In the previous section, we saw how to use pyenv in a global setup.
However, what you usually want is to set a specific python and package version on a per-project basis. This is how to do it.
First install your desired Python version as before.
Then, from inside your project directory, set the desired python version with:
pyenv local 3.8.0
which creates a file .python-version containing the version string.
And now let's install a package locally just for our project: TODO: there is no nice way it seems: Pyenv choose virtualenv directory
Now, when someone wants to use your project, they will do:
pyenv local
which sets the Python version to the correct one.
Tested on Ubuntu 18.04, pyenv 1.2.15.
Conda
I'm not a huge fan of conda's bloatedness, but for better or worse it has become a popular way to manage Python versions and prebuilt shared libraries.
Install miniconda on Linux with:
mkdir -p ~/miniconda3
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh
bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3
rm ~/miniconda3/miniconda.sh
and add this to your .bashrc:
PATH="$PATH:$HOME/miniconda3/bin"
then to create a new environment for a project with a specific Python version:
conda create -y -n mytest3.9 python=3.9
and then for each shell where you want to use it in:
eval "$(command conda 'shell.bash' 'hook' 2> /dev/null)"
conda activate mytest3.9
then:
python --version
gives:
Python 3.9.21
and:
which python
gives:
/home/ciro/miniconda3/envs/mytest3.9/bin/python
It also ships its own pip:
which pip
giving:
/home/ciro/miniconda3/envs/mytest3.9/bin/pip
from which you can pip install as in a virtualenv.
You can also let conda modify your .bashrc automatically for you with:
conda init
but unfortunately the code it adds automatically puts you into Conda on every shell which I don't like, so I prefer to do the eval manually per shell as mentioned at: Python - Activate conda env through shell script
Tested on conda 25.1.1, Ubuntu 24.10.
Related threads
apt-cache searchfor python and see if there is other package for 2.7? It is possible that the default package for python is 2.6.apt-cache search <query> | more. That should let you scroll through them more slowly and have a gander.