nedbat / coveragepy

The code coverage tool for Python
https://coverage.readthedocs.io
Apache License 2.0
3.01k stars 432 forks source link

uncovered branch coverage of outer statement is disabled by ignored coverage of contained statement #1505

Open asottile opened 1 year ago

asottile commented 1 year ago

Describe the bug

this was pretty tricky to narrow down -- initially I only found this through covdefaults and a particular branch which was conditionally ignored (only on windows) via the covdefaults-specific # pragma: win32 no cover

here's a case which reproduces without covdefaults:

def f():
    return True

def g():
    return False

if f():
    if g():  # pragma: no cover
        print('never')
    print('1')

To Reproduce

I don't think this is version specific but here's my versions:

$ python --version --version
Python 3.10.6 (main, Nov  2 2022, 18:53:38) [GCC 11.3.0]
$ coverage --version
Coverage.py, version 6.5.0 with C extension
Full documentation is at https://coverage.readthedocs.io

here's the output and commands:

$ coverage erase && coverage run --branch -m t && coverage report --show-missing
1
Name    Stmts   Miss Branch BrPart  Cover   Missing
---------------------------------------------------
t.py        6      0      0      0   100%
---------------------------------------------------
TOTAL       6      0      0      0   100%

I expect a missed branch from 7->exit, which is present if I remove the no cover:

$ sed -i 's/#.*//g' t.py
$ coverage erase && coverage run --branch -m t && coverage report --show-missing
1
Name    Stmts   Miss Branch BrPart  Cover   Missing
---------------------------------------------------
t.py        8      1      4      2    75%   7->exit, 9
---------------------------------------------------
TOTAL       8      1      4      2    75%
nedbat commented 1 year ago

That does indeed seem wrong. But tell me more about the pragma on line 8... if you don't expect line 8 to run, then how would line 10 run? Can you share the original code that led you down this path?

asottile commented 1 year ago

this branch was legitimately uncovered but was masked by a broken windows build https://github.com/pre-commit/pre-commit/blob/50c217964b0f00e38d67cac858b597501a86e22b/pre_commit/languages/rust.py#L99

when the build was fixed Linux had 100% coverage and windows was missing a branch -- but in reality the branch was not covered in either