circuitpython/tests/basics/special_comparisons.py
Nicko van Someren 3aab54bf43 py: Support non-boolean results for equality and inequality tests.
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.
2020-01-30 14:53:07 +11:00

34 lines
561 B
Python

class A:
def __eq__(self, other):
print("A __eq__ called")
return True
class B:
def __ne__(self, other):
print("B __ne__ called")
return True
class C:
def __eq__(self, other):
print("C __eq__ called")
return False
class D:
def __ne__(self, other):
print("D __ne__ called")
return False
a = A()
b = B()
c = C()
d = D()
def test(s):
print(s)
print(eval(s))
for x in 'abcd':
for y in 'abcd':
test('{} == {}'.format(x,y))
test('{} != {}'.format(x,y))