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:
- use
virtualenv
to keep runtime and package dependencies separate - use
virtualenvwrapper
to follow the DRY principle - use environment variables to prevent screwing the above
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.
- It creates a copy of the runtime in
~/dev/project_name/bin/python
, and also createsmyenv/bin/pip
- Sets the shell’s
$PATH
to
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:
- Symlinks to the specified Python runtimes, which will be in the path as long as the virtual environment is active
- Separates all dependencies
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"