| #! /usr/bin/env python |
| |
| """The Tab Police watches for possibly inconsistent indentation.""" |
| |
| import os |
| import sys |
| import getopt |
| import tokenize |
| |
| verbose = 0 |
| quiet = 0 |
| |
| def main(): |
| global verbose, quiet |
| try: |
| opts, args = getopt.getopt(sys.argv[1:], "qv") |
| except getopt.error, msg: |
| print msg |
| return |
| for o, a in opts: |
| if o == '-v': |
| verbose = verbose + 1 |
| quiet = 0 |
| if o == '-q': |
| quiet = 1 |
| verbose = 0 |
| if not args: |
| print "Usage:", sys.argv[0], "file_or_directory ..." |
| return |
| for arg in args: |
| check(arg) |
| |
| def check(file): |
| if os.path.isdir(file) and not os.path.islink(file): |
| if verbose: |
| print "%s: listing directory" % `file` |
| names = os.listdir(file) |
| for name in names: |
| fullname = os.path.join(file, name) |
| if (os.path.isdir(fullname) and |
| not os.path.islink(fullname) or |
| os.path.normcase(name[-3:]) == ".py"): |
| check(fullname) |
| return |
| |
| try: |
| f = open(file) |
| except IOError, msg: |
| print "%s: I/O Error: %s" % (`file`, str(msg)) |
| return |
| |
| if verbose > 1: |
| print "checking", `file`, "with tabsize 8..." |
| tokens = [] |
| tokenize.tabsize = 8 |
| try: |
| tokenize.tokenize(f.readline, tokens.append) |
| except tokenize.TokenError, msg: |
| print "%s: Token Error: %s" % (`file`, str(msg)) |
| |
| if verbose > 1: |
| print "checking", `file`, "with tabsize 1..." |
| f.seek(0) |
| alttokens = [] |
| tokenize.tabsize = 1 |
| try: |
| tokenize.tokenize(f.readline, alttokens.append) |
| except tokenize.TokenError, msg: |
| print "%s: Token Error: %s" % (`file`, str(msg)) |
| f.close() |
| |
| if tokens == alttokens: |
| if verbose: |
| print "%s: Clean bill of health." % `file` |
| elif quiet: |
| print file |
| else: |
| badline = 0 |
| n, altn = len(tokens), len(alttokens) |
| for i in range(max(n, altn)): |
| if i >= n: |
| x = None |
| else: |
| x = tokens[i] |
| if i >= altn: |
| y = None |
| else: |
| y = alttokens[i] |
| if x != y: |
| if x: |
| kind, token, start, end, line = x |
| else: |
| kind, token, start, end, line = y |
| badline = start[0] |
| break |
| if verbose: |
| print "%s: *** Line %d: trouble in tab city! ***" % ( |
| `file`, badline) |
| print "offending line:", `line` |
| else: |
| print file, badline, `line` |
| |
| if __name__ == '__main__': |
| main() |