tests/coverage.py
author Vadim Gelfer <vadim.gelfer@gmail.com>
Wed, 19 Apr 2006 08:33:46 -0700
changeset 2089 cb99c711c59f
parent 2067 3094becfd8e8
child 2144 d3bddedfdbd0
permissions -rwxr-xr-x
make appendfile simpler so it does not break with revlogng on windows. it used to cache open files. this made revlogng break because it wants to rename files when splitting .i into .i/.d, but cannot rename or unlink open files on windows. new code is bit slower, but safe on linux and windows. proper fix for too many open/close of changelog/manifest belongs in different place. can get 10% speed improvement back.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2066
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     1
#!/usr/bin/python
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     2
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     3
#             Perforce Defect Tracking Integration Project
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     4
#              <http://www.ravenbrook.com/project/p4dti/>
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     5
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     6
#                   COVERAGE.PY -- COVERAGE TESTING
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     7
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     8
#             Gareth Rees, Ravenbrook Limited, 2001-12-04
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     9
#                     Ned Batchelder, 2004-12-12
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    10
#         http://nedbatchelder.com/code/modules/coverage.html
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    11
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    12
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    13
# 1. INTRODUCTION
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    14
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    15
# This module provides coverage testing for Python code.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    16
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    17
# The intended readership is all Python developers.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    18
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    19
# This document is not confidential.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    20
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    21
# See [GDR 2001-12-04a] for the command-line interface, programmatic
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    22
# interface and limitations.  See [GDR 2001-12-04b] for requirements and
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    23
# design.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    24
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    25
"""Usage:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    26
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    27
coverage.py -x MODULE.py [ARG1 ARG2 ...]
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    28
    Execute module, passing the given command-line arguments, collecting
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    29
    coverage data.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    30
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    31
coverage.py -e
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    32
    Erase collected coverage data.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    33
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    34
coverage.py -r [-m] [-o dir1,dir2,...] FILE1 FILE2 ...
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    35
    Report on the statement coverage for the given files.  With the -m
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    36
    option, show line numbers of the statements that weren't executed.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    37
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    38
coverage.py -a [-d dir] [-o dir1,dir2,...] FILE1 FILE2 ...
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    39
    Make annotated copies of the given files, marking statements that
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    40
    are executed with > and statements that are missed with !.  With
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    41
    the -d option, make the copies in that directory.  Without the -d
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    42
    option, make each copy in the same directory as the original.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    43
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    44
-o dir,dir2,...
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    45
  Omit reporting or annotating files when their filename path starts with
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    46
  a directory listed in the omit list.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    47
  e.g. python coverage.py -i -r -o c:\python23,lib\enthought\traits
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    48
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    49
Coverage data is saved in the file .coverage by default.  Set the
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    50
COVERAGE_FILE environment variable to save it somewhere else."""
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    51
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    52
__version__ = "2.5.20051204"    # see detailed history at the end of this file.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    53
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    54
import compiler
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    55
import compiler.visitor
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    56
import os
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    57
import re
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    58
import string
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    59
import sys
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    60
import threading
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    61
import types
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    62
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    63
# 2. IMPLEMENTATION
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    64
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    65
# This uses the "singleton" pattern.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    66
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    67
# The word "morf" means a module object (from which the source file can
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    68
# be deduced by suitable manipulation of the __file__ attribute) or a
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    69
# filename.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    70
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    71
# When we generate a coverage report we have to canonicalize every
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    72
# filename in the coverage dictionary just in case it refers to the
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    73
# module we are reporting on.  It seems a shame to throw away this
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    74
# information so the data in the coverage dictionary is transferred to
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    75
# the 'cexecuted' dictionary under the canonical filenames.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    76
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    77
# The coverage dictionary is called "c" and the trace function "t".  The
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    78
# reason for these short names is that Python looks up variables by name
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    79
# at runtime and so execution time depends on the length of variables!
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    80
# In the bottleneck of this application it's appropriate to abbreviate
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    81
# names to increase speed.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    82
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    83
class StatementFindingAstVisitor(compiler.visitor.ASTVisitor):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    84
    def __init__(self, statements, excluded, suite_spots):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    85
        compiler.visitor.ASTVisitor.__init__(self)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    86
        self.statements = statements
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    87
        self.excluded = excluded
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    88
        self.suite_spots = suite_spots
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    89
        self.excluding_suite = 0
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    90
        
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    91
    def doRecursive(self, node):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    92
        self.recordNodeLine(node)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    93
        for n in node.getChildNodes():
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    94
            self.dispatch(n)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    95
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    96
    visitStmt = visitModule = doRecursive
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    97
    
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    98
    def doCode(self, node):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    99
        if hasattr(node, 'decorators') and node.decorators:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   100
            self.dispatch(node.decorators)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   101
        self.doSuite(node, node.code)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   102
    
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   103
    visitFunction = visitClass = doCode
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   104
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   105
    def getFirstLine(self, node):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   106
        # Find the first line in the tree node.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   107
        lineno = node.lineno
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   108
        for n in node.getChildNodes():
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   109
            f = self.getFirstLine(n)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   110
            if lineno and f:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   111
                lineno = min(lineno, f)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   112
            else:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   113
                lineno = lineno or f
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   114
        return lineno
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   115
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   116
    def getLastLine(self, node):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   117
        # Find the first line in the tree node.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   118
        lineno = node.lineno
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   119
        for n in node.getChildNodes():
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   120
            lineno = max(lineno, self.getLastLine(n))
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   121
        return lineno
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   122
    
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   123
    def doStatement(self, node):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   124
        self.recordLine(self.getFirstLine(node))
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   125
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   126
    visitAssert = visitAssign = visitAssTuple = visitDiscard = visitPrint = \
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   127
        visitPrintnl = visitRaise = visitSubscript = visitDecorators = \
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   128
        doStatement
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   129
    
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   130
    def recordNodeLine(self, node):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   131
        return self.recordLine(node.lineno)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   132
    
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   133
    def recordLine(self, lineno):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   134
        # Returns a bool, whether the line is included or excluded.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   135
        if lineno:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   136
            # Multi-line tests introducing suites have to get charged to their
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   137
            # keyword.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   138
            if lineno in self.suite_spots:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   139
                lineno = self.suite_spots[lineno][0]
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   140
            # If we're inside an exluded suite, record that this line was
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   141
            # excluded.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   142
            if self.excluding_suite:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   143
                self.excluded[lineno] = 1
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   144
                return 0
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   145
            # If this line is excluded, or suite_spots maps this line to
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   146
            # another line that is exlcuded, then we're excluded.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   147
            elif self.excluded.has_key(lineno) or \
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   148
                 self.suite_spots.has_key(lineno) and \
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   149
                 self.excluded.has_key(self.suite_spots[lineno][1]):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   150
                return 0
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   151
            # Otherwise, this is an executable line.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   152
            else:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   153
                self.statements[lineno] = 1
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   154
                return 1
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   155
        return 0
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   156
    
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   157
    default = recordNodeLine
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   158
    
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   159
    def recordAndDispatch(self, node):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   160
        self.recordNodeLine(node)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   161
        self.dispatch(node)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   162
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   163
    def doSuite(self, intro, body, exclude=0):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   164
        exsuite = self.excluding_suite
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   165
        if exclude or (intro and not self.recordNodeLine(intro)):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   166
            self.excluding_suite = 1
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   167
        self.recordAndDispatch(body)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   168
        self.excluding_suite = exsuite
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   169
        
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   170
    def doPlainWordSuite(self, prevsuite, suite):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   171
        # Finding the exclude lines for else's is tricky, because they aren't
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   172
        # present in the compiler parse tree.  Look at the previous suite,
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   173
        # and find its last line.  If any line between there and the else's
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   174
        # first line are excluded, then we exclude the else.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   175
        lastprev = self.getLastLine(prevsuite)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   176
        firstelse = self.getFirstLine(suite)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   177
        for l in range(lastprev+1, firstelse):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   178
            if self.suite_spots.has_key(l):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   179
                self.doSuite(None, suite, exclude=self.excluded.has_key(l))
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   180
                break
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   181
        else:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   182
            self.doSuite(None, suite)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   183
        
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   184
    def doElse(self, prevsuite, node):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   185
        if node.else_:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   186
            self.doPlainWordSuite(prevsuite, node.else_)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   187
    
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   188
    def visitFor(self, node):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   189
        self.doSuite(node, node.body)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   190
        self.doElse(node.body, node)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   191
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   192
    def visitIf(self, node):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   193
        # The first test has to be handled separately from the rest.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   194
        # The first test is credited to the line with the "if", but the others
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   195
        # are credited to the line with the test for the elif.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   196
        self.doSuite(node, node.tests[0][1])
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   197
        for t, n in node.tests[1:]:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   198
            self.doSuite(t, n)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   199
        self.doElse(node.tests[-1][1], node)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   200
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   201
    def visitWhile(self, node):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   202
        self.doSuite(node, node.body)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   203
        self.doElse(node.body, node)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   204
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   205
    def visitTryExcept(self, node):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   206
        self.doSuite(node, node.body)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   207
        for i in range(len(node.handlers)):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   208
            a, b, h = node.handlers[i]
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   209
            if not a:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   210
                # It's a plain "except:".  Find the previous suite.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   211
                if i > 0:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   212
                    prev = node.handlers[i-1][2]
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   213
                else:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   214
                    prev = node.body
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   215
                self.doPlainWordSuite(prev, h)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   216
            else:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   217
                self.doSuite(a, h)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   218
        self.doElse(node.handlers[-1][2], node)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   219
    
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   220
    def visitTryFinally(self, node):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   221
        self.doSuite(node, node.body)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   222
        self.doPlainWordSuite(node.body, node.final)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   223
        
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   224
    def visitGlobal(self, node):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   225
        # "global" statements don't execute like others (they don't call the
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   226
        # trace function), so don't record their line numbers.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   227
        pass
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   228
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   229
the_coverage = None
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   230
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   231
class coverage:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   232
    error = "coverage error"
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   233
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   234
    # Name of the cache file (unless environment variable is set).
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   235
    cache_default = ".coverage"
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   236
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   237
    # Environment variable naming the cache file.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   238
    cache_env = "COVERAGE_FILE"
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   239
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   240
    # A dictionary with an entry for (Python source file name, line number
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   241
    # in that file) if that line has been executed.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   242
    c = {}
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   243
    
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   244
    # A map from canonical Python source file name to a dictionary in
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   245
    # which there's an entry for each line number that has been
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   246
    # executed.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   247
    cexecuted = {}
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   248
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   249
    # Cache of results of calling the analysis2() method, so that you can
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   250
    # specify both -r and -a without doing double work.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   251
    analysis_cache = {}
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   252
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   253
    # Cache of results of calling the canonical_filename() method, to
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   254
    # avoid duplicating work.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   255
    canonical_filename_cache = {}
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   256
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   257
    def __init__(self):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   258
        global the_coverage
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   259
        if the_coverage:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   260
            raise self.error, "Only one coverage object allowed."
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   261
        self.usecache = 1
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   262
        self.cache = None
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   263
        self.exclude_re = ''
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   264
        self.nesting = 0
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   265
        self.cstack = []
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   266
        self.xstack = []
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   267
        self.relative_dir = os.path.normcase(os.path.abspath(os.curdir)+os.path.sep)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   268
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   269
    # t(f, x, y).  This method is passed to sys.settrace as a trace function.  
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   270
    # See [van Rossum 2001-07-20b, 9.2] for an explanation of sys.settrace and 
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   271
    # the arguments and return value of the trace function.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   272
    # See [van Rossum 2001-07-20a, 3.2] for a description of frame and code
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   273
    # objects.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   274
    
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   275
    def t(self, f, w, a):                                   #pragma: no cover
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   276
        #print w, f.f_code.co_filename, f.f_lineno
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   277
        if w == 'line':
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   278
            self.c[(f.f_code.co_filename, f.f_lineno)] = 1
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   279
            for c in self.cstack:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   280
                c[(f.f_code.co_filename, f.f_lineno)] = 1
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   281
        return self.t
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   282
    
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   283
    def help(self, error=None):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   284
        if error:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   285
            print error
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   286
            print
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   287
        print __doc__
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   288
        sys.exit(1)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   289
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   290
    def command_line(self):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   291
        import getopt
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   292
        settings = {}
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   293
        optmap = {
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   294
            '-a': 'annotate',
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   295
            '-d:': 'directory=',
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   296
            '-e': 'erase',
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   297
            '-h': 'help',
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   298
            '-i': 'ignore-errors',
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   299
            '-m': 'show-missing',
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   300
            '-r': 'report',
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   301
            '-x': 'execute',
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   302
            '-o': 'omit=',
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   303
            }
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   304
        short_opts = string.join(map(lambda o: o[1:], optmap.keys()), '')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   305
        long_opts = optmap.values()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   306
        options, args = getopt.getopt(sys.argv[1:], short_opts, long_opts)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   307
        for o, a in options:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   308
            if optmap.has_key(o):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   309
                settings[optmap[o]] = 1
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   310
            elif optmap.has_key(o + ':'):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   311
                settings[optmap[o + ':']] = a
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   312
            elif o[2:] in long_opts:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   313
                settings[o[2:]] = 1
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   314
            elif o[2:] + '=' in long_opts:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   315
                settings[o[2:]] = a
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   316
            else:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   317
                self.help("Unknown option: '%s'." % o)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   318
        if settings.get('help'):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   319
            self.help()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   320
        for i in ['erase', 'execute']:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   321
            for j in ['annotate', 'report']:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   322
                if settings.get(i) and settings.get(j):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   323
                    self.help("You can't specify the '%s' and '%s' "
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   324
                              "options at the same time." % (i, j))
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   325
        args_needed = (settings.get('execute')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   326
                       or settings.get('annotate')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   327
                       or settings.get('report'))
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   328
        action = settings.get('erase') or args_needed
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   329
        if not action:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   330
            self.help("You must specify at least one of -e, -x, -r, or -a.")
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   331
        if not args_needed and args:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   332
            self.help("Unexpected arguments %s." % args)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   333
        
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   334
        self.get_ready()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   335
        self.exclude('#pragma[: ]+[nN][oO] [cC][oO][vV][eE][rR]')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   336
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   337
        if settings.get('erase'):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   338
            self.erase()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   339
        if settings.get('execute'):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   340
            if not args:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   341
                self.help("Nothing to do.")
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   342
            sys.argv = args
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   343
            self.start()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   344
            import __main__
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   345
            sys.path[0] = os.path.dirname(sys.argv[0])
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   346
            execfile(sys.argv[0], __main__.__dict__)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   347
        if not args:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   348
            args = self.cexecuted.keys()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   349
        ignore_errors = settings.get('ignore-errors')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   350
        show_missing = settings.get('show-missing')
2067
3094becfd8e8 fix bugs in coverage.py.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2066
diff changeset
   351
        directory = settings.get('directory')
3094becfd8e8 fix bugs in coverage.py.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2066
diff changeset
   352
        omit = filter(None, settings.get('omit', '').split(','))
2066
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   353
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   354
        if settings.get('report'):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   355
            self.report(args, show_missing, ignore_errors, omit_prefixes=omit)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   356
        if settings.get('annotate'):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   357
            self.annotate(args, directory, ignore_errors, omit_prefixes=omit)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   358
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   359
    def use_cache(self, usecache):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   360
        self.usecache = usecache
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   361
        
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   362
    def get_ready(self):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   363
        if self.usecache and not self.cache:
2067
3094becfd8e8 fix bugs in coverage.py.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2066
diff changeset
   364
            self.cache = os.path.abspath(os.environ.get(self.cache_env,
3094becfd8e8 fix bugs in coverage.py.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2066
diff changeset
   365
                                                        self.cache_default))
2066
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   366
            self.restore()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   367
        self.analysis_cache = {}
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   368
        
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   369
    def start(self):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   370
        self.get_ready()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   371
        if self.nesting == 0:                               #pragma: no cover
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   372
            sys.settrace(self.t)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   373
            if hasattr(threading, 'settrace'):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   374
                threading.settrace(self.t)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   375
        self.nesting += 1
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   376
        
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   377
    def stop(self):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   378
        self.nesting -= 1
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   379
        if self.nesting == 0:                               #pragma: no cover
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   380
            sys.settrace(None)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   381
            if hasattr(threading, 'settrace'):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   382
                threading.settrace(None)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   383
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   384
    def erase(self):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   385
        self.c = {}
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   386
        self.analysis_cache = {}
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   387
        self.cexecuted = {}
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   388
        if self.cache and os.path.exists(self.cache):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   389
            os.remove(self.cache)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   390
        self.exclude_re = ""
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   391
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   392
    def exclude(self, re):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   393
        if self.exclude_re:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   394
            self.exclude_re += "|"
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   395
        self.exclude_re += "(" + re + ")"
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   396
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   397
    def begin_recursive(self):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   398
        self.cstack.append(self.c)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   399
        self.xstack.append(self.exclude_re)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   400
        
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   401
    def end_recursive(self):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   402
        self.c = self.cstack.pop()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   403
        self.exclude_re = self.xstack.pop()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   404
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   405
    # save().  Save coverage data to the coverage cache.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   406
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   407
    def save(self):
2067
3094becfd8e8 fix bugs in coverage.py.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2066
diff changeset
   408
        # move to directory that must exist.
3094becfd8e8 fix bugs in coverage.py.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2066
diff changeset
   409
        os.chdir(os.sep)
2066
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   410
        if self.usecache and self.cache:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   411
            self.canonicalize_filenames()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   412
            cache = open(self.cache, 'wb')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   413
            import marshal
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   414
            marshal.dump(self.cexecuted, cache)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   415
            cache.close()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   416
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   417
    # restore().  Restore coverage data from the coverage cache (if it exists).
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   418
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   419
    def restore(self):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   420
        self.c = {}
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   421
        self.cexecuted = {}
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   422
        assert self.usecache
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   423
        if not os.path.exists(self.cache):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   424
            return
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   425
        try:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   426
            cache = open(self.cache, 'rb')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   427
            import marshal
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   428
            cexecuted = marshal.load(cache)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   429
            cache.close()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   430
            if isinstance(cexecuted, types.DictType):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   431
                self.cexecuted = cexecuted
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   432
        except:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   433
            pass
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   434
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   435
    # canonical_filename(filename).  Return a canonical filename for the
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   436
    # file (that is, an absolute path with no redundant components and
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   437
    # normalized case).  See [GDR 2001-12-04b, 3.3].
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   438
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   439
    def canonical_filename(self, filename):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   440
        if not self.canonical_filename_cache.has_key(filename):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   441
            f = filename
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   442
            if os.path.isabs(f) and not os.path.exists(f):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   443
                f = os.path.basename(f)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   444
            if not os.path.isabs(f):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   445
                for path in [os.curdir] + sys.path:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   446
                    g = os.path.join(path, f)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   447
                    if os.path.exists(g):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   448
                        f = g
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   449
                        break
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   450
            cf = os.path.normcase(os.path.abspath(f))
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   451
            self.canonical_filename_cache[filename] = cf
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   452
        return self.canonical_filename_cache[filename]
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   453
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   454
    # canonicalize_filenames().  Copy results from "c" to "cexecuted", 
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   455
    # canonicalizing filenames on the way.  Clear the "c" map.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   456
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   457
    def canonicalize_filenames(self):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   458
        for filename, lineno in self.c.keys():
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   459
            f = self.canonical_filename(filename)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   460
            if not self.cexecuted.has_key(f):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   461
                self.cexecuted[f] = {}
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   462
            self.cexecuted[f][lineno] = 1
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   463
        self.c = {}
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   464
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   465
    # morf_filename(morf).  Return the filename for a module or file.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   466
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   467
    def morf_filename(self, morf):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   468
        if isinstance(morf, types.ModuleType):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   469
            if not hasattr(morf, '__file__'):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   470
                raise self.error, "Module has no __file__ attribute."
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   471
            file = morf.__file__
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   472
        else:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   473
            file = morf
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   474
        return self.canonical_filename(file)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   475
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   476
    # analyze_morf(morf).  Analyze the module or filename passed as
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   477
    # the argument.  If the source code can't be found, raise an error.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   478
    # Otherwise, return a tuple of (1) the canonical filename of the
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   479
    # source code for the module, (2) a list of lines of statements
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   480
    # in the source code, and (3) a list of lines of excluded statements.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   481
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   482
    def analyze_morf(self, morf):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   483
        if self.analysis_cache.has_key(morf):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   484
            return self.analysis_cache[morf]
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   485
        filename = self.morf_filename(morf)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   486
        ext = os.path.splitext(filename)[1]
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   487
        if ext == '.pyc':
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   488
            if not os.path.exists(filename[0:-1]):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   489
                raise self.error, ("No source for compiled code '%s'."
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   490
                                   % filename)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   491
            filename = filename[0:-1]
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   492
        elif ext != '.py':
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   493
            raise self.error, "File '%s' not Python source." % filename
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   494
        source = open(filename, 'r')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   495
        lines, excluded_lines = self.find_executable_statements(
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   496
            source.read(), exclude=self.exclude_re
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   497
            )
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   498
        source.close()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   499
        result = filename, lines, excluded_lines
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   500
        self.analysis_cache[morf] = result
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   501
        return result
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   502
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   503
    def get_suite_spots(self, tree, spots):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   504
        import symbol, token
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   505
        for i in range(1, len(tree)):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   506
            if type(tree[i]) == type(()):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   507
                if tree[i][0] == symbol.suite:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   508
                    # Found a suite, look back for the colon and keyword.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   509
                    lineno_colon = lineno_word = None
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   510
                    for j in range(i-1, 0, -1):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   511
                        if tree[j][0] == token.COLON:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   512
                            lineno_colon = tree[j][2]
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   513
                        elif tree[j][0] == token.NAME:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   514
                            if tree[j][1] == 'elif':
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   515
                                # Find the line number of the first non-terminal
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   516
                                # after the keyword.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   517
                                t = tree[j+1]
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   518
                                while t and token.ISNONTERMINAL(t[0]):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   519
                                    t = t[1]
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   520
                                if t:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   521
                                    lineno_word = t[2]
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   522
                            else:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   523
                                lineno_word = tree[j][2]
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   524
                            break
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   525
                        elif tree[j][0] == symbol.except_clause:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   526
                            # "except" clauses look like:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   527
                            # ('except_clause', ('NAME', 'except', lineno), ...)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   528
                            if tree[j][1][0] == token.NAME:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   529
                                lineno_word = tree[j][1][2]
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   530
                                break
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   531
                    if lineno_colon and lineno_word:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   532
                        # Found colon and keyword, mark all the lines
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   533
                        # between the two with the two line numbers.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   534
                        for l in range(lineno_word, lineno_colon+1):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   535
                            spots[l] = (lineno_word, lineno_colon)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   536
                self.get_suite_spots(tree[i], spots)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   537
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   538
    def find_executable_statements(self, text, exclude=None):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   539
        # Find lines which match an exclusion pattern.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   540
        excluded = {}
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   541
        suite_spots = {}
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   542
        if exclude:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   543
            reExclude = re.compile(exclude)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   544
            lines = text.split('\n')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   545
            for i in range(len(lines)):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   546
                if reExclude.search(lines[i]):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   547
                    excluded[i+1] = 1
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   548
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   549
        import parser
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   550
        tree = parser.suite(text+'\n\n').totuple(1)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   551
        self.get_suite_spots(tree, suite_spots)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   552
            
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   553
        # Use the compiler module to parse the text and find the executable
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   554
        # statements.  We add newlines to be impervious to final partial lines.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   555
        statements = {}
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   556
        ast = compiler.parse(text+'\n\n')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   557
        visitor = StatementFindingAstVisitor(statements, excluded, suite_spots)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   558
        compiler.walk(ast, visitor, walker=visitor)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   559
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   560
        lines = statements.keys()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   561
        lines.sort()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   562
        excluded_lines = excluded.keys()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   563
        excluded_lines.sort()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   564
        return lines, excluded_lines
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   565
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   566
    # format_lines(statements, lines).  Format a list of line numbers
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   567
    # for printing by coalescing groups of lines as long as the lines
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   568
    # represent consecutive statements.  This will coalesce even if
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   569
    # there are gaps between statements, so if statements =
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   570
    # [1,2,3,4,5,10,11,12,13,14] and lines = [1,2,5,10,11,13,14] then
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   571
    # format_lines will return "1-2, 5-11, 13-14".
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   572
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   573
    def format_lines(self, statements, lines):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   574
        pairs = []
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   575
        i = 0
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   576
        j = 0
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   577
        start = None
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   578
        pairs = []
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   579
        while i < len(statements) and j < len(lines):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   580
            if statements[i] == lines[j]:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   581
                if start == None:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   582
                    start = lines[j]
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   583
                end = lines[j]
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   584
                j = j + 1
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   585
            elif start:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   586
                pairs.append((start, end))
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   587
                start = None
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   588
            i = i + 1
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   589
        if start:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   590
            pairs.append((start, end))
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   591
        def stringify(pair):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   592
            start, end = pair
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   593
            if start == end:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   594
                return "%d" % start
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   595
            else:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   596
                return "%d-%d" % (start, end)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   597
        return string.join(map(stringify, pairs), ", ")
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   598
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   599
    # Backward compatibility with version 1.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   600
    def analysis(self, morf):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   601
        f, s, _, m, mf = self.analysis2(morf)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   602
        return f, s, m, mf
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   603
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   604
    def analysis2(self, morf):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   605
        filename, statements, excluded = self.analyze_morf(morf)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   606
        self.canonicalize_filenames()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   607
        if not self.cexecuted.has_key(filename):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   608
            self.cexecuted[filename] = {}
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   609
        missing = []
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   610
        for line in statements:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   611
            if not self.cexecuted[filename].has_key(line):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   612
                missing.append(line)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   613
        return (filename, statements, excluded, missing,
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   614
                self.format_lines(statements, missing))
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   615
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   616
    def relative_filename(self, filename):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   617
        """ Convert filename to relative filename from self.relative_dir.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   618
        """
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   619
        return filename.replace(self.relative_dir, "")
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   620
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   621
    def morf_name(self, morf):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   622
        """ Return the name of morf as used in report.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   623
        """
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   624
        if isinstance(morf, types.ModuleType):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   625
            return morf.__name__
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   626
        else:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   627
            return self.relative_filename(os.path.splitext(morf)[0])
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   628
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   629
    def filter_by_prefix(self, morfs, omit_prefixes):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   630
        """ Return list of morfs where the morf name does not begin
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   631
            with any one of the omit_prefixes.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   632
        """
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   633
        filtered_morfs = []
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   634
        for morf in morfs:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   635
            for prefix in omit_prefixes:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   636
                if self.morf_name(morf).startswith(prefix):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   637
                    break
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   638
            else:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   639
                filtered_morfs.append(morf)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   640
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   641
        return filtered_morfs
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   642
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   643
    def morf_name_compare(self, x, y):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   644
        return cmp(self.morf_name(x), self.morf_name(y))
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   645
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   646
    def report(self, morfs, show_missing=1, ignore_errors=0, file=None, omit_prefixes=[]):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   647
        if not isinstance(morfs, types.ListType):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   648
            morfs = [morfs]
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   649
        morfs = self.filter_by_prefix(morfs, omit_prefixes)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   650
        morfs.sort(self.morf_name_compare)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   651
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   652
        max_name = max([5,] + map(len, map(self.morf_name, morfs)))
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   653
        fmt_name = "%%- %ds  " % max_name
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   654
        fmt_err = fmt_name + "%s: %s"
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   655
        header = fmt_name % "Name" + " Stmts   Exec  Cover"
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   656
        fmt_coverage = fmt_name + "% 6d % 6d % 5d%%"
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   657
        if show_missing:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   658
            header = header + "   Missing"
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   659
            fmt_coverage = fmt_coverage + "   %s"
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   660
        if not file:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   661
            file = sys.stdout
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   662
        print >>file, header
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   663
        print >>file, "-" * len(header)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   664
        total_statements = 0
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   665
        total_executed = 0
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   666
        for morf in morfs:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   667
            name = self.morf_name(morf)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   668
            try:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   669
                _, statements, _, missing, readable  = self.analysis2(morf)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   670
                n = len(statements)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   671
                m = n - len(missing)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   672
                if n > 0:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   673
                    pc = 100.0 * m / n
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   674
                else:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   675
                    pc = 100.0
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   676
                args = (name, n, m, pc)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   677
                if show_missing:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   678
                    args = args + (readable,)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   679
                print >>file, fmt_coverage % args
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   680
                total_statements = total_statements + n
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   681
                total_executed = total_executed + m
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   682
            except KeyboardInterrupt:                       #pragma: no cover
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   683
                raise
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   684
            except:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   685
                if not ignore_errors:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   686
                    type, msg = sys.exc_info()[0:2]
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   687
                    print >>file, fmt_err % (name, type, msg)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   688
        if len(morfs) > 1:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   689
            print >>file, "-" * len(header)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   690
            if total_statements > 0:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   691
                pc = 100.0 * total_executed / total_statements
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   692
            else:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   693
                pc = 100.0
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   694
            args = ("TOTAL", total_statements, total_executed, pc)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   695
            if show_missing:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   696
                args = args + ("",)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   697
            print >>file, fmt_coverage % args
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   698
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   699
    # annotate(morfs, ignore_errors).
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   700
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   701
    blank_re = re.compile(r"\s*(#|$)")
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   702
    else_re = re.compile(r"\s*else\s*:\s*(#|$)")
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   703
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   704
    def annotate(self, morfs, directory=None, ignore_errors=0, omit_prefixes=[]):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   705
        morfs = self.filter_by_prefix(morfs, omit_prefixes)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   706
        for morf in morfs:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   707
            try:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   708
                filename, statements, excluded, missing, _ = self.analysis2(morf)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   709
                self.annotate_file(filename, statements, excluded, missing, directory)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   710
            except KeyboardInterrupt:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   711
                raise
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   712
            except:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   713
                if not ignore_errors:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   714
                    raise
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   715
                
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   716
    def annotate_file(self, filename, statements, excluded, missing, directory=None):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   717
        source = open(filename, 'r')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   718
        if directory:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   719
            dest_file = os.path.join(directory,
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   720
                                     os.path.basename(filename)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   721
                                     + ',cover')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   722
        else:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   723
            dest_file = filename + ',cover'
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   724
        dest = open(dest_file, 'w')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   725
        lineno = 0
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   726
        i = 0
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   727
        j = 0
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   728
        covered = 1
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   729
        while 1:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   730
            line = source.readline()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   731
            if line == '':
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   732
                break
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   733
            lineno = lineno + 1
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   734
            while i < len(statements) and statements[i] < lineno:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   735
                i = i + 1
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   736
            while j < len(missing) and missing[j] < lineno:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   737
                j = j + 1
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   738
            if i < len(statements) and statements[i] == lineno:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   739
                covered = j >= len(missing) or missing[j] > lineno
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   740
            if self.blank_re.match(line):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   741
                dest.write('  ')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   742
            elif self.else_re.match(line):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   743
                # Special logic for lines containing only 'else:'.  
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   744
                # See [GDR 2001-12-04b, 3.2].
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   745
                if i >= len(statements) and j >= len(missing):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   746
                    dest.write('! ')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   747
                elif i >= len(statements) or j >= len(missing):
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   748
                    dest.write('> ')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   749
                elif statements[i] == missing[j]:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   750
                    dest.write('! ')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   751
                else:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   752
                    dest.write('> ')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   753
            elif lineno in excluded:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   754
                dest.write('- ')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   755
            elif covered:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   756
                dest.write('> ')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   757
            else:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   758
                dest.write('! ')
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   759
            dest.write(line)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   760
        source.close()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   761
        dest.close()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   762
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   763
# Singleton object.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   764
the_coverage = coverage()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   765
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   766
# Module functions call methods in the singleton object.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   767
def use_cache(*args, **kw): return the_coverage.use_cache(*args, **kw)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   768
def start(*args, **kw): return the_coverage.start(*args, **kw)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   769
def stop(*args, **kw): return the_coverage.stop(*args, **kw)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   770
def erase(*args, **kw): return the_coverage.erase(*args, **kw)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   771
def begin_recursive(*args, **kw): return the_coverage.begin_recursive(*args, **kw)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   772
def end_recursive(*args, **kw): return the_coverage.end_recursive(*args, **kw)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   773
def exclude(*args, **kw): return the_coverage.exclude(*args, **kw)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   774
def analysis(*args, **kw): return the_coverage.analysis(*args, **kw)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   775
def analysis2(*args, **kw): return the_coverage.analysis2(*args, **kw)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   776
def report(*args, **kw): return the_coverage.report(*args, **kw)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   777
def annotate(*args, **kw): return the_coverage.annotate(*args, **kw)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   778
def annotate_file(*args, **kw): return the_coverage.annotate_file(*args, **kw)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   779
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   780
# Save coverage data when Python exits.  (The atexit module wasn't
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   781
# introduced until Python 2.0, so use sys.exitfunc when it's not
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   782
# available.)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   783
try:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   784
    import atexit
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   785
    atexit.register(the_coverage.save)
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   786
except ImportError:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   787
    sys.exitfunc = the_coverage.save
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   788
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   789
# Command-line interface.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   790
if __name__ == '__main__':
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   791
    the_coverage.command_line()
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   792
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   793
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   794
# A. REFERENCES
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   795
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   796
# [GDR 2001-12-04a] "Statement coverage for Python"; Gareth Rees;
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   797
# Ravenbrook Limited; 2001-12-04;
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   798
# <http://www.nedbatchelder.com/code/modules/rees-coverage.html>.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   799
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   800
# [GDR 2001-12-04b] "Statement coverage for Python: design and
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   801
# analysis"; Gareth Rees; Ravenbrook Limited; 2001-12-04;
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   802
# <http://www.nedbatchelder.com/code/modules/rees-design.html>.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   803
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   804
# [van Rossum 2001-07-20a] "Python Reference Manual (releae 2.1.1)";
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   805
# Guide van Rossum; 2001-07-20;
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   806
# <http://www.python.org/doc/2.1.1/ref/ref.html>.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   807
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   808
# [van Rossum 2001-07-20b] "Python Library Reference"; Guido van Rossum;
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   809
# 2001-07-20; <http://www.python.org/doc/2.1.1/lib/lib.html>.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   810
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   811
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   812
# B. DOCUMENT HISTORY
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   813
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   814
# 2001-12-04 GDR Created.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   815
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   816
# 2001-12-06 GDR Added command-line interface and source code
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   817
# annotation.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   818
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   819
# 2001-12-09 GDR Moved design and interface to separate documents.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   820
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   821
# 2001-12-10 GDR Open cache file as binary on Windows.  Allow
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   822
# simultaneous -e and -x, or -a and -r.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   823
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   824
# 2001-12-12 GDR Added command-line help.  Cache analysis so that it
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   825
# only needs to be done once when you specify -a and -r.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   826
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   827
# 2001-12-13 GDR Improved speed while recording.  Portable between
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   828
# Python 1.5.2 and 2.1.1.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   829
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   830
# 2002-01-03 GDR Module-level functions work correctly.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   831
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   832
# 2002-01-07 GDR Update sys.path when running a file with the -x option,
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   833
# so that it matches the value the program would get if it were run on
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   834
# its own.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   835
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   836
# 2004-12-12 NMB Significant code changes.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   837
# - Finding executable statements has been rewritten so that docstrings and
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   838
#   other quirks of Python execution aren't mistakenly identified as missing
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   839
#   lines.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   840
# - Lines can be excluded from consideration, even entire suites of lines.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   841
# - The filesystem cache of covered lines can be disabled programmatically.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   842
# - Modernized the code.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   843
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   844
# 2004-12-14 NMB Minor tweaks.  Return 'analysis' to its original behavior
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   845
# and add 'analysis2'.  Add a global for 'annotate', and factor it, adding
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   846
# 'annotate_file'.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   847
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   848
# 2004-12-31 NMB Allow for keyword arguments in the module global functions.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   849
# Thanks, Allen.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   850
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   851
# 2005-12-02 NMB Call threading.settrace so that all threads are measured.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   852
# Thanks Martin Fuzzey. Add a file argument to report so that reports can be 
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   853
# captured to a different destination.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   854
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   855
# 2005-12-03 NMB coverage.py can now measure itself.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   856
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   857
# 2005-12-04 NMB Adapted Greg Rogers' patch for using relative filenames,
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   858
# and sorting and omitting files to report on.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   859
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   860
# C. COPYRIGHT AND LICENCE
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   861
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   862
# Copyright 2001 Gareth Rees.  All rights reserved.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   863
# Copyright 2004-2005 Ned Batchelder.  All rights reserved.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   864
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   865
# Redistribution and use in source and binary forms, with or without
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   866
# modification, are permitted provided that the following conditions are
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   867
# met:
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   868
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   869
# 1. Redistributions of source code must retain the above copyright
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   870
#    notice, this list of conditions and the following disclaimer.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   871
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   872
# 2. Redistributions in binary form must reproduce the above copyright
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   873
#    notice, this list of conditions and the following disclaimer in the
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   874
#    documentation and/or other materials provided with the
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   875
#    distribution.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   876
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   877
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   878
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   879
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   880
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   881
# HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   882
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   883
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   884
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   885
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   886
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   887
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   888
# DAMAGE.
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   889
#
a5d072f38a4a add coverage.py module to tests directory.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   890
# $Id: coverage.py 26 2005-12-04 18:42:44Z ned $