@@ -53,10 +53,8 @@ class A:
53
53
def __or__ (self , other ) -> A:
54
54
return self
55
55
56
-
57
56
class B : ...
58
57
59
-
60
58
reveal_type(A() + B()) # revealed: A
61
59
reveal_type(A() - B()) # revealed: A
62
60
reveal_type(A() * B()) # revealed: A
@@ -117,10 +115,8 @@ class A:
117
115
def __ror__ (self , other ) -> A:
118
116
return self
119
117
120
-
121
118
class B : ...
122
119
123
-
124
120
reveal_type(B() + A()) # revealed: A
125
121
reveal_type(B() - A()) # revealed: A
126
122
reveal_type(B() * A()) # revealed: A
@@ -148,10 +144,8 @@ class A:
148
144
def __rsub__ (self , other ) -> int :
149
145
return 1
150
146
151
-
152
147
class B : ...
153
148
154
-
155
149
reveal_type(A() + B()) # revealed: int
156
150
reveal_type(B() - A()) # revealed: int
157
151
```
@@ -167,15 +161,12 @@ class A:
167
161
def __add__ (self , other : B) -> int :
168
162
return 42
169
163
170
-
171
164
class B :
172
165
def __radd__ (self , other : A) -> str :
173
166
return " foo"
174
167
175
-
176
168
reveal_type(A() + B()) # revealed: int
177
169
178
-
179
170
# Edge case: C is a subtype of C, *but* if the two sides are of *equal* types,
180
171
# the lhs *still* takes precedence
181
172
class C :
@@ -185,7 +176,6 @@ class C:
185
176
def __radd__ (self , other : C) -> str :
186
177
return " foo"
187
178
188
-
189
179
reveal_type(C() + C()) # revealed: int
190
180
```
191
181
@@ -203,22 +193,17 @@ class A:
203
193
def __radd__ (self , other ) -> str :
204
194
return " foo"
205
195
206
-
207
196
class MyString (str ): ...
208
197
209
-
210
198
class B (A ):
211
199
def __radd__ (self , other ) -> MyString:
212
200
return MyString()
213
201
214
-
215
202
reveal_type(A() + B()) # revealed: MyString
216
203
217
-
218
204
# N.B. Still a subtype of `A`, even though `A` does not appear directly in the class's `__bases__`
219
205
class C (B ): ...
220
206
221
-
222
207
# TODO : we currently only understand direct subclasses as subtypes of the superclass.
223
208
# We need to iterate through the full MRO rather than just the class's bases;
224
209
# if we do, we'll understand `C` as a subtype of `A`, and correctly understand this as being
@@ -240,10 +225,8 @@ class A:
240
225
def __radd__ (self , other ) -> int :
241
226
return 42
242
227
243
-
244
228
class B (A ): ...
245
229
246
-
247
230
reveal_type(A() + B()) # revealed: str
248
231
```
249
232
@@ -266,12 +249,10 @@ class A:
266
249
def __sub__ (self , other : A) -> A:
267
250
return A()
268
251
269
-
270
252
class B :
271
253
def __rsub__ (self , other : A) -> B:
272
254
return B()
273
255
274
-
275
256
# TODO : this should be `B` (the return annotation of `B.__rsub__`),
276
257
# because `A.__sub__` is annotated as only accepting `A`,
277
258
# but `B.__rsub__` will accept `A`.
@@ -287,11 +268,9 @@ class A:
287
268
def __call__ (self , other ) -> int :
288
269
return 42
289
270
290
-
291
271
class B :
292
272
__add__ = A()
293
273
294
-
295
274
reveal_type(B() + B()) # revealed: int
296
275
```
297
276
@@ -311,15 +290,12 @@ reveal_type(42 + 4.2) # revealed: int
311
290
# TODO should be complex, need to check arg type and fall back to `rhs.__radd__`
312
291
reveal_type(3 + 3j ) # revealed: int
313
292
314
-
315
293
def returns_int () -> int :
316
294
return 42
317
295
318
-
319
296
def returns_bool () -> bool :
320
297
return True
321
298
322
-
323
299
x = returns_bool()
324
300
y = returns_int()
325
301
@@ -343,7 +319,6 @@ class A:
343
319
def __radd__ (self , other ) -> A:
344
320
return self
345
321
346
-
347
322
reveal_type(A() + 1 ) # revealed: A
348
323
# TODO should be `A` since `int.__add__` doesn't support `A` instances
349
324
reveal_type(1 + A()) # revealed: int
@@ -388,15 +363,12 @@ from does_not_exist import Foo # error: [unresolved-import]
388
363
389
364
reveal_type(Foo) # revealed: Unknown
390
365
391
-
392
366
class X :
393
367
def __add__ (self , other : object ) -> int :
394
368
return 42
395
369
396
-
397
370
class Y (Foo ): ...
398
371
399
-
400
372
# TODO : Should be `int | Unknown`; see above discussion.
401
373
reveal_type(X() + Y()) # revealed: int
402
374
```
@@ -411,12 +383,10 @@ The magic method must exist on the class, not just on the instance:
411
383
def add_impl (self , other ) -> int :
412
384
return 1
413
385
414
-
415
386
class A :
416
387
def __init__ (self ):
417
388
self .__add__ = add_impl
418
389
419
-
420
390
# error: [unsupported-operator] "Operator `+` is unsupported between objects of type `A` and `A`"
421
391
# revealed: Unknown
422
392
reveal_type(A() + A())
@@ -427,7 +397,6 @@ reveal_type(A() + A())
427
397
``` py
428
398
class A : ...
429
399
430
-
431
400
# error: [unsupported-operator]
432
401
# revealed: Unknown
433
402
reveal_type(A() + A())
@@ -441,14 +410,11 @@ A left-hand dunder method doesn't apply for the right-hand operand, or vice vers
441
410
class A :
442
411
def __add__ (self , other ) -> int : ...
443
412
444
-
445
413
class B :
446
414
def __radd__ (self , other ) -> int : ...
447
415
448
-
449
416
class C : ...
450
417
451
-
452
418
# error: [unsupported-operator]
453
419
# revealed: Unknown
454
420
reveal_type(C() + A())
@@ -471,7 +437,6 @@ class Foo:
471
437
def __radd__ (self , other : Foo) -> Foo:
472
438
return self
473
439
474
-
475
440
# error: [unsupported-operator]
476
441
# revealed: Unknown
477
442
reveal_type(Foo() + Foo())
0 commit comments