October 21, 2019

Python for macOS

This is how I set up my mac to use different versions of python with virtualenvwrapper. virtualenvwrapper enables virtual environments with the friendly workon <project> command instead of source <path/to/venv>/bin/activate.

Prerequisites

We need homebrew. Install homebrew (I use the defaults) before proceeding.

Base Pythons

We now install both python3 and python2. These take over the default python2 and python3 binaries from macOS.

# python3
brew install python

# python2 
brew install python2

Use the homebrew versions of python2/3 for dependencies within homebrew. Don't use the homebrew versions of python for applications you develop. Homebrew updates packages like python quickly and causes headaches with my applications that need a pinned version of python2 or python3.

App-specific Pythons

For applications, install pyenv to manage pinned versions of python. Once again, reach for homebrew:

brew install pyenv

Now install the different versions of python you need for your code.

pyenv install 3.6.9
pyenv install 2.7.19

Now activate all the pythons. Enabling all versions of python removes the requirement of using pyenv to switch between current versions of python.

pyenv global system 3.6.9 2.7.19

Now you access each version of python with a version suffix – e.g., python3, python3.7, python3.6, python2, etc.  

virtualenvwrapper + pyenv

I love the workon <project> functionality enabled with virtualenvwrapper. virtualenvwrapper doesn’t work with pyenv naturally because the virtualenvwrapper package pins to the current version of python. This is problematic because pyenv swaps out the python path that virtualenv (and workon) expects. To have this work with pyenv use pyenv-virtualenvwrapper.

brew install pyenv-virtualenvwrapper

Now add the following to your bash shell's ~/.bashrc or ~/.profile:

if which pyenv > /dev/null; then eval "$(pyenv init -)"; fi
pyenv virtualenvwrapper_lazy

App Setup

To use the correct version of python with a virtualenv when setting up a new repository, use the following pattern:

cd <repo>
mkvirtualenv -p python3.6.8 -a $(pwd) myproject

Now you have workon myproject available in your shell that activates the correct version of python.