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.

Asked By: yigal

||

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.

Answered By: Ned Batchelder

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)))
Answered By: yigal

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__.:

Answered By: Erick Mendonça
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.