Posted on the 12th of Feb 2021 · By Sidharth Shanmugam · In Programming Adventures

The Ultimate Guide for Setting up Python on macOS


There are many ways to install and run Python on to your Mac device, you can install Python via Homebrew, via the binaries from the Python website, via Anaconda, and many others, there’s also the Python install built into macOS.

In this tutorial, we’re going to be installing Python via pyenv and Homebrew. We will also be installing and setting up tcl-tk so we can use the Tkinter libraries which will allow us to create GUI apps with Python. I will also be showing you how to maintain this environment with upgrades in the future.

What is pyenv and why is it amazing?

Before we proceed, I’d just like this say, this is completely subjective and there are many “correct” ways to set up Python on your Mac device. But many people including myself will suggest that pyenv is possibly the best way to do it.

Pyenv is a software tool that helps us install and manage Python installations. It allows us to download many different versions and easily switch between them. It also isolates the system version of Python (built into macOS), increasing safety by greatly reducing the likelihood of breaking the computer.

Let’s install pyenv!

There are a few parts to this so let’s break it down:

  1. Install the Xcode CLI Tools
  2. Install Homebrew
  3. Install pyenv
  4. Install tcl-tk

Xcode CLI Tools

The Command-Line Tools Package is a small self-contained package available for download separately from Xcode and that allows you to do command-line development in OS X. This allows Homebrew to function properly.

We can install this by simply opening up terminal and entering the following command:

xcode-select –install

Follow the prompts and install the CLI Tools.

Install Homebrew

Homebrew is a package manager for macOS. It is very similar to the apt-get command from Linux. Essentially, what it does it, it allows us to install software and packages straight from the terminal.

Installing it is extremely simple, just enter the following command into the terminal:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

The installation may take some time, but when it has completed, simply enter the brew doctor command to check if everything has been installed properly.

You should see the output, Your system is ready to brew, printed in the terminal. If you see this, proceed to the next step.

Install pyenv

Let’s now install the software which will help us get and manage Python. Enter the following commands into the terminal:

brew update
brew install pyenv

The brew update command tells brew (Homebrew) to update the list of packages, this will allow us to install the latest versions of packages. The brew install pyenv command tells brew to install the pyenv package including its dependencies.

To double check pyenv has been installed, enter brew list into the terminal, you should see pyenv, autoconf, [email protected], pkg-config and readline. Where pyenv is the package that we just installed, and the others are pyenv’s dependencies, we need these for pyenv to work properly.

Before we start using pyenv, we need to set up environment variables. This is so that pyenv can initialise itself and allow us to use all of pyenv’s features without any errors.

Enter the following into the terminal:

echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.zshrc

Now restart shell with the following command:

exec "$SHELL"

Pyenv should now be installed. Let’s move on to installing the tcl-tk package.

Installing tcl-tk

This step can be skipped if you don’t want to use the Tkinter libraries, but if you are planning to make GUI apps, then you need to set this up.

To install the tcl-tk package, simply enter the following into the terminal:

brew install tcl-tk

Now make a note of the version of tcl-tk that brew installed. Enter brew info tcl-tk into the terminal, you should see something like the following:

[email protected] ~ % brew info tcl-tk
tcl-tk: stable 8.6.11 (bottled) [keg-only]
...

As you can see, the version I’ve got installed is 8.6.11, this may be different to yours so keep a note of it, we need to reference this in the next step.

Now we need to set up the environment variables, enter nano ~/.zshenv into the terminal, this will open up the .zshenv file in the terminal based text editor, nano. In that file, append these lines:

# tcl-tk (brew) set paths and flags
export PATH="/usr/local/opt/tcl-tk/bin:$PATH"
export LDFLAGS="-L/usr/local/opt/tcl-tk/lib"
export CPPFLAGS="-I/usr/local/opt/tcl-tk/include"

# Python (pyenv) build config to use tcl-tk through brew
PYTHON_CONFIGURE_OPTS="--with-tcltk-includes='-I/usr/local/opt/tcl-tk/include' --with-tcltk-libs='-L/usr/local/opt/tcl-tk/lib -ltcl8.6 -ltk8.6'"

I have version 8.6.11, therefore the arguments on the last line are -ltcl8.6 -ltk8.6, change this to whichever version you have installed on your system. Finally, enter exec "$SHELL" to make sure these changes take place.

With that completed, we have finally finished settings up pyenv and everything we need to install Python!

Let's Install Python!

Before we begin, let’s check out which version is currently defaulted by entering python -V into the terminal.

[email protected] ~ % python -V          
Python 2.7.16

Currently, Python 2.7.16 is the current version on our Mac. This makes sense because, this is the system installation of Python and we haven’t installed any other version yet.

Do not use this version, doing so can break your computer!

Let’s do another check, enter pyenv versions into the terminal.

[email protected] ~ % pyenv versions     
* system (set by /Users/sids/.pyenv/version)

And great! Pyenv, thinks the same too, it has detected the system installation of python and the asterisk to the left of system shows that this is the default version which is on our system currently.

Let’s list the versions of Python currently available to pyenv with the pyenv install list command.

[email protected] ~ % pyenv install --list
Available versions:
  2.1.3
  2.2.3
  2.3.7
  2.4.0
  2.4.1
  2.4.2
  2.4.3
  2.4.4
  2.4.5
...

As you can see, there are hundreds of versions available to install. It is best to stay away from Python 2.x.x, version 2 has been depreciated and not used anymore. For this tutorial, I will be installing Python 3.8.7.

Simply enter pyenv install 3.8.7 into the terminal.

[email protected] ~ % pyenv install 3.8.7
python-build: use [email protected] from homebrew
python-build: use readline from homebrew
Downloading Python-3.8.7.tar.xz...
-> https://www.python.org/ftp/python/3.8.7/Python-3.8.7.tar.xz
Installing Python-3.8.7...
python-build: use readline from homebrew
python-build: use zlib from xcode sdk
Installed Python-3.8.7 to /Users/sids/.pyenv/versions/3.8.7

After the installation finishes, check the list of local versions (installed on our system), enter pyenv version into the terminal.

[email protected] ~ % pyenv versions
* system (set by /Users/sids/.pyenv/version)
  3.8.7

This shows that the version we just installed is fine but isn’t defaulted.

Now that Python 3.8.7 has been installed, let’s set this as the default version. Don’t worry, pyenv isolates the system version of python, this way macOS won’t start to fuss or break.

Simply enter pyenv global 3.8.7 into the terminal. Run pyenv versions again and you should see this:

[email protected] ~ % pyenv versions     
  system
* 3.8.7 (set by /Users/sids/.pyenv/version)

The asterisk has moved from system to 3.8.7.

Now that we have set the version we have just installed as global, let’s test this out with python -V in the terminal.

[email protected] ~ % python -V
Python 3.8.7

Now let’s check if the Tkinter libraries have been properly loaded into the Python installation, enter python into the terminal, the Python 3.8.7 shell will now open. Enter the following:

import tkinter as tk 
window = tk.Tk()

This should open a simple, blank window. With tkinter now confirmed to work, we can close the Python shell and the window by entering exit() into the shell.

Upgrading and Maintaining

Upgrading packages is another important thing, upgrading brew is really simple, enter brew update to update the list of packages, and brew upgrade to update all of the installed packages to the latest versions. If you’d like to update pyenv, you can enter the brew upgrade pyenv command, this will update pyenv to the latest version.

Uninstalling and Clean-up

Not sure why you’d want to get rid of the ultimate Python environment that you just set up, but here it is anyway.

Removing the Python installations and pyenv

Uninstalling is very simple, first set pyenv to use the system installation of Python as the global, with pyenv global system. Now we can uninstall Python with pyenv uninstall X, where X is the version. Repeat the uninstall command for every Python version you had installed. Enter pyenv versions into the terminal and make sure that system is the only entry.

With all of the Python versions uninstalled, we can now uninstall pyenv, tcl-tk and all of their dependencies. Tcl-tk only has one dependency, [email protected], and this is shared with pyenv.

Run the following commands one by one:

brew uninstall pyenv
brew uninstall tcl-tk
brew uninstall [email protected]
brew uninstall autoconf
brew uninstall pkg-config
brew uninstall readline
brew cleanup

With that done, we can now uninstall brew, enter the following command into the terminal to do just that:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall.sh)"

Uninstalling the Xcode CLI Tools

Now brew should be wiped, let’s uninstall the Xcode CLI Tools, enter the following command into the terminal to uninstall it:

sudo rm -rf /Library/Developer/CommandLineTools

Now we have uninstalled all of the software, we need to remove the environment variables, enter nano ~/.zshrc, In the terminal text editor which has just opened, remove the following:

if command -v pyenv 1>/dev/null 2>&1; then
  eval "$(pyenv init -)"
fi

To save enter Command+X, then enter “y”.

Next, enter nano ~/.zshenv, and remove the following from the file:

# tcl-tk (brew) set paths and flags
export PATH="/usr/local/opt/tcl-tk/bin:$PATH"
export LDFLAGS="-L/usr/local/opt/tcl-tk/lib"
export CPPFLAGS="-I/usr/local/opt/tcl-tk/include"

# Python (pyenv) build config to use tcl-tk through brew
PYTHON_CONFIGURE_OPTS="--with-tcltk-includes='-I/usr/local/opt/tcl-tk/include' --with-tcltk-libs='-L/usr/local/opt/tcl-tk/lib -ltcl8.6 -ltk8.6'"

Save the file and exit the editor, just like how we did before. Enter exec "$SHELL" to make sure these changes are reflected.

Now with that done, we have completely removed everything we had installed and set up in this tutorial.