How to Install Multiple Versions of Python (2.7 and 3.5) Without breaking System tools and Create Isolated environment using Virtualenv?

Updated on April 25, 2018

Today, I’m going to tell you how to install Python 2.7 and 3.5 versions on CentOS 6.4. And we are going to do this without breaking the existing Python installation (the default system installed version is 2.6.6 on CentOS 6.4) and other system tools such as yum. Well, the main reason behind this tutorial is – I recently installed Python 3 and broke everything – python, pip, yum etc…Here’s the snapshot of those: yum broke after installing/upgrading Python:

# yum
 There was a problem importing one of the Python modules
 required to run yum. The error leading to this problem was:
 No module named rpm
 Please install a package which provides this module, or
 verify that the module is installed correctly.

Python failed to import yum after installing/upgrading Python:

# python
 Python 2.6 (r26:66714, Dec 16 2015, 11:33:08)
 [GCC 4.4.7 20120313 (Red Hat 4.4.7-11)] on linux2
 Type "help", "copyright", "credits" or "license" for more information.
 >>> import yum
 Traceback (most recent call last):
 File "", line 1, in
 ImportError: No module named yum
 >>>

and pip broke as well:

# pip
 Traceback (most recent call last):
 File "/usr/bin/pip", line 5, in
 from pkg_resources import load_entry_point
 ImportError: No module named pkg_resources

So, the lesson learnt is – Never mess up with Python!! (Once the Python is broken, it’s very hard to fix). It means, if you ever want to install multiple versions of Python on a single machine, then do it in a right way!

Note: Always install new version of Python in a non-standard location (such as /usr/local/)

multiple python on centos

Prerequisites: You need root access or sudo privilege.

Get the system ready to setup Python by installing “Development Tools” and necessary libraries.

Install Development Tools:

#yum groupinstall "Development tools"
 :::::::::::::::::::::::::
 :::::::::::::::::::::::::
 rpm-libs.x86_64 0:4.8.0-47.el6
 rpm-python.x86_64 0:4.8.0-47.el6
 xz-libs.x86_64 0:4.999.9-0.5.beta.20091007git.el6
 Complete!

You may require these libraries as well:

These libraries are not must to install Python, but you may need those at a later stage.

#yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel
 :::::::::::::::::::::::::::
 :::::::::::::::::::::::::::
 ncurses-libs.x86_64 0:5.7-4.20090207.el6
 openssl.x86_64 0:1.0.1e-42.el6_7.2
 sqlite.x86_64 0:3.6.20-1.el6_7.2
 Complete!

Compile and Install Python 2.7 on CentOS 6.4

Download Python 2.7:

# wget http://python.org/ftp/python/2.7.6/Python-2.7.6.tar.xz
# tar xf Python-2.7.6.tar.xz

Note: The latest version of tar is capable of extracting .xz file. In case, if you couldn’t extract using tar, then here’s a guide to help you out.

# cd Python-2.7.6
#./configure --prefix=/usr/local --enable-unicode=ucs4 --enable-shared LDFLAGS="-Wl,-rpath /usr/local/lib"
 :::::::::::::::::::::::::::::::
 :::::::::::::::::::::::::::::::
 configure: creating ./config.status
 config.status: creating Makefile.pre
 config.status: creating Modules/Setup.config
 config.status: creating Misc/python.pc
 config.status: creating Modules/ld_so_aix
 config.status: creating pyconfig.h
 creating Modules/Setup
 creating Modules/Setup.local
 creating Makefile

Note: I’ll be installing Python in /usr/local. It means, the executable will be installed in /usr/local/bin and libraries in /usr/local/lib. Lookout for the LDFLAGS as well.

# make && make altinstall
 ::::::::::::::::::::::::::::::
 running install_scripts
 copying build/scripts-2.7/idle -> /usr/local/bin
 copying build/scripts-2.7/smtpd.py -> /usr/local/bin
 copying build/scripts-2.7/pydoc -> /usr/local/bin
 copying build/scripts-2.7/2to3 -> /usr/local/bin
 changing mode of /usr/local/bin/idle to 755
 changing mode of /usr/local/bin/smtpd.py to 755
 changing mode of /usr/local/bin/pydoc to 755
 changing mode of /usr/local/bin/2to3 to 755
 running install_egg_info
 Writing /usr/local/lib/python2.7/lib-dynload/Python-2.7.6-py2.7.egg-info
 rm /usr/local/lib/python2.7/lib-dynload/_sysconfigdata.py*

Note: Lookout for make altinstall – you should never use ‘make install’ as it will install both the versions on the same file-system and will mess up python.

The Python 2.7 is installed under:

# ls -ld /usr/local/lib/python2.7/

Compile and Install Python 3.5 on CentOS

# wget https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tar.xz
# tar xz Python-3.5.1.tar.xz
# cd Python-3.5.1
# ./configure --prefix=/usr/local --enable-shared LDFLAGS="-Wl,-rpath /usr/local/lib"
 :::::::::::::::::::::::::::::::::::::::::::
 :::::::::::::::::::::::::::::::::::::::::::
 configure: creating ./config.status
 config.status: creating Makefile.pre
 config.status: creating Modules/Setup.config
 config.status: creating Misc/python.pc
 config.status: creating Misc/python-config.sh
 config.status: creating Modules/ld_so_aix
 config.status: creating pyconfig.h
 creating Modules/Setup
 creating Modules/Setup.local
 creating Makefile
# make && make altinstall
 ::::::::::::::::::::::::
 ::::::::::::::::::::::::
 Ignoring indexes: https://pypi.python.org/simple
 Collecting setuptools
 Collecting pip
 Installing collected packages: setuptools, pip
 Successfully installed pip-7.1.2 setuptools-18.2
Python 3.5 installed:
 # ls -ld /usr/local/lib/python3.5/

Install Setuptools and Python Pip:

Let’s now install setuptools and pip for both the Python versions (2.7 and 3.5) we installed above:

# wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py
(or)
# curl https://raw.githubusercontent.com/pypa/pip/master/contrib/get-pip.py | /usr/local/bin/python2.7
You're using an outdated location for the get-pip.py script, please use the one available from https://bootstrap.pypa.io/get-pip.py

Update: The above command will fail with not found error. Instead use the below command to install pip2.7.

#curl https://bootstrap.pypa.io/get-pip.py | /usr/local/bin/python2.7

Install setuptools for Python 2.7:

# python2.7 ez_setup.py

Install setuptools for Python 3.5:

# python3.5 ez_setup.py
:::::::::::::::::::::::::
Installed /usr/local/lib/python3.5/site-packages/setuptools-19.4-py3.5.egg
Processing dependencies for setuptools==19.4
Finished processing dependencies for setuptools==19.4

Installing pip for Python 2.7:

# easy_install-2.7 pip
::::::::::::::::::::::
Installing pip script to /usr/local/bin
Installing pip2.7 script to /usr/local/bin
Installing pip2 script to /usr/local/bin
Installed /usr/local/lib/python2.7/site-packages/pip-8.0.0-py2.7.egg
Processing dependencies for pip
Finished processing dependencies for pip

Installing pip for Python 3.5:

# easy_install-3.5 pip
Searching for pip
Best match: pip 7.1.2
Adding pip 7.1.2 to easy-install.pth file
Installing pip3.4 script to /usr/local/bin
Installing pip3 script to /usr/local/bin
Installing pip script to /usr/local/bin
Using /usr/local/lib/python3.5/site-packages
Processing dependencies for pip
Finished processing dependencies for pip

So we have two versions of Python, pip and setuptools. We’ll now isolate those Python environments (2.7 and 3.5).

How to setup isolated Python environments

To do that, we need a package called virtualenv.

Install virtualenv for Python 2.7:

#pip2.7 install virtualenv
:::::::::::::::::::::::::::
Installing collected packages: virtualenv
Successfully installed virtualenv-14.0.0

Once installed, lookout for virtualenv commands as shown below:

# virtualenv<tab>
virtualenv virtualenv-3.5

Let’s us now create isolated environment using virtualenv for Python 2.7 and I’ll name that virtual environment as py27env (you may set a different name).

# virtualenv py27env
New python executable in /root/py27env/bin/python2.7
Also creating executable in /root/py27env/bin/python
Installing setuptools, pip, wheel...done.

The isolated environment (called as sandbox) will be created in the current directory where you executed the above command. Look out for the folder named as py27env (might be a different name in your case).

# ls -ld py27env/
drwxr-xr-x. 5 root root 4096 Jan 21 15:25 py27env/

You need to activate the sandbox py27env:

# source py27env/bin/activate
(py27env)

Now, check the version of python as shown below:

# python --version
Python 2.7.6

The above output shows that you are in Python 2.7.6 sandbox. To switch back to system installed Python version, you just need to deactivate it as below:

(py27env)# deactivate

Check the version now:

# python --version
Python 2.6.6 //You are now back to default Python environment.

Create a sandbox environment for Python 3.5

We used virtualenv to create a sandbox for Python 2.5, but for Python 3.5 we’ll use built-in command called pyvenv-3.5.

# pyvenv-3.5 py35environment
(py35environment)

You’ll find a directory named ‘py35environment’ in the current directory. Let’s now activate Python 3.5 environment as shown below:

# source py35environment/bin/activate
(py35environment)
(py35environment) # python --version
Python 3.5.1

Deactivate it as below:

(py35environment) # deactivate
# python --version
Python 2.6.6

That’s it! You now have two different Python environments and you did it without messing up anything. Hope this tutorial helped you.

Was this article helpful?

Related Articles

Comments Leave a Comment

  1. Thanks. I wish I had located this link a couple of days earlier. You mention that using “make install” can mess things up. Is there a way to “unmess” things?

  2. Hi,

    I’m trying to follow your guide. Which is very good!
    But I have issues to install the setuptools for Python 2.7.
    I was wondering if you know where I can find the file instead of using wget (other than the url mentioned in the article).

    Thanks

Leave a Comment