Installing Python 2 and Python 3 Alongside Each Other on Apple Mac OS X

While I do most of my Web development in Vagrant virtual machines running Ubuntu to provide completely isolated environments and a server environment that matches production (plus all the niceties of Aptitude packages), for pure Python projects -- development on the odd class or package or data projects using iPython and numpy -- I sometimes find an advantage to using my base Macintosh operating system with its native applications and packages.

Mac OS X comes with a Python installation. Unfortunately it's either somewhat or very out of date depending on how far into Python 3 development you are. The default version in OS X Yosemite is 2.7.6. The latest point release as of this writing in the Python 2 series is 9 and Python 3 is up to 3.4.3. The default installation also lacks some of the exploration tools that make quick work of small tasks, like IDLE as well as PIP which we otherwise would have to install from source.

Note: These directions assume some knowledge of Vim, such as the ability to save and quit, although feel free to substitute the editor of your choice. If you don't know Vim, Treehouse has a great quick tutorial in their Workshop series and saving and quitting are covered in the first couple minutes (if you don't have a Treehouse account, you can pay me back for this tutorial by using my reference code to sign up, it's a great resource for learning or staying current with development practices and this post was actually inspired as I completed the Treehouse Data Science Basics Course). These directions also assume use of the default Bash shell. If you're using ZSH or a different shell the paths and aliases will get set in your ~/.zshrc profile or whatever file is used to store your shell's profile.

As a minimum for any Python development I want to have PIP to fetch and install packages from PyPi as well as a virtualenv so that those packages don't get confused with any other versions of them I might be using.

The Python packages from the Python Software Foundation simplify installation by offering a shell updater, PIP installation, GUI applications and Unix command line tools in a one-click install.

Python 2

Installation

Install Python 2 from package. This allows you to run python2 and pip. (Software gets installed into /Library/Frameworks/Python.framework/Versions/2.7/bin/.)

Install virtualenv for Python 2 for the user only (this gets put into ~/Library/Python/2.7/bin:

$ pip install --user virtualenv

Append that to the path

$ vim ~/.bash_profile

And append the following, save and quit

alias virtualenv2='~/Library/Python/2.7/bin/virtualenv'

Source the profile to update the current Terminal window:

$ source ~/.bash_profile

Usage

To create an env (makes a directory within the current directory for the virtual environment) (use . instead of a name to create a virtualenv in the current directory):

$ virtualenv2 env_name

And to activate:

$ source env_name/bin/activate

Or, to activate from within the current directory:

$ source ./bin/activate

Then cd into the virtualenv if you're not already there.

$ cd env_name

Python 3

Installation

Install Python 3 from package. This allows you to run python3 and pip3. (Software gets installed into /Library/Frameworks/Python.framework/Versions/3.4/bin/.)

Install virtualenv for Python 3 for the user only (this gets put into ~/Library/Python/3.4/bin:

$ pip3 install --user virtualenv

Append that to the path

$ vim ~/.bash_profile

And append the following, save and quit

alias virtualenv3='~/Library/Python/3.4/bin/virtualenv'

Source the profile to update the current Terminal window:

$ source ~/.bash_profile

Usage

To create an env (makes a directory within the current directory for the virtual environment) (use . instead of a name to create a virtualenv in the current directory):

$ virtualenv3 env_name

And to activate:

$ source env_name/bin/activate

Or, to activate from within the current directory:

$ source ./bin/activate

Then cd into the virtualenv directory if you're not already there.

$ cd env_name

Verification

$ which python
/Library/Frameworks/Python.framework/Versions/2.7/bin/python
$ which python2
/Library/Frameworks/Python.framework/Versions/2.7/bin/python2
$ which python3
/Library/Frameworks/Python.framework/Versions/3.4/bin/python3
$ which pip
/Library/Frameworks/Python.framework/Versions/2.7/bin/pip
$ which pip3
/Library/Frameworks/Python.framework/Versions/3.4/bin/pip3
$ ls -al /Library/Frameworks/Python.framework/Versions/2.7/bin/ | grep 'python.*'
... python -> python2
...
... python2 -> python2.7
...
... python2.7

A Full Example

The process is the same for both Python 2 and 3, just the version specified will change. In this case I'll create a Python 3 virtualenv named stats_project in my Mac OS X User's Home directory and install the Pandas package.

$ cd $HOME
$ virtualenv3 stats_project
$ cd $_

This creates a new directory in my Home directory named stats_project. We can verify that by running pwd to see the full path to the working directory, in my case my username is Joe so my Home directory path is /Users/Joe/:

$ pwd
/Users/Joe/stats_project

It also sets up some other directories which contain the executables for Python, if we list the items in that directory we can see that:

$ ls -ll
drwxr-xr-x  15 Joe  staff  510 May  1 11:33 bin
drwxr-xr-x   3 Joe  staff  102 May  1 11:30 include
drwxr-xr-x   3 Joe  staff  102 May  1 11:30 lib

To activate the shell, source the activate script in the bin directory. This activates the virtualenv for the current shell session giving priority to the version of Python it is using and packages installed. If you close the Terminal window this session will end and you will be working with the system-wide version of Python unless you activate a different virtualenv.

$ source ./bin/activate

We can verify that we're using the virtualenv by asking which version of Python is being utilized, we'll see the path to the virtualenv's bin in the output:

$ which python
/Users/Joe/stats_project/bin/python

We can do the same thing for PIP:

$ which pip
/Users/Joe/stats_project/bin/pip

With that knowledge, we can safely install a package such as pandas:

$ pip install pandas

Once that's installed we can verify the installation by listing the packages:

$ pip list
numpy (1.9.2)
pandas (0.16.0)
pip (1.5.6)
python-dateutil (2.4.2)
pytz (2015.2)
setuptools (3.6)
six (1.9.0)

To create our own package, make a directory with an __init__.py script to tell Python it is a package and add the first Python file, for demonstration purposes we'll give the package the name statsanalysis and the script the name utils :

$ mkdir statsanalysis
$ cd $_
$ touch __init__.py
$ touch utils.py

The advantage to creating a package here instead of just creating utils.py is that you modularize your code. By going further and adding and configuring a setup.py file you can create a publishable package that others can use. It also allows you to easily initialize Git to version control the package's files without having to ignore the environment's directories.

Since numpy is installed in the environment you have full access to it:

$ python
Python 3.4.2 (v3.4.2:ab2c023a9432, Oct  5 2014, 20:42:22) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy
>>> exit()

With that knowledge you can edit utils.py to do whatever you need to do with numpy.

Revisions

  1. May 1, 2015 -- Added an introduction to explain why I'm installing what I'm installing. Noted that the tutorial requires a basic knowledge of the shell and Vim application. Added a full example.