Using PyEnv to manage your Python versions

With the deprecation of Python 2 most of us using Python 3 are upgrading and moving to ensure we continue to get support.

A practical reality of using Python 2 was that because it was not being worked on we never really had to worry about a new version or even a different version when installing it on a new machine. Unlike in Ruby and NodeJS we got away with using the same version for all our projects.

However, this won’t work since changes in Python 3 between versions 3.5-3.8 (latest at this time) are quite different. Some projects need specific versions, not just the latest one.

Django for instance only supports up to 3.6 on it’s 1.11 branch. To use 3.7 you must first upgrade to Django 2.x and fix any breaking changes. I haven’t noticed too many when upgrading, but going to a major new version in production (when the existing one already worked fine!) is scary!

Brew only supports installing the latest version of Python 3 which means you can’t simply install Python to make a virtual enviroment in order to upgrade your Django project to 2.x. Not to mention that once it updates, given how brew installs Python, it’ll break your virtual environments links to that old python install.

That’s where PyEnv comes in.

PyEnv is a set of scripts which help install and automatically use the correct version of Python for your project.

It works by using some Shell Scripts to “shim” python, virtualenv, and etc. commands through it’s script which then uses the right version.

Once installed, running which python should point at your PyEnv script (not python). When you run python -V you should see the version pyenv selected. At first this may be the “system” version and you’ll see the version you already had before.

Installing PyEnv

All you need to do to install PyEnv is clone their git repo into ~/pyenv.

Then you update your path to look in PyEnv first like this:

export PATH="$HOME/.pyenv/bin:$PATH"

If you’re not using bash or zsh it may look different and you’ll need to look up how to manage your path in your specific shell.

Once you’ve updated your shell config you’ll want to create a new shell.

exec $SHELL

Using PyEnv

Let’s install Python 3.6.10

Note: Installing new versions doesn’t affect other ones. It also does not break your system your brew-installed versions of python.

pyenv install 3.6.10

Now we can switch to it in our shell

pyenv shell 3.6.10

Check it

pyenv shell
python -V

Now we can use pip to install the latest version of itself as well as setuptools and virtualenv

pip install -U pip setuptools virtualenv

Now we can use virtualenv to create a new enviroment for our project. I’ve often used this command

$(pyenv which virtualenv) -p $(pyenv which python) --prompt '(project)' .venv

This makes a folder .venv in your project which you can activate by running

source .venv/bin/activate