Skip to content

Default ... exclusion rule misses when return type annotation is split over multiple lines #2185

Description

@samueljsb

Describe the bug

If a function's return type annotation is split over multiple lines, the default exclusion rule for functions containing only ... does not match.

To Reproduce

example.py:

from typing import Protocol

class C:
    def f() -> dict[
        str, str
    ]: ...
$ coverage erase
$ coverage run --branch -m example
$ coverage report --fail-under=100 --show-missing
Name         Stmts   Miss Branch BrPart  Cover   Missing
--------------------------------------------------------
example.py       3      0      2      1    80%   4->exit
--------------------------------------------------------
TOTAL            3      0      2      1    80%
Coverage failure: total of 80 is less than fail-under=100

N.B. This example is a little contrived, but many formatters (e.g. ruff) will format functions like this if the annotation is too long.

$ python --version --version
Python 3.14.5 (main, May 10 2026, 10:21:34) [Clang 21.0.0 (clang-2100.0.123.102)]

$ coverage --version
Coverage.py, version 7.14.1 with C extension

$ uv pip freeze
Using Python 3.14.5 environment at: venv
ast-serialize==0.5.0
coverage==7.14.1
librt==0.11.0
markdown-it-py==4.2.0
mdurl==0.1.2
mypy==2.1.0
mypy-extensions==1.1.0
pathspec==1.1.1
pip==26.1.1
pygments==2.20.0
rich==15.0.0
typing-extensions==4.15.0

Expected behavior

We expect the function to be excluded because it only contains ellipsis.

We believe this is because the regexp used to match functions containing only ellipsis expects the return type annotation to be on one line:

r"^\s*(((async )?def .*?)?\)(\s*->.*?)?:\s*)?\.\.\.\s*(#|$)",

Potentially related issues: #1616, #2112

Activity

nedbat commented on Jun 21, 2026

@nedbat
Member

Fixed in commit f4b2b4d.

nedbat commented on Jun 22, 2026

@nedbat
Member

This is now released as part of coverage 7.14.3.

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

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions