Nested matches of exclude_lines patterns leads to unmatched lines being excluded · Issue #1779 · nedbat/coveragepy (original) (raw)
Describe the bug
When multiple patterns of exclude_lines
overlap (like an abstractmethod
inside a Protocol
, which you see below), the exclusion for the abstractmethod
unexpectedly extends to the next coverable line, leading to an incorrect coverage report.
To Reproduce
.coveragerc
:
[report] exclude_lines = @(abc.)?abstractmethod class .?(.?Protocol.*?:
a.py
:
import abc from typing import Protocol
class MyProtocol(Protocol): @abc.abstractmethod def my_method(self) -> int: """Discombombulate the frobnicator."""
def function() -> int: x = 1 y = 2 return x + y
tests/test_a.py
:
import unittest
import a
class TestA(unittest.TestCase): ...
How can we reproduce the problem? Please be specific. Don't link to a failing CI job. Answer the questions below:
- What version of Python are you using?
3.10 - What version of coverage.py shows the problem? The output of
coverage debug sys
is helpful.coverage==7.5.1
- What versions of what packages do you have installed? The output of
pip freeze
is helpful.
... - What code shows the problem? Give us a specific commit of a specific repo that we can check out. If you've already worked around the problem, please provide a commit before that fix.
... - What commands should we run to reproduce the problem? Be specific. Include everything, even
git clone
,pip install
, and so on. Explain like we're five!
$ python -m pytest tests/test_a.py --cov=a.py $ coverage html $ python -m http.server
Expected behavior
I don't expect the exclusion to extend to the next line.
If you change Protocol
to abc.ABC
, it works as expected. If you remove @(abc\.)?abstractmethod
from exclude_lines
or modify it in a way s.t. it does not match the code, it works as expected.