Homebrew Python3
To add bindings for Python 3, please add dependson 'python@3.x' to work with the current Homebrew Python 3.x formula. Build Python 2 bindings with the system Python by default (don’t add an option) and they should be usable with any binary-compatible Python. If that isn’t the case, it’s an upstream bug; here’s some advice for resolving it. 1 Right now, there are only two distinct Formula for Python in homebrew-core: python, and python@2. Python@3 and python3 are both aliases to Formula/python.rb. Thus, they're just different names that install the same package. The right and wrong way to set up Python 3 on MacOS, Homebrew is so wonderful, it even offers a different formula for Python 2: # If you need Homebrew's Python 2.7 run $ brew install python@2. Installing Python 2.7 with Homebrew For Mac 10.8.x 1) Install XCode 4.4. Get it from the App Store. 2) Install Command Line Tools.
- Warnings
- Installation
- PATH and .bash_profile
- Homebrew - pyenv
- Uninstall python
- Homebrew
It’s easy to install multiple versions of python on a Mac computer using installers from python.org, Homebrew, Conda, or other sources. This could create conflicts if a user wants to run one version of python but bash calls a different version instead.
Homebrew complements macOS (or your Linux system). Install your RubyGems with gem and their dependencies with brew. “To install, drag this icon” no more. Homebrew Cask installs macOS apps, fonts and plugins and other non-open source software. $ brew install-cask firefox.
This is guide will show you how to:
- modify your bash profile to change which version of python is called by bash first.
- use virtual environments to specify a version of python that will run a project.
- uninstall specific versions of python.
Mac OS needs python
DO NOT remove any versions of Python found in the following folders:
/usr/bin
system/Library
These versions of Python—which should be Python 2.7—are installed by Apple and used by Mac OS and other software to perform some functions. Deleting Python from these directories will break Mac OS and force you to reinstall it on your computer.
Other projects may need specific versions of python
You may have a python project or you may use python packages that require particular versions of Python. Uninstalling those versions would prevent those projects or packages from working until that version of python is reinstalled. For example, Python 3 is a dependency of Numpy; if you uninstalled Python 3, then Numpy wouldn’t work until you reinstalled Python 3.
Three common methods of installing python can be found here:
python.org
The python.org (python.org) installer can be found here.
Homebrew
First install Homebrew. The instructions are here, or enter the following command:
To install Python 3:
To install Python 2:
Anaconda
Anaconda is generally used for scientific and machine learning applications.
For Ananconda follow installation instructions here.
Miniconda is a stripped down version of Anaconda.
For Miniconda follow installation instructions here.
PATH
The path is a list of directories that your shell will look through when you execute a command. You can display the path on your computer using the echo $PATH
command:
The directories above are separated by a colon, this is what they look like displayed in sequence:
- /Library/Frameworks/Python.framework/Versions/3.7/bin
- /Users/username/anaconda3/bin
- /Library/Frameworks/Python.framework/Versions/2.7/bin
- /Users/username/miniconda2/bin
- /Users/username/miniconda3/bin
- /Library/Frameworks/Python.framework/Versions/3.6/bin
- /usr/local/bin
- /usr/bin
- /bin
- /usr/sbin
- /sbin
- /usr/texbin
- /opt/X11/bin
- /usr/X11/bin
- /usr/local/git/bin
When you ask your shell to run a particular command or run an interpreter, python
for example, the shell looks through the different directories listed in the PATH in order they’re presented above. When the shell finds that command, it stops and calls it even if there is another version of the same command, with the same name, further down in the list.
.bash_profile
The bash profile is a set of instructions that are run by the shell when the user logs in to bash. You can add a variety of preferences to the bash profile, including modifications to the PATH. When anaconda, miniconda or other versions of python are installed they automatically add paths to their respective versions of python to the top of the bash profile.
Bash reads the bash profile in sequential order — from top to bottom — and adds those paths to the PATH in the order that they’re read. This means that the last path at the bottom of the bash profile will end up as the first path in the PATH. This means that if you have Python 3.6 installed on your computer, and then decide to add python 3.7, but keep 3.6, the installer will add Python 3.7 to the top of the bash profile but it will end up after python 3.6 in the PATH. Entering python3
in bash will call python 3.6, not 3.7.
If that was confusing compare the order that the python paths are added to my bash profile below to the PATH listed above. You’ll notice that their respective orders are opposite from each other.
Enter the following command to open the bash profile in TextEdit:
My .bash_profile currently looks like this:
If you want to keep all of your installed versions of python, but want bash to open a different version first, just copy and paste it to the bottom of the bash profile. If you don’t want bash to run a particular version of python then delete it from bash profile and uninstall that version by following the instructions further down.
Don’t forget to save the bash profile before closing TextEdit. You also have to reload the bash profile in bash before any changes take effect. Just enter one of the following commands:
source ~/.bash_profile
. ~/.bash_profile
Pyenv is a Homebrew package that allows a user to install multiple versions of python in Homebrew and specify which version of python they’d like to run.
Install pyenv:
Install different versions of python:
Show which versions of python are installed:
The asterisk indicates that the system version of python is active, but 3.5.0 and 3.6.0 are also installed.
Pyenv Local
Create a folder called PythonLocalProject
, then display the version of python called by bash by entering python -V
:
Now enter:
This creates a .python-version
file which tells pyenv
which version of python to run in that directory.
Entering ls -la
shows us that file:
Now enter pyenv versions
:
And running this command shows which version of python is called by pyenv:
To change pyenv to the system version of version 3.6.0 enter:
This procedure is fine, you can set a version of python to run in a particular folder. But what if you want to use pyenv to set a global version of python.
Pyenv Global
Pyenv gives these instructions when you enter pyenv init
in bash:
Open the bash profile:
open ~/.bash_profile
Add this text to the bottom of the file:
eval '$(pyenv init -)'
Save the file and then enter:
source ~/.bash_profile
Entering echo $PATH
will show that a pyenv shim has been added to the beginnning of the path:
/Users/username/.pyenv/shims:
And which python
will return:
/Users/username/.pyenv/shims/python
This means that bash will run the version of python set by pyenv.
Navigate to a folder that doesn’t have a .python-version
file and enter:
This shows us that the global version of python is 3.6.0 and it is set by pyenv
.
So this shows that bash will run whichever version of python that is set in pyenv.
If you navigate back to the PythonLocalProject
folder with the .python-version
file and run python -V
you will notice that it doesn’t run the global version of python, it runs whichever version was last set with the pyenv local
command.
We can use the which
command to identify where specific versions of python are located:
This shows some overlap as some versions of python appear in both searches.
The locations of the anaconda and miniconda versions of python are self explanatory, so are the pyenv installs, the python.org installer places python in the /Library/Frameworks/Python.framework/
directory. Homebrew installs all packages, including python, in /usr/local/Cellar
, then Homebrew adds a symlink to /usr/local/bin
so that its version of python can be found in the path. Finally, Apple installs python in /usr/bin
. Remember, don’t delete that version.
Follow these instructions if you want to remove particular versions of python.
python.org
The python.org installer places all it’s installed files in the following folders:
- The system applications folder,
/Applications
/Library/Frameworks/Python.framework
/usr/local/bin
To delete all versions of python that were installed using the python.org installer, enter these commands in terminal:
To remove particular versions of python, you have to refer to the particular framework. The frameworks are installed in /Library/Frameworks/Python.framework
and particular versions are found in /Library/Frameworks/Python.framework/Versions/X.Y
. So for example if you wanted to uninstall only version 3.5 but leave other versions you would enter the following commands in bash:
Homebrew
To uninstall python that was installed using homebrew you need to identify what versions of python have been installed by Homebrew:
Enter:
Currently brew refers to python3 as python
and python 2 is called python@2
.
To uninstall both python2 and python3 enter the following:
Homebrew will refuse to uninstall python if it has dependencies, just uninstall python and ignore the dependencies:
Homebrew Python 3.9
Or, add the dependencies to the list of items to be uninstalled:
Troubleshooting
It’s possible to have Homebrew’s Python directory at the beginning of the $PATH but calling python
will still start the Apple installed version of Python or some other version. If that’s the case it’s possible that Homebrew’s Python install has become unlinked. This command will unlink and relink Python in Homebrew:
Uninstall Python from Pyenv
To list versions of python installed using pyenv enter:
To uninstall versions of python installed using pyenv enter:
Anaconda
The official removal instructions are found here, but deleting anaconda and miniconda is easy.
Anaconda and miniconda are installed in the users home directory: ~/miniconda2
, ~/miniconda3
,~/anaconda2
, or ~/anaconda3
Depending on which version or versions you have, just enter the following commands:
Anaconda and miniconda also use several invisible files. Delete them by entering this command:
- Python Removal Instructions - towards the bottom of the README file.
And now for something completely different.
Don’t use Homebrew Python. It’s not meant for you.
At some point Homebrew made changes that adversely affect Python development. While Homebrew’s Python formula has been the go-to choice for Python developers (including me) for a long time, that time is past — there are now much better options available.
What’s the Problem?
Perhaps you heard stories about why you shouldn’t use the system-bundled Python1, so instead you use Homebrew to install Python and then use its interpreter to create a virtual environment. A month later, you activate that same environment, and when you try to use it, you see this inscrutable error:
What happened? The Python interpreter referenced by the virtual environment… no longer exists. But how can that be? You didn’t change anything!
You didn’t change anything… but Homebrew did. Of the adverse changes Homebrew made recently, two stand out as root causes of this problem.
First, Homebrew now upgrades dependent packages automatically. So if you upgrade any package that depends on the python
formula2 (and there are nearly 400 of them), then your Python interpreter will be upgraded also — whether you like it or not. You have no control over this.
Second, Homebrew now automatically deletes previous versions every 30 days, including of course any Python interpreters you used to create virtual environments.
The havoc wrought by the combination of these two changes is considerable. Those Python virtual environments you created over the last year? All of them are now broken. Why? Just because you ran brew upgrade ponysay
? Yup.3
Homebrew Python Is Not For You
The web is littered with frustrated reports about this problem and replete with hacked-together Bash scripts that purport to repair damaged Python virtual environments. And all because of one core misunderstanding.
Homebrew Python3-dev
Homebrew’s Python is not for you. It exists to serve Homebrew, or more accurately, Homebrew’s other formulae. The primary purpose of Homebrew’s Python formula is to enable other Python-dependent Homebrew packages to work. If installing Homebrew’s Python allows you to run the occasional Python script or access the REPL4, that’s a nice side benefit, but anything beyond that — including developing software with Python — is squarely out-of-scope.
Brew Install Python 3.7
Once you come to this realization, it should be clear that this is the wrong tool for the job. So what is the right tool?
Best Tool For the Job
There are several solutions that put you back in control of when Python versions are installed, upgraded, and removed. Personally, I use asdf and its Python plugin to do just that. I prefer asdf to similar tools such as Pyenv and Pythonz because not only can you install multiple Python versions but also multiple Node.js versions, Ruby versions, and many more.
After switching to this solution, would you like to guess how many times I’ve had something break due to a Python upgrade? Right: Zero. Zero times. Because I am now in control of when older Python versions are swept away, I can upgrade virtual environments at my leisure, and then, once I’ve confirmed no other environments rely on older versions, I can then uninstall those old Python versions without worrying about something breaking.
Epilogue
There are hack workarounds, and I’ve tried them. None of them fix the core problem.
For example, the automatic monthly clean-up can be disabled by defining a HOMEBREW_NO_INSTALL_CLEANUP
environment variable and setting it to “1”. But all it takes is one accidental brew
invocation in a shell session where that variable is not set, and your environments are laid to waste. Plus, even if you avoid that footgun, there is no easy way to remove specific old versions that you may no longer need; you have no choice but to rm -rf
directories in /usr/local/Cellar/
and hope you don’t break anything.
I also tried to avoid installing Homebrew Python entirely, with the idea that since I’m not using it anymore, I don’t need it to be installed. But assuming you use Homebrew to install other tools, that would be a fool’s errand — Homebrew Python will almost certainly be installed anyway when some other formula requires it. But that doesn’t mean we have to use it! Let the Homebrewed Python sit there and do its job serving other formulae, and we can forget it exists.
Homebrew Python 3 Download
If you liked this article, find me on Twitter so you’ll know when I post new ones.
Homebrew Python 2
- I’ve talked about some macOS-specific reasons to eschew its bundled Python, but Ubuntu/Debian is also affected. ↩
- You can see which of your installed formulae depend on the
python
formula by running:brew uses python --installed
… I have over 30 Python-dependent formulae installed on my workstation. ↩ - Previously, you had to manually run
brew cleanup
to get yourself into this mess. Now the carnage happens automatically. Any time a new Python version is released, even patch releases such as from 3.8.6 to 3.8.7, there is the very real potential that any virtual environment that depends on the previous Python version will just break horribly and without any warning. And it’s not just your virtual environments — any software that depends on Python can have the carpet yanked out from under it, including Pipx, YouCompleteMe, and other components that you may not even realize depend on the presence of a stable Python foundation. Moreover, this problem isn’t even confined to Python. Need a specific version of Node.js to build static assets for your web application? Have an old Rails app that needs a previous Ruby version? Under the Homebrew regime, those can also be swept away at any time. ↩ - Assuming you’re okay with bundled Python caveats, there’s no reason to install Homebrew just for Python, since macOS includes Python 3 in its command-line tools (CLT) package. ↩