I have some python code that have inconsistent indentation, there is a lot of mixture of tabs and spaces to make the matter even worse even space indentation is not preserve. The code works as expected but its difficult to maintain.

I'm looking for a tool that will fix the indentation (like html tidy but for python) and won't break the code :)

11 Answers
11

Use the reindent.py script that you find in the Tools/scripts/ directory of your Python installation:

Change Python (.py) files to use
4-space indents and no hard tab
characters. Also trim excess spaces
and tabs from ends of lines, and
remove empty lines at the end of
files. Also ensure the last line ends
with a newline.

*:ret* *:retab*
:[range]ret[ab][!] [new_tabstop]
Replace all sequences of white-space containing a
<Tab> with new strings of white-space using the new
tabstop value given. If you do not specify a new
tabstop size or it is zero, Vim uses the current value
of 'tabstop'.
The current value of 'tabstop' is always used to
compute the width of existing tabs.
With !, Vim also replaces strings of only normal
spaces with tabs where appropriate.
With 'expandtab' on, Vim replaces all tabs with the
appropriate number of spaces.
This command sets 'tabstop' to the new value given,
and if performed on the whole file, which is default,
should not make any visible change.
Careful: This command modifies any <Tab> characters
inside of strings in a C program. Use "\t" to avoid
this (that's a good habit anyway).
":retab!" may also change a sequence of spaces by
<Tab> characters, which can mess up a printf().
{not in Vi}
Not available when |+ex_extra| feature was disabled at
compile time.

For example, if you simply type

:ret

all your tabs will be expanded into spaces.

You may want to

:se et " shorthand for :set expandtab

to make sure that any new lines will not use literal tabs.

If you're not using Vim,

perl -i.bak -pe "s/\t/' 'x(8-pos()%8)/eg" file.py

will replace tabs with spaces, assuming tab stops every 8 characters, in file.py (with the original going to file.py.bak, just in case). Replace the 8s with 4s if your tab stops are every 4 spaces instead.

There is also PythonTidy (since you said you like HTMLTidy)
It can be found here: http://pypi.python.org/pypi/PythonTidy/1.16
It can do a lot more than just clean up tabs though. If you like that type of thing it's worth a look.

Things other than what you might think is indentation can cause the problem. THe compiler and tabnanny told me I had a problem at line 158 and the indentation there was perfect. The problem was about 15 lines up where I had typed ) instead of (.

from the command line, changing the number if you want to replace tabs with a number of spaces other than 4. You can easily write a shell script to do this with a bunch of files at once, retaining the original file names.