blob: 95bcb7b84ccdcf5e0ca0763060782a19276036cc [file] [log] [blame]
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<Node> method, where <Node> 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/.