[ty] Use typing.Self for the first parameter of instance methods#20517
Merged
[ty] Use typing.Self for the first parameter of instance methods#20517
typing.Self for the first parameter of instance methods#20517Conversation
Contributor
Diagnostic diff on typing conformance testsChanges were detected when running ty on typing conformance tests--- old-output.txt 2025-09-29 18:52:45.668425107 +0000
+++ new-output.txt 2025-09-29 18:52:49.013452786 +0000
@@ -420,17 +420,12 @@
generics_self_basic.py:14:9: error[type-assertion-failure] Argument does not have asserted type `Self@set_scale`
generics_self_basic.py:20:16: error[invalid-return-type] Return type does not match returned value: expected `Self@method2`, found `Shape`
generics_self_basic.py:33:16: error[invalid-return-type] Return type does not match returned value: expected `Self@cls_method2`, found `Shape`
-generics_self_basic.py:51:1: error[type-assertion-failure] Argument does not have asserted type `Shape`
-generics_self_basic.py:52:1: error[type-assertion-failure] Argument does not have asserted type `Circle`
generics_self_basic.py:54:1: error[type-assertion-failure] Argument does not have asserted type `Shape`
generics_self_basic.py:55:1: error[type-assertion-failure] Argument does not have asserted type `Circle`
generics_self_basic.py:64:38: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `Self@set_value`
generics_self_basic.py:67:26: error[invalid-type-form] Special form `typing.Self` expected no type parameter
-generics_self_basic.py:74:5: error[type-assertion-failure] Argument does not have asserted type `Container[int]`
-generics_self_basic.py:75:5: error[type-assertion-failure] Argument does not have asserted type `Container[str]`
-generics_self_basic.py:83:5: error[type-assertion-failure] Argument does not have asserted type `Container[T@object_with_generic_type]`
-generics_self_protocols.py:48:5: error[type-assertion-failure] Argument does not have asserted type `ShapeProtocol`
generics_self_protocols.py:61:19: error[invalid-argument-type] Argument to function `accepts_shape` is incorrect: Expected `ShapeProtocol`, found `BadReturnType`
+generics_self_usage.py:50:5: error[invalid-assignment] Object of type `def foo(self) -> int` is not assignable to `(typing.Self, /) -> int`
generics_self_usage.py:73:14: error[invalid-type-form] Variable of type `typing.Self` is not allowed in a type expression
generics_self_usage.py:73:23: error[invalid-type-form] Variable of type `typing.Self` is not allowed in a type expression
generics_self_usage.py:76:6: error[invalid-type-form] Variable of type `typing.Self` is not allowed in a type expression
@@ -860,5 +855,5 @@
typeddicts_usage.py:28:17: error[missing-typed-dict-key] Missing required key 'name' in TypedDict `Movie` constructor
typeddicts_usage.py:28:18: error[invalid-key] Invalid key access on TypedDict `Movie`: Unknown key "title"
typeddicts_usage.py:40:24: error[invalid-type-form] The special form `typing.TypedDict` is not allowed in type expressions. Did you mean to use a concrete TypedDict or `collections.abc.Mapping[str, object]` instead?
-Found 861 diagnostics
+Found 856 diagnostics
WARN A fatal error occurred while checking some files. Not all project files were analyzed. See the diagnostics list above for details. |
CodSpeed WallTime Performance ReportMerging #20517 will degrade performances by 14.5%Comparing Summary
Benchmarks breakdown
|
CodSpeed Instrumentation Performance ReportMerging #20517 will degrade performances by 9.78%Comparing Summary
Benchmarks breakdown
|
This comment was marked as off-topic.
This comment was marked as off-topic.
Contributor
|
Glyphack
reviewed
Sep 22, 2025
Contributor
|
| Lint rule | Added | Removed | Changed |
|---|---|---|---|
type-assertion-failure |
15 | 567 | 0 |
invalid-argument-type |
546 | 0 | 14 |
unsupported-operator |
170 | 0 | 8 |
unresolved-attribute |
96 | 0 | 0 |
unused-ignore-comment |
0 | 71 | 0 |
possibly-missing-attribute |
58 | 0 | 12 |
invalid-assignment |
33 | 0 | 6 |
non-subscriptable |
32 | 0 | 0 |
invalid-return-type |
19 | 4 | 7 |
no-matching-overload |
30 | 0 | 0 |
not-iterable |
9 | 0 | 0 |
call-non-callable |
5 | 2 | 0 |
division-by-zero |
0 | 3 | 0 |
invalid-key |
2 | 0 | 0 |
possibly-missing-implicit-call |
0 | 0 | 2 |
too-many-positional-arguments |
2 | 0 | 0 |
invalid-context-manager |
1 | 0 | 0 |
invalid-type-form |
1 | 0 | 0 |
parameter-already-assigned |
1 | 0 | 0 |
redundant-cast |
1 | 0 | 0 |
unknown-argument |
1 | 0 | 0 |
| Total | 1,022 | 647 | 49 |
92e01d5 to
433ec04
Compare
sharkdp
commented
Sep 23, 2025
| reveal_type(x) # revealed: list[A | str] | ||
| for item in x: | ||
| reveal_type(item) # revealed: list[A | str] | str | ||
| reveal_type(item) # revealed: list[Any | str] | str |
Contributor
Author
There was a problem hiding this comment.
This regression is tracked in astral-sh/ty#1157
sharkdp
commented
Sep 23, 2025
771fef0 to
e54903f
Compare
1254b5f to
b494fef
Compare
b494fef to
1b44768
Compare
sharkdp
commented
Sep 24, 2025
sharkdp
commented
Sep 24, 2025
Comment on lines
+149
to
+150
| # TODO: this should be B | ||
| reveal_type(B().a_property) # revealed: Unknown |
Contributor
Author
There was a problem hiding this comment.
This should also be fixed. I have not looked into it yet. Maybe it can be deferred to a follow-up.
sharkdp
commented
Sep 24, 2025
sharkdp
commented
Sep 24, 2025
Part of astral-sh/ty#159 This PR only adjusts the signature of a method so if it has a `self` argument then that argument will have type of `Typing.Self` even if it's not specified. If user provides an explicit annotation then Ty will not override that annotation. - astral-sh/ty#1131 - astral-sh/ty#1157 - astral-sh/ty#1156 - astral-sh/ty#1173 - #20328 - astral-sh/ty#1163 - astral-sh/ty#1196 Added mdtests. Also some tests need #18473 to work completely. So I added a todo for those new cases that I added. --------- Co-authored-by: David Peter <[email protected]>
2b3aec1 to
3ce98ce
Compare
Contributor
Author
|
The performance regressions look severe, but I am going to merge this. We can always work on performance later, and it's probably also important to keep in mind that across the whole ecosystem, this is more of a 3% slowdown. |
dcreager
added a commit
that referenced
this pull request
Sep 30, 2025
* main: (21 commits) [ty] Literal promotion refactor (#20646) [ty] Add tests for nested generic functions (#20631) [`cli`] Add conflict between `--add-noqa` and `--diff` options (#20642) [ty] Ensure first-party search paths always appear in a sensible order (#20629) [ty] Use `typing.Self` for the first parameter of instance methods (#20517) [ty] Remove unnecessary `parsed_module()` calls (#20630) Remove `TextEmitter` (#20595) [ty] Use fully qualified names to distinguish ambiguous protocols in diagnostics (#20627) [ty] Ecosystem analyzer: relax timeout thresholds (#20626) [ty] Apply type mappings to functions eagerly (#20596) [ty] Improve disambiguation of class names in diagnostics (#20603) Add the *The Basics* title back to CONTRIBUTING.md (#20624) [`playground`] Fix quick fixes for empty ranges in playground (#20599) Update dependency ruff to v0.13.2 (#20622) [`ruff`] Fix minor typos in doc comments (#20623) Update dependency PyYAML to v6.0.3 (#20621) Update cargo-bins/cargo-binstall action to v1.15.6 (#20620) Fixed documentation for try_consider_else (#20587) [ty] Use `Top` materializations for `TypeIs` special form (#20591) [ty] Simplify `Any | (Any & T)` to `Any` (#20593) ...
ibraheemdev
added a commit
that referenced
this pull request
Dec 10, 2025
## Summary Extends #20517 to support the implicit type of `cls` in `@classmethod` signatures. Part of astral-sh/ty#159.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Modify the (external) signature of instance methods such that the first parameter uses
Selfunless it is explicitly annotated. This allows us to correctly type-check more code, and allows us to infer correct return types for many functions that returnSelf. For example:part of astral-sh/ty#159
Co-authored by: @Glyphack
Performance
I ran benchmarks locally on
attrs,freqtradeandcolour, the projects with the largest regressions on CodSpeed. I see much smaller effects locally, but can definitely reproduce the regression onattrs. From looking at the profiling results (on Codspeed), it seems that we simply do more type inference work, which seems plausible, given that we now understand much more return types (of many stdlib functions). In particular, whenever a function uses an implicitselfand returnsSelf(without mentioningSelfanywhere else in its signature), we will now infer the correct type, whereas we would previously returnUnknown. This also means that we need to invoke the generics solver in more cases. Comparing half a million lines of log output on attrs, I can see that we do 5% more "work" (number of lines in the log), and have a lot moreapply_specializationevents (7108 vs 4304). On freqtrade, I see similar numbers forapply_specialization(11360 vs 5138 calls). Given these results, I'm not sure if it's generally worth doing more performance work, especially since none of the code modifications themselves seem to be likely candidates for regressions../ty_main check /home/shark/ecosystem/attrs./ty_self check /home/shark/ecosystem/attrs./ty_main check /home/shark/ecosystem/freqtrade./ty_self check /home/shark/ecosystem/freqtrade./ty_main check /home/shark/ecosystem/colour./ty_self check /home/shark/ecosystem/colourTest Plan
New Markdown tests
Ecosystem report
@staticmethod?invalid-operatorfalse positives in matrix multiplication due to our limited understanding of genericCallable[[Callable[[T1, T2], T3]], Callable[[T1, T2], T3]]"identity" types of decorators. This is not related to type-of-self.Typing conformance results
The changes are all correct, except for
+generics_self_usage.py:50:5: error[invalid-assignment] Object of type `def foo(self) -> int` is not assignable to `(typing.Self, /) -> int`which is related to an assignability problem involving type variables on both sides: