def find_branches(module_path): branches = set() with open(module_path) as f: source = f.read() if not source: return set() for start_line, function_source in get_function_sources( module_path, source): parser = PythonParser(text=function_source) try: parser.parse_source() arcs = parser.arcs() except coverage.misc.NotPython as e: logger.error(e) return set() offset = set() for fr, to in arcs: if fr < 0 or to < 0: continue new_fr = fr + start_line - 1 new_to = to + start_line - 1 offset.add((new_fr, new_to)) branches.update(offset) return branches
def get_parser(self, exclude=None): actual_filename, source = self._find_source(self.filename) return PythonParser( text=source, filename=actual_filename, exclude=exclude, )
def parser(self): if self._parser is None: self._parser = PythonParser( filename=self.filename, exclude=self.coverage._exclude_regex('exclude'), ) return self._parser
def compare_alternatives(source): all_all_arcs = collections.defaultdict(list) for i, alternate_source in enumerate(async_alternatives(source)): parser = PythonParser(alternate_source) arcs = parser.arcs() all_all_arcs[tuple(arcs)].append((i, alternate_source)) return len(all_all_arcs)
def parser(self): """Lazily create a :class:`PythonParser`.""" if self._parser is None: self._parser = PythonParser( filename=self.filename, exclude=self.coverage._exclude_regex('exclude'), ) return self._parser
def parse_source(self, text): """Parse `text` as source, and return the `PythonParser` used.""" if env.PY2: text = text.decode("ascii") text = textwrap.dedent(text) parser = PythonParser(text=text, exclude="nocover") parser.parse_source() return parser
def _extract_all_branches(python_source: str): parser = PythonParser(text=python_source) # This is a hack to force-disable Python optimization, otherwise Python will optimize away statements like # "if False: ..." and that would cause unexpected diffs in the coverage branches. Even when passing optimize=0 to # compile(). parser._byte_parser = _FakeByteParser( num_lines=len(python_source.splitlines()) + 1) parser.parse_source() return parser.arcs()
def one_file(self, options, filename): """Process just one file.""" try: text = get_python_source(filename) bp = ByteParser(text, filename=filename) except Exception as err: print("%s" % (err, )) return if options.dis: print("Main code:") self.disassemble(bp, histogram=options.histogram) arcs = bp._all_arcs() if options.chunks: chunks = bp._all_chunks() if options.recursive: print("%6d: %s" % (len(chunks), filename)) else: print("Chunks: %r" % chunks) print("Arcs: %r" % sorted(arcs)) if options.source or options.tokens: cp = PythonParser(filename=filename, exclude=r"no\s*cover") cp.show_tokens = options.tokens cp.parse_source() if options.source: arc_width = 0 arc_chars = {} if options.chunks: arc_chars = self.arc_ascii_art(arcs) if arc_chars: arc_width = max(len(a) for a in arc_chars.values()) exit_counts = cp.exit_counts() for lineno, ltext in enumerate(cp.lines, start=1): m0 = m1 = m2 = m3 = a = ' ' if lineno in cp.statements: m0 = '=' elif lineno in cp.raw_statements: m0 = '-' exits = exit_counts.get(lineno, 0) if exits > 1: m1 = str(exits) if lineno in cp.raw_docstrings: m2 = '"' if lineno in cp.raw_classdefs: m2 = 'C' if lineno in cp.raw_excluded: m3 = 'x' a = arc_chars[lineno].ljust(arc_width) print("%4d %s%s%s%s%s %s" % (lineno, m0, m1, m2, m3, a, ltext))
def check_human_coverage(self, text, lines=None, fingerprints=None): text = textwrap.dedent(text) coverage_lines, _ = self.write_and_run(text) m = Module(source_code=text) parser = PythonParser(text=text) parser.parse_source() statements = parser.statements executed = coverage_lines executed = parser.translate_lines(executed) hc = sorted( human_coverage(text, sorted(statements), sorted(statements - executed))) assert hc == lines if fingerprints: assert create_fingerprints(m.lines, m.special_blocks, lines) == fingerprints
def parse_text(self, source): """Parse Python source, and return the parser object.""" parser = PythonParser(text=textwrap.dedent(source)) parser.parse_source() return parser
def parse_file(self, filename): """Parse `text` as source, and return the `PythonParser` used.""" parser = PythonParser(filename=filename, exclude="nocover") parser.parse_source() return parser
def one_file(self, options, filename): """Process just one file.""" # `filename` can have a line number suffix. In that case, extract those # lines, dedent them, and use that. This is for trying test cases # embedded in the test files. match = re.search(r"^(.*):(\d+)-(\d+)$", filename) if match: filename, start, end = match.groups() start, end = int(start), int(end) else: start = end = None try: text = get_python_source(filename) if start is not None: lines = text.splitlines(True) text = textwrap.dedent("".join(lines[start - 1:end]).replace( "\\\\", "\\")) pyparser = PythonParser(text, filename=filename, exclude=r"no\s*cover") pyparser.parse_source() except Exception as err: print(f"{err}") return if options.dis: print("Main code:") self.disassemble(pyparser.byte_parser, histogram=options.histogram) arcs = pyparser.arcs() if options.source or options.tokens: pyparser.show_tokens = options.tokens pyparser.parse_source() if options.source: arc_chars = self.arc_ascii_art(arcs) if arc_chars: arc_width = max(len(a) for a in arc_chars.values()) exit_counts = pyparser.exit_counts() for lineno, ltext in enumerate(pyparser.lines, start=1): marks = [' ', ' ', ' ', ' ', ' '] a = ' ' if lineno in pyparser.raw_statements: marks[0] = '-' if lineno in pyparser.statements: marks[1] = '=' exits = exit_counts.get(lineno, 0) if exits > 1: marks[2] = str(exits) if lineno in pyparser.raw_docstrings: marks[3] = '"' if lineno in pyparser.raw_classdefs: marks[3] = 'C' if lineno in pyparser.raw_excluded: marks[4] = 'x' if arc_chars: a = arc_chars[lineno].ljust(arc_width) else: a = "" print("%4d %s%s %s" % (lineno, "".join(marks), a, ltext))
def parse_file(self, filename): """Parse `text` as source, and return the `PythonParser` used.""" # pylint: disable=attribute-defined-outside-init parser = PythonParser(filename=filename, exclude="nocover") self.statements, self.excluded = parser.parse_source() return parser
"""Parse every Python file in a tree.""" import os import sys from coverage.misc import CoverageException from coverage.parser import PythonParser for root, dirnames, filenames in os.walk(sys.argv[1]): for filename in filenames: if filename.endswith(".py"): filename = os.path.join(root, filename) print(":: {}".format(filename)) try: par = PythonParser(filename=filename) par.parse_source() par.arcs() except Exception as exc: print(" ** {}".format(exc))
def parser(self): if self._parser is None: self._parser = PythonParser(filename=self.filename) self._parser.parse_source() return self._parser
def parser(self): if self._parser is None: filename = self.filename if self.test_time else self.filename_with_source_root self._parser = PythonParser(filename=filename) self._parser.parse_source() return self._parser
def parse_source(self, text): """Parse `text` as source, and return the `PythonParser` used.""" text = textwrap.dedent(text) parser = PythonParser(text=text, exclude="nocover") parser.parse_source() return parser
def _get_file_lines(file: str) -> Set[int]: parser = PythonParser(filename=file) parser.parse_source() return parser.raw_statements