Safeguard
DevSecOps

Installing Python on Mac: A Safe, Step-by-Step Guide

Installing Python on Mac has a few paths, and the safest one keeps you off the system Python and away from sudo pip. Here is how to do it cleanly.

Marcus Chen
DevSecOps Engineer
5 min read

Installing Python on Mac is straightforward, but the safe way is to install a Python you control — via Homebrew or pyenv — and never touch the system Python that macOS ships or run sudo pip. The most common mistakes are modifying the macOS-managed interpreter, which can break OS tooling, and installing packages globally as root, which is both fragile and a security risk. Getting the setup right the first time saves you from a class of problems that are annoying to unwind later.

macOS historically bundled a Python interpreter for its own use. That copy exists for the operating system, not for your projects, and treating it as your development Python is where trouble starts. The whole strategy below is about keeping your work cleanly separated from it.

Why not just use the Python already on the Mac

Two reasons. First, the system Python is a dependency of macOS tooling; installing or upgrading packages into it with sudo can break scripts the OS relies on, and Apple can change or remove it in an update without warning. Second, running sudo pip install grants a downloaded package's installation code root privileges on your machine — an unnecessary risk when a compromised or typosquatted package could run arbitrary code as your most privileged user. The rule is simple: never sudo pip, and never build your projects on the system interpreter.

Option one: Homebrew, the pragmatic default

Homebrew is the standard macOS package manager and the fastest clean path. If you do not have it, install it from the official site, then:

# install a Homebrew-managed Python
brew install python

# confirm which python you're now getting
which python3
python3 --version

which python3 should point inside the Homebrew prefix — /opt/homebrew/bin/python3 on Apple Silicon or /usr/local/bin/python3 on Intel — not /usr/bin/python3, which is the system copy. Homebrew's Python comes with pip and stays updated when you run brew upgrade. For most developers this is enough.

Option two: pyenv, when you need multiple versions

If you work across projects pinned to different Python versions, install pyenv so you can switch cleanly without ever touching the system interpreter:

brew install pyenv

# add pyenv to your shell (zsh is the macOS default)
echo 'eval "$(pyenv init -)"' >> ~/.zshrc
source ~/.zshrc

# install and select a specific version
pyenv install 3.12.4
pyenv global 3.12.4
python --version

pyenv shims the python command so each project can declare its own version with a .python-version file. This is the setup I recommend for anyone maintaining more than one codebase, because version mismatches are a quiet source of "works on my machine" failures.

Always work inside a virtual environment

Regardless of how you installed Python, never install project dependencies globally. Create an isolated virtual environment per project so one project's packages cannot conflict with — or shadow — another's:

# from your project directory
python3 -m venv .venv
source .venv/bin/activate

# now pip installs into the isolated env, no sudo, no global pollution
pip install requests

Inside an activated venv, pip install writes only into .venv, so there is never a reason to reach for sudo. Add .venv/ to your .gitignore and record dependencies in a requirements.txt or a pyproject.toml so the environment is reproducible rather than a snowflake.

The security angle most guides skip

Once Python is installed cleanly, the ongoing risk shifts from the interpreter to what you install into it. pip pulls packages from PyPI, and PyPI has a documented history of typosquatting — malicious packages named to resemble popular ones, such as a subtle misspelling of a well-known library. Two habits reduce this exposure. Pin exact versions with a lockfile so you install the same reviewed code every time, and verify the package name before installing something you have not used before.

# pin what you actually resolved
pip freeze > requirements.txt

# reinstall exactly that set later
pip install -r requirements.txt

For projects that ship, scanning those pinned dependencies for known vulnerabilities belongs in CI; an SCA tool can flag a vulnerable or malicious package in your requirements.txt before it reaches production. If you want to go further on secure Python dependency practices, our academy covers supply-chain hygiene for the Python ecosystem.

FAQ

Can I use the Python that comes with macOS?

You can run it, but you should not build projects on it or install packages into it. The system Python exists for macOS tooling; modifying it with sudo pip can break the OS, and Apple may change or remove it in an update. Install your own via Homebrew or pyenv.

Should I ever run sudo pip install on a Mac?

No. sudo pip runs the package's installation code as root, which is a needless security risk if the package is compromised or typosquatted, and it pollutes the system interpreter. Use a virtual environment instead, where pip install needs no elevated privileges.

Homebrew or pyenv for installing Python on Mac?

Homebrew is the simplest if you only need one current Python version. Choose pyenv when you work across projects that require different Python versions, since it lets you install and switch between them per project without touching the system interpreter.

How do I keep pip packages from conflicting between projects?

Create a virtual environment per project with python3 -m venv .venv and activate it before installing anything. Each project gets an isolated package set, and a pinned requirements.txt makes the environment reproducible and safe to rebuild.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.