nedbat / coveragepy

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

"Jump to the function exit" in lcov report for branch at top level of module #1874

Open zackw opened 1 month ago

zackw commented 1 month ago

This rather peculiar test case was delta-minimized from real code (appdirs.py 1.4.1). It is formatting sensitive. In particular, removing the #! line or moving the close parenthesis that's currently on a line by itself to the return bar( line will break it.

#! /usr/bin/env python
def foo():
    return bar(
    )
if "x" == "y":  # line 5
    pass

Running coverage run --branch and then coverage lcov on this test case will produce these branch coverage records:

BRDA:5,0,jump to line 6,0
BRDA:5,0,jump to the function exit,1
BRF:2
BRH:1

But line 5 is not in a function. We should instead get

BRDA:5,0,jump to line 6,0
BRDA:5,0,exit the module,1

which is what we do get if the close paren on line 4 is moved to line 3 (modulo #1873).

I presume that the code on lines 1-4 has confused the static analysis engine into thinking line 5 is inside a function, but then the arc description logic can't get a name for that function (because it doesn't exist).

toebsen commented 1 month ago

I've also observed similar issues in unit tests when the last statement in a function is a with block, but only on mac and linux and only in a very small portion of test functions. Windows was fine though. Adding a final pass statement before the function ends solved it, but i guess the something broke with the recent changes.

nedbat commented 1 month ago

Hmm, this has been a bug for a long time. In 6.0.0 (Oct '21) through 6.4.1 (June '22), the message was "didn't jump to line 0". In 6.4.2 (July '22), it changed to "didn't jump to the function exit," and it's been that way ever since.