1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
# Simple-minded Python identifier checker (Ka-Ping Yee, 1 April 1997)
import sys, string, tokenize, pprint
##import os, getopt
import __builtin__
warnings = []
def terse_warn(file, linenum, line, message, start=0, end=0):
print '%s:%d: %s' % (file, linenum, message)
def log_warn(file, linenum, line, message, start=0, end=0):
warnings.append( (file, linenum, message) )
warn = log_warn
opt_i = 0
ignore_subobjs = 1
##def tty_warn(file, linenum, line, message, start=0, end=0):
## print '%s:%d: %s\n %s' % (file, linenum, message, line),
##
##BOLD, NORMAL = '\x1b[1m', '\x1b[0m'
##def vt100_warn(file, linenum, line, message, start=0, end=0):
## print '%s:%d: %s' % (file, linenum, message)
## print ' ' + line[:start] + BOLD + line[start:end] + NORMAL + line[end:],
##
##vt100_compatible = ('vt100', 'vt102', 'xterm', 'ansi', 'iris-ansi', 'linux')
##
##options, args = getopt.getopt(sys.argv[1:], 'vhi')
##if not args or ('-h', '') in options:
## print "PyLint (1 April 1997) by Ka-Ping Yee"
## print "usage: %s [-v] [-i] filename.py" % sys.argv[0]
## print " -v for verbose mode (display source lines)"
## print " -i to import modules that are imported in the file"
## sys.exit(0)
##
##if args[0] == '-': file = sys.stdin
##else: file = open(args[0])
##opt_i = ('-i', '') in options
##if ('-v', '') not in options:
## warn = terse_warn
##elif os.environ.has_key('TERM') and os.environ['TERM'] in vt100_compatible:
## warn = vt100_warn
##else:
## warn = tty_warn
try: 1/0
except: tb = sys.exc_traceback
special = {}
for name in string.split('and break class continue def del elif else except '
'exec finally for from global if import in is lambda not or pass print '
'raise return try while true false') + dir(__builtin__): special[name] = 1
member = {}
for name in [].__methods__ + {}.__methods__ + [].append.__members__ + \
warn.__members__ + warn.func_code.__members__ + \
tb.__members__ + tb.tb_frame.__members__ + \
['__dict__', '__methods__', '__members__']: member[name] = 1
# file.__methods__ + file.__members__ + \
reserved = {}
for name in string.split('abs add and bases builtin builtins call class cmp '
'coerce copy copyright deepcopy del delattr delitem delslice div divmod '
'file float getattr getinitargs getitem getslice getstate hash hello hex '
'init int invert len long lshift main mod mul name neg nonzero oct or pos '
'pow radd rand rcmp rdiv rdivmod repr rlshift rmod rmul ror rpow rrshift '
'rshift rsub rxor setattr setitem setslice setstate str sub version xor'):
reserved['__'+name+'__'] = 1
position, modules, defined = {}, {}, {}
def init_globals(afilename):
global warnings, position, modules, defined, modfrom, sawimport, last, parent, filename, bracket_depth
warnings[:] = []
position.clear(); modules.clear(); defined.clear()
modfrom = sawimport = 0
last = parent = ''
filename = afilename
bracket_depth = 0
init_globals('')
def count(type, token, (srow, scol), (erow, ecol), line,
seen = special.has_key, imported = modules.has_key):
global sawimport, modfrom, last, parent, modules, bracket_depth
if token == 'import': sawimport = 1
elif token in ('\r\n', '\n', ';'): modfrom, sawimport = '', 0
elif token == '.': parent = last
elif token == '(': bracket_depth = bracket_depth + 1
elif token == ')': bracket_depth = bracket_depth - 1
else:
try:
if last == 'from': modfrom = token
elif last in ('class', 'def'): defined[token] = 1
elif opt_i and modfrom and token == '*':
try:
for name in dir(__import__(modfrom)):
if name[0] != '_': special[name] = 1
except: pass
if type != tokenize.NAME or seen(token): return
if opt_i and not modfrom and sawimport and not imported(token):
try:
modules[token] = {}
for name in dir(__import__(token)):
modules[token][name] = 1
except: pass
if parent and member.has_key(token): pass
# RB:
# Added the following two cases:
# Optionally ignore all sub_obj if not in importing mode
# Boa can't use importing mode for fear of interpreter pollution
# Ignore all wx* names these are from wxPython and usually imported
# with a from wxPython.* import *
# Maybe test should rather be directly against the wxPython
# namespaces
# --
elif parent and parent == 'self':
special[token] = 1
elif parent and ignore_subobjs and not opt_i: pass
elif len(token) >= 3 and token[:2] == 'wx' and token[2] in string.uppercase: pass
elif len(token) >= 5 and token[:4] == 'EVT_': pass
# --
elif imported(parent) and modules[parent].has_key(token): pass
elif position.has_key(token):
del position[token]
special[token] = 1
elif token[:2] == '__' == token[-2:]:
if not reserved.has_key(token):
warn(filename, srow, line,
'dubious reserved name "%s"' % token, scol, ecol)
elif last != 'from': position[token] = (srow, line, scol, ecol, bracket_depth)
finally:
last, parent = token, ''
def pylint(afile, filename):
## print 'RESERVED'
## pprint.pprint(reserved)
## print 'SPECIAL'
## pprint.pprint(special)
init_globals(filename)
try: tokenize.tokenize(afile.readline, count)
except tokenize.TokenError, message:
warn(filename, 0, '', message)
sys.exit(1)
unique = []
for name, (linenum, line, start, end, brk_dpth) in position.items():
unique.append( (linenum, (start, end, name, line, brk_dpth)) )
unique.sort()
for linenum, (start, end, name, line, brk_dpth) in unique:
warn(filename, linenum, line, ('"%s" used only once (%d)',
'"%s" defined but unused (%d)')[defined.has_key(name)] % (name, brk_dpth), start, end)
if __name__ == '__main__':
pylint(open('pylint.py'), 'pylint.py')
pprint.pprint(warnings)
|