Skip to content

[ty] Add contextual secondary annotations in more places#24696

Merged
AlexWaygood merged 4 commits intomainfrom
alex/deco-context
Apr 20, 2026
Merged

[ty] Add contextual secondary annotations in more places#24696
AlexWaygood merged 4 commits intomainfrom
alex/deco-context

Conversation

@AlexWaygood
Copy link
Copy Markdown
Member

@AlexWaygood AlexWaygood commented Apr 17, 2026

Summary

Following #24689, it's now much more likely that a diagnostic regarding an invalid @final, for example, will not include the @final decorator in the code frame.

This was already a pre-existing issue, because there's nothing to stop a class from having multiple decorators, so @final was really only "accidentally" in the context window most of the time. E.g. for this class, @final would not have been in the context window even with our old context margin of 2:

from typing import final
from abc import abstractmethod
from dataclasses import dataclass
from functools import total_ordering

@final
@dataclass
@total_ordering
class Foo:
    @abstractmethod
    def __lt__(self, other): ...

Our diagnostic on the latest release of ty for that was:

image

But #24689 makes this problem much likelier to occur. This PR therefore adds secondary annotations to several diagnostics that ensure that relevant decorators are included in the diagnostic frames rendered to the user

Test plan

snapshots updated

@AlexWaygood AlexWaygood added ty Multi-file analysis & type inference diagnostics Related to reporting of diagnostics. labels Apr 17, 2026
@astral-sh-bot astral-sh-bot Bot requested a review from charliermarsh April 17, 2026 14:16
@carljm carljm removed their request for review April 17, 2026 14:19
@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot Bot commented Apr 17, 2026

Typing conformance results

No changes detected ✅

Current numbers
The percentage of diagnostics emitted that were expected errors held steady at 87.94%. The percentage of expected errors that received a diagnostic held steady at 83.36%. The number of fully passing files held steady at 79/133.

@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot Bot commented Apr 17, 2026

Memory usage report

Memory usage unchanged ✅

--> src/mdtest_snippet.py:5:5
|
5 | @abstractmethod
| ---------------
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Showing the @abstractmethod is great! But I wonder if the ---- without any trailing text is confusing. Should we say something like *method is abstract because of the abstractmethod decorator? Curious to hear if others feel the same.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I'm not sure. To me it feels pretty clear why we're highlighting it, given that the primary annotation already says that the issue is that method is an abstract classmethod? And the name of the decorator is pretty clear. Overloading the frame with too many labels also has a cost -- it makes it harder to spot the more important information in the diagnostic.

I feel like I've seen Clippy do similar things with secondary annotations in the past, too.

Here's what it looks like with a bit of colour:

Image

Copy link
Copy Markdown
Member

@MichaReiser MichaReiser Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example makes me wonder if it's now also necessary to underline raise NotImplementedError or the "trivial body" part isn't visible in the code frame.

Which makes me wonder if the code frame should spawn the entire method (which is generally bad?). You then only need one annotation and it's guaranteed that you see all relevant details.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a great point. Since we know this method has a trivial body in this situation, it's very unlikely that the method body will be huge. That makes a lot of sense

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you plan on changing this or did it turn out that it regresses the experience in some cases?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it in cad725c

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohh, that's different than what I had in mind. I would used the entire func_dev.range as the primary range.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, that might be better.

@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot Bot commented Apr 17, 2026

ecosystem-analyzer results

No diagnostic changes detected ✅

Flaky changes detected. This PR summary excludes flaky changes; see the HTML report for details.

Full report with detailed diff (timing results)

@codspeed-hq

This comment was marked as resolved.

@AlexWaygood

This comment was marked as resolved.

@AlexWaygood AlexWaygood force-pushed the alex/merge-annotations branch from 0dc2306 to 8c047d4 Compare April 17, 2026 15:43
@AlexWaygood AlexWaygood force-pushed the alex/deco-context branch 2 times, most recently from fef8da5 to 8512ce1 Compare April 17, 2026 15:50
Base automatically changed from alex/merge-annotations to main April 17, 2026 16:00
@AlexWaygood AlexWaygood marked this pull request as draft April 20, 2026 16:53
@AlexWaygood AlexWaygood marked this pull request as ready for review April 20, 2026 18:43
@AlexWaygood AlexWaygood requested a review from MichaReiser April 20, 2026 18:44
Comment thread crates/ty/tests/cli/rule_selection.rs Outdated
::: test.py:7:9
--> test.py:6:5
|
6 | @abstractmethod
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we make the same change here?

Copy link
Copy Markdown
Member Author

@AlexWaygood AlexWaygood Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, because here the stub body of the abstractmethod is irrelevant to the diagnostic. In this case, we would still emit the diagnostic if the function body was return 42 rather than raise NotImplementedError, and in this case we do not say anything about how the method has a stub body in the diagnostic message

--> src/mdtest_snippet.py:5:5
|
5 | @abstractmethod
| ---------------
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohh, that's different than what I had in mind. I would used the entire func_dev.range as the primary range.

@AlexWaygood AlexWaygood enabled auto-merge (squash) April 20, 2026 21:07
@AlexWaygood AlexWaygood merged commit be5736e into main Apr 20, 2026
55 checks passed
@AlexWaygood AlexWaygood deleted the alex/deco-context branch April 20, 2026 21:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

diagnostics Related to reporting of diagnostics. ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants