PyEnv is a tool that allows Python users to switch between multiple versions of Python easily without tampering with the system’s default Python installation. It achieves this by overriding the
python command on the command line, which helps you use a specific version for your projects. PyEnv creates isolated environments, each with its specific version of Python.
Table of Contents
Which problem does PyEnv solve?
Python, being an evolving language, has multiple versions available for use. At times, developers need to juggle between these versions to ensure compatibility or utilize features from a specific version for a specific project. Managing these versions manually can be challenging and may lead to conflicts or unexpected behaviors.
Another frequent issue developers run into is unexpected Python upgrades. For example, many developers on Macs use Brew. Many brew packages have Python as a dependency. As such, any package upgrade can trigger a change in the Python version installed by Brew. This, in turn, can break a virtual environment since the referenced Python binary is suddenly missing. A similar situation may occur when you use the default Python installation on a Linux machine.
PyEnv solves these issues with:
- Isolation: Each project can have its Python version, ensuring dependencies and environments don’t clash.
- Flexibility: Developers can test their code against multiple Python versions without changing the system settings.
- Consistency: Teams can ensure that every member uses the same Python version, leading to a consistent development environment.
How to install PyEnv
It’s important to note that PyEnv works on Unix-like environments, like Linux and Macs. There’s a Windows port (see the linked install instructions). The installation instructions for PyEnv can change occasionally, so it’s best to check the most recent instructions on the PyEnv Github repository. Ensure you follow the steps for your specific shell (bash, zsh, etc.), otherwise the
pyenv command won’t work.
Choosing a global Python version with PyEnv
Let’s first set a default, global Python version for your system. This version will be the default when you haven’t set a specific version for a directory or project.
Before we can do so, we need to know the list of available versions:
pyenv install --listCode language: plaintext (plaintext)
This is an extensive list and includes alternative Python interpreters like PyPy. You can also request the latest stable version, which you probably want anyway. For example, to get the latest stable Python 3 version:
pyenv latest 3Code language: plaintext (plaintext)
Now we can install the desired version. At the time of writing this, 3.11.5 was the latest version:
pyenv install 3.11.5Code language: plaintext (plaintext)
Once installed, you can set the global version using:
pyenv global 3.11.5Code language: plaintext (plaintext)
Choosing a specific Python version for a project
Now, let’s see how we can use an alternative version for a project. Say we have a project in the folder
~/Code/LegacyProject that requires Python 3.5.0.
We first need to install this Python version, and we have already learned how to do that:
pyenv install 3.5.0Code language: plaintext (plaintext)
First, navigate to the project’s folder to set the Python version for our legacy project. Then use the command:
pyenv local 3.5.0Code language: plaintext (plaintext)
This sets the Python version for the project and creates the hidden file
.python-version file in the directory, ensuring that the specified Python version will be used whenever you’re in this directory.
Suppose you share this legacy project with a colleague who’s also using Pyenv. If this colleague does not have Python 3.5.0 installed yet, Pyenv will notice the file and print a warning like this:
pyenv: version '3.5.0' is not installed (set by ~/Code/LegacyProject/.python-version)Code language: plaintext (plaintext)
Managing Virtual Environments with pyenv-virtualenv
PyEnv can be combined with
pyenv-virtualenv, an extension that offers support for managing virtual environments. It allows you to maintain project-specific dependencies without polluting the global namespace. I recommend following the link and seeing if this fits you. I prefer combining Pyenv for managing Python versions and Poetry for creating virtual environments and dependency management. But pyenv-virtualenv certainly has some advantages to note:
- Your pyenv-virtualenv will be activated seamlessly which is obviously very convenient. With a tool like poetry, this is an extra manual step.
- It allows you to create system-wide virtualenvs. E.g., you might have a system-wide virtualenv that has a particular Python version and particular versions of libraries like NumPy and Pandas.
PyEnv is an invaluable tool for Python developers aiming to maintain consistency and flexibility across projects. Whether you’re developing across different versions of Python or trying to maintain a consistent environment among a team, PyEnv offers a seamless and efficient solution.