Clearly, this stuff must be really hard to get right. I also must be a moron, since, after having written some thousand lines of Python, I don’t even know what problem we are trying to solve here, and the abundance of relevant programs with subtly different names has deterred me from reading up on it so far.

I think that will do. Is it self-contained, though? It doesn’t contain itself…

Jokes aside, there are only two things missing to actually make our directory a virtual environment as specified by PEP 405, the proposal that integrated a standard mechanism for virtual environments with Python.1

A file named pyvenv.cfg containing the line home = /usr/bin

A lib/python3.6/site-packages subdirectory

(Both paths are subject to the OS and the second one also to the Python version used.)

What’s the point?

When we run our copy of the Python binary, the pyvenv.cfg file changes what happens during startup: the presence of the home key tells Python the binary belongs to a virtual environment, the key’s value (/usr/bin) tells it where to find a complete Python installation that includes the standard library.

The bottom line is that ./lib/python3.6/site-packages becomes part of the module search path. The point is that we can now install packages to that location, in particular, specific versions that may conflict with the dependencies of another Python program on the same system.3

Another project on the same system could have a different version of left-pad in its own virtual environment, without interfering with this one.

The standard tool for creating virtual environments

In practice, one does not simply create virtual environments by hand, which brings us back to the dauntingly long list of tools above. Fortunately, one of them is not like the others. While it’s predated by most of them, this one ships with Python as part of the standard library: venv.4

In its simplest form, venv is used to create a virtual environment like so:

$ python3 -m venv virtual_env

This creates the virtual_env directory and also copies or symlinks the Python interpreter:

$ cd virtual_env
$ find -name python3
./bin/python3

It also copies a bunch of other stuff: I get 650 files in 89 subdirectories amounting to about 10 MiB in total. One of those files is the pip binary, and we can use it to install packages into the virtual environment without passing extra command-line arguments:

$ ./bin/pip install left-pad

You can read more about using venv and optional magic like “activate” scripts in the Python tutorial or venv’s documentation—this post is only meant to boil down what a virtual environment actually is.

Summary

A virtual environment is a directory containing a Python interpreter, a special pyvenv.cfg file that affects startup of the interpreter, and some third-party Python packages.

Python packages installed into a virtual environment will not interfere with other Python applications on the same system.