@@ -1145,40 +1145,78 @@ impl VirtualMachine {
1145
1145
} )
1146
1146
}
1147
1147
1148
+ // Perform a comparison, raising TypeError when the requested comparison
1149
+ // operator is not supported.
1150
+ // see: CPython PyObject_RichCompare
1151
+ fn _cmp < F > (
1152
+ & self ,
1153
+ v : PyObjectRef ,
1154
+ w : PyObjectRef ,
1155
+ op : & str ,
1156
+ swap_op : & str ,
1157
+ default : F ,
1158
+ ) -> PyResult
1159
+ where
1160
+ F : Fn ( & VirtualMachine , PyObjectRef , PyObjectRef ) -> PyResult ,
1161
+ {
1162
+ // TODO: _Py_EnterRecursiveCall(tstate, " in comparison")
1163
+
1164
+ let mut checked_reverse_op = false ;
1165
+ if !v. typ . is ( & w. typ ) && objtype:: issubclass ( & w. class ( ) , & v. class ( ) ) {
1166
+ if let Some ( method_or_err) = self . get_method ( w. clone ( ) , swap_op) {
1167
+ let method = method_or_err?;
1168
+ checked_reverse_op = true ;
1169
+
1170
+ let result = self . invoke ( & method, vec ! [ v. clone( ) ] ) ?;
1171
+ if !result. is ( & self . ctx . not_implemented ( ) ) {
1172
+ return Ok ( result) ;
1173
+ }
1174
+ }
1175
+ }
1176
+
1177
+ self . call_or_unsupported ( v, w, op, |vm, v, w| {
1178
+ if !checked_reverse_op {
1179
+ self . call_or_unsupported ( w, v, swap_op, |vm, v, w| default ( vm, v, w) )
1180
+ } else {
1181
+ default ( vm, v, w)
1182
+ }
1183
+ } )
1184
+
1185
+ // TODO: _Py_LeaveRecursiveCall(tstate);
1186
+ }
1187
+
1148
1188
pub fn _eq ( & self , a : PyObjectRef , b : PyObjectRef ) -> PyResult {
1149
- self . call_or_reflection (
1150
- a,
1151
- b,
1152
- "__eq__" ,
1153
- "__eq__" ,
1154
- |vm, _a, _b| Ok ( vm. new_bool ( false ) ) ,
1155
- )
1189
+ self . _cmp ( a, b, "__eq__" , "__eq__" , |vm, a, b| {
1190
+ Ok ( vm. new_bool ( a. is ( & b) ) )
1191
+ } )
1156
1192
}
1157
1193
1158
1194
pub fn _ne ( & self , a : PyObjectRef , b : PyObjectRef ) -> PyResult {
1159
- self . call_or_reflection ( a, b, "__ne__" , "__ne__" , |vm, _a, _b| Ok ( vm. new_bool ( true ) ) )
1195
+ self . _cmp ( a, b, "__ne__" , "__ne__" , |vm, a, b| {
1196
+ Ok ( vm. new_bool ( !a. is ( & b) ) )
1197
+ } )
1160
1198
}
1161
1199
1162
1200
pub fn _lt ( & self , a : PyObjectRef , b : PyObjectRef ) -> PyResult {
1163
- self . call_or_reflection ( a, b, "__lt__" , "__gt__" , |vm, a, b| {
1201
+ self . _cmp ( a, b, "__lt__" , "__gt__" , |vm, a, b| {
1164
1202
Err ( vm. new_unsupported_operand_error ( a, b, "<" ) )
1165
1203
} )
1166
1204
}
1167
1205
1168
1206
pub fn _le ( & self , a : PyObjectRef , b : PyObjectRef ) -> PyResult {
1169
- self . call_or_reflection ( a, b, "__le__" , "__ge__" , |vm, a, b| {
1207
+ self . _cmp ( a, b, "__le__" , "__ge__" , |vm, a, b| {
1170
1208
Err ( vm. new_unsupported_operand_error ( a, b, "<=" ) )
1171
1209
} )
1172
1210
}
1173
1211
1174
1212
pub fn _gt ( & self , a : PyObjectRef , b : PyObjectRef ) -> PyResult {
1175
- self . call_or_reflection ( a, b, "__gt__" , "__lt__" , |vm, a, b| {
1213
+ self . _cmp ( a, b, "__gt__" , "__lt__" , |vm, a, b| {
1176
1214
Err ( vm. new_unsupported_operand_error ( a, b, ">" ) )
1177
1215
} )
1178
1216
}
1179
1217
1180
1218
pub fn _ge ( & self , a : PyObjectRef , b : PyObjectRef ) -> PyResult {
1181
- self . call_or_reflection ( a, b, "__ge__" , "__le__" , |vm, a, b| {
1219
+ self . _cmp ( a, b, "__ge__" , "__le__" , |vm, a, b| {
1182
1220
Err ( vm. new_unsupported_operand_error ( a, b, ">=" ) )
1183
1221
} )
1184
1222
}
0 commit comments