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)
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 os.path.exists(self.filename): try: self.source = read_file(self.filename) except : _, err, _ = sys.exc_info() raise NoSource( "No source for code: %r: %s" % (self.filename, err) ) if self.source is None: raise NoSource("No source for code: %r" % self.filename) self.parser = DjangoTemplateCodeParser( 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) self.missing = sorted(set(self.statements) - set(executed)) 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_missing_branches = sum( [len(v) for k,v in mba.items() if k not in self.missing] ) else: n_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_missing_branches=n_missing_branches, )
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 os.path.exists(self.filename): try: self.source = read_file(self.filename) except: _, err, _ = sys.exc_info() raise NoSource("No source for code: %r: %s" % (self.filename, err)) if self.source is None: raise NoSource("No source for code: %r" % self.filename) self.parser = DjangoTemplateCodeParser( 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) self.missing = sorted(set(self.statements) - set(executed)) 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_missing_branches = sum( [len(v) for k, v in mba.items() if k not in self.missing]) else: n_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_missing_branches=n_missing_branches, )
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, )
def patched_lines_matching(self, *regexes): """Find the lines matching one of a list of regexes. Returns a set of line numbers, the lines that contain a match for one of the regexes in `regexes`. The entire line needn't match, just a part of it. """ combined = join_regex(regexes) if env.PY2: combined = combined.decode("utf8") exclude_until_marker = '' if 'ExcludeUntilPlugin' in combined: plugin_match = re.search('\(\?\:ExcludeUntilPlugin([^\)]+)\)', combined) if plugin_match: exclude_until_marker = plugin_match.group(1) combined = combined.replace('ExcludeUntilPlugin', '') regex_c = re.compile(combined) matches = set() for i, line_text in enumerate(self.lines, start=1): match = regex_c.search(line_text) if match: if exclude_until_marker and match.group(0) == exclude_until_marker: matches.update(range(1, i)) else: matches.add(i) return matches
def fnmatches_to_regex(patterns, case_insensitive=False, partial=False): """Convert fnmatch patterns to a compiled regex that matches any of them. Slashes are always converted to match either slash or backslash, for Windows support, even when running elsewhere. If `partial` is true, then the pattern will match if the target string starts with the pattern. Otherwise, it must match the entire string. Returns: a compiled regex object. Use the .match method to compare target strings. """ regexes = (fnmatch.translate(pattern) for pattern in patterns) # Python3.7 fnmatch translates "/" as "/". Before that, it translates as "\/", # so we have to deal with maybe a backslash. regexes = (re.sub(r"\\?/", r"[\\\\/]", regex) for regex in regexes) if partial: # fnmatch always adds a \Z to match the whole string, which we don't # want, so we remove the \Z. While removing it, we only replace \Z if # followed by paren (introducing flags), or at end, to keep from # destroying a literal \Z in the pattern. regexes = (re.sub(r'\\Z(\(\?|$)', r'\1', regex) for regex in regexes) flags = 0 if case_insensitive: flags |= re.IGNORECASE compiled = re.compile(join_regex(regexes), flags=flags) return compiled
def lines_matching(self, *regexes): regex_c = re.compile(join_regex(regexes)) matches = set() for i, ltext in enumerate(self.lines): if regex_c.search(ltext): matches.add(i + 1) return matches
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, )
def linecount(fname, excludes): """Return the number of lines in ``fname``, counting the same way that coverage does. """ cp = CodeParser(filename=fname, exclude=re.compile(misc.join_regex(excludes))) lines, excluded = cp.parse_source() return len(lines), len(excluded)
def __init__(self, cov, code_unit): self.coverage = cov self.code_unit = code_unit self.filename = self.code_unit.filename self.parser = code_unit.get_parser( exclude=self.coverage._exclude_regex('exclude') ) self.statements, self.excluded = self.parser.parse_source() self.callers_data = self.coverage.data.callers_data().get(self.filename, {}) # Identify missing statements. executed = self.coverage.data.executed_lines(self.filename) executed = self.parser.translate_lines(executed) self.missing = self.statements - executed 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() unique_tests = set() if self.callers_data: unique_tests = get_unique_tests(self.callers_data) 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, calling_tests=unique_tests, )
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 = self.statements - 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, )
def __init__(self, pats): self.pats = pats[:] # fnmatch is platform-specific. On Windows, it does the Windows thing # of treating / and \ as equivalent. But on other platforms, we need to # take care of that ourselves. fnpats = (fnmatch.translate(p) for p in pats) # Python3.7 fnmatch translates "/" as "/", before that, it translates as "\/", # so we have to deal with maybe a backslash. fnpats = (re.sub(r"\\?/", r"[\\\\/]", p) for p in fnpats) # Windows is also case-insensitive, so use the IGNORECASE flag self.re = re.compile(join_regex(fnpats), flags=re.IGNORECASE if env.WINDOWS else 0)
def __init__(self, pats): self.pats = pats[:] # fnmatch is platform-specific. On Windows, it does the Windows thing # of treating / and \ as equivalent. But on other platforms, we need to # take care of that ourselves. fnpats = (fnmatch.translate(p) for p in pats) fnpats = (p.replace(r"\/", r"[\\/]") for p in fnpats) if env.WINDOWS: # Windows is also case-insensitive. BTW: the regex docs say that # flags like (?i) have to be at the beginning, but fnmatch puts # them at the end, and having two there seems to work fine. fnpats = (p + "(?i)" for p in fnpats) self.re = re.compile(join_regex(fnpats))
def lines_matching(self, *regexes): """Find the lines matching one of a list of regexes. Returns a set of line numbers, the lines that contain a match for one of the regexes in `regexes`. The entire line needn't match, just a part of it. """ regex_c = re.compile(join_regex(regexes)) matches = set() for i, ltext in enumerate(self.lines): if regex_c.search(ltext): matches.add(i+1) return matches
def lines_matching(self, *regexes): """Find the lines matching one of a list of regexes. Returns a set of line numbers, the lines that contain a match for one of the regexes in `regexes`. The entire line needn't match, just a part of it. """ regex_c = re.compile(join_regex(regexes)) matches = set() for i, ltext in enumerate(self.lines, start=1): if regex_c.search(ltext): matches.add(i) return matches
def __init__(self, pats): self.pats = pats[:] # fnmatch is platform-specific. On Windows, it does the Windows thing # of treating / and \ as equivalent. But on other platforms, we need to # take care of that ourselves. fnpats = (fnmatch.translate(p) for p in pats) # Python3.7 fnmatch translates "/" as "/", before that, it translates as "\/", # so we have to deal with maybe a backslash. fnpats = (re.sub(r"\\?/", r"[\\\\/]", p) for p in fnpats) flags = 0 if env.WINDOWS: # Windows is also case-insensitive, so make the regex case-insensitive. flags |= re.IGNORECASE self.re = re.compile(join_regex(fnpats), flags=flags)
def __init__(self, cov, code_unit): self.coverage = cov self.code_unit = code_unit self.filename = self.code_unit.filename self.parser = code_unit.get_parser( 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) executed = self.parser.translate_lines(executed) self.missing = self.statements - executed 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, )
def lines_matching(self, *regexes): """Find the lines matching one of a list of regexes. Returns a set of line numbers, the lines that contain a match for one of the regexes in `regexes`. The entire line needn't match, just a part of it. """ combined = join_regex(regexes) if env.PY2: combined = combined.decode("utf8") regex_c = re.compile(combined) matches = set() for i, ltext in enumerate(self.lines, start=1): if regex_c.search(ltext): matches.add(i) return matches
def lines_matching(self, *regexes): """Find the lines matching one of a list of regexes. Returns a set of line numbers, the lines that contain a match for one of the regexes in `regexes`. The entire line needn't match, just a part of it. """ combined = join_regex(regexes) if env.PY2: # pylint: disable=redefined-variable-type combined = combined.decode("utf8") regex_c = re.compile(combined) matches = set() for i, ltext in enumerate(self.lines, start=1): if regex_c.search(ltext): matches.add(i) return matches
def __init__(self, pats): self.pats = pats[:] self.re = re.compile(join_regex([fnmatch.translate(p) for p in pats]))
def no_branch_lines(self): no_branch = self.parser.lines_matching( join_regex(self.coverage.config.partial_list), join_regex(self.coverage.config.partial_always_list) ) return no_branch
def no_branch_lines(self): return self.parser.lines_matching(join_regex(DEFAULT_PARTIAL[:]), join_regex(DEFAULT_PARTIAL_ALWAYS[:]))
def _exclude_regex(self, which): """Return a compiled regex for the given exclusion list.""" if which not in self._exclude_re: excl_list = getattr(self.config, which + "_list") self._exclude_re[which] = join_regex(excl_list) return self._exclude_re[which]
def no_branch_lines(self): return self.parser.lines_matching( join_regex(DEFAULT_PARTIAL[:]), join_regex(DEFAULT_PARTIAL_ALWAYS[:]))
def _exclude_regex(self, which): if which not in self._exclude_re: excl_list = getattr(self.config, which + '_list') self._exclude_re[which] = join_regex(excl_list) return self._exclude_re[which]