How to properly create a virtual Python environment.

python3 -m venv /path/to/venv
/path/to/venv/bin/python3 -m pip install wheel

I prefer to use venv, which is a native Python feature, rather than virtualenv which popularized the idea of virtual environments but remains a third party package (that, last time I looked, still relied on a bunch of hacks so that it can work with ancient Python versions that pre-date venv).

The result is an environment that is isolated from the system site-packages directory (dist-packages on Debian & derivatives) but *not* from the Python interpreter itself. Therefore, after the operating system's package manager updates the Python package, a simple restart of code running from the virtual environment is all that is needed to apply the update. Much better than a static copy of Python, or a mutant combination of a static python command that puts the operating system's Python package's standard library into its sys.path.

If there is one annoying thing about venv is that it does not always install the wheel package by default. Why is this useful?

Without wheel, pip install foo will download the foo source distribution package, and build it (invoking build) and install it ( install). This is annoying because it runs code, rather than merely downloading data and putting it into the right place; and because the build step may try to build extension modules, which will require you to have a C compiler and development libraries available. You can tell that pip is doing this because there's no nice progress bar showing the status of the download process, and you'll see the error: invalid command: 'bdist_wheel' message, which looks like an error but isn't really.

When wheel is available, pip install foo will instead download the foo built distribution in the form of a wheel. No code is invoked by pip; Python source code and pre-buid extension modules are merely downloaded and installed into the proper place. It's much faster and you get a nice progress bar to boot. So installing wheel should always be the first thing you do after you create a new virtual environment.

In case you're wondering if pip install wheel itself downloads the wheel source distribution and builds it; it does not. It will use the built distribution found in /usr/share/python-wheels.

I'm convinced that the only reason people insist on using Conda and similar third-party Python distributions is because they don't know about venv and wheel. On the other hands, it's hard to blame them for this, given the lamentable state of documentation regarding Python packaging, and the fact that most people type their problems into Google and then follow whatever instructions show up in the first search result, rather than bothering to learn how to do things properly...

I regard it something of a missing feature that pip does not have a flag (preferably enabled by default) that prevents it from running any downloaded code. Developers can disable this flag; users can benefit from its protection.

CategoryTechnote PythonVenvCreation (last edited 2019-11-09 11:09:12 by sam)

© Sam Morris <>.
Content may be distributed and modified providing this notice is preserved.