The Problem

When developing multiple Python projects concurrently, each having its own separate set of modules/packages which might conflict, and sometimes even its own version of Python, it is very hard to keep track of which Python interpreter and which set of libraries go with each project.

As for Python selection, an excellent tool called Pythonbrew exists to simplify the installation, usage, and reinstallation of Python versions.

As for the package sets, another industry-standard tool called virtualenv enables you to use "virtual pythons" on top of your existing installation to isolate environments. To simplify the workflow, a wrapper exists that enables you to quickly switch between virtual environments. pythonbrew also includes this functionality.

As a command-line-savvy developer you want to be able to access this functionality quickly when running your projects. For instance, you'd like to:

  1. start a shell
  2. workon your favorite virtualenv
  3. python develop your project and start working on it.

Problem no. 1: Wrong Environments

Running the wrong python can be a painful mistake. You can install your project in the global python installation (which means a lot of dependencies creeping in). Also one project being developed in one environment (via develop) can be a dependency in another environment, which can get you wasting a whole lot of time trying to regain control over your working environment.

A quick look at the above set of actions reveals a great potential for getting the wrong environment by mistake. It gets even worse when using "console scripts" -- for instance, if you have nose installed in your global Python installation, then the nosetests script will be in your $PATH somewhere. However, if you try to use it to test a project being developed in a virtual environment, it will fail importing stuff.

Problem no. 2: IDEs

Even if you got to activating your "right" environment, that only solves your problems for the current shell session. Once you start a new shell you're forced to deal with the same issue again.

It gets even worse when you try to integrate various scripts and tools into your editors/IDEs. If you want to run a script from your project with emacs, for instance, you can't just run it as-is, because it relies on the virtual python installation that it was installed on. This gets you to mess around with your configuration schemes on a per-project basis hoping to get it right, and is generally a headache.

Problem no. 3: Responsiveness

Many solutions involve a shell mode of some sort to switch your default python interpreter (like pb switch and They are great, but sometimes they take some time to execute. This causes your .bashrc or .zshrc to take an extra second or so, and sometimes even more. I don't know about you, but my workflow includes opening and closing many tabs and panes, so this can get pretty annoying pretty fast.

The Solution

Enter pytoggle. It is a tool which, through symlinks, lets you use python from various paths, deducing the "right" virtualenv and/or Python for you at any given point.

Installation is a breeze:

$ git clone ~/.pytoggle
$ ~/.pytoggle/pytoggle install

And put this in your shell init file (.bashrc, .zshrc, etc.):

export PATH=~/.pytoggle/aliases:$PATH

And from that point forward, you can create files like this, to control the python to be used for any script in the directory or any subdirectory:

path = ~/.pythonbrew/venvs/Python-2.7/proj1_venv/bin

For more information, source, issues and pull requests, see the github page


blog comments powered by Disqus