@@ -16,31 +16,38 @@ most common case involves implementing these methods for the same type:
16
16
``` py
17
17
from __future__ import annotations
18
18
19
+ class EqReturnType : ...
20
+ class NeReturnType : ...
21
+ class LtReturnType : ...
22
+ class LeReturnType : ...
23
+ class GtReturnType : ...
24
+ class GeReturnType : ...
25
+
19
26
class A :
20
- def __eq__ (self , other : A) -> int :
21
- return 42
27
+ def __eq__ (self , other : A) -> EqReturnType :
28
+ return EqReturnType()
22
29
23
- def __ne__ (self , other : A) -> bytearray :
24
- return bytearray ()
30
+ def __ne__ (self , other : A) -> NeReturnType :
31
+ return NeReturnType ()
25
32
26
- def __lt__ (self , other : A) -> str :
27
- return " 42 "
33
+ def __lt__ (self , other : A) -> LtReturnType :
34
+ return LtReturnType()
28
35
29
- def __le__ (self , other : A) -> bytes :
30
- return b " 42 "
36
+ def __le__ (self , other : A) -> LeReturnType :
37
+ return LeReturnType()
31
38
32
- def __gt__ (self , other : A) -> list :
33
- return [ 42 ]
39
+ def __gt__ (self , other : A) -> GtReturnType :
40
+ return GtReturnType()
34
41
35
- def __ge__ (self , other : A) -> set :
36
- return { 42 }
42
+ def __ge__ (self , other : A) -> GeReturnType :
43
+ return GeReturnType()
37
44
38
- reveal_type(A() == A()) # revealed: int
39
- reveal_type(A() != A()) # revealed: bytearray
40
- reveal_type(A() < A()) # revealed: str
41
- reveal_type(A() <= A()) # revealed: bytes
42
- reveal_type(A() > A()) # revealed: list
43
- reveal_type(A() >= A()) # revealed: set
45
+ reveal_type(A() == A()) # revealed: EqReturnType
46
+ reveal_type(A() != A()) # revealed: NeReturnType
47
+ reveal_type(A() < A()) # revealed: LtReturnType
48
+ reveal_type(A() <= A()) # revealed: LeReturnType
49
+ reveal_type(A() > A()) # revealed: GtReturnType
50
+ reveal_type(A() >= A()) # revealed: GeReturnType
44
51
```
45
52
46
53
## Rich Comparison Dunder Implementations for Other Class
@@ -51,33 +58,40 @@ type:
51
58
``` py
52
59
from __future__ import annotations
53
60
61
+ class EqReturnType : ...
62
+ class NeReturnType : ...
63
+ class LtReturnType : ...
64
+ class LeReturnType : ...
65
+ class GtReturnType : ...
66
+ class GeReturnType : ...
67
+
54
68
class A :
55
- def __eq__ (self , other : B) -> int :
56
- return 42
69
+ def __eq__ (self , other : B) -> EqReturnType :
70
+ return EqReturnType()
57
71
58
- def __ne__ (self , other : B) -> bytearray :
59
- return bytearray ()
72
+ def __ne__ (self , other : B) -> NeReturnType :
73
+ return NeReturnType ()
60
74
61
- def __lt__ (self , other : B) -> str :
62
- return " 42 "
75
+ def __lt__ (self , other : B) -> LtReturnType :
76
+ return LtReturnType()
63
77
64
- def __le__ (self , other : B) -> bytes :
65
- return b " 42 "
78
+ def __le__ (self , other : B) -> LeReturnType :
79
+ return LeReturnType()
66
80
67
- def __gt__ (self , other : B) -> list :
68
- return [ 42 ]
81
+ def __gt__ (self , other : B) -> GtReturnType :
82
+ return GtReturnType()
69
83
70
- def __ge__ (self , other : B) -> set :
71
- return { 42 }
84
+ def __ge__ (self , other : B) -> GeReturnType :
85
+ return GeReturnType()
72
86
73
87
class B : ...
74
88
75
- reveal_type(A() == B()) # revealed: int
76
- reveal_type(A() != B()) # revealed: bytearray
77
- reveal_type(A() < B()) # revealed: str
78
- reveal_type(A() <= B()) # revealed: bytes
79
- reveal_type(A() > B()) # revealed: list
80
- reveal_type(A() >= B()) # revealed: set
89
+ reveal_type(A() == B()) # revealed: EqReturnType
90
+ reveal_type(A() != B()) # revealed: NeReturnType
91
+ reveal_type(A() < B()) # revealed: LtReturnType
92
+ reveal_type(A() <= B()) # revealed: LeReturnType
93
+ reveal_type(A() > B()) # revealed: GtReturnType
94
+ reveal_type(A() >= B()) # revealed: GeReturnType
81
95
```
82
96
83
97
## Reflected Comparisons
@@ -89,55 +103,64 @@ these methods will be ignored here because they require a mismatched operand typ
89
103
``` py
90
104
from __future__ import annotations
91
105
106
+ class EqReturnType : ...
107
+ class NeReturnType : ...
108
+ class LtReturnType : ...
109
+ class LeReturnType : ...
110
+ class GtReturnType : ...
111
+ class GeReturnType : ...
112
+
92
113
class A :
93
- def __eq__ (self , other : B) -> int :
94
- return 42
114
+ def __eq__ (self , other : B) -> EqReturnType:
115
+ return EqReturnType()
116
+
117
+ def __ne__ (self , other : B) -> NeReturnType:
118
+ return NeReturnType()
95
119
96
- def __ne__ (self , other : B) -> bytearray :
97
- return bytearray ()
120
+ def __lt__ (self , other : B) -> LtReturnType :
121
+ return LtReturnType ()
98
122
99
- def __lt__ (self , other : B) -> str :
100
- return " 42 "
123
+ def __le__ (self , other : B) -> LeReturnType :
124
+ return LeReturnType()
101
125
102
- def __le__ (self , other : B) -> bytes :
103
- return b " 42 "
126
+ def __gt__ (self , other : B) -> GtReturnType :
127
+ return GtReturnType()
104
128
105
- def __gt__ (self , other : B) -> list :
106
- return [ 42 ]
129
+ def __ge__ (self , other : B) -> GeReturnType :
130
+ return GeReturnType()
107
131
108
- def __ge__ (self , other : B) -> set :
109
- return {42 }
132
+ class Unrelated : ...
110
133
111
134
class B :
112
135
# To override builtins.object.__eq__ and builtins.object.__ne__
113
136
# TODO these should emit an invalid override diagnostic
114
- def __eq__ (self , other : str ) -> B:
137
+ def __eq__ (self , other : Unrelated ) -> B:
115
138
return B()
116
139
117
- def __ne__ (self , other : str ) -> B:
140
+ def __ne__ (self , other : Unrelated ) -> B:
118
141
return B()
119
142
120
143
# Because `object.__eq__` and `object.__ne__` accept `object` in typeshed,
121
144
# this can only happen with an invalid override of these methods,
122
145
# but we still support it.
123
- reveal_type(B() == A()) # revealed: int
124
- reveal_type(B() != A()) # revealed: bytearray
146
+ reveal_type(B() == A()) # revealed: EqReturnType
147
+ reveal_type(B() != A()) # revealed: NeReturnType
125
148
126
- reveal_type(B() < A()) # revealed: list
127
- reveal_type(B() <= A()) # revealed: set
149
+ reveal_type(B() < A()) # revealed: GtReturnType
150
+ reveal_type(B() <= A()) # revealed: GeReturnType
128
151
129
- reveal_type(B() > A()) # revealed: str
130
- reveal_type(B() >= A()) # revealed: bytes
152
+ reveal_type(B() > A()) # revealed: LtReturnType
153
+ reveal_type(B() >= A()) # revealed: LeReturnType
131
154
132
155
class C :
133
- def __gt__ (self , other : C) -> int :
156
+ def __gt__ (self , other : C) -> EqReturnType :
134
157
return 42
135
158
136
- def __ge__ (self , other : C) -> bytearray :
137
- return bytearray ()
159
+ def __ge__ (self , other : C) -> NeReturnType :
160
+ return NeReturnType ()
138
161
139
- reveal_type(C() < C()) # revealed: int
140
- reveal_type(C() <= C()) # revealed: bytearray
162
+ reveal_type(C() < C()) # revealed: EqReturnType
163
+ reveal_type(C() <= C()) # revealed: NeReturnType
141
164
```
142
165
143
166
## Reflected Comparisons with Subclasses
@@ -149,6 +172,13 @@ than `A`.
149
172
``` py
150
173
from __future__ import annotations
151
174
175
+ class EqReturnType : ...
176
+ class NeReturnType : ...
177
+ class LtReturnType : ...
178
+ class LeReturnType : ...
179
+ class GtReturnType : ...
180
+ class GeReturnType : ...
181
+
152
182
class A :
153
183
def __eq__ (self , other : A) -> A:
154
184
return A()
@@ -169,32 +199,32 @@ class A:
169
199
return A()
170
200
171
201
class B (A ):
172
- def __eq__ (self , other : A) -> int :
173
- return 42
202
+ def __eq__ (self , other : A) -> EqReturnType :
203
+ return EqReturnType()
174
204
175
- def __ne__ (self , other : A) -> bytearray :
176
- return bytearray ()
205
+ def __ne__ (self , other : A) -> NeReturnType :
206
+ return NeReturnType ()
177
207
178
- def __lt__ (self , other : A) -> str :
179
- return " 42 "
208
+ def __lt__ (self , other : A) -> LtReturnType :
209
+ return LtReturnType()
180
210
181
- def __le__ (self , other : A) -> bytes :
182
- return b " 42 "
211
+ def __le__ (self , other : A) -> LeReturnType :
212
+ return LeReturnType()
183
213
184
- def __gt__ (self , other : A) -> list :
185
- return [ 42 ]
214
+ def __gt__ (self , other : A) -> GtReturnType :
215
+ return GtReturnType()
186
216
187
- def __ge__ (self , other : A) -> set :
188
- return { 42 }
217
+ def __ge__ (self , other : A) -> GeReturnType :
218
+ return GeReturnType()
189
219
190
- reveal_type(A() == B()) # revealed: int
191
- reveal_type(A() != B()) # revealed: bytearray
220
+ reveal_type(A() == B()) # revealed: EqReturnType
221
+ reveal_type(A() != B()) # revealed: NeReturnType
192
222
193
- reveal_type(A() < B()) # revealed: list
194
- reveal_type(A() <= B()) # revealed: set
223
+ reveal_type(A() < B()) # revealed: GtReturnType
224
+ reveal_type(A() <= B()) # revealed: GeReturnType
195
225
196
- reveal_type(A() > B()) # revealed: str
197
- reveal_type(A() >= B()) # revealed: bytes
226
+ reveal_type(A() > B()) # revealed: LtReturnType
227
+ reveal_type(A() >= B()) # revealed: LeReturnType
198
228
```
199
229
200
230
## Reflected Comparisons with Subclass But Falls Back to LHS
0 commit comments