The safe way to install Python on macOS is to use Homebrew or pyenv rather than the Python that ships with the operating system. If you have ever run python3 on a fresh Mac and wondered why the version looked stale, that is the system interpreter Apple bundles for its own tooling, and touching it is a good way to break things you did not know depended on it. This guide walks through a clean macOS install Python workflow, then covers the part most tutorials skip: keeping the packages you pull down from PyPI from becoming a supply chain problem.
Why Not the System Python
Every recent macOS ships with a Python 3 interpreter at /usr/bin/python3. It exists so Apple's own scripts and some Xcode command line tools can run. It is not there for your projects. If you pip install into it (assuming it even lets you), you risk shadowing packages the OS relies on, and a future macOS update can wipe or replace the whole thing without warning.
The rule I give every new hire: never install project dependencies into the macOS Python. Leave it alone. Install your own interpreter alongside it. That is the entire reason the rest of this post exists.
Option 1: Homebrew (Simplest)
Homebrew is the de facto package manager for macOS and the quickest path to a usable Python. If you do not have it yet, grab the install command from brew.sh and paste it into Terminal. Then:
brew install python@3.13
As of early 2026, Python 3.13.x is the current stable series (3.13 first shipped in October 2024), and Homebrew also carries a python@3.14 formula. brew install python without a version pin gives you whatever Homebrew considers current, which can move under you. Pinning the minor version is the more predictable choice for a work machine.
After install, Homebrew symlinks the interpreter so you can call it. Confirm it worked:
python3 --version
which python3
If which python3 still points at /usr/bin/python3, your PATH is putting the system one first. Homebrew on Apple Silicon lives under /opt/homebrew/bin, so make sure that directory comes early in your shell profile. One gotcha worth knowing: Homebrew may upgrade Python at any time when you run brew upgrade. If a project needs a frozen interpreter, brew pin python@3.13 stops it from moving.
Option 2: pyenv (Best for Multiple Versions)
If you work across projects that need different Python versions, Homebrew alone gets painful. pyenv lets you install many versions side by side and switch per directory.
brew install pyenv
pyenv install 3.13.1
pyenv global 3.13.1
Add the shims to your shell. For zsh, which is the default macOS shell:
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo 'command -v pyenv >/dev/null && eval "$(pyenv init -)"' >> ~/.zshrc
exec zsh
Now pyenv local 3.12.8 inside a project directory writes a .python-version file, and that folder uses 3.12.8 while the rest of your system stays on 3.13. This is the setup I run personally, because the macOS Python question stops mattering once pyenv owns the PATH.
Set Up Virtual Environments
Whichever interpreter you land on, do not install project packages globally. Use a virtual environment per project so dependency trees stay isolated:
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
When the environment is active, pip install requests drops packages into .venv and nowhere else. Deactivate with deactivate. Tools like uv and Poetry manage this for you if you prefer, but plain venv ships with Python and has no extra moving parts.
The Part Most Guides Skip: Dependency Security
Getting Python installed on macOS is the easy 10 percent. The other 90 percent is what you do with pip install afterward. PyPI is an open registry, and the same convenience that lets you pull requests in a second also lets a typosquatted package named reqeusts land malware on your machine. Several campaigns over the last few years have used exactly that trick, plus dependency confusion, where an attacker publishes a public package with the same name as a company's internal one and hopes your resolver grabs the wrong one.
A few habits that cost almost nothing:
Pin your dependencies. A requirements.txt with exact versions, or better a lockfile with hashes (pip install --require-hashes), means an attacker cannot silently swap a version out from under you. Poetry and uv both generate hashed lockfiles by default.
Audit what you install. pip-audit cross-references your installed packages against the Python advisory database:
pip install pip-audit
pip-audit
Watch transitive dependencies. The package you chose might be clean while something three levels down is not. This is where software composition analysis earns its keep. An SCA tool can flag a vulnerable transitive dependency that never appears in your own requirements.txt, and an SCA product such as Safeguard will trace which of your direct imports actually pulls it in. If you want the conceptual grounding first, the Safeguard Academy has a walk-through of how dependency resolution creates these blind spots.
Verifying Your Install
Before you call the setup done, sanity check the whole chain:
python3 --version # correct version?
which python3 # your interpreter, not /usr/bin?
pip --version # pip tied to the same interpreter?
python3 -c "import ssl; print(ssl.OPENSSL_VERSION)"
That last line matters more than people expect. A Python built against an ancient OpenSSL will happily make TLS connections with weak ciphers. Homebrew and pyenv builds link against a current OpenSSL; the system Python's crypto is tied to Apple's release cadence. It is one more reason the macos install python decision leans toward managing your own.
FAQ
Should I use Homebrew or pyenv to install Python on macOS?
Use Homebrew if you need one current Python and value simplicity. Use pyenv if you juggle multiple projects that pin different Python versions. Many developers run both: Homebrew to install pyenv, then pyenv to manage the interpreters. Either way, do not build on top of the system /usr/bin/python3.
Is the Python that comes with macOS safe to use for projects?
It is safe for Apple's own tooling, but not a good base for your work. Its version lags, its OpenSSL is tied to the OS, and a macOS update can replace it. Install a separate interpreter through Homebrew or pyenv and leave the system Python untouched.
How do I keep pip packages from introducing vulnerabilities?
Pin exact versions in a hashed lockfile, run pip-audit regularly, and scan transitive dependencies with a software composition analysis tool. Most real Python supply chain risk comes from dependencies you never chose directly, so visibility into the full tree is what protects you.
Which Python version should I install in 2025?
The 3.13 series is the current stable line and a safe default for new projects. If a specific framework has not yet certified 3.13, pin to the latest 3.12 release with pyenv until it does, rather than downgrading your whole machine.