Install the Latest Python on CentOS, Rocky Linux and RHEL

Build the latest Python 3 from source on Rocky Linux, AlmaLinux, CentOS Stream or RHEL, with a script that finds the newest release on python.org for you.

On this page

Updated September 2026. I wrote this post in 2019 for Python 3.7 on CentOS 7. CentOS 7 reached end of life in June 2024, so the guide now targets the RHEL 9 family (RHEL, Rocky Linux, AlmaLinux and CentOS Stream 9), and it installs the latest Python 3 release instead of a fixed version.

The Python that comes with RHEL-based systems is usually a few versions behind. RHEL 9 ships Python 3.9, with a couple of newer versions available as extra packages. If you want the newest release, you need to build it from source. In this post, I will go through installing the build dependencies, finding the latest version on python.org automatically, and building it without touching the system Python.

Install Build Dependencies

Some of the -devel packages are in the CRB repository, so we enable it first:

sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --set-enabled crb

On RHEL itself, the same repository is called CodeReady Builder:

sudo subscription-manager repos --enable codeready-builder-for-rhel-9-$(arch)-rpms

Now install the compiler and the libraries Python needs:

sudo dnf groupinstall -y "Development Tools"

sudo dnf install -y gcc make wget tar xz \
    openssl-devel bzip2-devel libffi-devel zlib-devel xz-devel \
    readline-devel sqlite-devel tk-devel gdbm-devel ncurses-devel \
    libuuid-devel

Each library turns on a part of Python. Without openssl-devel, pip can’t download packages over HTTPS. Without libffi-devel, there is no ctypes. Without sqlite-devel, there is no sqlite3, and without tk-devel, there is no tkinter. The build still finishes if one is missing, so it’s easy to miss.

Find the Latest Version Automatically

Instead of hardcoding a version number, we can read the latest release from the Python source downloads page:

PY_VERSION=$(curl -fsSL https://www.python.org/downloads/source/ \
    | grep -oP 'Latest Python 3 Release - Python \K[0-9.]+' | head -n 1)
PY_MINOR=${PY_VERSION%.*}
echo "Latest Python: $PY_VERSION"

When I ran this in September 2026, it printed 3.14.7. PY_MINOR holds the short version (3.14), which is the name of the command we get at the end.

If you need a specific version instead, set it yourself:

PY_VERSION=3.13.5
PY_MINOR=${PY_VERSION%.*}

Download and Build Python

Download the source archive for that version and extract it:

cd /tmp
wget "https://www.python.org/ftp/python/${PY_VERSION}/Python-${PY_VERSION}.tar.xz"
tar -xf "Python-${PY_VERSION}.tar.xz"
cd "Python-${PY_VERSION}"

Then configure and build it. --enable-optimizations runs the test suite to profile the build, so it takes a while (10 to 30 minutes, depending on the machine), but the resulting Python is noticeably faster:

./configure --enable-optimizations --with-lto
make -j "$(nproc)"

There is no need to run configure or make as root. Only the install step needs sudo:

sudo make altinstall

altinstall installs Python as /usr/local/bin/python3.14 and pip3.14 and leaves python3 alone. make install would also create python3 in /usr/local/bin, which shadows the system Python for every user.

Check the Installation

Check the version and make sure the optional modules were built:

python${PY_MINOR} --version
python${PY_MINOR} -c "import ssl, sqlite3, ctypes, lzma, bz2, readline, uuid; print('all modules OK')"

If one of the imports fails, scroll back through the make output. Near the end, it prints “The necessary bits to build these optional modules were not found” with the list of modules it skipped. Install the matching -devel package and run make and sudo make altinstall again.

If the shell can’t find python3.14, add /usr/local/bin to your PATH in ~/.bashrc:

export PATH=$PATH:/usr/local/bin

Don’t Replace the System python3

In the original version of this post, I linked the new Python to /usr/bin/python3. Don’t do that. On RHEL 9, dnf and other system tools run on /usr/bin/python3, and replacing it can break the package manager.

Use the versioned command, or better, create a virtual environment for each project:

python${PY_MINOR} -m venv ~/venvs/myproject
source ~/venvs/myproject/bin/activate
python --version
pip install --upgrade pip

Inside the virtual environment, python and pip point to the new version.

The Whole Thing as One Script

Here are all the steps in one script. Save it as install-latest-python.sh and run it with bash install-latest-python.sh:

#!/usr/bin/env bash
set -euo pipefail

sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --set-enabled crb
sudo dnf groupinstall -y "Development Tools"
sudo dnf install -y gcc make wget tar xz \
    openssl-devel bzip2-devel libffi-devel zlib-devel xz-devel \
    readline-devel sqlite-devel tk-devel gdbm-devel ncurses-devel \
    libuuid-devel

PY_VERSION=${PY_VERSION:-$(curl -fsSL https://www.python.org/downloads/source/ \
    | grep -oP 'Latest Python 3 Release - Python \K[0-9.]+' | head -n 1)}
PY_MINOR=${PY_VERSION%.*}
echo "Installing Python $PY_VERSION"

cd /tmp
wget -q "https://www.python.org/ftp/python/${PY_VERSION}/Python-${PY_VERSION}.tar.xz"
tar -xf "Python-${PY_VERSION}.tar.xz"
cd "Python-${PY_VERSION}"
./configure --enable-optimizations --with-lto
make -j "$(nproc)"
sudo make altinstall

"/usr/local/bin/python${PY_MINOR}" --version

To install a specific version instead of the latest one, pass it in: PY_VERSION=3.13.5 bash install-latest-python.sh.

Upgrading Later

When a new version comes out, run the script again. altinstall keeps each minor version side by side, so installing 3.15 doesn’t touch 3.14. A patch release, like 3.14.7 to 3.14.8, replaces the earlier build of the same minor version. Virtual environments keep pointing to the Python they were created with, so recreate them after a minor version upgrade.

Still on CentOS 7?

CentOS 7 no longer gets updates, and its package repositories moved to vault.centos.org. Recent Python versions also need a newer OpenSSL than CentOS 7 ships. If you can, move to Rocky Linux 9 or AlmaLinux 9. They are drop-in replacements, and the steps above work on them as written.

Please let me know if you had any questions or concerns in the comment section.

Written by Sina Fathi-Kazerooni

Lead AI Engineer. I write about reinforcement learning, transformers, multi-agent systems, and the tools I build along the way.