3aab54bf43
This commit implements a more complete replication of CPython's behaviour for equality and inequality testing of objects. This addresses the issues discussed in #5382 and a few other inconsistencies. Improvements over the old code include: - Support for returning non-boolean results from comparisons (as used by numpy and others). - Support for non-reflexive equality tests. - Preferential use of __ne__ methods and MP_BINARY_OP_NOT_EQUAL binary operators for inequality tests, when available. - Fallback to op2 == op1 or op2 != op1 when op1 does not implement the (in)equality operators. The scheme here makes use of a new flag, MP_TYPE_FLAG_NEEDS_FULL_EQ_TEST, in the flags word of mp_obj_type_t to indicate if various shortcuts can or cannot be used when performing equality and inequality tests. Currently four built-in classes have the flag set: float and complex are non-reflexive (since nan != nan) while bytearray and frozenszet instances can equal other builtin class instances (bytes and set respectively). The flag is also set for any new class defined by the user. This commit also includes a more comprehensive set of tests for the behaviour of (in)equality operators implemented in special methods.
32 lines
552 B
Python
32 lines
552 B
Python
class E:
|
|
def __repr__(self):
|
|
return "E"
|
|
|
|
def __eq__(self, other):
|
|
print('E eq', other)
|
|
return 123
|
|
|
|
class F:
|
|
def __repr__(self):
|
|
return "F"
|
|
|
|
def __ne__(self, other):
|
|
print('F ne', other)
|
|
return -456
|
|
|
|
print(E() != F())
|
|
print(F() != E())
|
|
|
|
tests = (None, 0, 1, 'a')
|
|
|
|
for val in tests:
|
|
print('==== testing', val)
|
|
print(E() == val)
|
|
print(val == E())
|
|
print(E() != val)
|
|
print(val != E())
|
|
print(F() == val)
|
|
print(val == F())
|
|
print(F() != val)
|
|
print(val != F())
|