[ty] Infer type of implicit cls parameter in method bodies#21685
[ty] Infer type of implicit cls parameter in method bodies#21685
cls parameter in method bodies#21685Conversation
Diagnostic diff on typing conformance testsChanges were detected when running ty on typing conformance tests--- old-output.txt 2025-12-03 02:01:47.774206207 +0000
+++ new-output.txt 2025-12-03 02:01:51.357221036 +0000
@@ -513,15 +513,13 @@
generics_self_advanced.py:36:9: error[type-assertion-failure] Type `list[Self@method2]` does not match asserted type `list[typing.Self]`
generics_self_advanced.py:37:9: error[type-assertion-failure] Type `Self@method2` does not match asserted type `typing.Self`
generics_self_advanced.py:38:9: error[type-assertion-failure] Type `Self@method2` does not match asserted type `Unknown`
-generics_self_advanced.py:42:9: error[type-assertion-failure] Type `type[Self@method3]` does not match asserted type `Unknown`
-generics_self_advanced.py:43:9: error[type-assertion-failure] Type `list[Self@method3]` does not match asserted type `Unknown`
-generics_self_advanced.py:44:9: error[type-assertion-failure] Type `Self@method3` does not match asserted type `Unknown`
+generics_self_advanced.py:43:9: error[type-assertion-failure] Type `list[Self@method3]` does not match asserted type `list[typing.Self]`
+generics_self_advanced.py:44:9: error[type-assertion-failure] Type `Self@method3` does not match asserted type `typing.Self`
generics_self_advanced.py:45:9: error[type-assertion-failure] Type `Self@method3` does not match asserted type `Unknown`
generics_self_attributes.py:26:33: error[invalid-argument-type] Argument is incorrect: Expected `typing.Self | None`, found `LinkedList[int]`
generics_self_attributes.py:29:5: error[invalid-assignment] Object of type `OrdinalLinkedList` is not assignable to attribute `next` of type `typing.Self | None`
generics_self_attributes.py:32:5: error[invalid-assignment] Object of type `LinkedList[int]` is not assignable to attribute `next` of type `typing.Self | None`
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:27:9: error[type-assertion-failure] Type `type[Self@from_config]` does not match asserted type `Unknown`
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:54:1: error[type-assertion-failure] Type `Shape` does not match asserted type `Unknown`
generics_self_basic.py:55:1: error[type-assertion-failure] Type `Circle` does not match asserted type `Unknown`
@@ -1029,4 +1027,4 @@
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] Unknown key "title" for 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
-Found 1031 diagnostics
+Found 1029 diagnostics
|
|
CodSpeed Performance ReportMerging #21685 will degrade performances by 11.61%Comparing Summary
Benchmarks breakdown
|
|
| Lint rule | Added | Removed | Changed |
|---|---|---|---|
invalid-argument-type |
69 | 18 | 77 |
unresolved-attribute |
85 | 0 | 0 |
unused-ignore-comment |
0 | 80 | 0 |
possibly-missing-attribute |
48 | 0 | 0 |
invalid-return-type |
34 | 1 | 5 |
unknown-argument |
39 | 0 | 0 |
invalid-assignment |
38 | 0 | 0 |
missing-argument |
10 | 0 | 0 |
parameter-already-assigned |
8 | 0 | 0 |
no-matching-overload |
7 | 0 | 0 |
too-many-positional-arguments |
5 | 0 | 0 |
unsupported-operator |
5 | 0 | 0 |
not-iterable |
2 | 0 | 0 |
unsupported-base |
0 | 2 | 0 |
deprecated |
1 | 0 | 0 |
invalid-context-manager |
1 | 0 | 0 |
invalid-type-form |
1 | 0 | 0 |
| Total | 353 | 101 | 82 |
|
|
Here's a minimal repro of one of the new diagnostics on from typing import Callable, Any
def needs_a_callable(x: Callable[[Any], Any] | Callable[[Any, object], Any]): ...
class F:
def __init__(self, arg) -> None: ...
def f[T: F](x: T):
needs_a_callable(type(x))It looks like we might not be implementing assignability correctly for |
|
The artigraph diagnostic in |
|
The new attrs diagnostics are the same as astral-sh/ty#1425, but for attrs rather than pydantic this time. We don't recognise the assignments in the class body of |
|
comtypes looks like it's doing some highly dynamic stuff that I don't think we should be expected to understand right now. The new diagnostics in The new diagnostics in |
|
Here's a minimal repro for the diagnostic on from typing import Iterable, Iterator, Self
class chain[T]:
def __new__(cls, *its: Iterable[T]): ...
def __iter__(self) -> Self:
return self
def __next__(self) -> T:
raise NotImplementedError
class Symbol:
@classmethod
def g(cls) -> list[Symbol]:
return list(chain((cls(),), (cls(),))) # error here...
# error [invalid-argument-type] "Argument to bound method `__init__` is incorrect: Expected `Iterable[Symbol]`, found `chain[Self@from_code]`"
def f[T: Symbol](x: type[T]) -> list[Symbol]:
return list(chain((x(),), (x(),))) # ... but no error here? |
|
That last one may be an issue with how we treat class Symbol:
@classmethod
def f(cls) -> list[Symbol]:
y = chain((cls(),), (cls(),))
reveal_type(y) # chain[Self@g]
return list(y) # error[invalid-argument-type]
def g(self) -> list[Symbol]:
y = chain((self,), (self,))
reveal_type(y) # chain[Self@g]
return list(y) # error[invalid-argument-type]
def f[T: Symbol](x: type[T]) -> list[Symbol]:
y = chain((x(),), (x(),))
reveal_type(y) # chain[T@g]
return list(y) # ok
def g[T: Symbol](x: T) -> list[Symbol]:
y = chain((x,), (x,))
reveal_type(y) # chain[T@g]
return list(y) # ok |
## Summary Resolves astral-sh#21685 (comment).
2ff8549 to
b691fbc
Compare
carljm
left a comment
There was a problem hiding this comment.
This looks good to me. I filed astral-sh/ty#1831 for the assignability-to-union-of-callables issue, but I don't think it should block landing this PR, either.
Summary
Extends #20922 to infer unannotated
clsparameters astype[Self]in method bodies.Part of astral-sh/ty#159.