Skip to main content

Current Method for Installing and Managing Python on macOS

It seems that I change my method of installing and managing multiple Python versions on macOS about every 9-12 months. This note describes my current method, which also happens to be the simplest that I've used.

Although Python 3 supports venv, I still work with Python 2.7 a great deal and am reluctant to use different tool sets for each release. To that end, I use virtualenv and virtualenvwrapper for both Python 2.7 and 3.6.

A quick comment for those somewhat new to Python on OS-X/macOS -- never modify or install packages into the Python that comes with the OS -- this never turns out well.

Installation

I install 2.7.x and 3.6.x using macports (I assume macports is already installed):

# install Python 2.7.x
$ sudo port install python27 +readline
$ sudo port install py27-pip
$ sudo port install py27-virtualenv
$ sudo port install py27-virtualenvwrapper

# install Python 3.5.x
$ sudo port install python35 +readline
$ sudo port install py35-pip
$ sudo port install py35-virtualenv
$ sudo port install py35-virtualenvwrapper

# install Python 3.6.x
$ sudo port install python36 +readline
$ sudo port install py36-pip
$ sudo port install py36-virtualenv
$ sudo port install py36-virtualenvwrapper

I've had a lot of issues with Macports python installations and tty corruption after exiting from a command line session. The details are here, but they are confusing. This has been going on for 1.5 years. Anyway, the '+readline' variant, which seems to be new as of Feb. 2017, seems to work. This has caused me some real pain and lost hours in the past; it's very frustrating. But I contribute nothing to the Macports project and I like it much better than 'brew', so I really can't complain.

Environment

A bit of a tangent... I set these virtualenv environment variables:

export WORKON_HOME=~/Documents/.virtualenvs
export VIRTUAL_ENV_DISABLE_PROMPT=""
export VIRTUALENVWRAPPER_VIRTUALENV_ARGS='--no-site-packages'

And note that the correct (based on your Python version) virtualenvwrapper.sh or virtualenvwrapper_lazy.sh must be sourced in to your environment.

Selecting the Default Python

I have a simple bash script called pyselect that I use to switch the default version of Python and related tools. I find that, if I don't use something like this, I sometimes end up with inconsistent defaults.

#!/usr/bin/env bash

function usage () {
    cat - <<-EOF

    pyselect [version]

    'Select' the default version of MacPorts python and python utilities.
    'version' should be '27', '35', or some valid Python version installed
    via MacPorts. If 'version' is not supplied, print the current defaults
    and available options.

EOF
    exit 0
}

VER="$*"

if [ -z "${VER}" ]
then
    port select --list python
    port select --list pip
    port select --list virtualenv
    exit 0
fi

if [ "${VER}" == 'help' ]
then
    usage
fi

sudo port select python            "python${VER}"
sudo port select pip               "pip${VER}"
sudo port select virtualenv        "virtualenv${VER}"

# FYI, virtualenvwrapper does not need to be selected, but the
# correct one should be sourced in to the environment.
# My 'python.sh' does this for me.  For more info, see the Python
# section of https://bitbucket.org/MaDeuce/dotfiles
. ~/.bash.d/python/python.sh