Setting up a Python environment on a mac for the average user can turn out to be quite baffling. Googling around and looking for a simple guide to set-up a Python development environment can be sometimes quite puzzling and even intimidating. Alarming posts about a good way and a bad way of installing python, and all sort of remedies to prevent future catastrophe when wildly installing packages for several versions of python without any sensible order. This is the setting I ended up with, hopefully it will help you.

Wether we like it or not, Python 2.7 comes pre-installed on Mac OS and it shouldn’t be messed with, as it’s used by the system itself (Several parts of the OS rely on python 2 scripts that Apple haven’t updated yet). However, it’s well out of date from what Python recommends using for development or data analysis.

In order to take advantage of the latest versions of Python, we would need to install a newer version alongside the system one. Basically, we would like to have the option to install several versions of python, dependencies and packages without any conflicts. Let’s say we want to create a project environment in Python 3.7 and another in Python 3.9?

Enter Pyenv and Pipenv

Fortunately, A handy tool called Pyenv might just make our life a bit easier. Pyenv is a Simple Python version management tool, which lets us install, manage and switch between multiple versions of Python. On top of that, it is very easy to assign and use different virtual python environments or integrate it as a python interpreter for PyCharm, a popular python IDE which I currently use.

The best thing with Pyenv is that it doesn’t interfere with the original Python version installed on my machine. Every new Python version that I install ends up in a separate folder, and Pyenv modifies the $PATH variable telling the computer to use specific Python versions (and not the system Python). This way, no conflicts occur and even if we mess up something with Pyenv, our system python stays intact and nothing breaks within the OS.

The second tool we are going to use is Pipenv, a complementary for Pyenv. While the latter manages our python versions in an orderly fashion, Pipenv not only fetches and installs Python packages but also creates and handles a virtual environment to capsulate all packages and dependencies for a project.

All installations and actions will be done using the MacOS Command Line Interface (CLI) which is called Terminal. We will use the Terminal mainly because it’s the only (but very easy and strait-forward) way to install and activate the mentioned tools. The Command Line is a powerful and versatile tool for interacting with the computer. CLI might look as if it is very old fashioned, nevertheless, it offers many advantages and is considered by many to be the ultimate seat of power.

If you are not familiar with Terminal at all, you can follow a gentle introduction to comfortably tuck you in.

Installing Homebrew and setting up Pyenv

Since mac OS doesn’t come with a default package manager out of the box, there are several ways to setup and install Python. Instead of manually manage applications, I prefer using a package manager to install, update, and remove unneeded software.

We will use Homebrew, a common and widely used package manager, to install Pyenv and Pipenv. We will first install Homebrew and some dependencies and then use it to download and install the rest.

# Install Homebrew and Xcode tools dependencies  
  /usr/bin/ruby -e "$(curl -fsSL"
# And install Pyenv with Homebrew:
  brew install pyenv
# Add pyenv to the shell startup script (~/.zprofile for zsh or ~/.bash_profile for bash): 
  echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zprofile
  echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zprofile
  echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.zprofile
# Reload profile:
  exec "$SHELL" 
# Or just Close the terminal and start a new one

Checking our initial set up

To check our installation we can type echo $PATH in a new terminal window. If all went well it should return something like: /Users/atzmonky/.pyenv/shims:/Users/atzmonky/.pyenv/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin

with the ~/.pyenv/shims directory out front.

Typing type -a python should give an output like this:

python is /Users/atzmonky/.pyenv/shims/python
python is /usr/bin/python

Great! Now that we have Pyenv installed on our computer we can go ahead and install any python version without messing things up.

Installing different Python versions

Installing multiple versions of Python and switching between them is quite simple using Pyenv:

# Checking for available python versions
  pyenv install --list
# Installing different Python versions
  pyenv install 3.9.6
  pyenv install 3.7.5
# Making sure everything is up to date
  pyenv rehash
# Checking all versions installed with Pyenv
  pyenv versions

The last command should output something like:

* system (set by /Users/atzmonky/.pyenv/version)

Where system version is the one that comes out of the box (For me it’s Python 2.7.1), while the other was installed using pyenv.

We can set a global version of Python to be used in all shells using a format like pyenv global <python version> :

# Setting up python 3.9.6 globally
  pyenv global 3.9.6

Alternatively, We can use a local setting for a specific project which sets a .python-version file in the project’s directory.

First, let’s create a project folder and assign a local python version for the project (folder):

# Navigate to my Projects directory 
  cd /Users/atzmonky/Documents/Projects
# And create a folder (project)
  mkdir test_project
# Create the local python setting with Pyenv
  pyenv local 3.9.6
# And we can also delete the local setup whenever we wish to with the command
  pyenv local --unset

That’s it! First step of setting up python is done. We have set up Pyenv to install and manage all python versions without messing up our system python.

Setting up Pipenv

Next, We will download and install Pipenv, again using Homebrew:

brew install Pipenv

When we use Pyenv, the Pipenv install command will use the global Python version of your system set by Pyenv. We can also set up a local python version specifically for that project. If that is the case, we will assign that using Pyenv and then indicate that to Pipenv:

# Switch to the project directory
  cd /Users/atzmonky/Documents/Projects/test_project

We have already set up a python version for this project, so we’ll go ahead and create the virtual environment for the project.

# Setting up specific python version virtual environment for the project
  pipenv install --python 3.9.6

The last command has created a virtual environment for python version 3.9.6 using /Users/atzmonky/.pyenv/versions/3.9.6/bin/python3.9 (3.9.6) and will look like this:

The last command had also created 2 files in the test_project directory. Pipfile and Pipfile.lock, which contain information about the installed packages and dependencies of the project.

# To activate the newly created virtual environment
  pipenv shell
# To leave virtual environment and go back to the original terminal session
# To delete the virtual environment altogether we can just run the following while in project directory
  pipenv --rm
# Adding a package to your new project
  pipenv install <package>

More information and workflows regarding advance use of Pipenv can be found in the project documentation on Github.


We are finally done!

I have covered the path I ended up with after exploring several different ways of setting up python on MacOS. The workflow I have illustrated takes advantage of two amazing tools. Pyenv is used to manage different Python versions, whereas Pipenv is used to manage Python packages and the virtual environments.

I find both tools quite easy to use and I hope I have encouraged you to check them out.