示例#1
0
    def analysis2(self, morf):
        """Analyze a module.

        `morf` is a module or a filename.  It will be analyzed to determine
        its coverage statistics.  The return value is a 5-tuple:

        * The filename for the module.
        * A list of line numbers of executable statements.
        * A list of line numbers of excluded statements.
        * A list of line numbers of statements not run (missing from
          execution).
        * A readable formatted string of the missing line numbers.

        The analysis uses the source file itself and the current measured
        coverage data.

        """
        analysis = self._analyze(morf)
        return (
            analysis.filename,
            sorted(analysis.statements),
            sorted(analysis.excluded),
            sorted(analysis.missing),
            analysis.missing_formatted(),
            )
示例#2
0
    def analysis2(self, morf):
        """Analyze a module.

        `morf` is a module or a filename.  It will be analyzed to determine
        its coverage statistics.  The return value is a 5-tuple:

        * The filename for the module.
        * A list of line numbers of executable statements.
        * A list of line numbers of excluded statements.
        * A list of line numbers of statements not run (missing from
          execution).
        * A readable formatted string of the missing line numbers.

        The analysis uses the source file itself and the current measured
        coverage data.

        """
        analysis = self._analyze(morf)
        return (
            analysis.filename,
            sorted(analysis.statements),
            sorted(analysis.excluded),
            sorted(analysis.missing),
            analysis.missing_formatted(),
        )
示例#3
0
    def report(self, morfs, outfile=None):
        """Generate a Cobertura-compatible XML report for `morfs`.

        `morfs` is a list of modules or filenames.

        `outfile` is a file object to write the XML to.

        """
        # Initial setup.
        outfile = outfile or sys.stdout

        # Create the DOM that will store the data.
        impl = xml.dom.minidom.getDOMImplementation()
        docType = impl.createDocumentType(
            "coverage", None,
            "http://cobertura.sourceforge.net/xml/coverage-03.dtd")
        self.xml_out = impl.createDocument(None, "coverage", docType)

        # Write header stuff.
        xcoverage = self.xml_out.documentElement
        xcoverage.setAttribute("version", __version__)
        xcoverage.setAttribute("timestamp", str(int(time.time() * 1000)))
        xcoverage.appendChild(
            self.xml_out.createComment(" Generated by coverage.py: %s " %
                                       __url__))
        xpackages = self.xml_out.createElement("packages")
        xcoverage.appendChild(xpackages)

        # Call xml_file for each file in the data.
        self.packages = {}
        self.report_files(self.xml_file, morfs)

        lnum_tot, lhits_tot = 0, 0
        bnum_tot, bhits_tot = 0, 0

        # Populate the XML DOM with the package info.
        for pkg_name in sorted(self.packages.keys()):
            pkg_data = self.packages[pkg_name]
            class_elts, lhits, lnum, bhits, bnum = pkg_data
            xpackage = self.xml_out.createElement("package")
            xpackages.appendChild(xpackage)
            xclasses = self.xml_out.createElement("classes")
            xpackage.appendChild(xclasses)
            for class_name in sorted(class_elts.keys()):
                xclasses.appendChild(class_elts[class_name])
            xpackage.setAttribute("name", pkg_name.replace(os.sep, '.'))
            xpackage.setAttribute("line-rate", rate(lhits, lnum))
            xpackage.setAttribute("branch-rate", rate(bhits, bnum))
            xpackage.setAttribute("complexity", "0")

            lnum_tot += lnum
            lhits_tot += lhits
            bnum_tot += bnum
            bhits_tot += bhits

        xcoverage.setAttribute("line-rate", rate(lhits_tot, lnum_tot))
        xcoverage.setAttribute("branch-rate", rate(bhits_tot, bnum_tot))

        # Use the DOM to write the output file.
        outfile.write(self.xml_out.toprettyxml())
示例#4
0
def format_lines(statements, lines):
    """Nicely format a list of line numbers.

    Format a list of line numbers for printing by coalescing groups of lines as
    long as the lines represent consecutive statements.  This will coalesce
    even if there are gaps between statements.

    For example, if `statements` is [1,2,3,4,5,10,11,12,13,14] and
    `lines` is [1,2,5,10,11,13,14] then the result will be "1-2, 5-11, 13-14".

    """
    pairs = []
    i = 0
    j = 0
    start = None
    statements = sorted(statements)
    lines = sorted(lines)
    while i < len(statements) and j < len(lines):
        if statements[i] == lines[j]:
            if start == None:
                start = lines[j]
            end = lines[j]
            j += 1
        elif start:
            pairs.append((start, end))
            start = None
        i += 1
    if start:
        pairs.append((start, end))
    ret = ', '.join(map(nice_pair, pairs))
    return ret
示例#5
0
def format_lines(statements, lines):
    """Nicely format a list of line numbers.

    Format a list of line numbers for printing by coalescing groups of lines as
    long as the lines represent consecutive statements.  This will coalesce
    even if there are gaps between statements.

    For example, if `statements` is [1,2,3,4,5,10,11,12,13,14] and
    `lines` is [1,2,5,10,11,13,14] then the result will be "1-2, 5-11, 13-14".

    """
    pairs = []
    i = 0
    j = 0
    start = None
    statements = sorted(statements)
    lines = sorted(lines)
    while i < len(statements) and j < len(lines):
        if statements[i] == lines[j]:
            if start == None:
                start = lines[j]
            end = lines[j]
            j += 1
        elif start:
            pairs.append((start, end))
            start = None
        i += 1
    if start:
        pairs.append((start, end))
    ret = ', '.join(map(nice_pair, pairs))
    return ret
示例#6
0
    def annotate_file(self, cu, analysis):
        """Annotate a single file.

        `cu` is the CodeUnit for the file to annotate.

        """
        if not cu.relative:
            return

        filename = cu.filename
        source = cu.source_file()
        if self.directory:
            dest_file = os.path.join(self.directory, cu.flat_rootname())
            dest_file += ".py,cover"
        else:
            dest_file = filename + ",cover"
        dest = open(dest_file, 'w')

        statements = sorted(analysis.statements)
        missing = sorted(analysis.missing)
        excluded = sorted(analysis.excluded)

        lineno = 0
        i = 0
        j = 0
        covered = True
        while True:
            line = source.readline()
            if line == '':
                break
            lineno += 1
            while i < len(statements) and statements[i] < lineno:
                i += 1
            while j < len(missing) and missing[j] < lineno:
                j += 1
            if i < len(statements) and statements[i] == lineno:
                covered = j >= len(missing) or missing[j] > lineno
            if self.blank_re.match(line):
                dest.write('  ')
            elif self.else_re.match(line):
                # Special logic for lines containing only 'else:'.
                if i >= len(statements) and j >= len(missing):
                    dest.write('! ')
                elif i >= len(statements) or j >= len(missing):
                    dest.write('> ')
                elif statements[i] == missing[j]:
                    dest.write('! ')
                else:
                    dest.write('> ')
            elif lineno in excluded:
                dest.write('- ')
            elif covered:
                dest.write('> ')
            else:
                dest.write('! ')
            dest.write(line)
        source.close()
        dest.close()
示例#7
0
    def annotate_file(self, cu, analysis):
        """Annotate a single file.

        `cu` is the CodeUnit for the file to annotate.

        """
        if not cu.relative:
            return

        filename = cu.filename
        source = cu.source_file()
        if self.directory:
            dest_file = os.path.join(self.directory, cu.flat_rootname())
            dest_file += ".py,cover"
        else:
            dest_file = filename + ",cover"
        dest = open(dest_file, 'w')

        statements = sorted(analysis.statements)
        missing = sorted(analysis.missing)
        excluded = sorted(analysis.excluded)

        lineno = 0
        i = 0
        j = 0
        covered = True
        while True:
            line = source.readline()
            if line == '':
                break
            lineno += 1
            while i < len(statements) and statements[i] < lineno:
                i += 1
            while j < len(missing) and missing[j] < lineno:
                j += 1
            if i < len(statements) and statements[i] == lineno:
                covered = j >= len(missing) or missing[j] > lineno
            if self.blank_re.match(line):
                dest.write('  ')
            elif self.else_re.match(line):
                # Special logic for lines containing only 'else:'.
                if i >= len(statements) and j >= len(missing):
                    dest.write('! ')
                elif i >= len(statements) or j >= len(missing):
                    dest.write('> ')
                elif statements[i] == missing[j]:
                    dest.write('! ')
                else:
                    dest.write('> ')
            elif lineno in excluded:
                dest.write('- ')
            elif covered:
                dest.write('> ')
            else:
                dest.write('! ')
            dest.write(line)
        source.close()
        dest.close()
示例#8
0
    def report(self, morfs, outfile=None, config=None):
        """Generate a Cobertura-compatible XML report for `morfs`.

        `morfs` is a list of modules or filenames.

        `outfile` is a file object to write the XML to.  `config` is a
        CoverageConfig instance.

        """
        # Initial setup.
        outfile = outfile or sys.stdout

        # Create the DOM that will store the data.
        impl = xml.dom.minidom.getDOMImplementation()
        docType = impl.createDocumentType("coverage", None, "http://cobertura.sourceforge.net/xml/coverage-03.dtd")
        self.xml_out = impl.createDocument(None, "coverage", docType)

        # Write header stuff.
        xcoverage = self.xml_out.documentElement
        xcoverage.setAttribute("version", __version__)
        xcoverage.setAttribute("timestamp", str(int(time.time() * 1000)))
        xcoverage.appendChild(self.xml_out.createComment(" Generated by coverage.py: %s " % __url__))
        xpackages = self.xml_out.createElement("packages")
        xcoverage.appendChild(xpackages)

        # Call xml_file for each file in the data.
        self.packages = {}
        self.report_files(self.xml_file, morfs, config)

        lnum_tot, lhits_tot = 0, 0
        bnum_tot, bhits_tot = 0, 0

        # Populate the XML DOM with the package info.
        for pkg_name in sorted(self.packages.keys()):
            pkg_data = self.packages[pkg_name]
            class_elts, lhits, lnum, bhits, bnum = pkg_data
            xpackage = self.xml_out.createElement("package")
            xpackages.appendChild(xpackage)
            xclasses = self.xml_out.createElement("classes")
            xpackage.appendChild(xclasses)
            for class_name in sorted(class_elts.keys()):
                xclasses.appendChild(class_elts[class_name])
            xpackage.setAttribute("name", pkg_name.replace(os.sep, "."))
            xpackage.setAttribute("line-rate", rate(lhits, lnum))
            xpackage.setAttribute("branch-rate", rate(bhits, bnum))
            xpackage.setAttribute("complexity", "0")

            lnum_tot += lnum
            lhits_tot += lhits
            bnum_tot += bnum
            bhits_tot += bhits

        xcoverage.setAttribute("line-rate", rate(lhits_tot, lnum_tot))
        xcoverage.setAttribute("branch-rate", rate(bhits_tot, bnum_tot))

        # Use the DOM to write the output file.
        outfile.write(self.xml_out.toprettyxml())
    def report(self, morfs, outfile=None):
        """Generate a Cobertura-compatible XML report for `morfs`.
        
        `morfs` is a list of modules or filenames.
        
        `outfile` is a file object to write the XML to.
        
        """
        outfile = outfile or sys.stdout
        impl = xml.dom.minidom.getDOMImplementation()
        docType = impl.createDocumentType(
            'coverage', None,
            'http://cobertura.sourceforge.net/xml/coverage-03.dtd')
        self.xml_out = impl.createDocument(None, 'coverage', docType)
        xcoverage = self.xml_out.documentElement
        xcoverage.setAttribute('version', __version__)
        xcoverage.setAttribute('timestamp', str(int(time.time() * 1000)))
        xcoverage.appendChild(
            self.xml_out.createComment(' Generated by coverage.py: %s ' %
                                       __url__))
        xpackages = self.xml_out.createElement('packages')
        xcoverage.appendChild(xpackages)
        self.packages = {}
        self.report_files(self.xml_file, morfs)
        lnum_tot, lhits_tot = (0, 0)
        bnum_tot, bhits_tot = (0, 0)
        for pkg_name in sorted(self.packages.keys()):
            pkg_data = self.packages[pkg_name]
            class_elts, lhits, lnum, bhits, bnum = pkg_data
            xpackage = self.xml_out.createElement('package')
            xpackages.appendChild(xpackage)
            xclasses = self.xml_out.createElement('classes')
            xpackage.appendChild(xclasses)
            for class_name in sorted(class_elts.keys()):
                xclasses.appendChild(class_elts[class_name])

            xpackage.setAttribute('name', pkg_name.replace(os.sep, '.'))
            xpackage.setAttribute('line-rate', rate(lhits, lnum))
            xpackage.setAttribute('branch-rate', rate(bhits, bnum))
            xpackage.setAttribute('complexity', '0')
            lnum_tot += lnum
            lhits_tot += lhits
            bnum_tot += bnum
            bhits_tot += bhits

        xcoverage.setAttribute('line-rate', rate(lhits_tot, lnum_tot))
        xcoverage.setAttribute('branch-rate', rate(bhits_tot, bnum_tot))
        outfile.write(self.xml_out.toprettyxml())
        denom = lnum_tot + bnum_tot
        if denom == 0:
            pct = 0.0
        else:
            pct = 100.0 * (lhits_tot + bhits_tot) / denom
        return pct
示例#10
0
 def update(self, v):
     """Add `v` to the hash, recursively if needed."""
     self.md5.update(to_bytes(str(type(v))))
     if isinstance(v, string_class):
         self.md5.update(to_bytes(v))
     elif v is None:
         pass
     elif isinstance(v, (int, float)):
         self.md5.update(to_bytes(str(v)))
     elif isinstance(v, (tuple, list)):
         for e in v:
             self.update(e)
     elif isinstance(v, dict):
         keys = v.keys()
         for k in sorted(keys):
             self.update(k)
             self.update(v[k])
     else:
         for k in dir(v):
             if k.startswith('__'):
                 continue
             a = getattr(v, k)
             if inspect.isroutine(a):
                 continue
             self.update(k)
             self.update(a)
示例#11
0
 def start(self):
     """Start measuring code coverage.
     
     Coverage measurement actually occurs in functions called after `start`
     is invoked.  Statements in the same scope as `start` won't be measured.
     
     Once you invoke `start`, you must also call `stop` eventually, or your
     process might not shut down cleanly.
     
     """
     if self.run_suffix:
         self.data_suffix = self.run_suffix
     if self.auto_data:
         self.load()
     if self.source or self.source_pkgs:
         self.source_match = TreeMatcher(self.source)
     else:
         if self.cover_dir:
             self.cover_match = TreeMatcher([self.cover_dir])
         if self.pylib_dirs:
             self.pylib_match = TreeMatcher(self.pylib_dirs)
     if self.include:
         self.include_match = FnmatchMatcher(self.include)
     if self.omit:
         self.omit_match = FnmatchMatcher(self.omit)
     if self.debug.should('config'):
         self.debug.write('Configuration values:')
         config_info = sorted(self.config.__dict__.items())
         self.debug.write_formatted_info(config_info)
     if self.debug.should('sys'):
         self.debug.write('Debugging info:')
         self.debug.write_formatted_info(self.sysinfo())
     self.collector.start()
     self._started = True
     self._measured = True
示例#12
0
 def start(self):
     if self.run_suffix:
         self.data_suffix = self.run_suffix
     if self.auto_data:
         self.load()
     if self.source or self.source_pkgs:
         self.source_match = TreeMatcher(self.source)
     else:
         if self.cover_dir:
             self.cover_match = TreeMatcher([self.cover_dir])
         if self.pylib_dirs:
             self.pylib_match = TreeMatcher(self.pylib_dirs)
     if self.include:
         self.include_match = FnmatchMatcher(self.include)
     if self.omit:
         self.omit_match = FnmatchMatcher(self.omit)
     if self.debug.should('config'):
         self.debug.write('Configuration values:')
         config_info = sorted(self.config.__dict__.items())
         self.debug.write_formatted_info(config_info)
     if self.debug.should('sys'):
         self.debug.write('Debugging info:')
         self.debug.write_formatted_info(self.sysinfo())
     self.collector.start()
     self._started = True
     self._measured = True
示例#13
0
    def arcz_to_arcs(self, arcz):
        """Convert a compact textual representation of arcs to a list of pairs.

        The text has space-separated pairs of letters.  Period is -1, 1-9 are
        1-9, A-Z are 10 through 36.  The resulting list is sorted regardless of
        the order of the input pairs.

        ".1 12 2." --> [(-1,1), (1,2), (2,-1)]

        Minus signs can be included in the pairs:

        "-11, 12, 2-5" --> [(-1,1), (1,2), (2,-5)]

        """
        arcs = []
        for pair in arcz.split():
            asgn = bsgn = 1
            if len(pair) == 2:
                a,b = pair
            else:
                assert len(pair) == 3
                if pair[0] == '-':
                    _,a,b = pair
                    asgn = -1
                else:
                    assert pair[1] == '-'
                    a,_,b = pair
                    bsgn = -1
            arcs.append((asgn*self._arcz_map[a], bsgn*self._arcz_map[b]))
        return sorted(arcs)
示例#14
0
    def do_debug(self, args):
        """Implementation of 'coverage debug'."""

        if not args:
            self.help_fn("What information would you like: data, sys?")
            return ERR
        for info in args:
            if info == 'sys':
                print("-- sys ----------------------------------------")
                for line in info_formatter(self.coverage.sysinfo()):
                    print(" %s" % line)
            elif info == 'data':
                print("-- data ---------------------------------------")
                self.coverage.load()
                print("path: %s" % self.coverage.data.filename)
                print("has_arcs: %r" % self.coverage.data.has_arcs())
                summary = self.coverage.data.summary(fullpath=True)
                if summary:
                    filenames = sorted(summary.keys())
                    print("\n%d files:" % len(filenames))
                    for f in filenames:
                        print("%s: %d lines" % (f, summary[f]))
                else:
                    print("No data collected")
            else:
                self.help_fn("Don't know what you mean by %r" % info)
                return ERR
        return OK
示例#15
0
    def update(self, v):
        self.md5.update(to_bytes(str(type(v))))
        if isinstance(v, string_class):
            self.md5.update(to_bytes(v))
        elif isinstance(v, (int, float)):
            self.update(str(v))
        elif isinstance(v, (tuple, list)):
            for e in v:
                self.update(e)

        elif isinstance(v, dict):
            keys = v.keys()
            for k in sorted(keys):
                self.update(k)
                self.update(v[k])

        else:
            for k in dir(v):
                if k.startswith('__'):
                    continue
                a = getattr(v, k)
                if inspect.isroutine(a):
                    continue
                self.update(k)
                self.update(a)
示例#16
0
    def sysinfo(self):
        import coverage as covmod
        import platform, re
        try:
            implementation = platform.python_implementation()
        except AttributeError:
            implementation = 'unknown'

        info = [('version', covmod.__version__),
         ('coverage', covmod.__file__),
         ('cover_dir', self.cover_dir),
         ('pylib_dirs', self.pylib_dirs),
         ('tracer', self.collector.tracer_name()),
         ('config_files', self.config.attempted_config_files),
         ('configs_read', self.config.config_files),
         ('data_path', self.data.filename),
         ('python', sys.version.replace('\n', '')),
         ('platform', platform.platform()),
         ('implementation', implementation),
         ('executable', sys.executable),
         ('cwd', os.getcwd()),
         ('path', sys.path),
         ('environment', sorted([ '%s = %s' % (k, v) for k, v in iitems(os.environ) if re.search('^COV|^PY', k) ])),
         ('command_line', ' '.join(getattr(sys, 'argv', ['???'])))]
        if self.source_match:
            info.append(('source_match', self.source_match.info()))
        if self.include_match:
            info.append(('include_match', self.include_match.info()))
        if self.omit_match:
            info.append(('omit_match', self.omit_match.info()))
        if self.cover_match:
            info.append(('cover_match', self.cover_match.info()))
        if self.pylib_match:
            info.append(('pylib_match', self.pylib_match.info()))
        return info
示例#17
0
 def arcs_unpredicted(self):
     possible = self.arc_possibilities()
     executed = self.arcs_executed()
     unpredicted = [
         e for e in executed if e not in possible and e[0] != e[1]
     ]
     return sorted(unpredicted)
示例#18
0
    def do_debug(self, args):
        """Implementation of 'coverage debug'."""

        if not args:
            self.help_fn("What information would you like: data, sys?")
            return ERR
        for info in args:
            if info == 'sys':
                print("-- sys ----------------------------------------")
                for line in info_formatter(self.coverage.sysinfo()):
                    print(" %s" % line)
            elif info == 'data':
                print("-- data ---------------------------------------")
                self.coverage.load()
                print("path: %s" % self.coverage.data.filename)
                print("has_arcs: %r" % self.coverage.data.has_arcs())
                summary = self.coverage.data.summary(fullpath=True)
                if summary:
                    filenames = sorted(summary.keys())
                    print("\n%d files:" % len(filenames))
                    for f in filenames:
                        print("%s: %d lines" % (f, summary[f]))
                else:
                    print("No data collected")
            else:
                self.help_fn("Don't know what you mean by %r" % info)
                return ERR
        return OK
示例#19
0
 def start(self):
     if self.run_suffix:
         self.data_suffix = self.run_suffix
     if self.auto_data:
         self.load()
     if self.source or self.source_pkgs:
         self.source_match = TreeMatcher(self.source)
     else:
         if self.cover_dir:
             self.cover_match = TreeMatcher([self.cover_dir])
         if self.pylib_dirs:
             self.pylib_match = TreeMatcher(self.pylib_dirs)
     if self.include:
         self.include_match = FnmatchMatcher(self.include)
     if self.omit:
         self.omit_match = FnmatchMatcher(self.omit)
     if self.debug.should('config'):
         self.debug.write('Configuration values:')
         config_info = sorted(self.config.__dict__.items())
         self.debug.write_formatted_info(config_info)
     if self.debug.should('sys'):
         self.debug.write('Debugging info:')
         self.debug.write_formatted_info(self.sysinfo())
     self.collector.start()
     self._started = True
     self._measured = True
示例#20
0
 def __init__(self, cov, code_unit):
     self.coverage = cov
     self.code_unit = code_unit
     self.filename = self.code_unit.filename
     actual_filename, source = self.find_source(self.filename)
     self.parser = CodeParser(
         text=source,
         filename=actual_filename,
         exclude=self.coverage._exclude_regex('exclude'))
     self.statements, self.excluded = self.parser.parse_source()
     executed = self.coverage.data.executed_lines(self.filename)
     exec1 = self.parser.first_lines(executed)
     self.missing = sorted(set(self.statements) - set(exec1))
     if self.coverage.data.has_arcs():
         self.no_branch = self.parser.lines_matching(
             join_regex(self.coverage.config.partial_list),
             join_regex(self.coverage.config.partial_always_list))
         n_branches = self.total_branches()
         mba = self.missing_branch_arcs()
         n_partial_branches = sum(
             [len(v) for k, v in iitems(mba) if k not in self.missing])
         n_missing_branches = sum([len(v) for k, v in iitems(mba)])
     else:
         n_branches = n_partial_branches = n_missing_branches = 0
         self.no_branch = set()
     self.numbers = Numbers(n_files=1,
                            n_statements=len(self.statements),
                            n_excluded=len(self.excluded),
                            n_missing=len(self.missing),
                            n_branches=n_branches,
                            n_partial_branches=n_partial_branches,
                            n_missing_branches=n_missing_branches)
示例#21
0
    def do_debug(self, args):
        if not args:
            self.help_fn('What information would you like: data, sys?')
            return ERR
        for info in args:
            if info == 'sys':
                print '-- sys ----------------------------------------'
                for line in info_formatter(self.coverage.sysinfo()):
                    print ' %s' % line

            elif info == 'data':
                print '-- data ---------------------------------------'
                self.coverage.load()
                print 'path: %s' % self.coverage.data.filename
                print 'has_arcs: %r' % self.coverage.data.has_arcs()
                summary = self.coverage.data.summary(fullpath=True)
                if summary:
                    filenames = sorted(summary.keys())
                    print '\n%d files:' % len(filenames)
                    for f in filenames:
                        print '%s: %d lines' % (f, summary[f])

                else:
                    print 'No data collected'
            else:
                self.help_fn("Don't know what you mean by %r" % info)
                return ERR

        return OK
示例#22
0
    def arcz_to_arcs(self, arcz):
        """Convert a compact textual representation of arcs to a list of pairs.

        The text has space-separated pairs of letters.  Period is -1, 1-9 are
        1-9, A-Z are 10 through 36.  The resulting list is sorted regardless of
        the order of the input pairs.

        ".1 12 2." --> [(-1,1), (1,2), (2,-1)]

        Minus signs can be included in the pairs:

        "-11, 12, 2-5" --> [(-1,1), (1,2), (2,-5)]

        """
        arcs = []
        for pair in arcz.split():
            asgn = bsgn = 1
            if len(pair) == 2:
                a, b = pair
            else:
                assert len(pair) == 3
                if pair[0] == '-':
                    _, a, b = pair
                    asgn = -1
                else:
                    assert pair[1] == '-'
                    a, _, b = pair
                    bsgn = -1
            arcs.append((asgn * self._arcz_map[a], bsgn * self._arcz_map[b]))
        return sorted(arcs)
示例#23
0
 def arcs_unpredicted(self):
     """Returns a sorted list of the executed arcs missing from the code."""
     possible = self.arc_possibilities()
     executed = self.arcs_executed()
     unpredicted = [
         e for e in executed if e not in possible and e[0] != e[1]
     ]
     return sorted(unpredicted)
示例#24
0
 def arcs_missing(self):
     possible = self.arc_possibilities()
     executed = self.arcs_executed()
     missing = [
         p for p in possible
         if p not in executed and p[0] not in self.no_branch
     ]
     return sorted(missing)
示例#25
0
    def arcs(self):
        all_arcs = []
        for l1, l2 in self.byte_parser._all_arcs():
            fl1 = self.first_line(l1)
            fl2 = self.first_line(l2)
            if fl1 != fl2:
                all_arcs.append((fl1, fl2))

        return sorted(all_arcs)
示例#26
0
 def arcs_missing(self):
     """Returns a sorted list of the arcs in the code not executed."""
     possible = self.arc_possibilities()
     executed = self.arcs_executed()
     missing = [
         p for p in possible
         if p not in executed and p[0] not in self.no_branch
     ]
     return sorted(missing)
示例#27
0
    def arcs(self):
        all_arcs = []
        for l1, l2 in self.byte_parser._all_arcs():
            fl1 = self.first_line(l1)
            fl2 = self.first_line(l2)
            if fl1 != fl2:
                all_arcs.append((fl1, fl2))

        return sorted(all_arcs)
示例#28
0
    def report(self, morfs, outfile = None):
        outfile = outfile or sys.stdout
        impl = xml.dom.minidom.getDOMImplementation()
        docType = impl.createDocumentType('coverage', None, 'http://cobertura.sourceforge.net/xml/coverage-03.dtd')
        self.xml_out = impl.createDocument(None, 'coverage', docType)
        xcoverage = self.xml_out.documentElement
        xcoverage.setAttribute('version', __version__)
        xcoverage.setAttribute('timestamp', str(int(time.time() * 1000)))
        xcoverage.appendChild(self.xml_out.createComment(' Generated by coverage.py: %s ' % __url__))
        xpackages = self.xml_out.createElement('packages')
        xcoverage.appendChild(xpackages)
        self.packages = {}
        self.report_files(self.xml_file, morfs)
        lnum_tot, lhits_tot = (0, 0)
        bnum_tot, bhits_tot = (0, 0)
        for pkg_name in sorted(self.packages.keys()):
            pkg_data = self.packages[pkg_name]
            class_elts, lhits, lnum, bhits, bnum = pkg_data
            xpackage = self.xml_out.createElement('package')
            xpackages.appendChild(xpackage)
            xclasses = self.xml_out.createElement('classes')
            xpackage.appendChild(xclasses)
            for class_name in sorted(class_elts.keys()):
                xclasses.appendChild(class_elts[class_name])

            xpackage.setAttribute('name', pkg_name.replace(os.sep, '.'))
            xpackage.setAttribute('line-rate', rate(lhits, lnum))
            xpackage.setAttribute('branch-rate', rate(bhits, bnum))
            xpackage.setAttribute('complexity', '0')
            lnum_tot += lnum
            lhits_tot += lhits
            bnum_tot += bnum
            bhits_tot += bhits

        xcoverage.setAttribute('line-rate', rate(lhits_tot, lnum_tot))
        xcoverage.setAttribute('branch-rate', rate(bhits_tot, bnum_tot))
        outfile.write(self.xml_out.toprettyxml())
        denom = lnum_tot + bnum_tot
        if denom == 0:
            pct = 0.0
        else:
            pct = 100.0 * (lhits_tot + bhits_tot) / denom
        return pct
示例#29
0
 def arcs_missing(self):
     """Returns a sorted list of the arcs in the code not executed."""
     possible = self.arc_possibilities()
     executed = self.arcs_executed()
     missing = [
         p for p in possible
             if p not in executed
                 and p[0] not in self.no_branch
         ]
     return sorted(missing)
示例#30
0
    def adhoc_one_file(self, options, filename):
        """Process just one file."""
        
        if options.dis or options.chunks:
            try:
                bp = ByteParser(filename=filename)
            except CoverageException:
                _, err, _ = sys.exc_info()                
                print("%s" % (err,))
                return

        if options.dis:
            print("Main code:")
            bp._disassemble()

        if options.chunks:
            chunks = bp._all_chunks()
            if options.recursive:
                print("%6d: %s" % (len(chunks), filename))
            else:
                print("Chunks: %r" % chunks)
                arcs = bp._all_arcs()
                print("Arcs: %r" % sorted(arcs))

        if options.source or options.tokens:
            cp = CodeParser(filename=filename, exclude=r"no\s*cover")
            cp.show_tokens = options.tokens
            cp._raw_parse()

            if options.source:
                if options.chunks:
                    arc_width, arc_chars = self.arc_ascii_art(arcs)
                else:
                    arc_width, arc_chars = 0, {}
                    
                exit_counts = cp.exit_counts()

                for i, ltext in enumerate(cp.lines):
                    lineno = i+1
                    m0 = m1 = m2 = m3 = a = ' '
                    if lineno in cp.statement_starts:
                        m0 = '-'
                    exits = exit_counts.get(lineno, 0)
                    if exits > 1:
                        m1 = str(exits)
                    if lineno in cp.docstrings:
                        m2 = '"'
                    if lineno in cp.classdefs:
                        m2 = 'C'
                    if lineno in cp.excluded:
                        m3 = 'x'
                    a = arc_chars.get(lineno, '').ljust(arc_width)
                    print("%4d %s%s%s%s%s %s" %
                                (lineno, m0, m1, m2, m3, a, ltext)
                        )
示例#31
0
 def arcs_unpredicted(self):
     """Returns a sorted list of the executed arcs missing from the code."""
     possible = self.arc_possibilities()
     executed = self.arcs_executed()
     # Exclude arcs here which connect a line to itself.  They can occur
     # in executed data in some cases.  This is where they can cause
     # trouble, and here is where it's the least burden to remove them.
     unpredicted = [
         e for e in executed if e not in possible and e[0] != e[1]
     ]
     return sorted(unpredicted)
示例#32
0
    def first_lines(self, lines, ignore=None):
        ignore = ignore or []
        lset = set()
        for l in lines:
            if l in ignore:
                continue
            new_l = self.first_line(l)
            if new_l not in ignore:
                lset.add(new_l)

        return sorted(lset)
示例#33
0
    def adhoc_one_file(self, options, filename):
        """Process just one file."""

        if options.dis or options.chunks:
            try:
                bp = ByteParser(filename=filename)
            except CoverageException:
                _, err, _ = sys.exc_info()
                print("%s" % (err, ))
                return

        if options.dis:
            print("Main code:")
            bp._disassemble()

        if options.chunks:
            chunks = bp._all_chunks()
            if options.recursive:
                print("%6d: %s" % (len(chunks), filename))
            else:
                print("Chunks: %r" % chunks)
                arcs = bp._all_arcs()
                print("Arcs: %r" % sorted(arcs))

        if options.source or options.tokens:
            cp = CodeParser(filename=filename, exclude=r"no\s*cover")
            cp.show_tokens = options.tokens
            cp._raw_parse()

            if options.source:
                if options.chunks:
                    arc_width, arc_chars = self.arc_ascii_art(arcs)
                else:
                    arc_width, arc_chars = 0, {}

                exit_counts = cp.exit_counts()

                for i, ltext in enumerate(cp.lines):
                    lineno = i + 1
                    m0 = m1 = m2 = m3 = a = ' '
                    if lineno in cp.statement_starts:
                        m0 = '-'
                    exits = exit_counts.get(lineno, 0)
                    if exits > 1:
                        m1 = str(exits)
                    if lineno in cp.docstrings:
                        m2 = '"'
                    if lineno in cp.classdefs:
                        m2 = 'C'
                    if lineno in cp.excluded:
                        m3 = 'x'
                    a = arc_chars.get(lineno, '').ljust(arc_width)
                    print("%4d %s%s%s%s%s %s" %
                          (lineno, m0, m1, m2, m3, a, ltext))
示例#34
0
    def first_lines(self, lines, ignore = None):
        ignore = ignore or []
        lset = set()
        for l in lines:
            if l in ignore:
                continue
            new_l = self.first_line(l)
            if new_l not in ignore:
                lset.add(new_l)

        return sorted(lset)
示例#35
0
 def arcs_unpredicted(self):
     """Returns a sorted list of the executed arcs missing from the code."""
     possible = self.arc_possibilities()
     executed = self.arcs_executed()
     # Exclude arcs here which connect a line to itself.  They can occur
     # in executed data in some cases.  This is where they can cause
     # trouble, and here is where it's the least burden to remove them.
     unpredicted = [
         e for e in executed
             if e not in possible and e[0] != e[1]
         ]
     return sorted(unpredicted)
示例#36
0
文件: parser.py 项目: dimatomp/play
    def arcs(self):
        """Get information about the arcs available in the code.

        Returns a sorted list of line number pairs.  Line numbers have been
        normalized to the first line of multiline statements.

        """
        all_arcs = []
        for l1, l2 in self.byte_parser._all_arcs():
            fl1 = self.first_line(l1)
            fl2 = self.first_line(l2)
            if fl1 != fl2:
                all_arcs.append((fl1, fl2))
        return sorted(all_arcs)
示例#37
0
    def arcs(self):
        """Get information about the arcs available in the code.

        Returns a sorted list of line number pairs.  Line numbers have been
        normalized to the first line of multiline statements.

        """
        all_arcs = []
        for l1, l2 in self.byte_parser._all_arcs():
            fl1 = self.first_line(l1)
            fl2 = self.first_line(l2)
            if fl1 != fl2:
                all_arcs.append((fl1, fl2))
        return sorted(all_arcs)
示例#38
0
    def __init__(self, cov, code_unit):
        self.coverage = cov
        self.code_unit = code_unit

        self.filename = self.code_unit.filename
        ext = os.path.splitext(self.filename)[1]
        source = None
        if ext == '.py':
            if not os.path.exists(self.filename):
                source = self.coverage.file_locator.get_zip_data(self.filename)
                if not source:
                    raise NoSource("No source for code: '%s'" % self.filename)

        self.parser = CodeParser(
            text=source, filename=self.filename,
            exclude=self.coverage._exclude_regex('exclude')
            )
        self.statements, self.excluded = self.parser.parse_source()

        # Identify missing statements.
        executed = self.coverage.data.executed_lines(self.filename)
        exec1 = self.parser.first_lines(executed)
        self.missing = sorted(set(self.statements) - set(exec1))

        if self.coverage.data.has_arcs():
            self.no_branch = self.parser.lines_matching(
                join_regex(self.coverage.config.partial_list),
                join_regex(self.coverage.config.partial_always_list)
                )
            n_branches = self.total_branches()
            mba = self.missing_branch_arcs()
            n_partial_branches = sum(
                [len(v) for k,v in iitems(mba) if k not in self.missing]
                )
            n_missing_branches = sum([len(v) for k,v in iitems(mba)])
        else:
            n_branches = n_partial_branches = n_missing_branches = 0
            self.no_branch = set()

        self.numbers = Numbers(
            n_files=1,
            n_statements=len(self.statements),
            n_excluded=len(self.excluded),
            n_missing=len(self.missing),
            n_branches=n_branches,
            n_partial_branches=n_partial_branches,
            n_missing_branches=n_missing_branches,
            )
示例#39
0
    def __init__(self, cov, code_unit):
        self.coverage = cov
        self.code_unit = code_unit

        self.filename = self.code_unit.filename
        ext = os.path.splitext(self.filename)[1]
        source = None
        if ext == '.py':
            if not os.path.exists(self.filename):
                source = self.coverage.file_locator.get_zip_data(self.filename)
                if not source:
                    raise NoSource("No source for code: '%s'" % self.filename)

        self.parser = CodeParser(
            text=source,
            filename=self.filename,
            exclude=self.coverage._exclude_regex('exclude'))
        self.statements, self.excluded = self.parser.parse_source()

        # Identify missing statements.
        executed = self.coverage.data.executed_lines(self.filename)
        exec1 = self.parser.first_lines(executed)
        self.missing = sorted(set(self.statements) - set(exec1))

        if self.coverage.data.has_arcs():
            self.no_branch = self.parser.lines_matching(
                join_regex(self.coverage.config.partial_list),
                join_regex(self.coverage.config.partial_always_list))
            n_branches = self.total_branches()
            mba = self.missing_branch_arcs()
            n_partial_branches = sum(
                [len(v) for k, v in iitems(mba) if k not in self.missing])
            n_missing_branches = sum([len(v) for k, v in iitems(mba)])
        else:
            n_branches = n_partial_branches = n_missing_branches = 0
            self.no_branch = set()

        self.numbers = Numbers(
            n_files=1,
            n_statements=len(self.statements),
            n_excluded=len(self.excluded),
            n_missing=len(self.missing),
            n_branches=n_branches,
            n_partial_branches=n_partial_branches,
            n_missing_branches=n_missing_branches,
        )
示例#40
0
文件: parser.py 项目: dimatomp/play
    def first_lines(self, lines, ignore=None):
        """Map the line numbers in `lines` to the correct first line of the
        statement.

        Skip any line mentioned in `ignore`.

        Returns a sorted list of the first lines.

        """
        ignore = ignore or []
        lset = set()
        for l in lines:
            if l in ignore:
                continue
            new_l = self.first_line(l)
            if new_l not in ignore:
                lset.add(new_l)
        return sorted(lset)
示例#41
0
    def first_lines(self, lines, ignore=None):
        """Map the line numbers in `lines` to the correct first line of the
        statement.

        Skip any line mentioned in `ignore`.

        Returns a sorted list of the first lines.

        """
        ignore = ignore or []
        lset = set()
        for l in lines:
            if l in ignore:
                continue
            new_l = self.first_line(l)
            if new_l not in ignore:
                lset.add(new_l)
        return sorted(lset)
示例#42
0
    def sysinfo(self):
        """Return a list of (key, value) pairs showing internal information."""

        import coverage as covmod
        import platform, re

        try:
            implementation = platform.python_implementation()
        except AttributeError:
            implementation = "unknown"

        info = [
            ('version', covmod.__version__),
            ('coverage', covmod.__file__),
            ('cover_dir', self.cover_dir),
            ('pylib_dirs', self.pylib_dirs),
            ('tracer', self.collector.tracer_name()),
            ('config_files', self.config.attempted_config_files),
            ('configs_read', self.config.config_files),
            ('data_path', self.data.filename),
            ('python', sys.version.replace('\n', '')),
            ('platform', platform.platform()),
            ('implementation', implementation),
            ('executable', sys.executable),
            ('cwd', os.getcwd()),
            ('path', sys.path),
            ('environment',
             sorted([("%s = %s" % (k, v)) for k, v in iitems(os.environ)
                     if re.search(r"^COV|^PY", k)])),
            ('command_line', " ".join(getattr(sys, 'argv', ['???']))),
        ]
        if self.source_match:
            info.append(('source_match', self.source_match.info()))
        if self.include_match:
            info.append(('include_match', self.include_match.info()))
        if self.omit_match:
            info.append(('omit_match', self.omit_match.info()))
        if self.cover_match:
            info.append(('cover_match', self.cover_match.info()))
        if self.pylib_match:
            info.append(('pylib_match', self.pylib_match.info()))

        return info
示例#43
0
    def start(self):
        """Start measuring code coverage.

        Coverage measurement actually occurs in functions called after `start`
        is invoked.  Statements in the same scope as `start` won't be measured.

        Once you invoke `start`, you must also call `stop` eventually, or your
        process might not shut down cleanly.

        """
        if self.run_suffix:
            # Calling start() means we're running code, so use the run_suffix
            # as the data_suffix when we eventually save the data.
            self.data_suffix = self.run_suffix
        if self.auto_data:
            self.load()

        # Create the matchers we need for _should_trace
        if self.source or self.source_pkgs:
            self.source_match = TreeMatcher(self.source)
        else:
            if self.cover_dir:
                self.cover_match = TreeMatcher([self.cover_dir])
            if self.pylib_dirs:
                self.pylib_match = TreeMatcher(self.pylib_dirs)
        if self.include:
            self.include_match = FnmatchMatcher(self.include)
        if self.omit:
            self.omit_match = FnmatchMatcher(self.omit)

        # The user may want to debug things, show info if desired.
        if self.debug.should('config'):
            self.debug.write("Configuration values:")
            config_info = sorted(self.config.__dict__.items())
            self.debug.write_formatted_info(config_info)

        if self.debug.should('sys'):
            self.debug.write("Debugging info:")
            self.debug.write_formatted_info(self.sysinfo())

        self.collector.start()
        self._started = True
        self._measured = True
示例#44
0
    def start(self):
        """Start measuring code coverage.

        Coverage measurement actually occurs in functions called after `start`
        is invoked.  Statements in the same scope as `start` won't be measured.

        Once you invoke `start`, you must also call `stop` eventually, or your
        process might not shut down cleanly.

        """
        if self.run_suffix:
            # Calling start() means we're running code, so use the run_suffix
            # as the data_suffix when we eventually save the data.
            self.data_suffix = self.run_suffix
        if self.auto_data:
            self.load()

        # Create the matchers we need for _should_trace
        if self.source or self.source_pkgs:
            self.source_match = TreeMatcher(self.source)
        else:
            if self.cover_dir:
                self.cover_match = TreeMatcher([self.cover_dir])
            if self.pylib_dirs:
                self.pylib_match = TreeMatcher(self.pylib_dirs)
        if self.include:
            self.include_match = FnmatchMatcher(self.include)
        if self.omit:
            self.omit_match = FnmatchMatcher(self.omit)

        # The user may want to debug things, show info if desired.
        if self.debug.should('config'):
            self.debug.write("Configuration values:")
            config_info = sorted(self.config.__dict__.items())
            self.debug.write_formatted_info(config_info)

        if self.debug.should('sys'):
            self.debug.write("Debugging info:")
            self.debug.write_formatted_info(self.sysinfo())

        self.collector.start()
        self._started = True
        self._measured = True
示例#45
0
    def __init__(self, cov, code_unit):
        self.coverage = cov
        self.code_unit = code_unit

        self.filename = self.code_unit.filename
        actual_filename, source = self.find_source(self.filename)

        self.parser = CodeParser(
            text=source, filename=actual_filename,
            exclude=self.coverage._exclude_regex('exclude')
            )
        self.statements, self.excluded = self.parser.parse_source()

        # Identify missing statements.
        executed = self.coverage.data.executed_lines(self.filename)
        exec1 = self.parser.first_lines(executed)
        self.missing = sorted(set(self.statements) - set(exec1))

        if self.coverage.data.has_arcs():
            self.no_branch = self.parser.lines_matching(
                join_regex(self.coverage.config.partial_list),
                join_regex(self.coverage.config.partial_always_list)
                )
            n_branches = self.total_branches()
            mba = self.missing_branch_arcs()
            n_partial_branches = sum(
                [len(v) for k,v in iitems(mba) if k not in self.missing]
                )
            n_missing_branches = sum([len(v) for k,v in iitems(mba)])
        else:
            n_branches = n_partial_branches = n_missing_branches = 0
            self.no_branch = set()

        self.numbers = Numbers(
            n_files=1,
            n_statements=len(self.statements),
            n_excluded=len(self.excluded),
            n_missing=len(self.missing),
            n_branches=n_branches,
            n_partial_branches=n_partial_branches,
            n_missing_branches=n_missing_branches,
            )
示例#46
0
    def __init__(self, cov, code_unit):
        self.coverage = cov
        self.code_unit = code_unit
        
        self.filename = self.code_unit.filename
        ext = os.path.splitext(self.filename)[1]
        source = None
        if ext == '.py':
            if not os.path.exists(self.filename):
                source = self.coverage.file_locator.get_zip_data(self.filename)
                if not source:
                    raise NoSource("No source for code: %r" % self.filename)

        self.parser = CodeParser(
            text=source, filename=self.filename,
            exclude=self.coverage.exclude_re
            )
        self.statements, self.excluded = self.parser.parse_source()

        # Identify missing statements.
        executed = self.coverage.data.executed_lines(self.filename)
        exec1 = self.parser.first_lines(executed)
        self.missing = sorted(set(self.statements) - set(exec1))

        if self.coverage.data.has_arcs():
            n_branches = self.total_branches()
            mba = self.missing_branch_arcs()
            n_missing_branches = sum([len(v) for v in mba.values()])
        else:
            n_branches = n_missing_branches = 0
            
        self.numbers = Numbers(
            n_files=1,
            n_statements=len(self.statements), 
            n_excluded=len(self.excluded),
            n_missing=len(self.missing),
            n_branches=n_branches,
            n_missing_branches=n_missing_branches,
            )
示例#47
0
    def arc_ascii_art(self, arcs):
        """Draw arcs as ascii art.

        Returns a width of characters needed to draw all the arcs, and a
        dictionary mapping line numbers to ascii strings to draw for that line.

        """
        arc_chars = {}
        for lfrom, lto in sorted(arcs):
            if lfrom < 0:
                arc_chars[lto] = arc_chars.get(lto, "") + "v"
            elif lto < 0:
                arc_chars[lfrom] = arc_chars.get(lfrom, "") + "^"
            else:
                if lfrom == lto - 1:
                    # Don't show obvious arcs.
                    continue
                if lfrom < lto:
                    l1, l2 = lfrom, lto
                else:
                    l1, l2 = lto, lfrom
                w = max([len(arc_chars.get(l, "")) for l in range(l1, l2 + 1)])
                for l in range(l1, l2 + 1):
                    if l == lfrom:
                        ch = "<"
                    elif l == lto:
                        ch = ">"
                    else:
                        ch = "|"
                    arc_chars[l] = arc_chars.get(l, "").ljust(w) + ch
                arc_width = 0

        if arc_chars:
            arc_width = max([len(a) for a in arc_chars.values()])
        else:
            arc_width = 0

        return arc_width, arc_chars
示例#48
0
    def arc_ascii_art(self, arcs):
        """Draw arcs as ascii art.

        Returns a width of characters needed to draw all the arcs, and a
        dictionary mapping line numbers to ascii strings to draw for that line.

        """
        arc_chars = {}
        for lfrom, lto in sorted(arcs):
            if lfrom < 0:
                arc_chars[lto] = arc_chars.get(lto, '') + 'v'
            elif lto < 0:
                arc_chars[lfrom] = arc_chars.get(lfrom, '') + '^'
            else:
                if lfrom == lto - 1:
                    # Don't show obvious arcs.
                    continue
                if lfrom < lto:
                    l1, l2 = lfrom, lto
                else:
                    l1, l2 = lto, lfrom
                w = max([len(arc_chars.get(l, '')) for l in range(l1, l2 + 1)])
                for l in range(l1, l2 + 1):
                    if l == lfrom:
                        ch = '<'
                    elif l == lto:
                        ch = '>'
                    else:
                        ch = '|'
                    arc_chars[l] = arc_chars.get(l, '').ljust(w) + ch
                arc_width = 0

        if arc_chars:
            arc_width = max([len(a) for a in arc_chars.values()])
        else:
            arc_width = 0

        return arc_width, arc_chars
示例#49
0
    def __init__(self, cov, code_unit):
        self.coverage = cov
        self.code_unit = code_unit

        self.filename = self.code_unit.filename
        ext = os.path.splitext(self.filename)[1]
        source = None
        if ext == '.py':
            if not os.path.exists(self.filename):
                source = self.coverage.file_locator.get_zip_data(self.filename)
                if not source:
                    raise NoSource("No source for code: %r" % self.filename)

        self.parser = CodeParser(text=source,
                                 filename=self.filename,
                                 exclude=self.coverage.exclude_re)
        self.statements, self.excluded = self.parser.parse_source()

        # Identify missing statements.
        executed = self.coverage.data.executed_lines(self.filename)
        exec1 = self.parser.first_lines(executed)
        self.missing = sorted(set(self.statements) - set(exec1))

        if self.coverage.data.has_arcs():
            n_branches = self.total_branches()
            mba = self.missing_branch_arcs()
            n_missing_branches = sum([len(v) for v in mba.values()])
        else:
            n_branches = n_missing_branches = 0

        self.numbers = Numbers(
            n_files=1,
            n_statements=len(self.statements),
            n_excluded=len(self.excluded),
            n_missing=len(self.missing),
            n_branches=n_branches,
            n_missing_branches=n_missing_branches,
        )
示例#50
0
文件: data.py 项目: hguochen/everhash
 def arc_data(self):
     """Return the map from filenames to lists of line number pairs."""
     return dict([(f, sorted(amap.keys())) for f, amap in iitems(self.arcs)])
示例#51
0
    def command_line(self, argv):
        """The bulk of the command line interface to Coverage.

        `argv` is the argument list to process.

        Returns 0 if all is well, 1 if something went wrong.

        """
        # Collect the command-line options.

        if not argv:
            self.help_fn(topic='minimum_help')
            return OK

        # The command syntax we parse depends on the first argument.  Classic
        # syntax always starts with an option.
        classic = argv[0].startswith('-')
        if classic:
            parser = ClassicOptionParser()
        else:
            parser = CMDS.get(argv[0])
            if not parser:
                self.help_fn("Unknown command: '%s'" % argv[0])
                return ERR
            argv = argv[1:]

        parser.help_fn = self.help_fn
        ok, options, args = parser.parse_args(argv)
        if not ok:
            return ERR

        # Handle help.
        if options.help:
            if classic:
                self.help_fn(topic='help')
            else:
                self.help_fn(parser=parser)
            return OK

        if "help" in options.actions:
            if args:
                for a in args:
                    parser = CMDS.get(a)
                    if parser:
                        self.help_fn(parser=parser)
                    else:
                        self.help_fn(topic=a)
            else:
                self.help_fn(topic='help')
            return OK

        # Handle version.
        if options.version:
            self.help_fn(topic='version')
            return OK

        # Check for conflicts and problems in the options.
        for i in ['erase', 'execute']:
            for j in ['annotate', 'html', 'report', 'combine']:
                if (i in options.actions) and (j in options.actions):
                    self.help_fn("You can't specify the '%s' and '%s' "
                              "options at the same time." % (i, j))
                    return ERR

        if not options.actions:
            self.help_fn(
                "You must specify at least one of -e, -x, -c, -r, -a, or -b."
                )
            return ERR
        args_allowed = (
            'execute' in options.actions or
            'annotate' in options.actions or
            'html' in options.actions or
            'debug' in options.actions or
            'report' in options.actions or
            'xml' in options.actions
            )
        if not args_allowed and args:
            self.help_fn("Unexpected arguments: %s" % " ".join(args))
            return ERR

        if 'execute' in options.actions and not args:
            self.help_fn("Nothing to do.")
            return ERR

        # Listify the list options.
        source = unshell_list(options.source)
        omit = unshell_list(options.omit)
        include = unshell_list(options.include)

        # Do something.
        self.coverage = self.covpkg.coverage(
            data_suffix = options.parallel_mode,
            cover_pylib = options.pylib,
            timid = options.timid,
            branch = options.branch,
            config_file = options.rcfile,
            source = source,
            omit = omit,
            include = include,
            )

        if 'debug' in options.actions:
            if not args:
                self.help_fn("What information would you like: data, sys?")
                return ERR
            for info in args:
                if info == 'sys':
                    print("-- sys ----------------------------------------")
                    for label, info in self.coverage.sysinfo():
                        if info == []:
                            info = "-none-"
                        if isinstance(info, list):
                            print("%15s:" % label)
                            for e in info:
                                print("%15s  %s" % ("", e))
                        else:
                            print("%15s: %s" % (label, info))
                elif info == 'data':
                    print("-- data ---------------------------------------")
                    self.coverage.load()
                    print("path: %s" % self.coverage.data.filename)
                    print("has_arcs: %r" % self.coverage.data.has_arcs())
                    summary = self.coverage.data.summary(fullpath=True)
                    if summary:
                        filenames = sorted(summary.keys())
                        print("\n%d files:" % len(filenames))
                        for f in filenames:
                            print("%s: %d lines" % (f, summary[f]))
                    else:
                        print("No data collected")
                else:
                    self.help_fn("Don't know what you mean by %r" % info)
                    return ERR
            return OK

        if 'erase' in options.actions or options.erase_first:
            self.coverage.erase()
        else:
            self.coverage.load()

        if 'execute' in options.actions:
            # Run the script.
            self.coverage.start()
            code_ran = True
            try:
                try:
                    if options.module:
                        self.run_python_module(args[0], args)
                    else:
                        self.run_python_file(args[0], args)
                except NoSource:
                    code_ran = False
                    raise
            finally:
                if code_ran:
                    self.coverage.stop()
                    self.coverage.save()

        if 'combine' in options.actions:
            self.coverage.combine()
            self.coverage.save()

        # Remaining actions are reporting, with some common options.
        report_args = dict(
            morfs = args,
            ignore_errors = options.ignore_errors,
            omit = omit,
            include = include,
            )

        if 'report' in options.actions:
            self.coverage.report(
                show_missing=options.show_missing, **report_args)
        if 'annotate' in options.actions:
            self.coverage.annotate(
                directory=options.directory, **report_args)
        if 'html' in options.actions:
            self.coverage.html_report(
                directory=options.directory, **report_args)
        if 'xml' in options.actions:
            outfile = options.outfile
            self.coverage.xml_report(outfile=outfile, **report_args)

        return OK
示例#52
0
    def xml_file(self, cu, analysis):
        """Add to the XML report for a single file."""

        # Create the 'lines' and 'package' XML elements, which
        # are populated later.  Note that a package == a directory.
        package_name = rpartition(cu.name, ".")[0]
        className = cu.name

        package = self.packages.setdefault(package_name, [{}, 0, 0, 0, 0])

        xclass = self.xml_out.createElement("class")

        xclass.appendChild(self.xml_out.createElement("methods"))

        xlines = self.xml_out.createElement("lines")
        xclass.appendChild(xlines)

        xclass.setAttribute("name", className)
        filename = cu.file_locator.relative_filename(cu.filename)
        xclass.setAttribute("filename", filename.replace("\\", "/"))
        xclass.setAttribute("complexity", "0")

        branch_stats = analysis.branch_stats()

        # For each statement, create an XML 'line' element.
        for line in sorted(analysis.statements):
            xline = self.xml_out.createElement("line")
            xline.setAttribute("number", str(line))

            # Q: can we get info about the number of times a statement is
            # executed?  If so, that should be recorded here.
            xline.setAttribute("hits", str(int(line not in analysis.missing)))

            if self.arcs:
                if line in branch_stats:
                    total, taken = branch_stats[line]
                    xline.setAttribute("branch", "true")
                    xline.setAttribute("condition-coverage",
                        "%d%% (%d/%d)" % (100*taken/total, taken, total)
                        )
            xlines.appendChild(xline)

        class_lines = len(analysis.statements)
        class_hits = class_lines - len(analysis.missing)

        if self.arcs:
            class_branches = sum([t for t,k in branch_stats.values()])
            missing_branches = sum([t-k for t,k in branch_stats.values()])
            class_br_hits = class_branches - missing_branches
        else:
            class_branches = 0.0
            class_br_hits = 0.0

        # Finalize the statistics that are collected in the XML DOM.
        xclass.setAttribute("line-rate", rate(class_hits, class_lines))
        xclass.setAttribute("branch-rate", rate(class_br_hits, class_branches))
        package[0][className] = xclass
        package[1] += class_hits
        package[2] += class_lines
        package[3] += class_br_hits
        package[4] += class_branches
示例#53
0
 def line_data(self):
     """Return the map from filenames to lists of line numbers executed."""
     return dict([(f, sorted(lmap.keys()))
                  for f, lmap in iitems(self.lines)])
示例#54
0
 def arc_data(self):
     """Return the map from filenames to lists of line number pairs."""
     return dict([(f, sorted(amap.keys()))
                  for f, amap in iitems(self.arcs)])
示例#55
0
文件: data.py 项目: hguochen/everhash
 def line_data(self):
     """Return the map from filenames to lists of line numbers executed."""
     return dict([(f, sorted(lmap.keys())) for f, lmap in iitems(self.lines)])
示例#56
0
 def line_data(self):
     return dict([ (f, sorted(lmap.keys())) for f, lmap in iitems(self.lines) ])
示例#57
0
 def arcs_executed(self):
     """Returns a sorted list of the arcs actually executed in the code."""
     executed = self.coverage.data.executed_arcs(self.filename)
     m2fl = self.parser.first_line
     executed = [(m2fl(l1), m2fl(l2)) for (l1, l2) in executed]
     return sorted(executed)
示例#58
0
 def arc_data(self):
     return dict([ (f, sorted(amap.keys())) for f, amap in iitems(self.arcs) ])
示例#59
0
 def arcs_executed(self):
     """Returns a sorted list of the arcs actually executed in the code."""
     executed = self.coverage.data.executed_arcs(self.filename)
     m2fl = self.parser.first_line
     executed = [(m2fl(l1), m2fl(l2)) for (l1,l2) in executed]
     return sorted(executed)
示例#60
0
    def check_coverage(self, text, lines=None, missing="", report="",
            excludes=None, partials="",
            arcz=None, arcz_missing="", arcz_unpredicted=""):
        """Check the coverage measurement of `text`.

        The source `text` is run and measured.  `lines` are the line numbers
        that are executable, or a list of possible line numbers, any of which
        could match. `missing` are the lines not executed, `excludes` are
        regexes to match against for excluding lines, and `report` is the text
        of the measurement report.

        For arc measurement, `arcz` is a string that can be decoded into arcs
        in the code (see `arcz_to_arcs` for the encoding scheme),
        `arcz_missing` are the arcs that are not executed, and
        `arcs_unpredicted` are the arcs executed in the code, but not deducible
        from the code.

        """
        # We write the code into a file so that we can import it.
        # Coverage wants to deal with things as modules with file names.
        modname = self.get_module_name()

        self.make_file(modname+".py", text)

        arcs = arcs_missing = arcs_unpredicted = None
        if arcz is not None:
            arcs = self.arcz_to_arcs(arcz)
            arcs_missing = self.arcz_to_arcs(arcz_missing or "")
            arcs_unpredicted = self.arcz_to_arcs(arcz_unpredicted or "")

        # Start up Coverage.
        cov = coverage.coverage(branch=(arcs_missing is not None))
        cov.erase()
        for exc in excludes or []:
            cov.exclude(exc)
        for par in partials or []:
            cov.exclude(par, which='partial')

        mod = self.start_import_stop(cov, modname)

        # Clean up our side effects
        del sys.modules[modname]

        # Get the analysis results, and check that they are right.
        analysis = cov._analyze(mod)
        statements = sorted(analysis.statements)
        if lines is not None:
            if type(lines[0]) == type(1):
                # lines is just a list of numbers, it must match the statements
                # found in the code.
                self.assertEqual(statements, lines)
            else:
                # lines is a list of possible line number lists, one of them
                # must match.
                for line_list in lines:
                    if statements == line_list:
                        break
                else:
                    self.fail("None of the lines choices matched %r" %
                                                                statements
                        )

            if type(missing) == type(""):
                self.assertEqual(analysis.missing_formatted(), missing)
            else:
                for missing_list in missing:
                    if analysis.missing_formatted() == missing_list:
                        break
                else:
                    self.fail("None of the missing choices matched %r" %
                                            analysis.missing_formatted()
                        )

        if arcs is not None:
            self.assertEqualArcs(
                analysis.arc_possibilities(), arcs, "Possible arcs differ"
                )

            if arcs_missing is not None:
                self.assertEqualArcs(
                    analysis.arcs_missing(), arcs_missing,
                    "Missing arcs differ"
                    )

            if arcs_unpredicted is not None:
                self.assertEqualArcs(
                    analysis.arcs_unpredicted(), arcs_unpredicted,
                    "Unpredicted arcs differ"
                    )

        if report:
            frep = StringIO()
            cov.report(mod, file=frep)
            rep = " ".join(frep.getvalue().split("\n")[2].split()[1:])
            self.assertEqual(report, rep)