Joe Bergantine | Designer

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

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.

Note: These directions use Vim as the command line editor. Feel free to substitute vim with the editor of your choice. For example, Sublime can also be launched from the command line.

These directions also assume use of the default Bash shell. If you're using ZSH or some other shell, the paths and aliases will be set in your ~/.zshrc profile or whatever file is used to store your other shell's profile rather than ~/.bash_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


Install Python 2 from the latest package. This allows you to run python2 and pip. After this installation Python 2.x will be accessible at /Library/Frameworks/Python.framework/Versions/2.7/bin/.

Once the Python 2 package is installed, install virtualenv for Python 2 for the User only. When specifying the User installation, Python packages are then accessible at ~/Library/Python/2.7/bin. Specifying the User installation doesn't automatically add virtualenv to the system path which we will do manually in the next step via an alias. This is what allows Python3 and Python2 to run alongside each other:

$ pip install --user virtualenv

To use the virtualenv command, it needs to be on the path, open the shell profile:

$ 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


To create a Python virtualenv, use the virtualenv2 command with a name argument. The name argument is used to make a directory within the current working directory to contain the virtual environment. If you are already within the directory you used for the project, 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 change directory into the virtualenv if you're not already there.

$ cd env_name

Python 3


Install Python 3 from the latest package. This allows you to run python3 and pip3. After installation, Python3 will be accessible from /Library/Frameworks/Python.framework/Versions/3.6/bin/.

Once Python 3 is installed, install virtualenv for Python 3 for the user only. Python3 packages are then accessible at ~/Library/Python/3.6/bin:

$ pip3 install --user virtualenv

To use the virtualenv3 command, it needs to be on the path, open the shell profile:

$ vim ~/.bash_profile

And append the following to the bottom, save and quit:

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

Source the profile to update the current Terminal window:

$ source ~/.bash_profile


To create a Python 3 virtualenv:

$ virtualenv3 env_name

And to activate:

$ source env_name/bin/activate

Then change directory into the virtualenv directory:

$ cd env_name


The above installation makes available the following commands: python to launch Python 2, python3 to launch Python 3, pip to install Python 2 packages, pip3 to install Python 3 packages, virtualenv2 to create a Python 2 virtual environment, virtualenv3 to create a Python 3 virtual environment. With the exception of the aliases for virtualenv2 and virtualenv3, these can be verified using which:

$ which python
$ which python2
$ which python3
$ which pip
$ which 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 test_project in my Mac OS X User's Home directory and install the Pandas package.

$ cd $HOME
$ virtualenv3 test_project
$ cd $_

This creates a new directory in my Home directory named test_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

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

We can do the same thing for PIP:

$ which 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 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
$ touch

The advantage to creating a package here instead of just creating is that you modularize your code. By going further and adding and configuring a 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.6.0 (v3.6.0:41df79263a11, Dec 22 2016, 17:23:13) 
[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 to do whatever you need to do with numpy.


Virtualenvwrapper provides some nice extras to virtualenv. Assuming Python 3 is the default and desired Python version to be used, install virtualenvwrapper for Python 3 for the user only. This keeps cross contamination with Python 2 to a minimum and allows us to point to the desired installation of virtualenv that virtualenvwrapper should reference. The Python package for the user are accessible at ~/Library/Python/3.6/bin/ which is where you will find after installation which is the shell wrapper that allows the use of virtualenvwrapper's commands:

$ pip3 install --user virtualenvwrapper

And then add the following to the shell profile to use it, setting the user's sites folder as the PROJECT_HOME and storing Python packages at ~/.virtualenvs:

First, open the shell profile:

$ vim ~/.bash_profile

And then add to the bottom:

# Point to virtualenv
export PATH

# VirtualenvWrapper
export WORKON_HOME=$HOME/.virtualenvs
export PROJECT_HOME=$HOME/sites
export VIRTUALENVWRAPPER_PYTHON=/Library/Frameworks/Python.framework/Versions/3.6/bin/python3
source $HOME/Library/Python/3.6/bin/

Save, quit and source the shell profile or restart the Terminal application to pick up the changes:

$ source ~/.bash_profile


  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.
  2. January 6, 2017 — Python 2.7 is now 2.7.13 and Python 3 is now Python 3.6.0. Updated accordingly. Added directions for using virtualenvwrapper. Changed the use of the phrase "installed to" to "accessible at" when referring to executables and Python packages. Noted the option to use Sublime rather than Vim with a link to the directions for using the Sublime command line tool. Removed some preamble language for clarity.