# Tests for rich comparisons
from test
import test_support
def __cmp__(self
, other
):
raise test_support
.TestFailed
, "Number.__cmp__() should not be called"
return "Number(%r)" % (self
.x
, )
def __init__(self
, data
):
def __getitem__(self
, i
):
def __setitem__(self
, i
, v
):
raise TypeError, "Vectors cannot be hashed"
raise TypeError, "Vectors cannot be used in Boolean contexts"
def __cmp__(self
, other
):
raise test_support
.TestFailed
, "Vector.__cmp__() should not be called"
return "Vector(%r)" % (self
.data
, )
return Vector([a
< b
for a
, b
in zip(self
.data
, self
.__cast
(other
))])
return Vector([a
<= b
for a
, b
in zip(self
.data
, self
.__cast
(other
))])
return Vector([a
== b
for a
, b
in zip(self
.data
, self
.__cast
(other
))])
return Vector([a
!= b
for a
, b
in zip(self
.data
, self
.__cast
(other
))])
return Vector([a
> b
for a
, b
in zip(self
.data
, self
.__cast
(other
))])
return Vector([a
>= b
for a
, b
in zip(self
.data
, self
.__cast
(other
))])
if isinstance(other
, Vector
):
if len(self
.data
) != len(other
):
raise ValueError, "Cannot compare vectors of different length"
"lt": (lambda a
,b
: a
< b
, operator
.lt
, operator
.__lt
__),
"le": (lambda a
,b
: a
<=b
, operator
.le
, operator
.__le
__),
"eq": (lambda a
,b
: a
==b
, operator
.eq
, operator
.__eq
__),
"ne": (lambda a
,b
: a
!=b
, operator
.ne
, operator
.__ne
__),
"gt": (lambda a
,b
: a
> b
, operator
.gt
, operator
.__gt
__),
"ge": (lambda a
,b
: a
>=b
, operator
.ge
, operator
.__ge
__)
class VectorTest(unittest
.TestCase
):
def checkfail(self
, error
, opname
, *args
):
self
.assertRaises(error
, op
, *args
)
def checkequal(self
, opname
, a
, b
, expres
):
# can't use assertEqual(realres, expres) here
self
.assertEqual(len(realres
), len(expres
))
for i
in xrange(len(realres
)):
# results are bool, so we can use "is" here
self
.assert_(realres
[i
] is expres
[i
])
# check that comparisons involving Vector objects
# which return rich results (i.e. Vectors with itemwise
# comparison results) work
# all comparisons should fail for different length
self
.checkfail(ValueError, opname
, a
, b
)
# try mixed arguments (but not (a, b) as that won't return a bool vector)
args
= [(a
, Vector(b
)), (Vector(a
), b
), (Vector(a
), Vector(b
))]
self
.checkequal("lt", a
, b
, [True, True, False, False, False])
self
.checkequal("le", a
, b
, [True, True, True, False, False])
self
.checkequal("eq", a
, b
, [False, False, True, False, False])
self
.checkequal("ne", a
, b
, [True, True, False, True, True ])
self
.checkequal("gt", a
, b
, [False, False, False, True, True ])
self
.checkequal("ge", a
, b
, [False, False, True, True, True ])
for ops
in opmap
.itervalues():
# calls __nonzero__, which should fail
self
.assertRaises(TypeError, bool, op(a
, b
))
class NumberTest(unittest
.TestCase
):
# Check that comparisons involving Number objects
# give the same results give as comparing the
for typea
in (int, Number
):
for typeb
in (int, Number
):
continue # the combination int, int is useless
for ops
in opmap
.itervalues():
self
.assertEqual(realoutcome
, testoutcome
)
def checkvalue(self
, opname
, a
, b
, expres
):
for typea
in (int, Number
):
for typeb
in (int, Number
):
realres
= getattr(realres
, "x", realres
)
self
.assert_(realres
is expres
)
# check all operators and all comparison results
self
.checkvalue("lt", 0, 0, False)
self
.checkvalue("le", 0, 0, True )
self
.checkvalue("eq", 0, 0, True )
self
.checkvalue("ne", 0, 0, False)
self
.checkvalue("gt", 0, 0, False)
self
.checkvalue("ge", 0, 0, True )
self
.checkvalue("lt", 0, 1, True )
self
.checkvalue("le", 0, 1, True )
self
.checkvalue("eq", 0, 1, False)
self
.checkvalue("ne", 0, 1, True )
self
.checkvalue("gt", 0, 1, False)
self
.checkvalue("ge", 0, 1, False)
self
.checkvalue("lt", 1, 0, False)
self
.checkvalue("le", 1, 0, False)
self
.checkvalue("eq", 1, 0, False)
self
.checkvalue("ne", 1, 0, True )
self
.checkvalue("gt", 1, 0, True )
self
.checkvalue("ge", 1, 0, True )
class MiscTest(unittest
.TestCase
):
def test_misbehavin(self
):
def __lt__(self
, other
): return 0
def __gt__(self
, other
): return 0
def __eq__(self
, other
): return 0
def __le__(self
, other
): raise TestFailed
, "This shouldn't happen"
def __ge__(self
, other
): raise TestFailed
, "This shouldn't happen"
def __ne__(self
, other
): raise TestFailed
, "This shouldn't happen"
def __cmp__(self
, other
): raise RuntimeError, "expected"
self
.assertEqual(a
==b
, 0)
self
.assertRaises(RuntimeError, cmp, a
, b
)
# Check that exceptions in __nonzero__ are properly
# propagated by the not operator
for func
in (do
, operator
.not_
):
self
.assertRaises(Exc
, func
, Bad())
def test_recursion(self
):
# Check that comparison for recursive objects fails gracefully
from UserList
import UserList
self
.assertRaises(RuntimeError, operator
.eq
, a
, b
)
self
.assertRaises(RuntimeError, operator
.ne
, a
, b
)
self
.assertRaises(RuntimeError, operator
.lt
, a
, b
)
self
.assertRaises(RuntimeError, operator
.le
, a
, b
)
self
.assertRaises(RuntimeError, operator
.gt
, a
, b
)
self
.assertRaises(RuntimeError, operator
.ge
, a
, b
)
# Even recursive lists of different lengths are different,
# but they cannot be ordered
self
.assert_(not (a
== b
))
self
.assertRaises(RuntimeError, operator
.lt
, a
, b
)
self
.assertRaises(RuntimeError, operator
.le
, a
, b
)
self
.assertRaises(RuntimeError, operator
.gt
, a
, b
)
self
.assertRaises(RuntimeError, operator
.ge
, a
, b
)
self
.assertRaises(RuntimeError, operator
.eq
, a
, b
)
self
.assertRaises(RuntimeError, operator
.ne
, a
, b
)
self
.assert_(not (a
== b
))
class DictTest(unittest
.TestCase
):
# Verify that __eq__ and __ne__ work for dicts even if the keys and
# values don't support anything other than __eq__ and __ne__. Complex
# numbers are a fine example of that.
imag1a
[random
.randrange(100)*1j
] = random
.randrange(100)*1j
self
.assert_(imag1a
== imag1a
)
self
.assert_(imag1a
== imag1b
)
self
.assert_(imag2
== imag2
)
self
.assert_(imag1a
!= imag2
)
for opname
in ("lt", "le", "gt", "ge"):
self
.assertRaises(TypeError, op
, imag1a
, imag2
)
class ListTest(unittest
.TestCase
):
def assertIs(self
, a
, b
):
# exercise all comparisons for lists
self
.assertIs(x
<x
, False)
self
.assertIs(x
<=x
, True)
self
.assertIs(x
==x
, True)
self
.assertIs(x
!=x
, False)
self
.assertIs(x
>x
, False)
self
.assertIs(x
>=x
, True)
self
.assertIs(x
<=y
, True)
self
.assertIs(x
==y
, False)
self
.assertIs(x
!=y
, True)
self
.assertIs(x
>y
, False)
self
.assertIs(x
>=y
, False)
# make sure that exceptions for item comparison are properly
# propagated in list comparisons
self
.assertRaises(Exc
, op
, x
, y
)
def test_goodentry(self
):
# This test exercises the final call to PyObject_RichCompare()
# in Objects/listobject.c::list_richcompare()
self
.assertIs(op(x
, y
), True)
test_support
.run_unittest(VectorTest
, NumberTest
, MiscTest
, DictTest
, ListTest
)
if __name__
== "__main__":