Code sanity checker?

Stefan Franke spamfranke at bigfoot.de
Tue May 16 16:33:46 EDT 2000


[Sorry if this is a repost, my newsreader produced some error messages]

On Mon, 15 May 2000 01:02:38 +0300 (IDT), Moshe Zadka <moshez at math.huji.ac.il> wrote:

>No, but it wouldn't be too hard to catch the common cases with the
>``parser'' module.

Phewh...too lazy to fiddle around with those nested tuples, so I just
wrote a real dumb one - using the token stream. Find the code below.

Stefan

--------------------------

#! /usr/local/bin/python

# Script ddcheck version 0.0.1, 16-May-2000
# Written and released to the public domain by
# Stefan Franke (franke at meso.net).
# The code is provided as-is, so use at your own risk.
# Improvements are welcome.

"""Script ddcheck.py -- check another Python script for double definitions

USAGE:
    ddcheck <script.py>

Checks if the given Python script conains multiple class or function with
the same name inside the same scope. 'Scope' is defined rather dumb in this
case - it just means the same indentation level.

Since it is perfectly valid to write code like, let's say,

    class C:
        def f(): pass
            if 1:
                def f(): pass

by far not all possible conflicts are found.
"""

__version__ = 0, 0, 1

import token, tokenize

interesting_tokens = [token.INDENT, token.DEDENT, token.NAME]

class DefChecker:
    def __init__(self):
        self.was_def = 0
        self.error_count = 0
        self.scope_stack = [{}]

    def tokeneater(self, type, token, (srow, scol), (erow, ecol), line):
        if type in interesting_tokens:
            self.check(type, token, srow)

    def check(self, type, name, line):
        if type == token.INDENT:
            self.scope_stack.append({})
            self.was_def = 0
        elif type == token.DEDENT:
            del self.scope_stack[-1]
            self.was_def = 0
        else: # type == token.NAME
            if name in ["class", "def"]:
                self.was_def = 1
            else:
                scope = self.scope_stack[-1]
                if self.was_def:
                    if scope.has_key(name):
                        self.error(name, scope[name], line)
                        self.error_count = self.error_count +1
                    else:
                        scope[name] = line
                self.was_def = 0

    def error(self, name, line1, line2):
        print "Definition of '%s' in line %d is overwritten in line %d." %(    
            name, line1, line2)

if __name__ == "__main__":
    import sys
    checker = DefChecker()
    try:
        fname = sys.argv[1]
        print "Checking file '%s'..." %fname
        tokens = tokenize.tokenize(open(fname, "r").readline,
                                   checker.tokeneater)
        print "%d error(s) found." %(checker.error_count)
    except IndexError:
        print "Usage: ddcheck <script.py>"




More information about the Python-list mailing list