Skip to content

Instantly share code, notes, and snippets.

@groner
Created October 4, 2022 02:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save groner/0ba32d4489b6c865318098e26cd84cc5 to your computer and use it in GitHub Desktop.
Save groner/0ba32d4489b6c865318098e26cd84cc5 to your computer and use it in GitHub Desktop.
coverage.py crossreferencer
from argparse import ArgumentParser
from os import fspath
from pathlib import Path
import re
import sys
from textwrap import dedent
from coverage import Coverage
from coverage.exceptions import NotPython
def main():
parser = ArgumentParser(
description=dedent('''\
Cross reference fn:ln annotated text with python coverage database
example usage:
:; git grep -n some_function | python3 coverage-xref.py -v
'''))
parser.add_argument(
'-v', dest='invert', action='store_true', help='Match unexecuted lines')
parser.add_argument(
'-s', dest='silent', action='store_true', help='Supress error messages')
args = parser.parse_args()
# match filename:line[:col]:CONTENT
location_pattern = re.compile(r'(\S+):(\d+)(?:(:\d+))?:(.*)')
cdb = CoverageCoverage()
cwd = Path.cwd()
if args.invert:
def report(line, covered):
if covered is False:
print(line, end='')
else:
def report(line, covered):
if covered is True:
print(line, end='')
# Lines that don't match location_pattern get reported like the previous
# line that did match.
last_covered = None
for line in sys.stdin:
m = location_pattern.match(line)
if m is None:
report(line, last_covered)
continue
fn, ln, col, content = m.groups()
fn = fspath(cwd/fn)
ln = int(ln)
try:
covered = cdb.lookup(fn, ln)
except NotPython as e:
if not args.silent:
print(e, file=sys.stderr)
else:
report(line, covered)
last_covered = covered
class CoverageCoverage:
def __init__(self):
self.cov = Coverage()
self.cov.load()
self.fn_lines = {}
def lookup(self, fn, ln):
if fn not in self.fn_lines:
_, executable, not_executed, _ = self.cov.analysis(fn)
not_executed = {*not_executed}
executed = {*executable} - not_executed
self.fn_lines[fn] = executed, not_executed
else:
executed, not_executed = self.fn_lines[fn]
if ln in executed:
return True
if ln in not_executed:
return False
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment