Bitdoze Logo

How to Install Python on Mac, Upgrade It & Use VENV (2026)

Step-by-step guide to install Python on Mac using Homebrew, upgrade to the latest version, and set up a Python virtual environment (venv) for your projects.

DragosDragos16 min read
How to Install Python on Mac, Upgrade It & Use VENV (2026)

If you’ve tried to pip install something on a Mac recently, you’ve hit the externally-managed-environment error. Since Python 3.12, Homebrew follows PEP 668, which means virtual environments are no longer optional. They’re mandatory. This guide walks you through how to install Python on Mac using Homebrew, configure your PATH so python works, upgrade between versions without breaking things, and set up venv properly for your projects.

Updated for 2026

Python 3.14 is the current stable release (released October 2025). Homebrew’s default python formula now installs 3.14.x. PEP 668 is enforced for all Homebrew Python 3.12+ builds. pip install outside a venv will fail by design.

Before you begin: prerequisites

Check your macOS version and architecture (Apple Silicon vs Intel)

Homebrew installs to different locations depending on your Mac’s processor:

Mac type Homebrew prefix Python binary path
Apple Silicon (M1/M2/M3/M4) /opt/homebrew/ /opt/homebrew/bin/python3
Intel /usr/local/ /usr/local/bin/python3

Check which you have:

uname -m
  • arm64 → Apple Silicon
  • x86_64 → Intel

Apple Silicon vs Intel

All commands in this guide use Apple Silicon paths (/opt/homebrew/). If you’re on Intel, substitute /usr/local/ where applicable. The commands themselves (brew install, python3, etc.) are identical.

If you want a better terminal experience before diving in, consider setting up a modern Mac development terminal first.

Install Xcode Command Line Tools

macOS ships with its own Python 3 (installed via Xcode Command Line Tools, typically 3.9.x). You need the CLT for Homebrew to work, but do not remove the system Python. macOS tools depend on it.

xcode-select --install

Click “Install” in the dialog. This takes a few minutes.

Verify it installed:

xcode-select -p

Expected output: /Library/Developer/CommandLineTools

Don't remove system Python

macOS uses its built-in Python 3 for system tools and scripts. Homebrew installs alongside it, not over it. Never delete or modify /usr/bin/python3.

Install Homebrew on Mac

Homebrew is the package manager that makes Python installation simple. If you don’t have it yet:

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

On Apple Silicon, Homebrew adds its PATH entry to ~/.zprofile automatically. Follow the post-install instructions shown in the terminal. You may need to run:

eval "$(/opt/homebrew/bin/brew shellenv)"

Verify Homebrew is healthy:

brew doctor

Expected: Your system is ready to brew.

If you’re customizing your shell, supercharge your Zsh terminal with useful plugins and enable syntax highlighting in Zsh for a better experience.

Install latest Python on Mac with Homebrew

With Homebrew ready, install the latest stable Python:

brew install python

This installs Python 3.14.x (the current stable release as of 2026), along with pip, setuptools, and wheel.

Verify your Python installation

Run these checks to confirm everything is working:

  • python3 –version → should show Python 3.14.x
  • which python3 → should show /opt/homebrew/bin/python3 (Apple Silicon)
  • which pip3 → should show /opt/homebrew/bin/pip3
  • python –version → works after PATH configuration (see next section)
python3 --version
which python3
which pip3

Expected output:

Python 3.14.6
/opt/homebrew/bin/python3
/opt/homebrew/bin/pip3

Configure your PATH for Python on Mac

Here’s the thing nobody tells you: after brew install python, the command python3 works, but python does NOT. You’ll get:

zsh: command not found: python

Homebrew installs the unversioned symlinks (python, pip) to a separate directory that’s not on your PATH by default. Fix it:

# Add Homebrew Python's unversioned commands to PATH
echo 'export PATH="$(brew --prefix python)/libexec/bin:$PATH"' >> ~/.zprofile
source ~/.zprofile

`python` command not found?

This is expected before PATH configuration. The fix is the export PATH line above. Add it to ~/.zprofile (for login shells) or ~/.zshrc (for interactive shells). Either works in Terminal.app.

Verify:

python --version

Should show the same version as python3 --version.

Install a specific Python version on Mac

Sometimes a project requires a specific Python version. Homebrew provides versioned formulae for this.

How to search for available Python versions in Homebrew

brew search python@

You’ll see entries like [email protected] through [email protected]. For the live, up-to-date list with exact version numbers:

View all Python formulae on Homebrew

Install the version you need. For example, Python 3.13:

brew install [email protected]

The versioned command works immediately after install:

python3.13 --version
Python 3.13.14

No linking required. You can use python3.13 directly in your commands and virtual environments.

Linking keg-only Python formulae

Versioned Python formulae (like [email protected]) are “keg-only.” Homebrew does not symlink them into your PATH by default. If you try to brew link one and another Python version is already linked, you’ll get an error:

Error: Cannot link [email protected]

If you actually need python3 to point to a different version:

# Unlink the current version first
brew unlink python

# Link the version you want
brew link --force [email protected]

Relinking changes `python3` globally

After brew link --force [email protected], the python3 command will point to 3.13 instead of 3.14. This affects all your terminal sessions. In most cases, it’s simpler to just use the versioned command (python3.13) and skip relinking entirely.

Upgrade Python to the latest version on Mac

This is where most guides get it wrong, including the previous version of this article.

The truth about brew upgrade python (major vs patch upgrades)

brew upgrade python does not jump between major versions. It upgrades to the latest patch of whatever formula you have installed.

# Update Homebrew's package index
brew update

# Upgrade to latest patch of current formula (e.g., 3.14.5 to 3.14.6)
brew upgrade python

Verify:

python3 --version

Major vs patch upgrades

brew upgrade python will NOT upgrade from Python 3.13 to 3.14. To switch major versions, you must brew install [email protected] explicitly. This is the #1 misconception about upgrading Python with Homebrew.

To jump from one major version to another:

# Install the new major version
brew install [email protected]

# Use it with the versioned command
python3.14 --version

Pin Python to prevent accidental upgrades

When Homebrew upgrades other packages, it can sometimes upgrade Python as a dependency. This changes the Python binary path, which breaks existing virtual environments. Pin your Python version to prevent this:

# Pin prevents accidental upgrades
brew pin [email protected]

# Check what's pinned
brew list --pinned

# Unpin when you're ready to upgrade
brew unpin [email protected]
Why did my virtual environment break?

When Homebrew upgrades Python (even a patch version), it can change the absolute path to the Python binary inside your .venv. Since venvs store absolute paths in pyvenv.cfg and inside the activate scripts, the old venv may stop working after an upgrade.

Fix: recreate the venv and reinstall dependencies.

rm -rf .venv
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Prevention: use brew pin on your Python formula.

Understanding PEP 668: why you need virtual environments

This is the section I wish existed when I first ran into the error. If you’ve tried to install a Python package globally with pip and gotten a wall of red text, here’s why.

The externally-managed-environment error explained

Starting with Python 3.12, Homebrew marks its Python installation as “externally managed” (per PEP 668). This means:

pip install requests

Results in:

error: externally-managed-environment

× This environment is externally managed
╰─> To install Python packages system-wide, try brew install
    xyz, where xyz is the package you are trying to install.

This is not a bug. It’s a deliberate protection. Homebrew Python is managed by Homebrew. Letting pip install packages globally could conflict with Homebrew-managed packages and break your system.

The fix: use a virtual environment (for project dependencies) or pipx (for CLI tools). Both are covered in the next sections.

`externally-managed-environment` error?

This is expected behavior since Python 3.12, not a mistake. Activate a virtual environment before using pip install, or use pipx for global CLI tools. See the next sections for both approaches.

Reference: Homebrew and Python documentation.

Run Python in VENV on Mac

Virtual environments are now the standard (and required) way to manage Python project dependencies. Here’s the full workflow.

Create a Python virtual environment on Mac

Navigate to your project directory and create a venv:

cd ~/my-project
python3 -m venv .venv

Why `.venv`?

.venv is the modern convention. It’s what VS Code, PyCharm, uv, and Poetry auto-detect. It’s hidden by default on macOS (the leading dot), and it’s the name you’ll see in most Python projects on GitHub. You can use a custom name if you prefer, but .venv is the default for a reason.

Activate and use your virtual environment

source .venv/bin/activate

Your terminal prompt changes to show the active environment:

(.venv) user@mac my-project %

Verify it’s working:

which python

Should show: /Users/youruser/my-project/.venv/bin/python

Now pip install works without PEP 668 errors:

pip install requests

Install packages and freeze requirements

This is the practical workflow that was missing from the old article:

# Install packages inside your active venv
pip install requests pandas fastapi

# Freeze current dependencies to a file
pip freeze > requirements.txt

The requirements.txt file lets anyone recreate the same environment:

# On another machine (or after cloning a repo):
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Using uv instead of pip?

uv is a drop-in replacement for pip that’s 10-100x faster. Install it with brew install uv and use:

uv pip install requests pandas
uv pip freeze > requirements.txt
uv venv  # creates venvs faster than python -m venv

For a full walkthrough, see uv, a modern Python package manager.

Deactivate the virtual environment

When you’re done working:

deactivate

Your prompt returns to normal. The packages stay installed in .venv/. Nothing is lost.

Add .venv to .gitignore

Never commit your virtual environment to git. Add these entries to your .gitignore:

.venv/
venv/
env/
  • Add .venv/ to .gitignore
  • Add venv/ and env/ as well (common alternatives)
  • Commit requirements.txt instead of the venv directory
  • GitHub’s default Python .gitignore template already includes these

Troubleshooting common Python on Mac issues

Fix: `python` command not found

Cause: Homebrew doesn’t add python (unversioned) to your PATH by default.

Fix:

echo 'export PATH="$(brew --prefix python)/libexec/bin:$PATH"' >> ~/.zprofile
source ~/.zprofile
python --version

In the meantime, python3 always works after brew install python.

Fix: `brew link` fails for versioned Python

Cause: Versioned Python formulae are keg-only. Another Python version is already linked.

Fix: Use the versioned command directly instead of relinking:

# Just use the versioned command. No linking needed.
python3.13 --version
python3.13 -m venv .venv

If you must relink:

brew unlink python
brew link --force [email protected]
Fix: `externally-managed-environment` error

Cause: You’re running pip install outside a virtual environment. PEP 668 blocks this with Homebrew Python 3.12+.

Fix: Activate a venv first:

python3 -m venv .venv
source .venv/bin/activate
pip install <package>

For global CLI tools (black, ruff, mypy), use pipx instead:

brew install pipx
pipx ensurepath
pipx install black
Fix: broken venv after `brew upgrade`

Cause: Homebrew upgraded Python, changing the binary path that your venv references.

Fix: Recreate the venv:

rm -rf .venv
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Prevention: Pin your Python version with brew pin [email protected].

Alternatives to consider

Homebrew is the simplest path, but it’s not the only one. Here are the main alternatives.

uv: a modern Python package manager

uv by Astral is an all-in-one Python tool that replaces pip, venv, pyenv, and pipx. It’s written in Rust and significantly faster than pip.

brew install uv
uv venv           # create venvs faster
uv pip install requests  # drop-in pip replacement
uv python install 3.13   # install specific Python versions

If you want a single tool that handles everything covered in this article, uv is worth a look. Full guide: uv, a modern Python package manager. For deployment: deploy a Python project with uv and Dokploy.

pyenv: manage multiple Python versions

pyenv is for when you need to switch between Python versions frequently across different projects. Homebrew’s own docs recommend it “if you require stability of minor or patch versions for virtual environments.”

brew install pyenv
pyenv install 3.13.14
pyenv install 3.14.6
pyenv global 3.14.6

pyenv manages versions independently of Homebrew, so upgrading Homebrew won’t accidentally change your project’s Python version. More overhead to set up, but more control.

Official Python.org installers

Python.org provides macOS universal2 installers that work on both Apple Silicon and Intel. These are standalone, no Homebrew dependency.

Use this if you don’t want Homebrew at all, or if you need a specific Python build. The downside: manual PATH setup, no automatic updates, and it doesn’t integrate with the Homebrew ecosystem.

pipx: install Python CLI tools globally

pipx installs Python CLI tools (like black, ruff, mypy, poetry) in isolated environments, making them available globally without polluting your system Python.

brew install pipx
pipx ensurepath
pipx install black
pipx install ruff

pipx vs venv

pipx is for CLI tools you run from anywhere (formatters, linters, build tools). venv is for project dependencies your code imports. They solve different problems and work well together.

Next steps: what to build with Python on Mac

Now that you have Python installed and know how to manage environments, here’s where to go from here:

If you’re deploying to a server, Hetzner offers affordable EU VPS that works well for Python apps.

Browse All Python Tutorials