When developing in Python, it is generally a good practice not to rely on the Python version that ships with the operating system (OS). This is to ensure that the system version of Python remains relatively ‘clean’ for the OS processes. In addition, by installing a custom version(s) of Python, we open many possibilities. For one, it gives us control over which specific version(s) to use in our projects, and two, by using a virtual environment manager, we ensure that each project has access to its own tailored list of packages. One way of achieving this is by using pyenv.

How does pyenv works?

The way pyenv works is that every time we issue a Python command, it intercepts this call, using shim executables injected in our environment’s PATH, and redirects the call to the correct Python installation based on our configurations.

How to install pyenv?

Personally, on macOS, I prefer to use HomeBrew.

1brew install pyenv pyenv-virtualenv

This command will install both pyenv and pyenv-virtualenv which is a virtual environment manager for Python.

We also need to add pyenv to our shell ~/.zshrc to enable shims and autocompletion:

1# Pyenv configruation ----------------
2if command -v pyenv 1>/dev/null 2>&1; then
3  eval "$(pyenv init -)"
4fi
5if command -v pyenv virtualenv-init 1>/dev/null 2>&1; then
6  eval "$(pyenv virtualenv-init -)"
7fi

Once added, restart your terminal or execute exec zsh to reload the above configuration.

Once pyenv is installed, we can list all the available versions of Python (there are many!) by issuing the following command.

1pyenv install --list
2# Available versions:
3#   2.1.3
4#   2.2.3
5#   2.3.7
6#   2.4.0
7#   2.4.1
8#   2.4.2
9# ... output truncated ...

To install one of these versions (for example 3.9.4), we would normally use

1pyenv install 3.9.4

However, to use the environment with reticulate package in RStudio, we need to use env PYTHON_CONFIGURE_OPTS="--enable-shared" with the above command, otherwise we may receive the following error when loading reticulate in R:

1Error: Python shared library not found, Python bindings not loaded. Use reticulate::install_miniconda() if you'd like to install a Miniconda Python environment.
21. stop(paste(msg, hint, sep = "\n"), call. = FALSE)
32. python_not_found("Python shared library not found, Python bindings not loaded.")
43. initialize_python(required_module, use_environment)
54. ensure_python_initialized()
65. reticulate::py_config()

This is to satisfy one of the requirements of reticulate as specified here.

Note that for reticulate to bind to a version of Python it must be compiled with shared library support (i.e. with the –enable-shared flag).

To proceed with installing Python 3.9.4 use:

1env PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install 3.9.4

How to prepare a Python environment for reticulate?

First, create an environment named, for example, PyRStudio that is based on the Python version we installed above (3.9.4).

1pyenv virtualenv 3.9.4 PyRStudio

Then use pyenv activate PyRStudio to manually activate the environment, or if you prefer to activate this environment automatically every time we change into the project directory, do:

1cd ~/path/to/projectDir
2pyenv local PyRStudio

One last step is to install numpy in the activated environment.

1pyenv activate PyRStudio
2pip3 install numpy

Final check

Launch a new Rstudio session, e.g. open -a Rstudio and check whether reticulate can recognise the activated environment.

 1reticulate::py_config()
 2# python:         /Users/firas/.pyenv/shims/python3
 3# libpython:      /Users/firas/.pyenv/versions/3.9.4/lib/libpython3.9.dylib
 4# pythonhome:     /Users/firas/.pyenv/versions/PyRStudio:/Users/firas/.pyenv/versions/PyRStudio
 5# version:        3.9.4 (default, Apr 27 2021, 20:14:35)  [Clang 12.0.0 (clang-1200.0.32.29)]
 6# numpy:          /Users/firas/.pyenv/versions/3.9.4/envs/PyRStudio/lib/python3.9/site-packages/numpy
 7# numpy_version:  1.20.2
 8#
 9# python versions found:
10#  /Users/firas/.pyenv/shims/python3
11#  /usr/bin/python3
12#  /usr/local/bin/python3
13#  /usr/bin/python

And test numpy in a new Python code chunk:

1import numpy as np
2a = np.array([1, 2, 3])
3print(a)
4
5# Python 3.9.4 (/Users/firas/.pyenv/shims/python3)
6# Reticulate 1.19 REPL -- A Python interpreter in R.
7# [1 2 3]

How to revert this setup?

  • To uninstall the virtual environment, use:
1pyenv uninstall PyRstudio
  • To uninstall both the virtual environment and the custom Python version (3.9.4 in our example), use:
1pyenv uninstall 3.9.4
  • To uninstall pyenv
1rm -rf $(pyenv root)
2brew uninstall pyenv

Additionally, delete/comment the pyenv configuration commands that we added to ~/.zshrc during the installation step above.