diff --git a/ChangeLog b/ChangeLog index 0d2217d..9e1afa6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2009-05-22 Thomas Vander Stichele + + * RELEASE: + * misc/pycheckerrc: + * misc/show-coverage.py: + * morituri/image/Makefile.am: + * morituri/program/Makefile.am: + * RELEASE (added): + * morituri/image/Makefile.am (added): + * morituri/program/Makefile.am (added): + * misc/show-coverage.py (added): + * misc/pycheckerrc (added): + more additions + 2009-05-22 Thomas Vander Stichele * AUTHORS: diff --git a/RELEASE b/RELEASE new file mode 100644 index 0000000..e69de29 diff --git a/misc/pycheckerrc b/misc/pycheckerrc new file mode 100644 index 0000000..354b201 --- /dev/null +++ b/misc/pycheckerrc @@ -0,0 +1,240 @@ +# -*- python -*- +# .pycheckrc file created by PyChecker v0.8.14 @ Thu Oct 21 19:22:09 2004 +# +# It should be placed in your home directory (value of $HOME). +# If $HOME is not set, it will look in the current directory. +# + +# list of evil C extensions that crash the interpreter +evil = [] + +# unused imports +importUsed = 1 + +# unused imports from __init__.py +packageImportUsed = 1 + +# module imports itself +reimportSelf = 0 + +# reimporting a module +moduleImportErrors = 0 + +# module does import and from ... import +mixImport = 0 + +# unused local variables, except tuples +localVariablesUsed = 1 + +# all unused local variables, including tuples +unusedLocalTuple = 0 + +# all unused class data members +membersUsed = 0 + +# all unused module variables +allVariablesUsed = 0 + +# unused private module variables +privateVariableUsed = 0 + +# report each occurrence of global warnings +reportAllGlobals = 0 + +# functions called with named arguments (like keywords) +namedArgs = 0 + +# Attributes (members) must be defined in __init__() +onlyCheckInitForMembers = 0 + +# Subclass.__init__() not defined +initDefinedInSubclass = 0 + +# Baseclass.__init__() not called +baseClassInitted = 0 + +# Subclass needs to override methods that only throw exceptions +abstractClasses = 0 + +# Return None from __init__() +returnNoneFromInit = 1 + +# unreachable code +unreachableCode = 0 + +# a constant is used in a conditional statement +constantConditions = 1 + +# 1 is used in a conditional statement (if 1: or while 1:) +constant1 = 0 + +# check if iterating over a string +stringIteration = 1 + +# check improper use of string.find() +# This is new in pychecker 0.8.14 which is not installed everywhere +#stringFind = 1 + +# Calling data members as functions +callingAttribute = 0 + +# class attribute does not exist +# FIXME: need to fix bug in pychecker so we can disable this per admin_gtk +# class +# classAttrExists = 1 +classAttrExists = 0 + +# First argument to methods +methodArgName = 'self' + +# First argument to classmethods +# classmethodArgNames = ['cls', 'klass'] + +# unused method/function arguments +argumentsUsed = 0 + +# unused method/function variable arguments +varArgumentsUsed = 0 + +# ignore if self is unused in methods +ignoreSelfUnused = 0 + +# check if overridden methods have the same signature +checkOverridenMethods = 0 + +# check if __special__ methods exist and have the correct signature +checkSpecialMethods = 1 + +# check if function/class/method names are reused +redefiningFunction = 1 + +# check if using unary positive (+) which is usually meaningless +unaryPositive = 1 + +# check if modify (call method) on a parameter that has a default value +modifyDefaultValue = 1 + +# check if variables are set to different types +inconsistentTypes = 0 + +# check if unpacking a non-sequence +unpackNonSequence = 1 + +# check if unpacking sequence with the wrong length +unpackLength = 1 + +# check if raising or catching bad exceptions +badExceptions = 1 + +# check if statement appears to have no effect +noEffect = 1 + +# check if using (expr % 1), it has no effect on integers and strings +modulo1 = 1 + +# check if using (expr is const-literal), doesn't always work on integers and strings +isLiteral = 1 + +# check consistent return values +checkReturnValues = 1 + +# check if using implict and explicit return values +checkImplicitReturns = 0 + +# check that attributes of objects exist +checkObjectAttrs = 1 + +# various warnings about incorrect usage of __slots__ +slots = 1 + +# using properties with classic classes +classicProperties = 1 + +# check if __slots__ is empty +emptySlots = 1 + +# check if using integer division +intDivide = 1 + +# check if local variable shadows a global +# disabled because it doesn't give useful output: +# test_input/test24.py:11: Local variable (shadow) shadows global defined on line 0 in file +shadows = 0 + +# check if a variable shadows a builtin +shadowBuiltins = 1 + +# check if input() is used +usesInput = 1 + +# check if the exec statement is used +usesExec = 0 + +# ignore warnings from files under standard library +ignoreStandardLibrary = 1 + +# ignore warnings from the list of modules +blacklist = [ + 'gtk', 'twisted', 'twisted.python', 'pyexpat', + 'zope.interface', 'zope.interface.declarations', + 'zope.interface.interface', + '_interface_coptimizations', +#warning: couldn't find real module for class xml.parsers.expat.ExpatError (module name: xml.parsers.expat) + 'xml.parsers.expat', +] + +# ignore global variables not used if name is one of these values +variablesToIgnore = ['__version__', '__warningregistry__', '__all__', '__credits__', '__test__', '__author__', '__email__', '__revision__'] + +# ignore unused locals/arguments if name is one of these values +unusedNames = ['_', 'empty', 'unused', 'dummy'] + +# ignore use of deprecated modules/functions +deprecated = 1 + +# maximum lines in a function +maxLines = 250 + +# maximum branches in a function +maxBranches = 50 + +# maximum returns in a function +maxReturns = 10 + +# maximum # of arguments to a function +maxArgs = 10 + +# maximum # of locals in a function +maxLocals = 40 + +# maximum # of identifier references (Law of Demeter) +maxReferences = 5 + +# no module doc strings +noDocModule = 0 + +# no class doc strings +noDocClass = 0 + +# no function/method doc strings +noDocFunc = 0 + +# print internal checker parse structures +printParse = 0 + +# turn on debugging for checker +debug = 0 + +# suppressions work like this +suppressions = { + # FIXME: Consumption has a get_next with steps=None + 'flumotion.wizard.steps.Consumption': "no-override", + # FIXME: the import there is for registering steps; do an actual method + 'flumotion.wizard.wizard.Wizard': "no-import", +# 'flumotion.twisted.defer.defer_generator': "self=wrapperself", +# deferToThread imports reactor, which e.g. flumotion.worker.checks.video010 +# does as well + 'twisted.internet.threads.deferToThread' : "no-shadow", + # FIXME: doing this inline doesn't seem to work + 'flumotion.component.producers.looper.admin_gtk.py': 'no-classattr', +} diff --git a/misc/show-coverage.py b/misc/show-coverage.py new file mode 100644 index 0000000..4b562c7 --- /dev/null +++ b/misc/show-coverage.py @@ -0,0 +1,87 @@ +import os +import sys + +class Presentation: + def __init__(self, name, lines, covered): + self.name = name + self.lines = lines + self.covered = covered + + if self.covered == 0: + self.percent = 0 + else: + self.percent = 100 * self.covered / float(self.lines) + + def show(self, maxlen=20): + format = '%%-%ds %%3d %%%% (%%4d / %%4d)' % maxlen + print format % (self.name, self.percent, self.covered, self.lines) + + +class Coverage: + def __init__(self): + self.files = [] + self.total_lines = 0 + self.total_covered = 0 + + def _strip_filename(self, filename): + filename = os.path.basename(filename) + if filename.endswith('.cover'): + filename = filename[:-6] + return filename + + def add_file(self, file): + self.files.append(file) + + def show_results(self): + if not hasattr(self, 'files'): + print 'No coverage data' + return + + self.maxlen = max(map(lambda f: len(self._strip_filename(f)), + self.files)) + print 'Coverage report:' + print '-' * (self.maxlen + 23) + for file in self.files: + self.show_one(file) + print '-' * (self.maxlen + 23) + + p = Presentation('Total', self.total_lines, self.total_covered) + p.show(self.maxlen) + + def show_one(self, filename): + f = open(filename) + lines = [line for line in f.readlines() + if (':' in line or line.startswith('>>>>>>')) and + not line.strip().startswith('#') and + not line.endswith(':\n')] + + uncovered_lines = [line for line in lines + if line.startswith('>>>>>>')] + if not lines: + return + + filename = self._strip_filename(filename) + + p = Presentation(filename, + len(lines), + len(lines) - len(uncovered_lines)) + p.show(self.maxlen) + + self.total_lines += p.lines + self.total_covered += p.covered + +def main(args): + c = Coverage() + files = args[1:] + files.sort() + for file in files: + if 'flumotion.test' in file: + continue + if '__init__' in file: + continue + c.add_file(file) + + c.show_results() + +if __name__ == '__main__': + sys.exit(main(sys.argv)) diff --git a/morituri/image/Makefile.am b/morituri/image/Makefile.am new file mode 100644 index 0000000..be3a2e6 --- /dev/null +++ b/morituri/image/Makefile.am @@ -0,0 +1,10 @@ +CLEANFILES = *.py{c,o} + +morituridir = $(PYTHONLIBDIR)/morituri/image + +morituri_PYTHON = \ + __init__.py \ + cue.py \ + image.py \ + table.py \ + toc.py diff --git a/morituri/program/Makefile.am b/morituri/program/Makefile.am new file mode 100644 index 0000000..dc15eb2 --- /dev/null +++ b/morituri/program/Makefile.am @@ -0,0 +1,8 @@ +CLEANFILES = *.py{c,o} + +morituridir = $(PYTHONLIBDIR)/morituri/program + +morituri_PYTHON = \ + __init__.py \ + cdparanoia.py \ + cdrdao.py