isort is a package delicate to make your import statements fall in line more uniformly, orderly.

Basically, it groups up each type import of __future__, standard libraries, third ones, and yours, plus some extra. It works fine, generally, if the code isn’t doing some tricks. In the README, it’s already stated that it wouldn’t work for try ... except1.

But I noticed another issue, here is an output diff:

 ~/p/smartypants.py [hg:default] $ isort -df $(find . -name \*.py)
--- /home/livibetter/p/smartypants.py/docs/conf.py:before
+++ /home/livibetter/p/smartypants.py/docs/conf.py:after
@@ -11,14 +11,16 @@
 # All configuration values have a default; values that are commented out
 # serve to show the default.

-import sys, os
+import os
+import sys
+
+import smartypants

 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
 sys.path.insert(0, os.path.abspath('..'))

-import smartypants

 # -- General configuration -----------------------------------------------------

isort wanted to move the last import statement, but it’s there for a reason, the system path is manipulated. In order to prevent that, I will need to use # isort:skip to tell isort to skip that one.

You may want to use --diff or -df for first time, by default, all files are edited in-place. Or you can also use -c to check. There are a few of plugins for isort listed in README for some editors, you may want to check them out.

It can also be used as a utility for adding imports, like print_function and unicode_literals:

isort -a 'from __future__ import print_function' \
      -a 'from __future__ import unicode_literals' $(find . -name \*.py)

isort doesn’t seem to be able to handle space in directory name, so using find‘s -exec wouldn’t be helpful, the command substitute above is doing all isort can take. Buy why would you have a space in directory name which is part of Python project?

You can use as many -a as you like, the pair above will be merged into one as the following, sort is smart.

from __future__ import print_function, unicode_literal

Of course, it also supports removal, but you have to do like

isort -r '__future__' files

It means that all imports from __future__ will be removed, you use name, not the import statement. This seems to be one drawback to me, another is it’s Python 2 only at the moment.

I have included it in one of my project’s setup.py command, I think it’s worth to have it, even though it has quite a lot of dependencies. Five extra along with it installed via pip.

[1]This is used for different library names for different Python versions mainly, or different implemtations and same interface of libraries.