tests/coverage.py
changeset 10282 08a0f04b56bd
parent 7047 277c91fe8384
child 10319 86a6bc519592
--- a/tests/coverage.py	Mon Jan 25 00:05:22 2010 -0600
+++ b/tests/coverage.py	Mon Jan 25 00:05:27 2010 -0600
@@ -106,20 +106,20 @@
         self.excluded = excluded
         self.suite_spots = suite_spots
         self.excluding_suite = 0
-        
+
     def doRecursive(self, node):
         for n in node.getChildNodes():
             self.dispatch(n)
 
     visitStmt = visitModule = doRecursive
-    
+
     def doCode(self, node):
         if hasattr(node, 'decorators') and node.decorators:
             self.dispatch(node.decorators)
             self.recordAndDispatch(node.code)
         else:
             self.doSuite(node, node.code)
-            
+
     visitFunction = visitClass = doCode
 
     def getFirstLine(self, node):
@@ -139,26 +139,26 @@
         for n in node.getChildNodes():
             lineno = max(lineno, self.getLastLine(n))
         return lineno
-    
+
     def doStatement(self, node):
         self.recordLine(self.getFirstLine(node))
 
     visitAssert = visitAssign = visitAssTuple = visitPrint = \
         visitPrintnl = visitRaise = visitSubscript = visitDecorators = \
         doStatement
-    
+
     def visitPass(self, node):
-        # Pass statements have weird interactions with docstrings.  If this
-        # pass statement is part of one of those pairs, claim that the statement
-        # is on the later of the two lines.
+        # Pass statements have weird interactions with docstrings. If
+        # this pass statement is part of one of those pairs, claim
+        # that the statement is on the later of the two lines.
         l = node.lineno
         if l:
-            lines = self.suite_spots.get(l, [l,l])
+            lines = self.suite_spots.get(l, [l, l])
             self.statements[lines[1]] = 1
-        
+
     def visitDiscard(self, node):
         # Discard nodes are statements that execute an expression, but then
-        # discard the results.  This includes function calls, so we can't 
+        # discard the results.  This includes function calls, so we can't
         # ignore them all.  But if the expression is a constant, the statement
         # won't be "executed", so don't count it now.
         if node.expr.__class__.__name__ != 'Const':
@@ -172,7 +172,7 @@
             return self.recordLine(self.getFirstLine(node))
         else:
             return 0
-    
+
     def recordLine(self, lineno):
         # Returns a bool, whether the line is included or excluded.
         if lineno:
@@ -196,9 +196,9 @@
                 self.statements[lineno] = 1
                 return 1
         return 0
-    
+
     default = recordNodeLine
-    
+
     def recordAndDispatch(self, node):
         self.recordNodeLine(node)
         self.dispatch(node)
@@ -209,7 +209,7 @@
             self.excluding_suite = 1
         self.recordAndDispatch(body)
         self.excluding_suite = exsuite
-        
+
     def doPlainWordSuite(self, prevsuite, suite):
         # Finding the exclude lines for else's is tricky, because they aren't
         # present in the compiler parse tree.  Look at the previous suite,
@@ -217,17 +217,17 @@
         # first line are excluded, then we exclude the else.
         lastprev = self.getLastLine(prevsuite)
         firstelse = self.getFirstLine(suite)
-        for l in range(lastprev+1, firstelse):
+        for l in range(lastprev + 1, firstelse):
             if self.suite_spots.has_key(l):
                 self.doSuite(None, suite, exclude=self.excluded.has_key(l))
                 break
         else:
             self.doSuite(None, suite)
-        
+
     def doElse(self, prevsuite, node):
         if node.else_:
             self.doPlainWordSuite(prevsuite, node.else_)
-    
+
     def visitFor(self, node):
         self.doSuite(node, node.body)
         self.doElse(node.body, node)
@@ -250,21 +250,21 @@
             if not a:
                 # It's a plain "except:".  Find the previous suite.
                 if i > 0:
-                    prev = node.handlers[i-1][2]
+                    prev = node.handlers[i - 1][2]
                 else:
                     prev = node.body
                 self.doPlainWordSuite(prev, h)
             else:
                 self.doSuite(a, h)
         self.doElse(node.handlers[-1][2], node)
-    
+
     def visitTryFinally(self, node):
         self.doSuite(node, node.body)
         self.doPlainWordSuite(node.body, node.final)
-        
+
     def visitWith(self, node):
         self.doSuite(node, node.body)
-        
+
     def visitGlobal(self, node):
         # "global" statements don't execute like others (they don't call the
         # trace function), so don't record their line numbers.
@@ -285,7 +285,7 @@
     # A dictionary with an entry for (Python source file name, line number
     # in that file) if that line has been executed.
     c = {}
-    
+
     # A map from canonical Python source file name to a dictionary in
     # which there's an entry for each line number that has been
     # executed.
@@ -313,19 +313,18 @@
         self.relative_dir = self.abs_file(os.curdir)+os.sep
         self.exclude('# *pragma[: ]*[nN][oO] *[cC][oO][vV][eE][rR]')
 
-    # t(f, x, y).  This method is passed to sys.settrace as a trace function.  
-    # See [van Rossum 2001-07-20b, 9.2] for an explanation of sys.settrace and 
+    # t(f, x, y).  This method is passed to sys.settrace as a trace function.
+    # See [van Rossum 2001-07-20b, 9.2] for an explanation of sys.settrace and
     # the arguments and return value of the trace function.
     # See [van Rossum 2001-07-20a, 3.2] for a description of frame and code
     # objects.
-    
-    def t(self, f, w, unused):                                 #pragma: no cover
+    def t(self, f, w, unused): #pragma: no cover
         if w == 'line':
             self.c[(f.f_code.co_filename, f.f_lineno)] = 1
             #-for c in self.cstack:
             #-    c[(f.f_code.co_filename, f.f_lineno)] = 1
         return self.t
-    
+
     def help(self, error=None):     #pragma: no cover
         if error:
             print error
@@ -363,7 +362,8 @@
             elif o[2:] + '=' in long_opts:
                 settings[o[2:]+'='] = a
             else:       #pragma: no cover
-                pass    # Can't get here, because getopt won't return anything unknown.
+                # Can't get here, because getopt won't return anything unknown.
+                pass
 
         if settings.get('help'):
             help_fn()
@@ -377,14 +377,14 @@
         args_needed = (settings.get('execute')
                        or settings.get('annotate')
                        or settings.get('report'))
-        action = (settings.get('erase') 
+        action = (settings.get('erase')
                   or settings.get('collect')
                   or args_needed)
         if not action:
             help_fn("You must specify at least one of -e, -x, -c, -r, or -a.")
         if not args_needed and args:
             help_fn("Unexpected arguments: %s" % " ".join(args))
-        
+
         self.parallel_mode = settings.get('parallel-mode')
         self.get_ready()
 
@@ -402,7 +402,7 @@
             self.collect()
         if not args:
             args = self.cexecuted.keys()
-        
+
         ignore_errors = settings.get('ignore-errors')
         show_missing = settings.get('show-missing')
         directory = settings.get('directory=')
@@ -412,7 +412,7 @@
             omit = [self.abs_file(p) for p in omit.split(',')]
         else:
             omit = []
-        
+
         if settings.get('report'):
             self.report(args, show_missing, ignore_errors, omit_prefixes=omit)
         if settings.get('annotate'):
@@ -422,7 +422,7 @@
         self.usecache = usecache
         if cache_file and not self.cache:
             self.cache_default = cache_file
-        
+
     def get_ready(self, parallel_mode=False):
         if self.usecache and not self.cache:
             self.cache = os.environ.get(self.cache_env, self.cache_default)
@@ -430,7 +430,7 @@
                 self.cache += "." + gethostname() + "." + str(os.getpid())
             self.restore()
         self.analysis_cache = {}
-        
+
     def start(self, parallel_mode=False):
         self.get_ready()
         if self.nesting == 0:                               #pragma: no cover
@@ -438,7 +438,7 @@
             if hasattr(threading, 'settrace'):
                 threading.settrace(self.t)
         self.nesting += 1
-        
+
     def stop(self):
         self.nesting -= 1
         if self.nesting == 0:                               #pragma: no cover
@@ -462,7 +462,7 @@
     def begin_recursive(self):
         self.cstack.append(self.c)
         self.xstack.append(self.exclude_re)
-        
+
     def end_recursive(self):
         self.c = self.cstack.pop()
         self.exclude_re = self.xstack.pop()
@@ -568,7 +568,7 @@
             self.canonical_filename_cache[filename] = cf
         return self.canonical_filename_cache[filename]
 
-    # canonicalize_filenames().  Copy results from "c" to "cexecuted", 
+    # canonicalize_filenames().  Copy results from "c" to "cexecuted",
     # canonicalizing filenames on the way.  Clear the "c" map.
 
     def canonicalize_filenames(self):
@@ -598,7 +598,6 @@
     # in the source code, (3) a list of lines of excluded statements,
     # and (4), a map of line numbers to multi-line line number ranges, for
     # statements that cross lines.
-    
     def analyze_morf(self, morf):
         if self.analysis_cache.has_key(morf):
             return self.analysis_cache[morf]
@@ -636,26 +635,27 @@
             if len(tree) == 3 and type(tree[2]) == type(1):
                 return tree[2]
             tree = tree[1]
-    
+
     def last_line_of_tree(self, tree):
         while True:
             if len(tree) == 3 and type(tree[2]) == type(1):
                 return tree[2]
             tree = tree[-1]
-    
+
     def find_docstring_pass_pair(self, tree, spots):
         for i in range(1, len(tree)):
-            if self.is_string_constant(tree[i]) and self.is_pass_stmt(tree[i+1]):
+            if (self.is_string_constant(tree[i]) and
+                self.is_pass_stmt(tree[i + 1]):
                 first_line = self.first_line_of_tree(tree[i])
-                last_line = self.last_line_of_tree(tree[i+1])
+                last_line = self.last_line_of_tree(tree[i + 1])
                 self.record_multiline(spots, first_line, last_line)
-        
+
     def is_string_constant(self, tree):
         try:
             return tree[0] == symbol.stmt and tree[1][1][1][0] == symbol.expr_stmt
         except:
             return False
-        
+
     def is_pass_stmt(self, tree):
         try:
             return tree[0] == symbol.stmt and tree[1][1][1][0] == symbol.pass_stmt
@@ -663,9 +663,9 @@
             return False
 
     def record_multiline(self, spots, i, j):
-        for l in range(i, j+1):
+        for l in range(i, j + 1):
             spots[l] = (i, j)
-            
+
     def get_suite_spots(self, tree, spots):
         """ Analyze a parse tree to find suite introducers which span a number
             of lines.
@@ -675,16 +675,16 @@
                 if tree[i][0] == symbol.suite:
                     # Found a suite, look back for the colon and keyword.
                     lineno_colon = lineno_word = None
-                    for j in range(i-1, 0, -1):
+                    for j in range(i - 1, 0, -1):
                         if tree[j][0] == token.COLON:
                             # Colons are never executed themselves: we want the
                             # line number of the last token before the colon.
-                            lineno_colon = self.last_line_of_tree(tree[j-1])
+                            lineno_colon = self.last_line_of_tree(tree[j - 1])
                         elif tree[j][0] == token.NAME:
                             if tree[j][1] == 'elif':
-                                # Find the line number of the first non-terminal
-                                # after the keyword.
-                                t = tree[j+1]
+                                # Find the line number of the first
+                                # non-terminal after the keyword.
+                                t = tree[j + 1]
                                 while t and token.ISNONTERMINAL(t[0]):
                                     t = t[1]
                                 if t:
@@ -694,7 +694,7 @@
                             break
                         elif tree[j][0] == symbol.except_clause:
                             # "except" clauses look like:
-                            # ('except_clause', ('NAME', 'except', lineno), ...)
+                            # ('except_clause', ('NAME', 'except', lineno),...)
                             if tree[j][1][0] == token.NAME:
                                 lineno_word = tree[j][1][2]
                                 break
@@ -703,11 +703,11 @@
                         # between the two with the two line numbers.
                         self.record_multiline(spots, lineno_word, lineno_colon)
 
-                    # "pass" statements are tricky: different versions of Python
-                    # treat them differently, especially in the common case of a
-                    # function with a doc string and a single pass statement.
+                    # "pass" statements are tricky: different versions
+                    # of Python treat them differently, especially in
+                    # the common case of a function with a doc string
+                    # and a single pass statement.
                     self.find_docstring_pass_pair(tree[i], spots)
-                    
                 elif tree[i][0] == symbol.simple_stmt:
                     first_line = self.first_line_of_tree(tree[i])
                     last_line = self.last_line_of_tree(tree[i])
@@ -724,7 +724,7 @@
             lines = text.split('\n')
             for i in range(len(lines)):
                 if reExclude.search(lines[i]):
-                    excluded[i+1] = 1
+                    excluded[i + 1] = 1
 
         # Parse the code and analyze the parse tree to find out which statements
         # are multiline, and where suites begin and end.
@@ -732,7 +732,7 @@
         tree = parser.suite(text+'\n\n').totuple(1)
         self.get_suite_spots(tree, suite_spots)
         #print "Suite spots:", suite_spots
-        
+
         # Use the compiler module to parse the text and find the executable
         # statements.  We add newlines to be impervious to final partial lines.
         statements = {}
@@ -831,7 +831,8 @@
     def morf_name_compare(self, x, y):
         return cmp(self.morf_name(x), self.morf_name(y))
 
-    def report(self, morfs, show_missing=1, ignore_errors=0, file=None, omit_prefixes=[]):
+    def report(self, morfs, show_missing=1, ignore_errors=0, file=None,
+               omit_prefixes=[]):
         if not isinstance(morfs, types.ListType):
             morfs = [morfs]
         # On windows, the shell doesn't expand wildcards.  Do it here.
@@ -842,7 +843,7 @@
             else:
                 globbed.append(morf)
         morfs = globbed
-        
+
         morfs = self.filter_by_prefix(morfs, omit_prefixes)
         morfs.sort(self.morf_name_compare)
 
@@ -856,8 +857,8 @@
             fmt_coverage = fmt_coverage + "   %s"
         if not file:
             file = sys.stdout
-        print >>file, header
-        print >>file, "-" * len(header)
+        print >> file, header
+        print >> file, "-" * len(header)
         total_statements = 0
         total_executed = 0
         for morf in morfs:
@@ -903,14 +904,16 @@
         for morf in morfs:
             try:
                 filename, statements, excluded, missing, _ = self.analysis2(morf)
-                self.annotate_file(filename, statements, excluded, missing, directory)
+                self.annotate_file(filename, statements, excluded, missing,
+                                   directory)
             except KeyboardInterrupt:
                 raise
             except:
                 if not ignore_errors:
                     raise
-                
-    def annotate_file(self, filename, statements, excluded, missing, directory=None):
+
+    def annotate_file(self, filename, statements, excluded, missing,
+                      directory=None):
         source = open(filename, 'r')
         if directory:
             dest_file = os.path.join(directory,
@@ -937,7 +940,7 @@
             if self.blank_re.match(line):
                 dest.write('  ')
             elif self.else_re.match(line):
-                # Special logic for lines containing only 'else:'.  
+                # Special logic for lines containing only 'else:'.
                 # See [GDR 2001-12-04b, 3.2].
                 if i >= len(statements) and j >= len(missing):
                     dest.write('! ')
@@ -961,40 +964,40 @@
 the_coverage = coverage()
 
 # Module functions call methods in the singleton object.
-def use_cache(*args, **kw): 
+def use_cache(*args, **kw):
     return the_coverage.use_cache(*args, **kw)
 
-def start(*args, **kw): 
+def start(*args, **kw):
     return the_coverage.start(*args, **kw)
 
-def stop(*args, **kw): 
+def stop(*args, **kw):
     return the_coverage.stop(*args, **kw)
 
-def erase(*args, **kw): 
+def erase(*args, **kw):
     return the_coverage.erase(*args, **kw)
 
-def begin_recursive(*args, **kw): 
+def begin_recursive(*args, **kw):
     return the_coverage.begin_recursive(*args, **kw)
 
-def end_recursive(*args, **kw): 
+def end_recursive(*args, **kw):
     return the_coverage.end_recursive(*args, **kw)
 
-def exclude(*args, **kw): 
+def exclude(*args, **kw):
     return the_coverage.exclude(*args, **kw)
 
-def analysis(*args, **kw): 
+def analysis(*args, **kw):
     return the_coverage.analysis(*args, **kw)
 
-def analysis2(*args, **kw): 
+def analysis2(*args, **kw):
     return the_coverage.analysis2(*args, **kw)
 
-def report(*args, **kw): 
+def report(*args, **kw):
     return the_coverage.report(*args, **kw)
 
-def annotate(*args, **kw): 
+def annotate(*args, **kw):
     return the_coverage.annotate(*args, **kw)
 
-def annotate_file(*args, **kw): 
+def annotate_file(*args, **kw):
     return the_coverage.annotate_file(*args, **kw)
 
 # Save coverage data when Python exits.  (The atexit module wasn't
@@ -1008,7 +1011,7 @@
 
 def main():
     the_coverage.command_line(sys.argv[1:])
-    
+
 # Command-line interface.
 if __name__ == '__main__':
     main()
@@ -1072,7 +1075,7 @@
 # Thanks, Allen.
 #
 # 2005-12-02 NMB Call threading.settrace so that all threads are measured.
-# Thanks Martin Fuzzey. Add a file argument to report so that reports can be 
+# Thanks Martin Fuzzey. Add a file argument to report so that reports can be
 # captured to a different destination.
 #
 # 2005-12-03 NMB coverage.py can now measure itself.