coveragepy icon indicating copy to clipboard operation
coveragepy copied to clipboard

Question: Can `no-cover` "cover" the rest of the function?

Open stdedos opened this issue 1 year ago • 2 comments

Is your feature request related to a problem? Please describe.

I have the end of the main() function like so:

    ...

    if args.command == Commands.CMD.value:
        return cmd_handler(j, args)
    
    print(f"Either command '{args.command}' was not handled, or the end of the world is coming!\n", file=sys.stderr)
    parser.print_help(file=sys.stderr)

    return os.EX_USAGE

I'd like to ignore it with a no-cover.

Basically, the rest of the function would be hard to hit (somehow argparse does not "match" command with its function, or dev forgets to return cmd_handler().

I'd like to avoid the if return else pattern since, on top of that, I agree with the https://pylint.pycqa.org/en/latest/user_guide/messages/refactor/no-else-return.html check aesthetically

Any solutions I missed?

Describe the solution you'd like A clear and concise description of what you want to happen.

Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.

Additional context Add any other context about the feature request here.

stdedos avatar Jan 30 '24 09:01 stdedos

Currently there is not a pragma comment that means "ignore the rest of this." The simplest approach that you haven't mentioned is to put that tail of the function into a new function, then you can pragma the call and the function definition with one comment each. It will still look a bit odd though.

nedbat avatar Jan 30 '24 11:01 nedbat

Oh yeah - something like def handle_unexpected_main_fallthrough(cmd): # pragma: no-cover

... ofc that will still need the return handle_unexpected_main_fallthrough(cmd), I guess. But better than nothing, or throwing some "known ignored exception" I guess.

I can go with that. Thank you for the idea 🙃

stdedos avatar Jan 30 '24 11:01 stdedos

See proposal #1803

xqt avatar Jun 24 '24 14:06 xqt

As of commit 1fe897d740ebc67bd1f6493bcc889846f16abf10, you can do this with a multi-line exclusion regex if you are careful. You need to come up with a regex that matches the region you want to exclude, perhaps this:

[report]
exclude_also =
    # no cover: to return(?s:.)*?return

which will work exclude everything from # no cover: to return to the next return in the function.

nedbat avatar Jul 04 '24 20:07 nedbat

This is now released as part of coverage 7.6.0.

nedbat avatar Jul 11 '24 17:07 nedbat