Skip to content

LCOV function records include functions excluded by report config #2205

Description

@TrapsterDK

Describe the bug

coverage lcov includes function records for functions that are excluded by [report] exclude_also. The line records respect the exclusions, but FN/FNDA/FNF/FNH still count the excluded function, causing tools like genhtml to report lower function coverage even when line coverage is 100%.

This was observed with excluded abstract methods such as @(abc\.)?abstractmethod.

This issue was drafted with AI assistance, but it describes a real observed issue from an actual codebase. The behavior was reproduced with a minimal example and human-validated before filing.

To Reproduce

module_under_test.py:

from abc import ABC, abstractmethod


class Base(ABC):
    @abstractmethod
    def excluded_abstract(self) -> int:
        raise NotImplementedError

    def covered(self) -> int:
        return 1


class Concrete(Base):
    def excluded_abstract(self) -> int:
        return 2


assert Concrete().covered() == 1
assert Concrete().excluded_abstract() == 2

.coveragerc:

[run]
source = .

[report]
exclude_also =
    @(abc\.)?abstractmethod
    raise NotImplementedError

Commands:

python -m coverage run module_under_test.py
python -m coverage report
python -m coverage lcov -o coverage.lcov

Text report:

Name                   Stmts   Miss  Cover
------------------------------------------
module_under_test.py       9      0   100%

LCOV output includes the excluded abstract method:

FN:6,7,Base.excluded_abstract
FNDA:0,Base.excluded_abstract
FN:9,10,Base.covered
FNDA:1,Base.covered
FN:14,15,Concrete.excluded_abstract
FNDA:1,Concrete.excluded_abstract
FNF:3
FNH:2

Expected behavior

Because Base.excluded_abstract is excluded from reportable statements, it should not contribute to LCOV function totals. Expected function records:

FN:9,10,Base.covered
FNDA:1,Base.covered
FN:14,15,Concrete.excluded_abstract
FNDA:1,Concrete.excluded_abstract
FNF:2
FNH:2

Versions tested

  • coverage.py 7.13.4
  • coverage.py 7.14.3

I also checked the current main implementation and the LCOV function record path still appears to count all function code regions before filtering out fully excluded regions.

Context

This is similar in spirit to #1684, but for LCOV function records rather than line records. The line totals are correct; only function records ignore/report around excluded regions.

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions