With coverage.py, how to skip coverage of import and def statements
Question:
I have a python program that imports other files which potentially import other files, as is normal with python development
The problem is, when I measure coverage with coverage.py, some files which are imported but not used, get coverage “hits” on the def and import statements.
My question is: is there are way to avoid those hits? For my particular application these hits are considered noise.
Answers:
Coverage.py has controls for what files to include, and which to omit: http://coverage.readthedocs.io/en/coverage-4.5.1/source.html You can tailor which files it will measure.
Since coverage.py does not provide this feature, my solution was to write a small ast based function that calculate ghost hit points and remove them from the the coverage.py results
Edit (after 5 years), here is the relevant code:
import ast
def calc_ghost_hits(text):
def calc_args(node):
args=node.args
if args:
args=args.args
if args:
for arg in args:
yield arg.lineno
def calc_decorators(node):
for x in calc_args(node): yield x
for decorator in node.decorator_list:
yield decorator.lineno
returns=node.returns
if returns:
yield returns.lineno
def calc_it(branch,level):
for x in ast.iter_child_nodes(branch):
lineno=x.lineno
if lineno is not None:
yield lineno
t=type(x).__name__
if t=='ClassDef' and level==0:
for x in calc_it(x,level+1):
yield x
if t=='FunctionDef' and level<=1:
for x in calc_decorators(x):
yield x
return list(set(calc_it(ast.parse(text),0)))
You can use the exclude_lines
configuration, as per documentation https://coverage.readthedocs.io/en/coverage-4.2/excluding.html#advanced-exclusion.
For example (quoting from the link pasted above):
[report]
exclude_lines =
pragma: no cover
def __repr__
if self.debug:
if settings.DEBUG
raise AssertionError
raise NotImplementedError
if 0:
if __name__ == .__main__.:
I have a python program that imports other files which potentially import other files, as is normal with python development
The problem is, when I measure coverage with coverage.py, some files which are imported but not used, get coverage “hits” on the def and import statements.
My question is: is there are way to avoid those hits? For my particular application these hits are considered noise.
Coverage.py has controls for what files to include, and which to omit: http://coverage.readthedocs.io/en/coverage-4.5.1/source.html You can tailor which files it will measure.
Since coverage.py does not provide this feature, my solution was to write a small ast based function that calculate ghost hit points and remove them from the the coverage.py results
Edit (after 5 years), here is the relevant code:
import ast
def calc_ghost_hits(text):
def calc_args(node):
args=node.args
if args:
args=args.args
if args:
for arg in args:
yield arg.lineno
def calc_decorators(node):
for x in calc_args(node): yield x
for decorator in node.decorator_list:
yield decorator.lineno
returns=node.returns
if returns:
yield returns.lineno
def calc_it(branch,level):
for x in ast.iter_child_nodes(branch):
lineno=x.lineno
if lineno is not None:
yield lineno
t=type(x).__name__
if t=='ClassDef' and level==0:
for x in calc_it(x,level+1):
yield x
if t=='FunctionDef' and level<=1:
for x in calc_decorators(x):
yield x
return list(set(calc_it(ast.parse(text),0)))
You can use the exclude_lines
configuration, as per documentation https://coverage.readthedocs.io/en/coverage-4.2/excluding.html#advanced-exclusion.
For example (quoting from the link pasted above):
[report]
exclude_lines =
pragma: no cover
def __repr__
if self.debug:
if settings.DEBUG
raise AssertionError
raise NotImplementedError
if 0:
if __name__ == .__main__.: