Python on macOS or:

corcoran
4 min readSep 14, 2020

Remember when you’d enjoy chips* cooked three-ways?

virtual python=$(which python3)

Yeah me either. Legit medium.com story-for-claps. So my bash history is 5000 entries of my trying to understand how to install Python, different versions of Python, pip, pipenv, pyenv and so on. Somewhat labourious. I do understand the distinct advantages of virtual environments, and why folks enjoy Python [version here] .. but how in the name of Zeus’ butthole* did you get Python [version here] running in the first place on macOS? Legit question.

Update for Sonoma:

brew install pyenv xz
# update bash rc
brew install pyenv-virtualenv
pyenv install 3.12.0
pyenv virtualenv 3.12.0 my3-12-0-env
pyenv local my3-12-0-env

Start

As a Windows user (yeah, yeah), until the advent of choco/winget I was always proper jealous of brew — and this is a decent place to install Python from. So let’s do that:

brew install python

Oh god, we’re already in hell and we’ve installed Python 2.x

brew install python3

I’m assuming you’re reading this in the future, so likely you’ve gotten 3.8+ as a result of that install. So let’s ensure we’re digging in the [right] place* and add some lazy bash/zsh aliases (last two aliases you don’t need, but they’re useful):

alias python=$(which python3)
alias pip=$(which pip3)
alias pipconfig="pip config list -v"
alias pythoncerts="python -c "import ssl; print(ssl.get_default_verify_paths())""

Environments

Python <3.9 — Cool. So onwards to the python package manager or “ppm” as it isn’t called: pip+XYZenv. I want to make sure pip is up-to-date so I update it with notPip, then install XYZenv, etc.

python -m pip install --upgrade pippip install virtualenv virtualenvwrapper pipenv pyenvbrew install direnv

Python 3.9+ — Cool. Pip no longer supported for installing pyenv, so use brew instead.

brew install pyenv direnv

Let’s do the usual nonsense with virtualenv because the commands have slightly different constructs :facepalm:

export VIRTUALENVWRAPPER_PYTHON=$(which python3)
export WORKON_HOME=~/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh
alias workoff=deactivate
alias workdel=rmvirtualenv

Amazing work! You’re all sorted and everything will now work brilliantly (1 minute read). Let’s try it out and create a virtualenv in an older version of Python3:

python -mvirtualenv /Users/your_name_here/tmp -p python3.7

Probably not working as expected, eh? Not to worry, let’s ignore that problem and just use pyenv instead:

pyenv install 3.7

Glorious. I’m sure that definitely worked. Not so much? Sod it; let’s just try the following instead:

pipenv --python 3.7

Terrific. Python is definitely broken forever. What’s next, Mrs. Landingham?*

homebrew-python

Now let’s stand on the shoulders of giants and grab the Python version(s) we want from https://github.com/sashkab/homebrew-python. Side-note, ‘installing formulae’ for Python 3.7 took about 40 minutes on my Mac. No, I don’t know why.

Installing formulae:

Replace X in examples below with minor version of Python: 5 for Python 3.5, 6 for Python 3.6, 7 for Python 3.7, or 8 for Python 3.8.

Python 3.X will be installed into /usr/local/opt/python@3.X, as a keg, i.e without linking into /usr/local/bin in order to avoid conflicts with the python formulae.

brew install sashkab/python/python@3.X

You can use it to create a virtual environment by passing full path to the Python executable:

/usr/local/opt/python@3.X/bin/python3.X -mvenv <path to venv>

In order to update to latest version of pip, setuptools and wheel, use following command:

/usr/local/opt/python@3.X/bin/python3.X -mpip install -U pip setuptools wheel

Covering all my bases

So “creating a virtual environment by passing full path to the Python executable” above, works (for real this time); but I ran into more issues with pre-commit, where a pal of mine (who shall remain nameless) had pinned his pre-commit hook to a specific version and pre-commit still fails. Which is why this entire medium.com story exists, thanks James Woolfenden. Oopsie. So more bashery-pokery with aliases:

export PATH="/usr/local/opt/python@3.7/bin:$PATH"
alias python3.7="/usr/local/opt/python@3.7/bin/python3.7"

Now when I run/or/or:

python -mvirtualenv /Users/your_name_here/tmp -p python3.7pyenv install 3.7pipenv --python 3.7

This works for both - me being lazy because I can’t remember the full path to the Python executable *and* for pre-commit hooks where your favourite devops engineers have pinned versions of Python because on Windows 10 “it just works” :burn:

Asterisks

Chips — I’m sure the locale of the largest demo of medium.com users is the US, but yes, I mean chips. Triple cooked. Try it sometime**.

Zeus’ butthole — a reference to the movie The Rock

Digging in the [right] place — a reference to the movie Indiana Jones and the Raiders of the Lost Ark

Mrs. Landingham — a character from the TV Show, The West Wing; don’t forget to vote

** Don’t triple-fry your chips, obviously I mean chips because I’m English

--

--

corcoran

Is this bio too short? Or is it just the right length?