Handling multiple python versions

(Note: I am assuming familiarity with virtualenv and conda, and a general agreement that using them are Good Things. See here and here, respectively, if you want an introduction, or to be convinced.)

My new day job is on python 3.5.2, PyMC3 runs on 2.7 and 3.6, and supports both pip and conda installations, and my personal projects are all over the place, but I think I have a great and simple set up for having sane and explicit control of all the versions and dependencies.

The short version

I want to have bash functions for

  • new virtualenvs (vn),
  • activating virtualenvs (va),
  • deactivating virtualenvs (vd), and
  • ddeleting virtualenvs (vdd),

along with pyenv for handling the version of python I am using, and pyenv-virtualenv because pyenv does not play that well with conda.

How to set it up!

$ brew install pyenv pyenv-virtualenv

Then add to ~/.bashrc:

# virtualenv aliases
function virtualenv_name { echo "${PWD##*/}" ; }
function vn { pyenv virtualenv "$(virtualenv_name)" ; }
function va { pyenv activate "$(virtualenv_name)" ; }
alias vd="pyenv deactivate"
function vdd { pyenv uninstall "$(virtualenv_name)" ; }

# sets up pyenv and pyenv-virtualenv
export PYENV_ROOT=/usr/local/var/pyenv
if which pyenv > /dev/null; then eval "$(pyenv init -)"; fi
if which pyenv-virtualenv > /dev/null; then eval "$(pyenv virtualenv-init -)"; fi

This allows me to set up a new project with, for example

$ mkdir my_new_project
$ cd my_new_project
$ pyenv local 3.6.3
$ vn
Requirement already satisfied: setuptools in /usr/local/var/pyenv/versions/3.6.3/envs/my_new_project/lib/python3.6/site-packages
Requirement already satisfied: pip in /usr/local/var/pyenv/versions/3.6.3/envs/my_new_project/lib/python3.6/site-packages
$ va
$ (my_new_project) pip install whatever

If I had wanted a conda version, I could have used pyenv local anaconda3-4.3.1 instead.

Note that your virtual environment is always the name of the directory you are in, and you cannot have two different virtual environments in the same folder. I usually only develop PyMC3 using Python 3, and use travis and experience to make sure it works on Python 2. If something is funky though, I can delete one environment, swap to Python 2.7, and rebuild a fresh one to debug.

As an aside, pyenv does an incredible job of keeping up with the latest Python releases - the alpha candidate for Python 3.7.0 was up a day after it was released.