This is a re-write of pychecker using traditional parse tree techniques, rather than the bytecode. There are some other design changes, related to Warning objects and Option handling. In general, pychecker2 tries to distribute checks to separate classes. These classes are more self-contained: they hold onto the option variables and define the Warning objects they support. ToDo: All missing stuff Always returning None It is illegal to delete a name from the local namespace if it occurs as a free variable in a nested block. More path analysis used before set for if/else try/except Warn about unpacking args: def f(a, (b, c)): pass Items still missing: Error suppression (errors may be suppressed globally) Detail of exception is an exception Local used after deleted, already deleted, deleted before set Not calling base class __init__ Using return value which is always None Wrong # of args on function (including ctor) Function arguments, kwargs Abstract methods exec may use locals/globals import x with from x import Modifying a default parameter Tuple access to list list[1, 2] List .append() takes one argument Return None from __getattr__ string iteration Inconsistent return type Object has no attr Method read as attribute, but not called: Function always returns None (use empty return) Unpack wrong size Unpack wrong type Exec warnings Security warning: input() Module imports itself Complexity Doc strings New python features: slots properties integer division Warning for string raising Bugs: More member not used Speed Is __file__ a builtin? Aliases: class C: def f(a, b): pass def g(a, b): pass h = f h = g # redef of h, not caught now foo = 1 del foo # should not be unused from __future__ import produces unused warnings import of readline has side effect on input/raw_input, and should be marked as used Important stuff: If you want to add new checks, there are some parts to be aware of: File A stupid data structure to hold everything we know about a file to be checked. Members: name The file name. parseTree The root of the Abstract Syntax Tree returned from compiler.parseFile. Will be None if the file won't even parse. scopes A dictionary of { node, scope } computed with from compiler.symbols. For convenience, scopes also refer back to the node and to the enclosing parent scope (node and parent, respectively). root_scope Convience for scopes[parseTree] Check Basic step for checking a file. Usually contributes Warnings or additional information to File. New checks will subclass this, and be added to the chain of checks given in main(). Warning A description of a warning emitted by pychecker. CheckList Contains "global" check information: cached module data and the list of Check objects. Command line options are pulled from each check. A Warning is also turned into a boolean-style command line option. To add a new check, write a class (e.g., CompareCheck) that subclasses the Check class. In its check method if you need to visit nodes of a particular type, write a Visitor class (subclass of BaseVisitor) which has a visit method, where is the name of a type of node to visit. See http://www.python.org/~jeremy/compiler/module-compiler.ast.html for the types of the nodes or print file.parseTree to see what classes all the nodes are. See the OpChecks.CompareCheck class for an example of a check that visits all Compare nodes and the OpChecksExceptCheck class for an example that visits all TryExcept nodes. New checks should have unit tests in utest/.