I use Python more and more regularly and each time I set up a new machine I go through the same steps to enable a clean and modular way to run multiple versions of Python, each time I forget a step and am left scratching my head, this time I decided to document those steps.
Problem
- I want to use multiple versions of Python locally
- I do not want to override the default version of Python on the Mac in-case it’s required some something else.
- I do not want to edit symlinks to the python binaries or use brew/python installers to force overwrite current Python installations
Solution
The solution is pyenv. Pyenv allows us to install and manage as many versions of Python as I need and flip between them where required, it uses a convention to allow my terminal session to use a version on Python installed under my home directory rather then over writing the global install.
In this example I am setting up my 2020 M1 MacBook pro, by default the Python version is:
~ python --version
Python 2.7.16
and
~ python3 --version ok
Python 3.8.9
I really want Python 3.10 for Pygame, and 3.9 for AWS Lambda, this is how you can accomplish that.
Setup and Installation
To accomplish this we first start with Homebrew, If your reading this your likely familiar, if not Homebrew is a software manager that is primarily used for MacOs ( though I do use it on linux ) to install the software I require with ease.
You can install HomeBrew in a terminal like so:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Next we update brew and install pyenv
brew update
brew install pyenv
We need to add a few exports and commands to our .zshrc or .bash_profile this will enable pyenv each time we start a fresh terminal session.
Paste int eh following if you are running zsh
cat <<EOT >> ~/.zshrc
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/shims:$PATH"
export PATH="$PYENV_ROOT/bin:$PATH"
if command -v pyenv 1>/dev/null 2>&1; then
eval "$(pyenv init -)"
fi
EOT
and for Bash
cat <<EOT >> ~/.bash_profile
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/shims:$PATH"
export PATH="$PYENV_ROOT/bin:$PATH"
if command -v pyenv 1>/dev/null 2>&1; then
eval "$(pyenv init -)"
fi
EOT
We now reload our session profile
source ~/.zshrc
#or for Bash
source ~/.bash_profile
We now have pyenv correctly installed and ready for application.
Let’s install Python 3.10 and set it as the local version of Python to use for this terminal session.
I have Xcode installed, if you don’t then you may need to follow these steps first:
xcode-select --install
Then install Python 3.10
pyenv install 3.10.0
OK, let’s check it out did it work?
~ python --version
Python 2.7.16
No, not yet, we still need to enable it, do so for this session by running:
~ pyenv local 3.10.0
#now test
~ python --version
Python 3.10.0
Great! Now how do we set that as the “global” default so that each time we open a new session Python 3.10.0 is set.
~ pyenv global 3.10.0
#now test
~ python --version
Python 3.10.0
Open a new terminal session and you’ll see that it’s still 3.10.0
Additional Python versions
For this new session we actually want Python 3.9.6, to accomplish this install 3.9.6 like so:
pyenv install 3.9.6
The enable it:
~ pyenv local 3.9.6
#now test
~ python --version
Python 3.9.6
Perfect! Nice and clean and ready for development!
Now off to build something!