Repairing Python Virtual Environments

When upgrading Python breaks our environment, we can rebuild.

Python virtual environments are a fantastic method of insulating your projects from each other, allowing each project to have different versions of their requirements.

They work (at a very high level) by making a lightweight copy of the system Python, which symlinks back to the real thing whenever necessary. You can then install whatever you want in lib/pythonX.Y/site-packages (e.g. via pip), and you are good to go.

Depending on what provides your source Python, however, upgrading it can break things. For example, I use Homebrew, which (under the hood) stores everything it builds in versioned directories:

$ readlink $(which python)
../Cellar/python/2.7.8_2/bin/python

Whenever there even a minor change to this Python, symlinks back to that versioned directory may not work anymore, which breaks my virtual environments:

$ python
dyld: Library not loaded: @executable_path/../.Python
  Referenced from: /Users/mikeboers/Documents/Flask-Images/venv/bin/python
  Reason: image not found
Trace/BPT trap: 5

There is an easy fix: manually remove the links back to the old Python, and rebuild the virtual environment.


NOTE: the following is rm, NOT rm -rf; we only want to remove files and links, not directories!

$ cd /path/to/the/venv
$ rm .Python bin/python* lib/python2.7/* include/python2.7
rm: lib/python2.7/distutils: is a directory
rm: lib/python2.7/site-packages: is a directory

This will have cleared out the python executables, links back to the standard library, headers, and the primary shared library. Now you can recreate a virtual environment on top:

$ virtualenv .
New python executable in ./bin/python2.7
Also creating executable in ./bin/python
Installing setuptools, pip...done.

$ python -c 'print "Hello, blog!"'
Hello, blog!
Posted . Categories: .