[Patches] selfnanny.py: checking for "self" in every method
Moshe Zadka
Moshe Zadka <mzadka@geocities.com>
Sat, 4 Mar 2000 15:15:04 +0200 (IST)
This simple nanny checks a Python source for methods that don't have
arguments, or that the first argument isn't called "self". This is an
important enough style guideline that I believe it is worth putting in
a check, besides, it would stop bugs like
class foo:
def __init__():
self.i = 1
a = foo()
NameError: self
---------------- selfnanny.py ----------------------
#!/usr/local/bin/python
import parser, symbol, types
def check_file(file):
return check_string(file.read())
def check_string(s):
return check_ast(parser.suite(s))
def check_ast(ast):
return check_tuple(ast.totuple(1)) # retain line numbers
def check_tuple(tup, classname=None):
if type(tup) != types.TupleType:
return []
problems = []
if tup[0] == symbol.funcdef:
if classname is not None:
args = get_function_args(tup)
if not args or args[0] != 'self':
funcname, funcline = tup[2][1:]
problems.append((funcline, funcname, classname))
classname = None
if tup[0] == symbol.classdef:
classname = tup[2][1]
for t in tup[1:]:
problems.extend(check_tuple(t, classname))
return problems
def get_function_args(tup):
ret = []
for t in tup[1:]:
if t[0] == symbol.parameters:
parameters = t
arglist = ()
for t in parameters[1:]:
if t[0] == symbol.varargslist:
arglist = t
for arg in arglist[1:]:
if arg[0] == symbol.fpdef:
ret.append(arg[1][1])
return ret
def format_problem(problem):
s = 'line %d: method %s in class %s missing first argument "self"'
return s % problem
def print_problems(problems):
for problem in problems:
print format_problem(problem)
def nanny(filename):
print_problems(check_file(open(filename)))
if __name__=='__main__':
import sys
for filename in sys.argv[1:]:
nanny(filename)
------------------- selfnanny.py ---------------------
Legal:
I confirm that, to the best of my knowledge and belief, this
contribution is free of any claims of third parties under
copyright, patent or other rights or interests ("claims"). To
the extent that I have any such claims, I hereby grant to CNRI a
nonexclusive, irrevocable, royalty-free, worldwide license to
reproduce, distribute, perform and/or display publicly, prepare
derivative versions, and otherwise use this contribution as part
of the Python software and its related documentation, or any
derivative versions thereof, at no cost to CNRI or its licensed
users, and to authorize others to do so.
I acknowledge that CNRI may, at its sole discretion, decide
whether or not to incorporate this contribution in the Python
software and its related documentation. I further grant CNRI
permission to use my name and other identifying information
provided to CNRI by me for use in connection with the Python
software and its related documentation.
--
Moshe Zadka <mzadka@geocities.com>.
http://www.oreilly.com/news/prescod_0300.html