Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3.14 field annotation not covered #1908

Closed
nickdrozd opened this issue Dec 22, 2024 · 6 comments
Closed

3.14 field annotation not covered #1908

nickdrozd opened this issue Dec 22, 2024 · 6 comments
Labels
bug Something isn't working fixed

Comments

@nickdrozd
Copy link
Contributor

The following snippet gets counted as 100% coverage under 3.13 and earlier versions, but under 3.14 it is counted as having a missing line:

class X:
    x: int  # <-- not covered under 3.14
python3.14 -m coverage run asdf.py && python3.14 -m coverage combine --quiet && python3.14 -m coverage report --fail-under 100
Name      Stmts   Miss Branch BrPart  Cover
-------------------------------------------
asdf.py       2      1      0      0    50%
-------------------------------------------
TOTAL         2      1      0      0    50%
Coverage failure: total of 50 is less than fail-under=100

Adding from __future__ import annotations causes everything to be counted:

from __future__ import annotations

class X:
    x: int  # <-- covered

Could have something to do with https://docs.python.org/3.14/whatsnew/3.14.html#whatsnew314-pep649?

@nickdrozd nickdrozd added the bug Something isn't working label Dec 22, 2024
@nedbat
Copy link
Owner

nedbat commented Dec 22, 2024

This definitely is because of deferred annotations. I'm not sure what to do here. The fact is there is code that has not been run. But also, it is likely never to be run, and it's fine that it isn't run.

But it can have errors. This will be an error if you run it in 3.13:

class X:
    x: inttttt
    y = 1
% python3.13 att.py
Traceback (most recent call last):
  File "/Users/ned/coverage/trunk/att.py", line 1, in <module>
    class X:
        x: inttttt
        y = 1
  File "/Users/ned/coverage/trunk/att.py", line 2, in X
    x: inttttt
       ^^^^^^^
NameError: name 'inttttt' is not defined

In 3.14, it won't error, but it will if you try to get the annotation:

class X:
    x: inttttt
    y = 1

from annotationlib import get_annotations, Format
get_annotations(X, format=Format.VALUE)
% python3.14 att.py
Traceback (most recent call last):
  File "/Users/ned/coverage/trunk/att.py", line 7, in <module>
    get_annotations(X, format=Format.VALUE)
    ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/pyenv/pyenv/versions/3.14.0a3/lib/python3.14/annotationlib.py", line 707, in get_annotations
    ann = _get_dunder_annotations(obj)
  File "/usr/local/pyenv/pyenv/versions/3.14.0a3/lib/python3.14/annotationlib.py", line 842, in _get_dunder_annotations
    ann = _BASE_GET_ANNOTATIONS(obj)
  File "/Users/ned/coverage/trunk/att.py", line 2, in __annotate__
    x: inttttt
       ^^^^^^^
NameError: name 'inttttt' is not defined

@nedbat
Copy link
Owner

nedbat commented Dec 22, 2024

btw, I also opened a discussion thread about this: https://discuss.python.org/t/how-should-coverage-py-treat-deferred-annotations/74990

@nickdrozd
Copy link
Contributor Author

As a user, my feeling is that if the field annotation is considered covered in 3.13 with from __future__ import annotations, then it should also be considered covered under 3.14 without the import.

Here is a naive suggestion. I assume there is a line somewhere to the effect of:

if has_future_annotations_import():
    field_annotation.count_as_covered()

Maybe that could be changed to:

if has_future_annotations_import() or PY_VER_314_PLUS:
    field_annotation.count_as_covered()

@nickdrozd nickdrozd changed the title 3.14 field annoation not covered 3.14 field annotation not covered Dec 22, 2024
@nedbat
Copy link
Owner

nedbat commented Dec 22, 2024

All of the annotations are put into code objects called __annotate__, so I can ignore those when looking for executable lines, and the problem is fixed in commit 2d04835.

@nedbat nedbat closed this as completed Dec 22, 2024
@nedbat nedbat added the fixed label Dec 22, 2024
@nickdrozd
Copy link
Contributor Author

Tested; works. Thanks!

@nedbat
Copy link
Owner

nedbat commented Dec 26, 2024

This is now released as part of coverage 7.6.10.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working fixed
Projects
None yet
Development

No branches or pull requests

2 participants