You have understood this correctly. It is not an issue with Python, but with your Linux distribution (I use Mint, so I am affected by the same). In general, every distro can be expected to have this issue with every package offered: only specific versions are available in the package repository, because those are the ones that the distro maintainers have pre-built for you.
If you want a different version of a library or application then you will have to use methods that are specific to that library or application, as documented by its author - and you no longer have the distro maintainer’s assurances about quality, security etc. (This is still much more secure than the Windows world, in which you are basically always on your own and at the mercy of the author to pre-build something for you, without any opportunity to review the source code.)
In the case of Python, the standard way to install on Linux is to build from source. While there are PPAs (third-party providers of pre-built application packages) that may carry Python, such as the “deadsnakes” PPA, the Python dev team has put a lot of effort into producing something that builds smoothly on the vast majority of Linux systems.
The basic guidance on installation is here:
However, I strongly recommend also reading the setup instructions from the Python developer’s guide, since I find they explain the actual build process much better (and point out a couple of non-obvious, useful command-line options):
On Ubuntu, the overall process typically looks something like:
$ # only the first time that you build Python from source:
$ # ensure that the system has the appropriate dependencies installed
$ # minimal dependencies:
$ sudo apt-get build-dep python3
$ sudo apt-get install pkg-config
$ # full optional dependencies:
$ sudo apt-get install build-essential gdb lcov pkg-config \
libbz2-dev libffi-dev libgdbm-dev libgdbm-compat-dev liblzma-dev \
libncurses5-dev libreadline6-dev libsqlite3-dev libssl-dev \
lzma lzma-dev tk-dev uuid-dev zlib1g-dev
$ # Next, the actual building - assuming we have cd'd
$ # into the folder for an unzipped source tarball:
$ ./configure
$ # replace the 4 here with the number of cores your processor has
$ # with some versions of make, just "-j" will work
$ make -j4 -s
$ # install in a way that won't interfere with the system Python
$ make altinstall
The Fedora python team packages the latest python at the time that a Fedora release is made as the system’s python. Fedora 39 has 3.12 for example and Fedora 41 is expected to get 3.13.
They also package many of the pervious versions as well.
At the moment that is python 3.6 through to python 3.11, but they do not package the PyPI packages for these versions.
I find this is very useful for testing my python packages against old versions.
Does it have to be Ubuntu 22.04 for some reason? Because if you use a later version of Ubuntu such as 23.10, or a distro with newer packages such as Fedora, you will have python 3.11 out of the box.
Does it have to be Ubuntu 22.04 for some reason? Because if you use a later version of Ubuntu such as 23.10, or a distro with newer packages such as Fedora, you will have python 3.11 out of the box.
I’m on Linux Mint 21.1 which is based on Ubuntu 22.04. Python 3.11
is in Ubuntu’s “universe” repo and doesn’t need an additional PPA,
let alone an own build from source.
I received message:
python3.11 is already the latest version (3.11.9-1+jammy1)
So, this indicates, that Python 3.11 is already installed, and the
confusion comes from running “python3 --version” which “still”
returns “Python 3.10.12”. It’s the same (similar) here:
Carefully note, that this is absolutely correct and expected –
this is, how it should be!
Most modern Linux distros use Python themself and Python 3.10.6 is
the “system’s Python”. On my (and the OP’s) system, 3.11 is
installed as an additional version.
Carefully note: Do not replace the system’s python! (symlinking,
overwriting, etc). The system itself needs 3.10, but you can have
any other python version installed additionally.
You could also use pyenv to install and work with multiple versions of Python, without the burden of trying to build specific versions yourselves from source.
Any supported version that is requested for installation is built from source during the installation process, and this requires Python build dependencies (for Mac this includes zlib, ncurses, and a few others I think), but there is an installer which you can use (below), and I think it will preinstall these dependencies for you, in addition to pyenv:
curl https://pyenv.run | bash
I’m on a Mac, so I installed mine via Homebrew - I have never used the installer directly, but I believe it can also manage updates with pyenv update.
Once pyenv is installed, run this
pyenv versions
to list all installed versions - for you initially it should be your 3.10.12 installation (which should be labelled as "system", depending on what your PATH looks like).
Then you can install 3.11.9 with:
pyenv install "3.11.9"
I think 3.11.9 was only added very recently. Versions are installed to ~/.pyenv/versions, and your 3.11.9 bin should be located at:
~/.pyenv/versions/3.11.9/bin/python3.11
To get the latest supported versions keep your pyenv up-to-date - with the installer I think this would be with pyenv update. Supported versions can be listed with:
python3 will continue to point to the default python that comes with the system even once a different version is installed from deadsnakes[1]. The versions installed from deadsnakes are accessible through the longer version name pythonX.Y. For example, on my Ubuntu system: