diff --git a/crates/ty_python_semantic/resources/mdtest/call/dunder.md b/crates/ty_python_semantic/resources/mdtest/call/dunder.md index 8c2a70a2c4..15cf01b7a1 100644 --- a/crates/ty_python_semantic/resources/mdtest/call/dunder.md +++ b/crates/ty_python_semantic/resources/mdtest/call/dunder.md @@ -59,6 +59,8 @@ ClassWithNormalDunder[0] ## Operating on instances +### Attaching dunder methods to instances in methods + When invoking a dunder method on an instance of a class, it is looked up on the class: ```py @@ -116,6 +118,40 @@ def _(flag: bool): reveal_type(this_fails[0]) # revealed: Unknown | str ``` +### Dunder methods as class-level annotations with no value + +Class-level annotations with no value assigned are considered instance-only, and aren't available as +dunder methods: + +```py +from typing import Callable + +class C: + __call__: Callable[..., None] + +# error: [call-non-callable] +C()() + +# error: [invalid-assignment] +_: Callable[..., None] = C() +``` + +And of course the same is true if we have only an implicit assignment inside a method: + +```py +from typing import Callable + +class C: + def __init__(self): + self.__call__ = lambda *a, **kw: None + +# error: [call-non-callable] +C()() + +# error: [invalid-assignment] +_: Callable[..., None] = C() +``` + ## When the dunder is not a method A dunder can also be a non-method callable: @@ -239,37 +275,3 @@ def _(flag: bool): # error: [possibly-unbound-implicit-call] reveal_type(c[0]) # revealed: str ``` - -## Dunder methods cannot be looked up on instances - -Class-level annotations with no value assigned are considered instance-only, and aren't available as -dunder methods: - -```py -from typing import Callable - -class C: - __call__: Callable[..., None] - -# error: [call-non-callable] -C()() - -# error: [invalid-assignment] -_: Callable[..., None] = C() -``` - -And of course the same is true if we have only an implicit assignment inside a method: - -```py -from typing import Callable - -class C: - def __init__(self): - self.__call__ = lambda *a, **kw: None - -# error: [call-non-callable] -C()() - -# error: [invalid-assignment] -_: Callable[..., None] = C() -```