Skip to content

Nested matches of exclude_lines patterns leads to unmatched lines being excluded #1779

Closed
@ringohoffman

Description

@ringohoffman

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):
    ...
Screenshot 2024-05-09 at 10 57 56

How can we reproduce the problem? Please be specific. Don't link to a failing CI job. Answer the questions below:

  1. What version of Python are you using?
    3.10
  2. What version of coverage.py shows the problem? The output of coverage debug sys is helpful.
    coverage==7.5.1
  3. What versions of what packages do you have installed? The output of pip freeze is helpful.
    ...
  4. 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.
    ...
  5. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions