14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Tests for rich comparisons
24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport unittest
44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom test import test_support
54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport operator
74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass Number:
94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __init__(self, x):
114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.x = x
124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __lt__(self, other):
144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.x < other
154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __le__(self, other):
174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.x <= other
184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __eq__(self, other):
204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.x == other
214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __ne__(self, other):
234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.x != other
244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __gt__(self, other):
264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.x > other
274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __ge__(self, other):
294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.x >= other
304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __cmp__(self, other):
324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        raise test_support.TestFailed, "Number.__cmp__() should not be called"
334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __repr__(self):
354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return "Number(%r)" % (self.x, )
364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass Vector:
384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __init__(self, data):
404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.data = data
414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __len__(self):
434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return len(self.data)
444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __getitem__(self, i):
464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.data[i]
474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __setitem__(self, i, v):
494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.data[i] = v
504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    __hash__ = None # Vectors cannot be hashed
524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __nonzero__(self):
544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        raise TypeError, "Vectors cannot be used in Boolean contexts"
554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __cmp__(self, other):
574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        raise test_support.TestFailed, "Vector.__cmp__() should not be called"
584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __repr__(self):
604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return "Vector(%r)" % (self.data, )
614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __lt__(self, other):
634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return Vector([a < b for a, b in zip(self.data, self.__cast(other))])
644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __le__(self, other):
664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return Vector([a <= b for a, b in zip(self.data, self.__cast(other))])
674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __eq__(self, other):
694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return Vector([a == b for a, b in zip(self.data, self.__cast(other))])
704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __ne__(self, other):
724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return Vector([a != b for a, b in zip(self.data, self.__cast(other))])
734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __gt__(self, other):
754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return Vector([a > b for a, b in zip(self.data, self.__cast(other))])
764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __ge__(self, other):
784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return Vector([a >= b for a, b in zip(self.data, self.__cast(other))])
794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __cast(self, other):
814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if isinstance(other, Vector):
824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            other = other.data
834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if len(self.data) != len(other):
844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            raise ValueError, "Cannot compare vectors of different length"
854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return other
864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmopmap = {
884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    "lt": (lambda a,b: a< b, operator.lt, operator.__lt__),
894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    "le": (lambda a,b: a<=b, operator.le, operator.__le__),
904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    "eq": (lambda a,b: a==b, operator.eq, operator.__eq__),
914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    "ne": (lambda a,b: a!=b, operator.ne, operator.__ne__),
924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    "gt": (lambda a,b: a> b, operator.gt, operator.__gt__),
934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    "ge": (lambda a,b: a>=b, operator.ge, operator.__ge__)
944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass VectorTest(unittest.TestCase):
974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def checkfail(self, error, opname, *args):
994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for op in opmap[opname]:
1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertRaises(error, op, *args)
1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def checkequal(self, opname, a, b, expres):
1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for op in opmap[opname]:
1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            realres = op(a, b)
1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # can't use assertEqual(realres, expres) here
1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertEqual(len(realres), len(expres))
1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            for i in xrange(len(realres)):
1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # results are bool, so we can use "is" here
1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.assertTrue(realres[i] is expres[i])
1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_mixed(self):
1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # check that comparisons involving Vector objects
1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # which return rich results (i.e. Vectors with itemwise
1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # comparison results) work
1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        a = Vector(range(2))
1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        b = Vector(range(3))
1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # all comparisons should fail for different length
1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for opname in opmap:
1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.checkfail(ValueError, opname, a, b)
1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        a = range(5)
1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        b = 5 * [2]
1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # try mixed arguments (but not (a, b) as that won't return a bool vector)
1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        args = [(a, Vector(b)), (Vector(a), b), (Vector(a), Vector(b))]
1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for (a, b) in args:
1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.checkequal("lt", a, b, [True,  True,  False, False, False])
1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.checkequal("le", a, b, [True,  True,  True,  False, False])
1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.checkequal("eq", a, b, [False, False, True,  False, False])
1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.checkequal("ne", a, b, [True,  True,  False, True,  True ])
1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.checkequal("gt", a, b, [False, False, False, True,  True ])
1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.checkequal("ge", a, b, [False, False, True,  True,  True ])
1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            for ops in opmap.itervalues():
1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                for op in ops:
1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    # calls __nonzero__, which should fail
1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.assertRaises(TypeError, bool, op(a, b))
1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass NumberTest(unittest.TestCase):
1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_basic(self):
1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Check that comparisons involving Number objects
1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # give the same results give as comparing the
1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # corresponding ints
1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for a in xrange(3):
1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            for b in xrange(3):
1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                for typea in (int, Number):
1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    for typeb in (int, Number):
1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        if typea==typeb==int:
1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            continue # the combination int, int is useless
1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        ta = typea(a)
1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        tb = typeb(b)
1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        for ops in opmap.itervalues():
1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            for op in ops:
1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                realoutcome = op(a, b)
1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                testoutcome = op(ta, tb)
1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                self.assertEqual(realoutcome, testoutcome)
1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def checkvalue(self, opname, a, b, expres):
1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for typea in (int, Number):
1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            for typeb in (int, Number):
1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                ta = typea(a)
1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                tb = typeb(b)
1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                for op in opmap[opname]:
1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    realres = op(ta, tb)
1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    realres = getattr(realres, "x", realres)
1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.assertTrue(realres is expres)
1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_values(self):
1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # check all operators and all comparison results
1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.checkvalue("lt", 0, 0, False)
1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.checkvalue("le", 0, 0, True )
1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.checkvalue("eq", 0, 0, True )
1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.checkvalue("ne", 0, 0, False)
1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.checkvalue("gt", 0, 0, False)
1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.checkvalue("ge", 0, 0, True )
1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.checkvalue("lt", 0, 1, True )
1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.checkvalue("le", 0, 1, True )
1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.checkvalue("eq", 0, 1, False)
1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.checkvalue("ne", 0, 1, True )
1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.checkvalue("gt", 0, 1, False)
1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.checkvalue("ge", 0, 1, False)
1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.checkvalue("lt", 1, 0, False)
1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.checkvalue("le", 1, 0, False)
1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.checkvalue("eq", 1, 0, False)
1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.checkvalue("ne", 1, 0, True )
1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.checkvalue("gt", 1, 0, True )
1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.checkvalue("ge", 1, 0, True )
1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass MiscTest(unittest.TestCase):
1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_misbehavin(self):
1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        class Misb:
1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __lt__(self_, other): return 0
1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __gt__(self_, other): return 0
1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __eq__(self_, other): return 0
1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __le__(self_, other): self.fail("This shouldn't happen")
1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __ge__(self_, other): self.fail("This shouldn't happen")
2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __ne__(self_, other): self.fail("This shouldn't happen")
2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __cmp__(self_, other): raise RuntimeError, "expected"
2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        a = Misb()
2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        b = Misb()
2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(a<b, 0)
2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(a==b, 0)
2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(a>b, 0)
2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(RuntimeError, cmp, a, b)
2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_not(self):
2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Check that exceptions in __nonzero__ are properly
2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # propagated by the not operator
2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        import operator
2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        class Exc(Exception):
2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        class Bad:
2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __nonzero__(self):
2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                raise Exc
2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def do(bad):
2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            not bad
2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for func in (do, operator.not_):
2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertRaises(Exc, func, Bad())
2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_recursion(self):
2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Check that comparison for recursive objects fails gracefully
2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        from UserList import UserList
2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        a = UserList()
2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        b = UserList()
2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        a.append(b)
2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        b.append(a)
2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(RuntimeError, operator.eq, a, b)
2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(RuntimeError, operator.ne, a, b)
2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(RuntimeError, operator.lt, a, b)
2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(RuntimeError, operator.le, a, b)
2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(RuntimeError, operator.gt, a, b)
2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(RuntimeError, operator.ge, a, b)
2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        b.append(17)
2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Even recursive lists of different lengths are different,
2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # but they cannot be ordered
2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(not (a == b))
2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(a != b)
2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(RuntimeError, operator.lt, a, b)
2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(RuntimeError, operator.le, a, b)
2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(RuntimeError, operator.gt, a, b)
2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(RuntimeError, operator.ge, a, b)
2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        a.append(17)
2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(RuntimeError, operator.eq, a, b)
2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(RuntimeError, operator.ne, a, b)
2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        a.insert(0, 11)
2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        b.insert(0, 12)
2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(not (a == b))
2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(a != b)
2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(a < b)
2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass DictTest(unittest.TestCase):
2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_dicts(self):
2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Verify that __eq__ and __ne__ work for dicts even if the keys and
2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # values don't support anything other than __eq__ and __ne__ (and
2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # __hash__).  Complex numbers are a fine example of that.
2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        import random
2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        imag1a = {}
2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for i in range(50):
2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            imag1a[random.randrange(100)*1j] = random.randrange(100)*1j
2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        items = imag1a.items()
2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        random.shuffle(items)
2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        imag1b = {}
2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for k, v in items:
2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            imag1b[k] = v
2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        imag2 = imag1b.copy()
2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        imag2[k] = v + 1.0
2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(imag1a == imag1a)
2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(imag1a == imag1b)
2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(imag2 == imag2)
2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(imag1a != imag2)
2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for opname in ("lt", "le", "gt", "ge"):
2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            for op in opmap[opname]:
2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.assertRaises(TypeError, op, imag1a, imag2)
2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass ListTest(unittest.TestCase):
2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_coverage(self):
2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # exercise all comparisons for lists
2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        x = [42]
2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertIs(x<x, False)
2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertIs(x<=x, True)
2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertIs(x==x, True)
2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertIs(x!=x, False)
2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertIs(x>x, False)
2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertIs(x>=x, True)
2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        y = [42, 42]
2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertIs(x<y, True)
2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertIs(x<=y, True)
2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertIs(x==y, False)
2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertIs(x!=y, True)
2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertIs(x>y, False)
2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertIs(x>=y, False)
3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_badentry(self):
3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # make sure that exceptions for item comparison are properly
3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # propagated in list comparisons
3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        class Exc(Exception):
3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        class Bad:
3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __eq__(self, other):
3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                raise Exc
3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        x = [Bad()]
3114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        y = [Bad()]
3124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for op in opmap["eq"]:
3144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertRaises(Exc, op, x, y)
3154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_goodentry(self):
3174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # This test exercises the final call to PyObject_RichCompare()
3184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # in Objects/listobject.c::list_richcompare()
3194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        class Good:
3204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __lt__(self, other):
3214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return True
3224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        x = [Good()]
3244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        y = [Good()]
3254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for op in opmap["lt"]:
3274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertIs(op(x, y), True)
3284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_main():
3304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    test_support.run_unittest(VectorTest, NumberTest, MiscTest, ListTest)
3314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    with test_support.check_py3k_warnings(("dict inequality comparisons "
3324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                             "not supported in 3.x",
3334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                             DeprecationWarning)):
3344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        test_support.run_unittest(DictTest)
3354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif __name__ == "__main__":
3384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    test_main()
339