A Python development environment

One of the most frustrating things about getting started with Python is managing Python runtime (2.x vs 3.x) and package versions. Tools built for Python 3.x are not always backwards compatible and vice-versa.

Another issue is that the standard-issue Python package manager, called pip, likes to install new libraries to a global directory, which depends on the Python runtime.

Many projects depend on a specific version of Python as well as a specific version of the pip library. The problem here is two fold: (1) How do we keep track of the Python runtime, and (2) How do we separate package requirements?

The best solution I have encountered is 3-fold:

virtualenv

For example, normally you might have a project saved in

~/dev/project_name

But dependencies are installed using the default pip go into:

~/usr/local/bin/.../.../

Activating a virtualenv modifies your $PATH for Python.

myenv/python

Each virtualenv gets its own Python and modules. When you call the Python runtime, it will encounter the virtualenv runtimes before the system installs.

virtualenvwrapper

The problem with using virtualenv is that every virtual environment gets a full Python installation and a full set of dependencies. It’s more efficient to segregate Python runtimes and packages amongst themselves.

Creating a virtualenv using virtualenvwrapper’s mkvirtualenv will create a directory for the virtual environment, with the following:

The great thing is that you can share these virtual environments in your different projects: for my use cases, I share a Python 2.x environment and a Python 3.x environment with a number of projects.

environment variables

For virtualenvwrapper to function correctly, you will need to define a base directory for your environments. I also recommend that you require a virtual environment be active for pip to function: this will prevent installing packages outside of defined virtual environments. I’m also not a fan of .pyc files, so I have set an environment variable telling the runtime not to save these bytecodes.

export PIP_REQUIRE_VIRTUALENV=True
export PYTHONDONTWRITEBYTECODE=True
export PROJECT_HOME="${HOME}/dev"
export WORKON_HOME="${HOME}/.virtualenvs"