Skip to content

Commit 3eada01

Browse files
authored
put similar dunder-call tests next to each other (#18343)
Follow-up from post-land review on #18260
1 parent 3e811fc commit 3eada01

File tree

1 file changed

+36
-34
lines changed
  • crates/ty_python_semantic/resources/mdtest/call

1 file changed

+36
-34
lines changed

crates/ty_python_semantic/resources/mdtest/call/dunder.md

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ ClassWithNormalDunder[0]
5959

6060
## Operating on instances
6161

62+
### Attaching dunder methods to instances in methods
63+
6264
When invoking a dunder method on an instance of a class, it is looked up on the class:
6365

6466
```py
@@ -116,6 +118,40 @@ def _(flag: bool):
116118
reveal_type(this_fails[0]) # revealed: Unknown | str
117119
```
118120

121+
### Dunder methods as class-level annotations with no value
122+
123+
Class-level annotations with no value assigned are considered instance-only, and aren't available as
124+
dunder methods:
125+
126+
```py
127+
from typing import Callable
128+
129+
class C:
130+
__call__: Callable[..., None]
131+
132+
# error: [call-non-callable]
133+
C()()
134+
135+
# error: [invalid-assignment]
136+
_: Callable[..., None] = C()
137+
```
138+
139+
And of course the same is true if we have only an implicit assignment inside a method:
140+
141+
```py
142+
from typing import Callable
143+
144+
class C:
145+
def __init__(self):
146+
self.__call__ = lambda *a, **kw: None
147+
148+
# error: [call-non-callable]
149+
C()()
150+
151+
# error: [invalid-assignment]
152+
_: Callable[..., None] = C()
153+
```
154+
119155
## When the dunder is not a method
120156

121157
A dunder can also be a non-method callable:
@@ -239,37 +275,3 @@ def _(flag: bool):
239275
# error: [possibly-unbound-implicit-call]
240276
reveal_type(c[0]) # revealed: str
241277
```
242-
243-
## Dunder methods cannot be looked up on instances
244-
245-
Class-level annotations with no value assigned are considered instance-only, and aren't available as
246-
dunder methods:
247-
248-
```py
249-
from typing import Callable
250-
251-
class C:
252-
__call__: Callable[..., None]
253-
254-
# error: [call-non-callable]
255-
C()()
256-
257-
# error: [invalid-assignment]
258-
_: Callable[..., None] = C()
259-
```
260-
261-
And of course the same is true if we have only an implicit assignment inside a method:
262-
263-
```py
264-
from typing import Callable
265-
266-
class C:
267-
def __init__(self):
268-
self.__call__ = lambda *a, **kw: None
269-
270-
# error: [call-non-callable]
271-
C()()
272-
273-
# error: [invalid-assignment]
274-
_: Callable[..., None] = C()
275-
```

0 commit comments

Comments
 (0)