CentOS 7 Python 2.7 Upgrade Deprecation Message – End Of Life January 1st, 2020

For CentOS 7 based Centmin Mod users, you may run into the Python 2.7 deprecation message when running CentOS 7 native Python 2.7 and that Python 2.7’s end of life is on January 1, 2020 and that you need to upgrade Python 2.7. You should not upgrade the CentOS 7 native Python 2.7 as that may break your system and YUM operation. Instead, you should install a newer Python version side by side.

You ran Python 2.7 via command line and got the below message. So what do you do?

DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won’t be maintained after that date. A future version of pip will drop support for Python 2.7. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support

CentOS Python 2.7 usually gets backported updates to same Python 2.7 version package as would Redhat upstream Python 2.7. So that message is just cosmetic – you do not overwrite and upgrade system Python 2.7 on CentOS otherwise you break CentOS and possibly YUM itself so won’t be able to update via YUM and break any system dependencies on Python 2.7. However, if you updated CentOS Python 2.7 pip command to pip version 21.x, it could have broken pip command due to deprecated support for Python 2.7. For a workaround for pip jump to below section.

Python 3.6 Install

Instead, you can install Python 3.6 side by side with Python 2.7 via Centmin Mod 123.09beta01’s addons/python36_install.sh and you’d have pip3.6 and python3.6 access to 3.6 version. For non-Centmin Mod users, there’s plenty of online guides for installing Python 3.6 side by side with CentOS 7’s Python 2.7. Note: CentOS 7 only has Python version up to 3.6 installable via YUM packages. For Python 3.7 and above you may need to result to source compilations (see below).

Latest Python 3 version available in CentOS 7’s YUM repository right now is Python 3.6.8.

yum -q list python3
Installed Packages
python3.x86_64 3.6.8-18.el7 @updates

Centmin Mod CentOS 7 users can run addons/python36_install.sh installer to install Python 3.6 by side by side with CentOS 7’s Python 2.7.

/usr/local/src/centminmod/addons/python36_install.sh

Then you’d have access to both native CentOS 7’s Python 2.7 and Python 3.6

python --version
Python 2.7.5

python3.6 --version
Python 3.6.8

Then if your python app needs python 3.6, you can use virtualenv to setup sandbox for python 3.6 similar to outline at How to install the latest version of Python on CentOS – Daniel Eriksson – skip directly to section under Create your first isolated Python environment header instead though of pip2.7 it’s just pip for 1st step. There are 2 ways of creating sandboxes, virtualenv and pipenv see Pipenv & Virtual Environments — The Hitchhiker’s Guide to Python along with virtualenvwrapper

Example for virtualenv using python3.6 interpreter

pip install virtualenv
mkdir -p /home/python_projects
cd /home/python_projects
virtualenv -p /usr/bin/python3.6 venv1

Example output from virtualenv command

virtualenv -p /usr/bin/python3.6 venv1
Running virtualenv with interpreter /usr/bin/python3.6
Already using interpreter /usr/bin/python3.6
Using base prefix '/usr'
  No LICENSE.txt / LICENSE found in source
New python executable in /home/python_projects/venv1/bin/python3.6
Also creating executable in /home/python_projects/venv1/bin/python
Installing setuptools, pip, wheel...
done.

Then to activate Python 3.6 sandbox

source venv1/bin/activate

Once activated, you can update pip version within sandbox and install other Python related dependencies for your Python apps.

  • Centmin Mod uses ccache for compiler caching, which pip doesn’t like, so you disable ccache first and
  • Centmin Mod secures /tmp with noexec permissions so need to use a different temp directory for pip compilations.
  • Finally, update pip command to latest version within sandbox.
# pip doesn't like ccache so disable it
export CC='gcc'
export CXX="g++"

# pip needs a tmp directory that doesn't have noexec restrictions
mkdir -p /home/piptmp
chmod 1777 /home/piptmp
export TMPDIR=/home/piptmp

# update pip defined by -p flag to use python3.6 binary
pip install -U pip
pip --version

Example of updating pip within the Python 3.6 virtualenv project named venv1

(venv1) [02:20][root@host.domain.com python_projects]# pip install -U pip
Collecting pip
Downloading https://files.pythonhosted.org/packages/54/eb/4a3642e971f404d69d4f6fa3885559d67562801b99d7592487f1ecc4e017/pip-20.3.3-py2.py3-none-any.whl (1.5MB)
|████████████████████████████████| 1.5MB 8.5MB/s
Installing collected packages: pip
Found existing installation: pip 19.3.1
Uninstalling pip-19.3.1:
Successfully uninstalled pip-19.3.1
Successfully installed pip-20.3.3

(venv1) [02:20][root@host.domain.com python_projects]# pip --version
pip 20.3.3 from /home/python_projects/venv1/lib/python3.6/site-packages/pip (python 3.6)

The Python and pip binaries installed in virtual environment called venv1 in bin directory at /home/python_projects/venv1/bin

ls -lah /home/python_projects/venv1/bin/
total 72K
drwxr-xr-x 2 root root 4.0K Jan  5 02:20 .
drwxr-xr-x 5 root root 4.0K Dec  7  2019 ..
-rw-r--r-- 1 root root 2.2K Dec  7  2019 activate
-rw-r--r-- 1 root root 1.5K Dec  7  2019 activate.csh
-rw-r--r-- 1 root root 3.1K Dec  7  2019 activate.fish
-rw-r--r-- 1 root root 1.8K Dec  7  2019 activate.ps1
-rw-r--r-- 1 root root 1.5K Dec  7  2019 activate_this.py
-rw-r--r-- 1 root root 1.2K Dec  7  2019 activate.xsh
-rwxr-xr-x 1 root root  255 Dec  7  2019 easy_install
-rwxr-xr-x 1 root root  255 Dec  7  2019 easy_install-3.6
-rwxr-xr-x 1 root root  246 Jan  5 02:20 pip
-rwxr-xr-x 1 root root  246 Jan  5 02:20 pip3
-rwxr-xr-x 1 root root  246 Jan  5 02:20 pip3.6
lrwxrwxrwx 1 root root    9 Dec  7  2019 python -> python3.6
lrwxrwxrwx 1 root root    9 Dec  7  2019 python3 -> python3.6
-rwxr-xr-x 1 root root  12K Dec  7  2019 python3.6
-rwxr-xr-x 1 root root 2.3K Dec  7  2019 python-config
-rwxr-xr-x 1 root root  233 Dec  7  2019 wheel

Direct access to venv1 sandbox’s version of python 3.6 and pip 3.6 to install python packages will end up in /home/python_projects/venv1/ sandbox directory not to pollute system python 2.7.

(venv1) [02:24][root@host.domain.com python_projects]# /home/python_projects/venv1/bin/python3.6 --version
Python 3.6.8

(venv1) [02:26][root@host.domain.com python_projects]# /home/python_projects/venv1/bin/pip3.6 --version
pip 20.3.3 from /home/python_projects/venv1/lib/python3.6/site-packages/pip (python 3.6)

(venv1) [02:26][root@host.domain.com python_projects]# /home/python_projects/venv1/bin/pip --version
pip 20.3.3 from /home/python_projects/venv1/lib/python3.6/site-packages/pip (python 3.6)

Python 3.7+ Install

Python 3.7+ and higher would need to be source installed on CentOS 7. The source compilation can take a long time to install especially on slow servers or single cpu threaded servers – could take hours on very slow servers! So if you don’t have a specific Python 3.7+ version requirement, you might want to stick with above Python 3.6 install and virtualenv setup method.

You can see the current Python versions on official Python site. Latest versions are Python 3.7.9 for security release and for bug fix and feature releases, Python 3.8.7 and Python 3.9.1.

I’ve only tested Python 3.7, so will do example install for Python 3.7.9.

Preparations to update Centmin Mod 123.09beta01 and newer local code via cmupdate command and then disable ccache compiler caching and to setup dedicated temp directory for PIP as normal temp has noexec permissions configured.

# update Centmin Mod code
cmupdate

# pip doesn't like ccache so disable it
export CC='gcc'
export CXX="g++"

# pip needs a tmp directory that doesn't have noexec restrictions
mkdir -p /home/piptmp
chmod 1777 /home/piptmp
export TMPDIR=/home/piptmp

Install Python 3.7.9 which took ~18 minutes to compile and install on a dedicated Intel Core i7 4790K Haswell server with 32GB memory.

yum -y install libffi-devel
python_ver=3.7.9
python_prefixver=$(echo $python_ver | cut -d . -f1,2)
cd /svr-setup
wget https://www.python.org/ftp/python/${python_ver}/Python-${python_ver}.tgz
tar xzf Python-${python_ver}.tgz
cd Python-${python_ver}
make clean
if [[ "$(nproc)" -le '2' ]]; then time ./configure --prefix=/opt/python${python_prefixver} --with-openssl=/usr; else time ./configure --enable-optimizations --prefix=/opt/python${python_prefixver} --with-openssl=/usr; fi
time make -j$(nproc)
time make altinstall
ls -lah /opt/python${python_prefixver}/bin
ln -s /opt/python${python_prefixver}/bin/python${python_prefixver} /opt/python${python_prefixver}/bin/python3
ln -s /opt/python${python_prefixver}/bin/python${python_prefixver} /opt/python${python_prefixver}/bin/python
ln -s /opt/python${python_prefixver}/bin/python${python_prefixver} /usr/bin/python${python_prefixver}
ln -s /opt/python${python_prefixver}/bin/pip${python_prefixver} /opt/python${python_prefixver}/bin/pip3
ln -s /opt/python${python_prefixver}/bin/pip${python_prefixver} /opt/python${python_prefixver}/bin/pip
ln -s /opt/python${python_prefixver}/bin/easy_install-${python_prefixver} /opt/python${python_prefixver}/bin/easy_install
ln -s /opt/python${python_prefixver}/bin/idle${python_prefixver} /opt/python${python_prefixver}/bin/idle
ln -s /opt/python${python_prefixver}/bin/2to3-${python_prefixver} /opt/python${python_prefixver}/bin/2to3
ln -s /opt/python${python_prefixver}/bin/pydoc${python_prefixver} /opt/python${python_prefixver}/bin/pydoc
ln -s /opt/python${python_prefixver}/bin/pyvenv-${python_prefixver} /opt/python${python_prefixver}/bin/pyvenv
rm -f /svr-setup/Python-${python_ver}.tgz
/opt/python${python_prefixver}/bin/python${python_prefixver} --version
/opt/python${python_prefixver}/bin/pip${python_prefixver} --version

Note at make altinstall completion the message at the end will output

Installing collected packages: setuptools, pip
Attempting uninstall: setuptools
Found existing installation: setuptools 41.2.0
Uninstalling setuptools-41.2.0:
Successfully uninstalled setuptools-41.2.0
WARNING: The script easy_install-3.7 is installed in '/opt/python3.7/bin' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Attempting uninstall: pip
Found existing installation: pip 19.2.3
Uninstalling pip-19.2.3:
Successfully uninstalled pip-19.2.3
WARNING: The script pip3.7 is installed in '/opt/python3.7/bin' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed pip-20.1.1 setuptools-47.1.0

The end result are Python and pip 3.7.9 binaries at

/opt/python3.7/bin/python --version
Python 3.7.9

/opt/python3.7/bin/pip --version
pip 20.1.1 from /opt/python3.7/lib/python3.7/site-packages/pip (python 3.7)

Then to setup Python 3.7 virtual environment using a method different from Python 3.6 above outlined method via the -m env flag for /home/python_projects/myproject or whatever directory you choose

python_ver=3.7.9
python_prefixver=$(echo $python_ver | cut -d . -f1,2)
mkdir -p /home/python_projects/myproject
/opt/python${python_prefixver}/bin/python${python_prefixver} -m venv /home/python_projects/myproject

Contents of Python 3.7.9 virtual environments bin directory at /home/python_projects/myproject/bin

ls -lah /home/python_projects/myproject/bin
total 40K
drwxr-xr-x 2 root root 4.0K Jan 5 03:14 .
drwxr-xr-x 5 root root 4.0K Jan 5 03:14 ..
-rw-r--r-- 1 root root 2.2K Jan 5 03:14 activate
-rw-r--r-- 1 root root 1.3K Jan 5 03:14 activate.csh
-rw-r--r-- 1 root root 2.4K Jan 5 03:14 activate.fish
-rwxr-xr-x 1 root root 259 Jan 5 03:14 easy_install
-rwxr-xr-x 1 root root 259 Jan 5 03:14 easy_install-3.7
-rwxr-xr-x 1 root root 250 Jan 5 03:14 pip
-rwxr-xr-x 1 root root 250 Jan 5 03:14 pip3
-rwxr-xr-x 1 root root 250 Jan 5 03:14 pip3.7
lrwxrwxrwx 1 root root 9 Jan 5 03:14 python -> python3.7
lrwxrwxrwx 1 root root 9 Jan 5 03:14 python3 -> python3.7
lrwxrwxrwx 1 root root 28 Jan 5 03:14 python3.7 -> /opt/python3.7/bin/python3.7

Then to activate the sandbox virtual environment called myprojects

source /home/python_projects/myproject/bin/activate

Then within activated myproject virtual environment you can update pip

# pip doesn't like ccache so disable it
export CC='gcc'
export CXX="g++"

# pip needs a tmp directory that doesn't have noexec restrictions
mkdir -p /home/piptmp
chmod 1777 /home/piptmp
export TMPDIR=/home/piptmp

pip install -U pip

Update pip output within virtual environment

(myproject) [03:16][root@host.domain.com Python-3.7.9]# pip install -U pip
Collecting pip
Using cached pip-20.3.3-py2.py3-none-any.whl (1.5 MB)
Installing collected packages: pip
Attempting uninstall: pip
Found existing installation: pip 20.1.1
Uninstalling pip-20.1.1:
Successfully uninstalled pip-20.1.1
Successfully installed pip-20.3.3

Then directly calling python 3.7.9 virtual environment

/home/python_projects/myproject/bin/pip --version
pip 20.3.3 from /home/python_projects/myproject/lib/python3.7/site-packages/pip (python 3.7)

/home/python_projects/myproject/bin/python --version
Python 3.7.9

PIP 21.x Deprecated Python 2.7 Workaround Fix For CentOS 7

pip 21.x version was released on Jan 24, 2021, and it drops support for Python 2.7 and can break pip on CentOS 7 systems if you update to that version. So for CentOS systems make sure you do not upgrade to pip 21.x and if you did, downgrade to pip 20.3.4 using below outlined method.

Centmin Mod 123.09beta01 has 2 updates related to this

  1. While troubleshooting this issue, I disabled centmin.sh menu triggered tools/pip-updates.sh runs to auto update pip as at the time it updated to pip 21.x and break pip commands for python 2.7 system installed pip. Beta Branch – skip centmin.sh triggered pip updates in 123.09beta01. I may at a later time re-enable tools/pip-update.sh centmin.sh triggered routines once I get a better grasp of the issue.
  2. This update applies to new fresh Centmin Mod 123.09beta01 and higher installs to make sure initial install only upgrades pip to 20.3.4 and not 21.x for python 2.7 system pip Beta Branch – update python 2.7 pip update to 20.3.4 max in 123.09beta01. Doing this seems to allow pip upgrades to max out at 20.3.4 instead of installing 21.x version which drops support for python 2.7
    pip install --upgrade pip
    DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
    Requirement already up-to-date: pip in /usr/lib/python2.7/site-packages (20.3.4)

Python 2.7 upgrade message can be ignored as outlined in this above blog post.

If you incorrectly auto updated or manually updated python 2.7 system pip version to 21.x, you will get errors like below due to pip 21.x dropping support for python 2.7

pip -V
Traceback (most recent call last):
File "/bin/pip", line 9, in 
load_entry_point('pip==21.0', 'console_scripts', 'pip')()
File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 378, in load_entry_point
return get_distribution(dist).load_entry_point(group, name)
File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 2566, in load_entry_point
return ep.load()
File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 2260, in load
entry = __import__(self.module_name, globals(),globals(), ['__name__'])
File "/usr/lib/python2.7/site-packages/pip/_internal/cli/main.py", line 60
sys.stderr.write(f"ERROR: {exc}")
^
SyntaxError: invalid syntax

For CentOS 7 at least, to fix the errors, you need to reinstall python2-pip YUM package and only update pip to 20.3.4 max version using below commands. For Centmin Mod 123.09beta01 and higher, need to set a TMPDIR which isn’t noexec restricted and disable ccache compiler caching by only using gcc.

mkdir -p /home/piptmp
chmod 1777 /home/piptmp
export TMPDIR=/home/piptmp
export CC='gcc'

yum -y reinstall python2-pip --disableplugin=versionlock,priorities --disableexcludes=main
pip install --upgrade pip==20.3.4
pip install --upgrade "pip==20.3.4" setuptools

pip list command to verify installed pip and setuptools versions

pip list
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
Package                          Version
-------------------------------- -------
backports.ssl-match-hostname     3.5.0.1
chardet                          2.2.1
configobj                        4.7.2
decorator                        3.4.0
future                           0.18.2
Glances                          3.1.6.1
iniparse                         0.4
iotop                            0.6
ipaddress                        1.0.16
IPy                              0.75
kitchen                          1.1.1
netifaces                        0.10.9
perf                             0.1
pip                              20.3.4
policycoreutils-default-encoding 0.1
psutil                           5.8.0
py-cpuinfo                       4.0.0
pycurl                           7.19.0
pygobject                        3.22.0
pygpgme                          0.3
pyliblzma                        0.5.3
pymdstat                         0.4.2
pyOpenSSL                        0.13.1
pyparsing                        1.5.6
python-dateutil                  1.5
python-linux-procfs              0.4.9
pyudev                           0.15
pyxattr                          0.5.1
schedutils                       0.4
seobject                         0.1
sepolicy                         1.1
setuptools                       44.1.1
six                              1.9.0
slip                             0.4.0
slip.dbus                        0.4.0
urlgrabber                       3.10
urllib3                          1.26.2
yum-metadata-parser              1.1.4