The basic problem being addressed is one of dependencies and versions,
and indirectly permissions. Imagine you have an application that
needs version 1 of LibFoo, but another application requires version
2. How can you use both these applications? If you install
everything into /usr/lib/python2.7/site-packages (or whatever your
platform’s standard location is), it’s easy to end up in a situation
where you unintentionally upgrade an application that shouldn’t be
upgraded.

Or more generally, what if you want to install an application and
leave it be? If an application works, any change in its libraries or
the versions of those libraries can break the application.

Also, what if you can’t install packages into the global
site-packages directory? For instance, on a shared host.

In all these cases, virtualenv can help you. It creates an
environment that has its own installation directories, that doesn’t
share libraries with other virtualenv environments (and optionally
doesn’t access the globally installed libraries either).

Python bugfix releases 2.6.8, 2.7.3, 3.1.5 and 3.2.3 include a change that
will cause “import random” to fail with “cannot import name urandom” on any
virtualenv created on a Unix host with an earlier release of Python
2.6/2.7/3.1/3.2, if the underlying system Python is upgraded. This is due to
the fact that a virtualenv uses the system Python’s standard library but
contains its own copy of the Python interpreter, so an upgrade to the system
Python results in a mismatch between the version of the Python interpreter
and the version of the standard library. It can be fixed by removing
$ENV/bin/python and re-running virtualenv on the same target directory
with the upgraded Python.

workingenv (which I do not suggest you use anymore) is the
predecessor to this library. It used the main Python interpreter,
but relied on setting $PYTHONPATH to activate the environment.
This causes problems when running Python scripts that aren’t part of
the environment (e.g., a globally installed hg or bzr). It
also conflicted a lot with Setuptools.

virtual-python
is also a predecessor to this library. It uses only symlinks, so it
couldn’t work on Windows. It also symlinks over the entire
standard library and global site-packages. As a result, it
won’t see new additions to the global site-packages.

This script only symlinks a small portion of the standard library
into the environment, and so on Windows it is feasible to simply
copy these files over. Also, it creates a new/empty
site-packages and also adds the global site-packages to the
path, so updates are tracked separately. This script also installs
Setuptools automatically, saving a step and avoiding the need for
network access.

zc.buildout doesn’t
create an isolated Python environment in the same style, but
achieves similar results through a declarative config file that sets
up scripts with very particular packages. As a declarative system,
it is somewhat easier to repeat and manage, but more difficult to
experiment with. zc.buildout includes the ability to setup
non-Python systems (e.g., a database server or an Apache instance).

I strongly recommend anyone doing application development or
deployment use one of these tools.