Goals for next minor release: ----------------------------- * Run pychecker on itself and clean up * Add warning for duplicated elif conditions * Check for "if s.find(str):" s/b "if s.find(str) >= 0:" where s is a string * Add warning for: x % x is always 0 * Add warning when using listcomp variable (x) outside of [... for x in ...] * Add warning for import overriding builtin (from os import *) * Add warning if defining a module name that's also in the stdlib * Add decorator so you can do: @pychecker(maxlocals=42) def myfunc(): * Support function attributes in addition to __pychecker__ * Add warning when iterating over a dict (keys, values, items) and mutating it * Add warning for __special_ or __special or _special__ etc. * Add warning about redefining a function/method with different signatures * Add warning when base class has similar name and same signature: class Base: def foobar(): class Sub(Base): def foobaz(): # damn, I wanted to override foobar * If unknown name, suggest similar names * Check for return from finally (disables exception, default off?) * Add another boolean warning for: if bool(xxx): * Need way to configure broken (and non-broken) versions of evil C extensions * Add estimated difficulty to research/fix error * Shouldn't warn about using return value for generators * Suppress argument (self) name warnings if func has no impl? * Add warning for a variable that is constant ie, initialized and used, but never changed * Add warning for catching AttributeError when there is no attr access ZeroDivisionError w/no division? KeyError UnboundLocalError IndexError IndentationError ImportError * Add warning for a import b & b import a (import loops) * Check that classes with __slots__ don't get/set any other attributes * Expectations of __methods__, constness (don't modify in __nonzero__) * Add warning if dict has duplicate keys when creating from literals * __new__ should use cls, not self??? * If arg has default value of None, check that arg is assigned some value * check if returning self from __str__() * check for str1 in str2 == otherValue * Fix dependancy problem w/checkReturnValues & checkImplicitReturns * check for use of self.attr before setting self.attr in __init__ method * Handle sys.exit() as non-returnable condition * Warn about non-escaping backslashes??? * vars() should use locals, like locals(), hmmm, it should already ... Goals for next major release (0.9): ----------------------------------- * Improve handling when importing packages (ie, don't import modules) - Make a base class to handle stack operations - Override base class with classes to handle module scope, functions, etc. - Process module and create Module/Class/Function objects w/o dir(), etc. - Finish tests: 44 * Add a config option to ignore certain cantankerous modules * Add warning for global statement inside a conditional * Fix spurious warnings for unreachable code checks * Fix most of the FIXMEs * Add check for import module (from within package p-should be import p.module) - don't use relative imports, should always use absolute paths * If there is a warnings for unused varargs parameter (varArgumentsUsed), why not for kwargs ? Longer Term goals: ------------------ * Add check for magic #s/consts (need dict of consts, count, max count, consts to ignore) * Add check for unsupported operand type(s) for * + / etc * Store types of globals, class attributes, function & method return values * Output stats about pychecker's job, good, bad, otherwise... annotate code for problem areas, well checked areas, etc. * Add original line warnings for those that refer to another place (e.g., overridden method doesn't match signature) * Add capability to check features from a specified version of python which is different from runtime interpreter * Security checks for known issues. Adrian Likins @redhat recommends looking at http://www.securesw.com/rats/ * Make check for 'self' a list instead of a string * Check function return values - partially complete * Add check that private functions are used in module/class * Add check for using object members outside of class * Add portability checks for win32/unix * Add check for except: pass * Spell check doc strings # need to read source code for these: * Add warning for unnecessary global stmts * Add check for implicit string concatentation * Add check for creating tuple when don't want a tuple, like: 1, or not creating tuple when want one, like: (1) * Warn when using () with statements (assert, print, del, if, while) * Add check for <>, should use != * Find lines that end w/semi-colons (;) * inconsistent camel-case Fixing testsuite: ----------------- Tested on 2010-12-18, after 2.7 fixes: On Fedora 14, system Python 2.7: 7 TESTS FAILED: test13 test34 test44 test70 test71 test77 test85 On Fedora 14, source Python 2.6: 6 TESTS FAILED: test13 test34 test44 test70 test71 test77 On Fedora 14, source Python 2.5: 6 TESTS FAILED: test13 test34 test44 test70 test71 test77 On Fedora 14, source Python 2.4: 4 TESTS FAILED: test13 test44 test70 test77 On Fedora 14, source Python 2.3: 8 TESTS FAILED: test103 test13 test44 test68 test70 test77 test78 test85 On Fedora 14, source Python 2.2: 11 TESTS FAILED: test101 test103 test13 test1 test34 test3 test44 test58 test77 test78 test85 Tested on 2009-06-27: On Fedora 9, system Python 2.5: TESTS FAILED: test103 test13 test22 test44 test48 test53 test70 test71 test77 test78 test87 On Fedora 9, Python 2.4 built by hand: TESTS FAILED: test13 test44 test70 test78 test88 On Fedora 9, Python 2.3 built by hand: TESTS FAILED: test103 test13 test44 test68 test70 test77 test78 test85 On Fedora 9, Python 2.2 built by hand: all tests fail due to a bug in this_mod.__filename__ test76: when adding the patch on 2011-01-07 to process nested functions in order, line numbers for warnings changed from 6 to 7. Not clear which should be correct; it seems like a should be 6 and d should be 7 ? test103: a generator statement run twice should not generate a warning, but does in python 2.3 and 2.5, but not 2.4 test22: two constant warnings went away since python 2.5 test26: fails in 2.6 test34: fails in 2.5, 2.6 locale.py added a currency method which uses digits as a local var; this shadows global defined in the test. Not sure if this is a valid warning that should be flagged (due to from ... import *) I would argue no, since locale.py being good or bad shouldn't change based on where it's imported from. Formatter was added to string.py, without docstring, so looks like a valid new warning. test36: fails in 2.6 test44: test44.py imports * from import44, which has a class Ccc named the same but whose init takes an extra argument. test48: line 57 (the single character '5') no longer triggers statement has no effect warning since python 2.5 test53: the operator ~~ stopped generating a warning since python 2.5 test59: fails in 2.6 test68: only fails in python 2.3 test70: 5 conditional warnings went away since python 2.5; but test fails in all test71: unreachable code moved from test a to test c; since 2.5 In the pre-2.5 warnings, the line numbers don't point at the unreachable code, but the statement before. In 2.5 and later, the right blocks don't even get found; it looks like this is because the implicit return None is gone from the byte code; compare: 2.6, py-dis test_input.test71.a ... 9 25 LOAD_FAST 0 (x) 28 PRINT_ITEM 29 PRINT_NEWLINE 2.4, py-dis test_input.test71.a 9 25 LOAD_FAST 0 (x) 28 PRINT_ITEM 29 PRINT_NEWLINE 30 LOAD_CONST 0 (None) 33 RETURN_VALUE So the implied return None is not found as a terminal Aditionally, b disassembles differently too: 2.6, py-dis test_intput.test71.b ... 13 13 LOAD_FAST 0 (x) 16 RETURN_VALUE >> 17 POP_TOP 2.4, py-dis test_intput.test71.b 13 13 LOAD_FAST 0 (x) 16 RETURN_VALUE 17 JUMP_FORWARD 1 (to 21) >> 20 POP_TOP index 9 is different test77: doesn't get error formatting exception value; since 2.5 gets linenumber wrong (698 and not 704) in 2.3 test78: generated output has, at offset 0x35, [?1034h.Warnings; expected output does not have this; since 2.3 test85: 9: Using a conditional statement with a constant value (true) fails in 2.3, works in 2.4/2.5/2.6 test87: the expected output is able to clearly identify the line number of a broken up statement; the current output is not and blames the first line of the broken up statement; since python 2.5 test88: DeprecationWarning for whrandom pointing to the prefix path instead of expected /usr/lib Test questions -------------- test3: why does 'dict shadows builtin' trigger in 2.3 but not 2.4/2.5 ? Bugs ---- figure out why running pychecker on test/input/test_dict.py fails in 2.6 while it doesn't when you copy it to ./test.py and run it on that (Probably because there is also test/__init__.py and it is trying to import that instead ?)