Tuesday, 7 December 2021

Fun with Python and PyEnv on macOS

Via the Advent of Code 2021 I've been doing more with Python on macOS, and was struggling with versions, given that Apple kindly include Python 2 embedded in the OS, whereas I needed Python 3.10.0 for the work that I was doing.

This was of use: -

How to Install Python 3 on Mac – Brew Install Update Tutorial

and introduced me to PyEnv via Homebrew: -

brew install pyenv

One thing that didn't work was the way that PyEnv sets up $PATH in terms of different Python versions.

Looking at this: -

cat ~/.pyenv/version

I could see: -

3.10.0

but I couldn't initially work out how to add this to my PATH.

PyEnv uses the concept of a shim, as defined in: -

pyenv works by inserting a directory of shims at the front of your PATH:

$(pyenv root)/shims:/usr/local/bin:/usr/bin:/bin

Through a process called rehashing, pyenv maintains shims in that directory to match every Python command across every installed version of Python—python, pip, and so on.

Shims are lightweight executables that simply pass your command along to pyenv. So with pyenv installed, when you run, say, pip, your operating system will do the following:

    Search your PATH for an executable file named pip
    Find the pyenv shim named pip at the beginning of your PATH
    Run the shim named pip, which in turn passes the command along to pyenv


The first article describes how to setup $PATH: -

echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile

This didn't work for me for one simple reason - I don't have $PYENV_ROOT/bin : -

ls $PYENV_ROOT/bin

ls: /Users/hayd/.pyenv/bin: No such file or directory

However, I do have $PYENV_ROOT/shims: -

ls $PYENV_ROOT/shims

2to3 easy_install-3.7 pip pydoc python-config python3.10-gdb.py python3.7m-config
2to3-3.10 idle pip3 pydoc3 python3 python3.7 pyvenv
2to3-3.7 idle3 pip3.10 pydoc3.10 python3-config python3.7-config pyvenv-3.7
autopep8 idle3.10 pip3.7 pydoc3.7 python3.10 python3.7-gdb.py
easy_install idle3.7 pycodestyle python python3.10-config python3.7m

Therefore, I setup ~/.bash_profile accordingly : -

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/shims:$PATH"
if command -v pyenv 1>/dev/null 2>&1; then
  eval "$(pyenv init -)"
fi

And now I have Python 3.10 

python3 --version

Python 3.10.0

For the record, this helped massively: -

 As Vadorequest said, if pyenv is installed using homebrew, you have to add $PYENV_ROOT/shims to the path as $PYENV_ROOT/bin does not exist. I think that is unique to homebrew installs of pyenv. 


No comments:

SSH keys and variables

Leaving this here to remind my future self ... I wanted to generate a variable containing my SSH public  key .. I tried to simply copy the k...