diff -r d28b92dabc2b -r bc64243b7672 DebugClients/Python/coverage/results.py --- a/DebugClients/Python/coverage/results.py Fri Sep 02 19:08:02 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,274 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt - -"""Results of coverage measurement.""" - -import collections - -from coverage.backward import iitems -from coverage.misc import format_lines - - -class Analysis(object): - """The results of analyzing a FileReporter.""" - - def __init__(self, data, file_reporter): - self.data = data - self.file_reporter = file_reporter - self.filename = self.file_reporter.filename - self.statements = self.file_reporter.lines() - self.excluded = self.file_reporter.excluded_lines() - - # Identify missing statements. - executed = self.data.lines(self.filename) or [] - executed = self.file_reporter.translate_lines(executed) - self.missing = self.statements - executed - - if self.data.has_arcs(): - self._arc_possibilities = sorted(self.file_reporter.arcs()) - self.exit_counts = self.file_reporter.exit_counts() - self.no_branch = self.file_reporter.no_branch_lines() - 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: - self._arc_possibilities = [] - self.exit_counts = {} - self.no_branch = set() - n_branches = n_partial_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_partial_branches=n_partial_branches, - n_missing_branches=n_missing_branches, - ) - - def missing_formatted(self): - """The missing line numbers, formatted nicely. - - Returns a string like "1-2, 5-11, 13-14". - - """ - return format_lines(self.statements, self.missing) - - def has_arcs(self): - """Were arcs measured in this result?""" - return self.data.has_arcs() - - def arc_possibilities(self): - """Returns a sorted list of the arcs in the code.""" - return self._arc_possibilities - - def arcs_executed(self): - """Returns a sorted list of the arcs actually executed in the code.""" - executed = self.data.arcs(self.filename) or [] - executed = self.file_reporter.translate_arcs(executed) - return sorted(executed) - - 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) - - def arcs_missing_formatted(self): - """The missing branch arcs, formatted nicely. - - Returns a string like "1->2, 1->3, 16->20". Omits any mention of - branches from missing lines, so if line 17 is missing, then 17->18 - won't be included. - - """ - arcs = self.missing_branch_arcs() - missing = self.missing - line_exits = sorted(iitems(arcs)) - pairs = [] - for line, exits in line_exits: - for ex in sorted(exits): - if line not in missing: - pairs.append("%d->%s" % (line, (ex if ex > 0 else "exit"))) - return ', '.join(pairs) - - 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. - # Also, generators can somehow cause arcs from "enter" to "exit", so - # make sure we have at least one positive value. - unpredicted = ( - e for e in executed - if e not in possible - and e[0] != e[1] - and (e[0] > 0 or e[1] > 0) - ) - return sorted(unpredicted) - - def branch_lines(self): - """Returns a list of line numbers that have more than one exit.""" - return [l1 for l1,count in iitems(self.exit_counts) if count > 1] - - def total_branches(self): - """How many total branches are there?""" - return sum(count for count in self.exit_counts.values() if count > 1) - - def missing_branch_arcs(self): - """Return arcs that weren't executed from branch lines. - - Returns {l1:[l2a,l2b,...], ...} - - """ - missing = self.arcs_missing() - branch_lines = set(self.branch_lines()) - mba = collections.defaultdict(list) - for l1, l2 in missing: - if l1 in branch_lines: - mba[l1].append(l2) - return mba - - def branch_stats(self): - """Get stats about branches. - - Returns a dict mapping line numbers to a tuple: - (total_exits, taken_exits). - """ - - missing_arcs = self.missing_branch_arcs() - stats = {} - for lnum in self.branch_lines(): - exits = self.exit_counts[lnum] - try: - missing = len(missing_arcs[lnum]) - except KeyError: - missing = 0 - stats[lnum] = (exits, exits - missing) - return stats - - -class Numbers(object): - """The numerical results of measuring coverage. - - This holds the basic statistics from `Analysis`, and is used to roll - up statistics across files. - - """ - # A global to determine the precision on coverage percentages, the number - # of decimal places. - _precision = 0 - _near0 = 1.0 # These will change when _precision is changed. - _near100 = 99.0 - - def __init__(self, n_files=0, n_statements=0, n_excluded=0, n_missing=0, - n_branches=0, n_partial_branches=0, n_missing_branches=0 - ): - self.n_files = n_files - self.n_statements = n_statements - self.n_excluded = n_excluded - self.n_missing = n_missing - self.n_branches = n_branches - self.n_partial_branches = n_partial_branches - self.n_missing_branches = n_missing_branches - - def init_args(self): - """Return a list for __init__(*args) to recreate this object.""" - return [ - self.n_files, self.n_statements, self.n_excluded, self.n_missing, - self.n_branches, self.n_partial_branches, self.n_missing_branches, - ] - - @classmethod - def set_precision(cls, precision): - """Set the number of decimal places used to report percentages.""" - assert 0 <= precision < 10 - cls._precision = precision - cls._near0 = 1.0 / 10**precision - cls._near100 = 100.0 - cls._near0 - - @property - def n_executed(self): - """Returns the number of executed statements.""" - return self.n_statements - self.n_missing - - @property - def n_executed_branches(self): - """Returns the number of executed branches.""" - return self.n_branches - self.n_missing_branches - - @property - def pc_covered(self): - """Returns a single percentage value for coverage.""" - if self.n_statements > 0: - numerator, denominator = self.ratio_covered - pc_cov = (100.0 * numerator) / denominator - else: - pc_cov = 100.0 - return pc_cov - - @property - def pc_covered_str(self): - """Returns the percent covered, as a string, without a percent sign. - - Note that "0" is only returned when the value is truly zero, and "100" - is only returned when the value is truly 100. Rounding can never - result in either "0" or "100". - - """ - pc = self.pc_covered - if 0 < pc < self._near0: - pc = self._near0 - elif self._near100 < pc < 100: - pc = self._near100 - else: - pc = round(pc, self._precision) - return "%.*f" % (self._precision, pc) - - @classmethod - def pc_str_width(cls): - """How many characters wide can pc_covered_str be?""" - width = 3 # "100" - if cls._precision > 0: - width += 1 + cls._precision - return width - - @property - def ratio_covered(self): - """Return a numerator and denominator for the coverage ratio.""" - numerator = self.n_executed + self.n_executed_branches - denominator = self.n_statements + self.n_branches - return numerator, denominator - - def __add__(self, other): - nums = Numbers() - nums.n_files = self.n_files + other.n_files - nums.n_statements = self.n_statements + other.n_statements - nums.n_excluded = self.n_excluded + other.n_excluded - nums.n_missing = self.n_missing + other.n_missing - nums.n_branches = self.n_branches + other.n_branches - nums.n_partial_branches = ( - self.n_partial_branches + other.n_partial_branches - ) - nums.n_missing_branches = ( - self.n_missing_branches + other.n_missing_branches - ) - return nums - - def __radd__(self, other): - # Implementing 0+Numbers allows us to sum() a list of Numbers. - if other == 0: - return self - return NotImplemented - -# -# eflag: FileType = Python2