Install Latest Python on CentOS 7

There are many options to install newer Python on CentOS, including building from source, installing from EPEL, installing from Software Collections (SCL), installing third party rpm package, etc. These all work to some degree of success. I had a different use case and could not find a pre-built rpm package to fit it.

My use case had these restraints:

  • Install newer Python alongside the default system version
  • Install multiple Python versions simultaneously
  • Install the latest release from upstream Python project not just the latest release from a repository (repo)
  • Do not build from source unless absolutely necessary

Unfortunately, even after trying for a good part of three days I could not take a source rpm (srpm) and modify it to fit these restraints. Some of my assumptions that proved false include:

  • Edit ~/.rpmmacros replace _prefix /usr with _prefix /usr/local
  • Make the package relocatable with Prefix: /usr/local in the spec file

The easiest way I found to get the latest Python 2.7 was to replace the system version with a newer rpm package. Python 3 is in a much better position when you use the IUS repo.

UPDATE (2016-04-20): I have created a companion git repo that provides a quick start alternative to the manual steps described here.

Install Latest Python 3

The IUS repo community has done a wonderful job of providing the absolute latest Python 3 releases as rpm packages for RHEL and CentOS that easily install alongside the default system Python.

$ sudo yum install -y https://centos7.iuscommunity.org/ius-release.rpm
$ sudo yum update

Install Python 3.4

$ sudo yum install -y python34u python34u-libs python34u-devel python34u-pip
$ which -a python3.4
/bin/python3.4
/usr/bin/python3.4

Install Python 3.5

$ sudo yum install -y python35u python35u-libs python35u-devel python35u-pip
$ which -a python3.5
/bin/python3.5
/usr/bin/python3.5

Install Latest Python 2

SCL was on Python 2.7.8 at the time of writing while the latest upstream release was 2.7.11. IUS does not provide Python 2 packages. Since I didn't want to build from source myself I had to come up with a better solution. I like to think I found that solution.

I believe in building on the work of others in the free software community. For this reason I decided to look at Fedora. They build newer releases regularly. Why not take their rpm and make a few changes to differentiate my version from theirs to prevent any conflicts when installed? This is the path I chose and it was pretty successful.

Here I'll provide a step-by-step process of what I did to rebuild a custom rpm from the source rpm built by the Fedora project.

Step 1

Install CentOS 7 in a virtual machine (VM) and install all updates.

Step 2

Install packages to prepare for building an rpm package.

$ sudo yum install -y rpm-build

$ sudo yum install -y redhat-rpm-config

$ sudo yum install -y yum-utils

$ sudo yum groupinstall -y "Development Tools"

Step 3

Install prerequisites for building Python 2.7.11.

$ sudo yum-builddep -y python-2.7.11-4.fc24.src.rpm

Step 4

Create necessary directory structure.

$ mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}

Step 5

Fedora has a build system, Koji, that provides access to all public builds. Latest Python available there was 2.7.11 build 4 for Fedora 24.

Download the srpm to the directory structure created in step 4.

$ cd ~/rpmbuild/SRPMS
$ curl -O https://kojipkgs.fedoraproject.org//packages/python/2.7.11/4.fc24/src/python-2.7.11-4.fc24.src.rpm

Step 6a

"Install" (unpack) the srpm in the directory structure created.

$ cd ~/rpmbuild/SRPMS
$ rpm -i python-2.7.11-4.fc24.src.rpm

Step 6b

If you don't want to customize anything and don't mind the build taking about 90 minutes (as tests are run after the build is done) you can rebuild like so

$ cd ~/rpmbuild/SRPMS
$ rpmbuild --rebuild python-2.7.11-4.fc24.src.rpm

If you do this then ignore steps 7 & 8 and skip to step 9.

Step 7

Optional: Patch python.spec with your changes.

$ cd ~/rpmbuild/SPECS/
$ vim python.spec
.. Your Changes Here ..

Step 8

Build rpm and srpm from the spec file.

Warning: On my VM it took more than 90 minutes for the builds to complete and tests to run. To disable tests set %global run_selftest_suite to 0.

$ cd ~/rpmbuild/SPECS/
$ sed -i -e "s/^%global run_selftest_suite 1/%global run_selftest_suite 0/g" python.spec  # OPTIONAL
$ rpmbuild -ba python.spec

You may also build rpms from the newly created srpm. It's up to you.

$ cd ~/rpmbuild/SRPMS/
$ rpmbuild --rebuild python2711-2.7.11-4.el7.centos.src.rpm

Step 9

All rpms are located in ~/rpmbuild/RPMS/x86_64 directory. Install them from the file system or even better copy them to a local repo to let other machines install from there as well.

$ cd ~/rpmbuild/RPMS/
$ sudo yum localinstall --nogpgcheck python-libs-2.7.11-4.el7.centos.x86_64.rpm python-2.7.11-4.el7.centos.x86_64.rpm

This will replace the system-installed version. For newer releases this process must be repeated every time.

Epilogue

For Python 3 I could have taken a Python 3 srpm from Koji and re-built it just like I did for Python 2. Unfortunately, its build requirements included packages that I would have needed from Koji as well. That was a rabbit hole I didn't want to climb down. Therefore, I used the commendable work of the IUS community.

I'm disappointed that there's no easy way to take an rpm, make a few changes, and install it in /usr/local. This is a use case sorely missing in the Fedora, RHEL, and CentOS communities.

I'm also glad that I could build on the work of communities and that the RHEL ecosystem is open enough to allow such quick turnaround for installing latest Python releases.

A good rule of thumb: use IUS to install Python from packages that don't conflict with stock CentOS packages and to rebuild srpms from Fedora when they are not available on IUS or EPEL.