Index: Tools/unicode/makeunicodedata.py =================================================================== --- Tools/unicode/makeunicodedata.py (revision 68921) +++ Tools/unicode/makeunicodedata.py (working copy) @@ -457,15 +457,6 @@ # -------------------------------------------------------------------- # unicode name database -def CmpToKey(mycmp): - 'Convert a cmp= function into a key= function' - class K(object): - def __init__(self, obj, *args): - self.obj = obj - def __lt__(self, other): - return mycmp(self.obj, other.obj) == -1 - return K - def makeunicodename(unicode, trace): FILE = "Modules/unicodename_db.h" @@ -508,14 +499,10 @@ wordlist = list(words.items()) # sort on falling frequency, then by name - def cmpwords(a,b): + def word_key(a): aword, alist = a - bword, blist = b - r = -cmp(len(alist),len(blist)) - if r: - return r - return cmp(aword, bword) - wordlist.sort(key=CmpToKey(cmpwords)) + return -len(alist), aword + wordlist.sort(key=word_key) # figure out how many phrasebook escapes we need escapes = 0 Index: Lib/xmlrpc/client.py =================================================================== --- Lib/xmlrpc/client.py (revision 68921) +++ Lib/xmlrpc/client.py (working copy) @@ -349,10 +349,6 @@ def timetuple(self): return time.strptime(self.value, "%Y%m%dT%H:%M:%S") - def __cmp__(self, other): - s, o = self.make_comparable(other) - return cmp(s, o) - ## # Get date/time value. # Index: Lib/distutils/version.py =================================================================== --- Lib/distutils/version.py (revision 68921) +++ Lib/distutils/version.py (working copy) @@ -21,7 +21,7 @@ an equivalent string -- ie. one that will generate an equivalent version number instance) * __repr__ generates Python code to recreate the version number instance - * __cmp__ compares the current instance with either another instance + * _cmp compares the current instance with either another instance of the same class or a string (which will be parsed to an instance of the same class, thus must follow the same rules) """ @@ -32,7 +32,7 @@ """Abstract base class for version numbering classes. Just provides constructor (__init__) and reproducer (__repr__), because those seem to be the same for all version numbering classes; and route - rich comparisons to __cmp__. + rich comparisons to _cmp. """ def __init__ (self, vstring=None): @@ -43,37 +43,37 @@ return "%s ('%s')" % (self.__class__.__name__, str(self)) def __eq__(self, other): - c = self.__cmp__(other) + c = self._cmp(other) if c is NotImplemented: return c return c == 0 def __ne__(self, other): - c = self.__cmp__(other) + c = self._cmp(other) if c is NotImplemented: return c return c != 0 def __lt__(self, other): - c = self.__cmp__(other) + c = self._cmp(other) if c is NotImplemented: return c return c < 0 def __le__(self, other): - c = self.__cmp__(other) + c = self._cmp(other) if c is NotImplemented: return c return c <= 0 def __gt__(self, other): - c = self.__cmp__(other) + c = self._cmp(other) if c is NotImplemented: return c return c > 0 def __ge__(self, other): - c = self.__cmp__(other) + c = self._cmp(other) if c is NotImplemented: return c return c >= 0 @@ -91,7 +91,7 @@ # (if not identical to) the string supplied to parse # __repr__ (self) - generate Python code to recreate # the instance -# __cmp__ (self, other) - compare two version numbers ('other' may +# _cmp (self, other) - compare two version numbers ('other' may # be an unparsed version string, or another # instance of your version class) @@ -169,31 +169,40 @@ return vstring - def __cmp__ (self, other): + def _cmp (self, other): if isinstance(other, str): other = StrictVersion(other) - compare = cmp(self.version, other.version) - if (compare == 0): # have to compare prerelease + if self.version != other.version: + # numeric versions don't match + # prerelease stuff doesn't matter + if self.version < other.version: + return -1 + else: + return 1 - # case 1: neither has prerelease; they're equal - # case 2: self has prerelease, other doesn't; other is greater - # case 3: self doesn't have prerelease, other does: self is greater - # case 4: both have prerelease: must compare them! + # have to compare prerelease + # case 1: neither has prerelease; they're equal + # case 2: self has prerelease, other doesn't; other is greater + # case 3: self doesn't have prerelease, other does: self is greater + # case 4: both have prerelease: must compare them! - if (not self.prerelease and not other.prerelease): + if (not self.prerelease and not other.prerelease): + return 0 + elif (self.prerelease and not other.prerelease): + return -1 + elif (not self.prerelease and other.prerelease): + return 1 + elif (self.prerelease and other.prerelease): + if self.prerelease == other.prerelease: return 0 - elif (self.prerelease and not other.prerelease): + elif self.prerelease < other.prerelease: return -1 - elif (not self.prerelease and other.prerelease): + else: return 1 - elif (self.prerelease and other.prerelease): - return cmp(self.prerelease, other.prerelease) + else: + assert False, "never get here" - else: # numeric versions don't match -- - return compare # prerelease stuff doesn't matter - - # end class StrictVersion @@ -325,7 +334,7 @@ return "LooseVersion ('%s')" % str(self) - def __cmp__ (self, other): + def _cmp (self, other): if isinstance(other, str): other = LooseVersion(other) Index: Lib/heapq.py =================================================================== --- Lib/heapq.py (revision 68921) +++ Lib/heapq.py (working copy) @@ -262,7 +262,7 @@ # # Cutting the # of comparisons is important, since these routines have no # way to extract "the priority" from an array element, so that intelligence -# is likely to be hiding in custom __cmp__ methods, or in array elements +# is likely to be hiding in custom comparison methods, or in array elements # storing (priority, record) tuples. Comparisons are thus potentially # expensive. # Index: Lib/collections.py =================================================================== --- Lib/collections.py (revision 68921) +++ Lib/collections.py (working copy) @@ -436,8 +436,6 @@ def __ge__(self, other): return self.data >= self.__cast(other) def __cast(self, other): return other.data if isinstance(other, UserList) else other - def __cmp__(self, other): - return cmp(self.data, self.__cast(other)) def __contains__(self, item): return item in self.data def __len__(self): return len(self.data) def __getitem__(self, i): return self.data[i] Index: Lib/ctypes/test/test_libc.py =================================================================== --- Lib/ctypes/test/test_libc.py (revision 68921) +++ Lib/ctypes/test/test_libc.py (working copy) @@ -5,6 +5,9 @@ lib = CDLL(_ctypes_test.__file__) +def twcmp(x, y): + return (x > y) - (x < y) + class LibTest(unittest.TestCase): def test_sqrt(self): lib.my_sqrt.argtypes = c_double, @@ -19,7 +22,7 @@ lib.my_qsort.restype = None def sort(a, b): - return cmp(a[0], b[0]) + return twcmp(a[0], b[0]) chars = create_string_buffer("spam, spam, and spam") lib.my_qsort(chars, len(chars)-1, sizeof(c_char), comparefunc(sort)) Index: Lib/pydoc.py =================================================================== --- Lib/pydoc.py (revision 68921) +++ Lib/pydoc.py (working copy) @@ -1643,7 +1643,7 @@ 'SPECIALMETHODS': ('specialnames', 'BASICMETHODS ATTRIBUTEMETHODS ' 'CALLABLEMETHODS SEQUENCEMETHODS1 MAPPINGMETHODS ' 'SEQUENCEMETHODS2 NUMBERMETHODS CLASSES'), - 'BASICMETHODS': ('customization', 'cmp hash repr str SPECIALMETHODS'), + 'BASICMETHODS': ('customization', 'hash repr str SPECIALMETHODS'), 'ATTRIBUTEMETHODS': ('attribute-access', 'ATTRIBUTES SPECIALMETHODS'), 'CALLABLEMETHODS': ('callable-types', 'CALLS SPECIALMETHODS'), 'SEQUENCEMETHODS': ('sequence-types', 'SEQUENCES SEQUENCEMETHODS2 ' Index: Lib/sqlite3/test/hooks.py =================================================================== --- Lib/sqlite3/test/hooks.py (revision 68921) +++ Lib/sqlite3/test/hooks.py (working copy) @@ -42,7 +42,7 @@ def CheckCreateCollationNotAscii(self): con = sqlite.connect(":memory:") try: - con.create_collation("collä", cmp) + con.create_collation("collä", lambda x, y: (x > y) - (x < y)) self.fail("should have raised a ProgrammingError") except sqlite.ProgrammingError as e: pass @@ -52,7 +52,7 @@ return def mycoll(x, y): # reverse order - return -cmp(x, y) + return -((x > y) - (x < y)) con = sqlite.connect(":memory:") con.create_collation("mycoll", mycoll) @@ -82,8 +82,8 @@ Verify that the last one is actually used. """ con = sqlite.connect(":memory:") - con.create_collation("mycoll", cmp) - con.create_collation("mycoll", lambda x, y: -cmp(x, y)) + con.create_collation("mycoll", lambda x, y: (x > y) - (x < y)) + con.create_collation("mycoll", lambda x, y: -((x > y) - (x < y))) result = con.execute(""" select x from (select 'a' as x union select 'b' as x) order by x collate mycoll """).fetchall() @@ -96,7 +96,7 @@ to use it. """ con = sqlite.connect(":memory:") - con.create_collation("mycoll", cmp) + con.create_collation("mycoll", lambda x, y: (x > y) - (x < y)) con.create_collation("mycoll", None) try: con.execute("select 'a' as x union select 'b' as x order by x collate mycoll") Index: Lib/unittest.py =================================================================== --- Lib/unittest.py (revision 68921) +++ Lib/unittest.py (working copy) @@ -539,12 +539,15 @@ return mycmp(self.obj, other.obj) == -1 return K +def cmp(x, y): + return (x > y) - (x < y) + class TestLoader(object): """This class is responsible for loading tests according to various criteria and returning them wrapped in a TestSuite """ testMethodPrefix = 'test' - sortTestMethodsUsing = cmp + sortTestMethodsUsing = staticmethod(cmp) suiteClass = TestSuite def loadTestsFromTestCase(self, testCaseClass): Index: Lib/test/crashers/loosing_mro_ref.py =================================================================== --- Lib/test/crashers/loosing_mro_ref.py (revision 68921) +++ Lib/test/crashers/loosing_mro_ref.py (working copy) @@ -10,7 +10,7 @@ def __hash__(self): return hash('mykey') - def __cmp__(self, other): + def __eq__(self, other): # the following line decrefs the previous X.__mro__ X.__bases__ = (Base2,) # trash all tuples of length 3, to make sure that the items of @@ -18,7 +18,7 @@ z = [] for i in range(1000): z.append((i, None, None)) - return -1 + return 0 class Base(object): Index: Lib/test/test_dict.py =================================================================== --- Lib/test/test_dict.py (revision 68921) +++ Lib/test/test_dict.py (working copy) @@ -570,7 +570,7 @@ self.fail("missing KeyError") def test_bad_key(self): - # Dictionary lookups should fail if __cmp__() raises an exception. + # Dictionary lookups should fail if __eq__() raises an exception. class CustomException(Exception): pass Index: Lib/test/test_set.py =================================================================== --- Lib/test/test_set.py (revision 68921) +++ Lib/test/test_set.py (working copy) @@ -1036,16 +1036,6 @@ result = self.set ^ set([8]) self.assertEqual(result, set([2, 4, 6, 8])) - def test_cmp(self): - a, b = set('a'), set('b') - self.assertRaises(TypeError, cmp, a, b) - - # In py3k, this works! - self.assertRaises(TypeError, cmp, a, a) - - self.assertRaises(TypeError, cmp, a, 12) - self.assertRaises(TypeError, cmp, "abc", a) - #============================================================================== class TestUpdateOps(unittest.TestCase): Index: Lib/test/test_descr.py =================================================================== --- Lib/test/test_descr.py (revision 68921) +++ Lib/test/test_descr.py (working copy) @@ -172,7 +172,6 @@ def test_dicts(self): # Testing dict operations... - ## self.binop_test({1:2}, {2:1}, -1, "cmp(a,b)", "__cmp__") self.binop_test({1:2,3:4}, 1, 1, "b in a", "__contains__") self.binop_test({1:2,3:4}, 2, 0, "b in a", "__contains__") self.binop_test({1:2,3:4}, 1, 2, "a[b]", "__getitem__") @@ -332,8 +331,6 @@ # This is an ugly hack: copy._deepcopy_dispatch[spam.spamdict] = spamdict - ## self.binop_test(spamdict({1:2}), spamdict({2:1}), -1, "cmp(a,b)", - ## "__cmp__") self.binop_test(spamdict({1:2,3:4}), 1, 1, "b in a", "__contains__") self.binop_test(spamdict({1:2,3:4}), 2, 0, "b in a", "__contains__") self.binop_test(spamdict({1:2,3:4}), 1, 2, "a[b]", "__getitem__") @@ -1004,8 +1001,8 @@ # Test lookup leaks [SF bug 572567] import sys,gc class G(object): - def __cmp__(self, other): - return 0 + def __eq__(self, other): + return 1 g = G() orig_objects = len(gc.get_objects()) for i in range(10): @@ -1525,7 +1522,6 @@ self.assertNotEqual(id(c1), id(c2)) hash(c1) hash(c2) - ## self.assertEqual(cmp(c1, c2), cmp(id(c1), id(c2))) self.assertEqual(c1, c1) self.assert_(c1 != c2) self.assert_(not c1 != c1) @@ -1549,7 +1545,6 @@ self.assertNotEqual(id(d1), id(d2)) hash(d1) hash(d2) - ## self.assertEqual(cmp(d1, d2), cmp(id(d1), id(d2))) self.assertEqual(d1, d1) self.assertNotEqual(d1, d2) self.assert_(not d1 != d1) @@ -1610,23 +1605,6 @@ self.assert_(i in p10) self.assertFalse(10 in p10) - ## # Safety test for __cmp__ - ## def unsafecmp(a, b): - ## try: - ## a.__class__.__cmp__(a, b) - ## except TypeError: - ## pass - ## else: - ## self.fail("shouldn't allow %s.__cmp__(%r, %r)" % ( - ## a.__class__, a, b)) - ## - ## unsafecmp("123", "123") - ## unsafecmp("123", "123") - ## unsafecmp(1, 1.0) - ## unsafecmp(1.0, 1) - ## unsafecmp(1, 1) - ## unsafecmp(1, 1) - def test_weakrefs(self): # Testing weak references... import weakref @@ -2538,12 +2516,16 @@ c = {1: c1, 2: c2, 3: c3} for x in 1, 2, 3: for y in 1, 2, 3: - ## self.assert_(cmp(c[x], c[y]) == cmp(x, y), "x=%d, y=%d" % (x, y)) for op in "<", "<=", "==", "!=", ">", ">=": - self.assert_(eval("c[x] %s c[y]" % op) == eval("x %s y" % op), - "x=%d, y=%d" % (x, y)) - ## self.assert_(cmp(c[x], y) == cmp(x, y), "x=%d, y=%d" % (x, y)) - ## self.assert_(cmp(x, c[y]) == cmp(x, y), "x=%d, y=%d" % (x, y)) + self.assert_(eval("c[x] %s c[y]" % op) == + eval("x %s y" % op), + "x=%d, y=%d" % (x, y)) + self.assert_(eval("c[x] %s y" % op) == + eval("x %s y" % op), + "x=%d, y=%d" % (x, y)) + self.assert_(eval("x %s c[y]" % op) == + eval("x %s y" % op), + "x=%d, y=%d" % (x, y)) def test_rich_comparisons(self): # Testing rich comparisons... Index: Lib/test/test_hmac.py =================================================================== --- Lib/test/test_hmac.py (revision 68921) +++ Lib/test/test_hmac.py (working copy) @@ -291,7 +291,7 @@ # Testing if the copy method created a real copy. h1 = hmac.HMAC(b"key") h2 = h1.copy() - # Using id() in case somebody has overridden __cmp__. + # Using id() in case somebody has overridden __eq__/__ne__. self.failUnless(id(h1) != id(h2), "No real copy of the HMAC instance.") self.failUnless(id(h1.inner) != id(h2.inner), "No real copy of the attribute 'inner'.") Index: Lib/test/test_kqueue.py =================================================================== --- Lib/test/test_kqueue.py (revision 68921) +++ Lib/test/test_kqueue.py (working copy) @@ -22,6 +22,7 @@ self.assertRaises(ValueError, kq.fileno) def test_create_event(self): + from operator import lt, le, gt, ge fd = sys.stderr.fileno() ev = select.kevent(fd) other = select.kevent(1000) @@ -33,12 +34,12 @@ self.assertEqual(ev.udata, 0) self.assertEqual(ev, ev) self.assertNotEqual(ev, other) - self.assertEqual(cmp(ev, other), -1) self.assert_(ev < other) self.assert_(other >= ev) - self.assertRaises(TypeError, cmp, ev, None) - self.assertRaises(TypeError, cmp, ev, 1) - self.assertRaises(TypeError, cmp, ev, "ev") + for op in lt, le, gt, ge: + self.assertRaises(TypeError, op, ev, None) + self.assertRaises(TypeError, op, ev, 1) + self.assertRaises(TypeError, op, ev, "ev") ev = select.kevent(fd, select.KQ_FILTER_WRITE) self.assertEqual(ev.ident, fd) Index: Lib/test/test_contains.py =================================================================== --- Lib/test/test_contains.py (revision 68921) +++ Lib/test/test_contains.py (working copy) @@ -57,7 +57,7 @@ works when the list is modified during the check. """ aList = range(15) - def __cmp__(self, other): + def __lt__(self, other): if other == 12: self.aList.remove(12) self.aList.remove(13) @@ -72,7 +72,7 @@ This class raises an exception during comparison. That in turn causes the comparison to fail with a TypeError. """ - def __cmp__(self, other): + def __lt__(self, other): if other == 4: raise RuntimeError("gotcha") Index: Lib/test/test_heapq.py =================================================================== --- Lib/test/test_heapq.py (revision 68921) +++ Lib/test/test_heapq.py (working copy) @@ -234,9 +234,9 @@ class CmpErr: "Dummy element that always raises an error during comparison" - def __cmp__(self, other): + def __eq__(self, other): raise ZeroDivisionError - __eq__ = __ne__ = __lt__ = __le__ = __gt__ = __ge__ = __cmp__ + __ne__ = __lt__ = __le__ = __gt__ = __ge__ = __eq__ def R(seqn): 'Regular generator' Index: Lib/test/test_long.py =================================================================== --- Lib/test/test_long.py (revision 68921) +++ Lib/test/test_long.py (working copy) @@ -697,7 +697,8 @@ def _cmp__(self, other): if not isinstance(other, Rat): other = Rat(other) - return cmp(self.n * other.d, self.d * other.n) + x, y = self.n * other.d, self.d * other.n + return (x > y) - (x < y) def __eq__(self, other): return self._cmp__(other) == 0 def __ne__(self, other): @@ -727,8 +728,8 @@ Rx = Rat(x) for y in cases: Ry = Rat(y) - Rcmp = cmp(Rx, Ry) - xycmp = cmp(x, y) + Rcmp = (Rx > Ry) - (Rx < Ry) + xycmp = (x > y) - (x < y) eq(Rcmp, xycmp, Frm("%r %r %d %d", x, y, Rcmp, xycmp)) eq(x == y, Rcmp == 0, Frm("%r == %r %d", x, y, Rcmp)) eq(x != y, Rcmp != 0, Frm("%r != %r %d", x, y, Rcmp)) Index: Lib/test/list_tests.py =================================================================== --- Lib/test/list_tests.py (revision 68921) +++ Lib/test/list_tests.py (working copy) @@ -439,13 +439,24 @@ self.assertRaises(TypeError, u.sort, 42, 42) def revcmp(a, b): - return cmp(b, a) + if a == b: + return 0 + elif a < b: + return 1 + else: # a > b + return -1 u.sort(key=CmpToKey(revcmp)) self.assertEqual(u, self.type2test([2,1,0,-1,-2])) # The following dumps core in unpatched Python 1.5: def myComparison(x,y): - return cmp(x%3, y%7) + xmod, ymod = x%3, y%7 + if xmod == ymod: + return 0 + elif xmod < ymod: + return -1 + else: # xmod > ymod + return 1 z = self.type2test(range(12)) z.sort(key=CmpToKey(myComparison)) @@ -453,7 +464,12 @@ def selfmodifyingComparison(x,y): z.append(1) - return cmp(x, y) + if x == y: + return 0 + elif x < y: + return -1 + else: # x > y + return 1 self.assertRaises(ValueError, z.sort, key=CmpToKey(selfmodifyingComparison)) self.assertRaises(TypeError, z.sort, 42, 42, 42, 42) Index: Lib/test/test_sort.py =================================================================== --- Lib/test/test_sort.py (revision 68921) +++ Lib/test/test_sort.py (working copy) @@ -102,7 +102,7 @@ y = x[:] y.reverse() s = x[:] - check("reversed via function", y, s, lambda a, b: cmp(b, a)) + check("reversed via function", y, s, lambda a, b: (b>a)-(b y) - (x < y) L = [1,2] self.assertRaises(ValueError, L.sort, key=CmpToKey(mutating_cmp)) def mutating_cmp(x, y): L.append(3) del L[:] - return cmp(x, y) + return (x > y) - (x < y) self.assertRaises(ValueError, L.sort, key=CmpToKey(mutating_cmp)) memorywaster = [memorywaster] @@ -176,7 +176,10 @@ copy = data[:] random.shuffle(data) data.sort(key=str.lower) - copy.sort(key=CmpToKey(lambda x,y: cmp(x.lower(), y.lower()))) + def my_cmp(x, y): + xlower, ylower = x.lower(), y.lower() + return (xlower > ylower) - (xlower < ylower) + copy.sort(key=CmpToKey(my_cmp)) def test_baddecorator(self): data = 'The quick Brown fox Jumped over The lazy Dog'.split() @@ -246,8 +249,14 @@ data = [(random.randrange(100), i) for i in range(200)] copy1 = data[:] copy2 = data[:] - data.sort(key=CmpToKey(lambda x,y: cmp(x[0],y[0])), reverse=True) - copy1.sort(key=CmpToKey(lambda x,y: cmp(y[0],x[0]))) + def my_cmp(x, y): + x0, y0 = x[0], y[0] + return (x0 > y0) - (x0 < y0) + def my_cmp_reversed(x, y): + x0, y0 = x[0], y[0] + return (y0 > x0) - (y0 < x0) + data.sort(key=CmpToKey(my_cmp), reverse=True) + copy1.sort(key=CmpToKey(my_cmp_reversed)) self.assertEqual(data, copy1) copy2.sort(key=lambda x: x[0], reverse=True) self.assertEqual(data, copy2) Index: Lib/test/test_deque.py =================================================================== --- Lib/test/test_deque.py (revision 68921) +++ Lib/test/test_deque.py (working copy) @@ -103,7 +103,6 @@ self.assertEqual(x <= y, list(x) <= list(y), (x,y)) self.assertEqual(x > y, list(x) > list(y), (x,y)) self.assertEqual(x >= y, list(x) >= list(y), (x,y)) - self.assertEqual(cmp(x,y), cmp(list(x),list(y)), (x,y)) def test_extend(self): d = deque('a') Index: Lib/test/test_datetime.py =================================================================== --- Lib/test/test_datetime.py (revision 68921) +++ Lib/test/test_datetime.py (working copy) @@ -8,6 +8,7 @@ import unittest from test import support +from test.support import fcmp from datetime import MINYEAR, MAXYEAR from datetime import timedelta @@ -156,9 +157,6 @@ self.assertRaises(TypeError, lambda: () > me) self.assertRaises(TypeError, lambda: () >= me) - self.assertRaises(TypeError, cmp, (), me) - self.assertRaises(TypeError, cmp, me, ()) - ############################################################################# # timedelta tests @@ -309,8 +307,6 @@ self.failUnless(not t1 != t2) self.failUnless(not t1 < t2) self.failUnless(not t1 > t2) - self.assertEqual(cmp(t1, t2), 0) - self.assertEqual(cmp(t2, t1), 0) for args in (3, 3, 3), (2, 4, 4), (2, 3, 5): t2 = timedelta(*args) # this is larger than t1 @@ -326,8 +322,6 @@ self.failUnless(not t2 < t1) self.failUnless(not t1 >= t2) self.failUnless(not t2 <= t1) - self.assertEqual(cmp(t1, t2), -1) - self.assertEqual(cmp(t2, t1), 1) for badarg in OTHERSTUFF: self.assertEqual(t1 == badarg, False) @@ -953,8 +947,6 @@ self.failUnless(not t1 != t2) self.failUnless(not t1 < t2) self.failUnless(not t1 > t2) - self.assertEqual(cmp(t1, t2), 0) - self.assertEqual(cmp(t2, t1), 0) for args in (3, 3, 3), (2, 4, 4), (2, 3, 5): t2 = self.theclass(*args) # this is larger than t1 @@ -970,8 +962,6 @@ self.failUnless(not t2 < t1) self.failUnless(not t1 >= t2) self.failUnless(not t2 <= t1) - self.assertEqual(cmp(t1, t2), -1) - self.assertEqual(cmp(t2, t1), 1) for badarg in OTHERSTUFF: self.assertEqual(t1 == badarg, False) @@ -999,8 +989,6 @@ # But the ordering is undefined self.assertRaises(TypeError, lambda: our < 1) self.assertRaises(TypeError, lambda: 1 < our) - self.assertRaises(TypeError, cmp, our, 1) - self.assertRaises(TypeError, cmp, 1, our) # Repeat those tests with a different class @@ -1014,8 +1002,6 @@ self.assertEqual(their != our, True) self.assertRaises(TypeError, lambda: our < their) self.assertRaises(TypeError, lambda: their < our) - self.assertRaises(TypeError, cmp, our, their) - self.assertRaises(TypeError, cmp, their, our) # However, if the other class explicitly defines ordering # relative to our class, it is allowed to do so @@ -1041,8 +1027,6 @@ self.assertEqual(their != our, True) self.assertEqual(our < their, True) self.assertEqual(their < our, False) - self.assertEqual(cmp(our, their), -1) - self.assertEqual(cmp(their, our), 1) def test_bool(self): # All dates are considered true. @@ -1440,8 +1424,6 @@ self.failUnless(not t1 != t2) self.failUnless(not t1 < t2) self.failUnless(not t1 > t2) - self.assertEqual(cmp(t1, t2), 0) - self.assertEqual(cmp(t2, t1), 0) for i in range(len(args)): newargs = args[:] @@ -1459,8 +1441,6 @@ self.failUnless(not t2 < t1) self.failUnless(not t1 >= t2) self.failUnless(not t2 <= t1) - self.assertEqual(cmp(t1, t2), -1) - self.assertEqual(cmp(t2, t1), 1) # A helper for timestamp constructor tests. @@ -1728,8 +1708,6 @@ self.failUnless(not t1 != t2) self.failUnless(not t1 < t2) self.failUnless(not t1 > t2) - self.assertEqual(cmp(t1, t2), 0) - self.assertEqual(cmp(t2, t1), 0) for i in range(len(args)): newargs = args[:] @@ -1747,8 +1725,6 @@ self.failUnless(not t2 < t1) self.failUnless(not t1 >= t2) self.failUnless(not t2 <= t1) - self.assertEqual(cmp(t1, t2), -1) - self.assertEqual(cmp(t2, t1), 1) for badarg in OTHERSTUFF: self.assertEqual(t1 == badarg, False) @@ -2122,8 +2098,8 @@ d2 = base.replace(minute=11) for x in d0, d1, d2: for y in d0, d1, d2: - got = cmp(x, y) - expected = cmp(x.minute, y.minute) + got = fcmp(x, y) + expected = fcmp(x.minute, y.minute) self.assertEqual(got, expected) # However, if they're different members, uctoffset is not ignored. @@ -2136,7 +2112,7 @@ d2 = base.replace(minute=11, tzinfo=OperandDependentOffset()) for x in d0, d1, d2: for y in d0, d1, d2: - got = cmp(x, y) + got = fcmp(x, y) if (x is d0 or x is d1) and (y is d0 or y is d1): expected = 0 elif x is y is d2: Index: Lib/test/test_decimal.py =================================================================== --- Lib/test/test_decimal.py (revision 68921) +++ Lib/test/test_decimal.py (working copy) @@ -1012,17 +1012,11 @@ self.failUnless(da != dc) self.failUnless(da <= db) self.failUnless(da >= db) - self.assertEqual(cmp(dc,da), 1) - self.assertEqual(cmp(da,dc), -1) - self.assertEqual(cmp(da,db), 0) #a Decimal and an int self.failUnless(dc > 23) self.failUnless(23 < dc) self.assertEqual(dc, 45) - self.assertEqual(cmp(dc,23), 1) - self.assertEqual(cmp(23,dc), -1) - self.assertEqual(cmp(dc,45), 0) #a Decimal and uncomparable self.assertNotEqual(da, 'ugly') Index: Lib/test/test_uuid.py =================================================================== --- Lib/test/test_uuid.py (revision 68921) +++ Lib/test/test_uuid.py (working copy) @@ -1,5 +1,6 @@ from unittest import TestCase from test import support +from test.support import fcmp import uuid def importable(name): @@ -181,7 +182,7 @@ # Test comparison of UUIDs. for i in range(len(ascending)): for j in range(len(ascending)): - equal(cmp(i, j), cmp(ascending[i], ascending[j])) + equal(fcmp(i, j), fcmp(ascending[i], ascending[j])) # Test sorting of UUIDs (above list is in ascending order). resorted = ascending[:] Index: Lib/test/test_unittest.py =================================================================== --- Lib/test/test_unittest.py (revision 68921) +++ Lib/test/test_unittest.py (working copy) @@ -1103,7 +1103,7 @@ # getTestCaseNames() and all the loadTestsFromX() methods" def test_sortTestMethodsUsing__loadTestsFromTestCase(self): def reversed_cmp(x, y): - return -cmp(x, y) + return -((x > y) - (x < y)) class Foo(unittest.TestCase): def test_1(self): pass @@ -1119,7 +1119,7 @@ # getTestCaseNames() and all the loadTestsFromX() methods" def test_sortTestMethodsUsing__loadTestsFromModule(self): def reversed_cmp(x, y): - return -cmp(x, y) + return -((x > y) - (x < y)) m = types.ModuleType('m') class Foo(unittest.TestCase): @@ -1137,7 +1137,7 @@ # getTestCaseNames() and all the loadTestsFromX() methods" def test_sortTestMethodsUsing__loadTestsFromName(self): def reversed_cmp(x, y): - return -cmp(x, y) + return -((x > y) - (x < y)) m = types.ModuleType('m') class Foo(unittest.TestCase): @@ -1155,7 +1155,7 @@ # getTestCaseNames() and all the loadTestsFromX() methods" def test_sortTestMethodsUsing__loadTestsFromNames(self): def reversed_cmp(x, y): - return -cmp(x, y) + return -((x > y) - (x < y)) m = types.ModuleType('m') class Foo(unittest.TestCase): @@ -1175,7 +1175,7 @@ # Does it actually affect getTestCaseNames()? def test_sortTestMethodsUsing__getTestCaseNames(self): def reversed_cmp(x, y): - return -cmp(x, y) + return -((x > y) - (x < y)) class Foo(unittest.TestCase): def test_1(self): pass @@ -1188,10 +1188,20 @@ self.assertEqual(loader.getTestCaseNames(Foo), test_names) # "The default value is the built-in cmp() function" + # Since cmp is now defunct, we simply verify that the results + # occur in the same order as they would with the default sort. def test_sortTestMethodsUsing__default_value(self): loader = unittest.TestLoader() - self.failUnless(loader.sortTestMethodsUsing is cmp) + class Foo(unittest.TestCase): + def test_2(self): pass + def test_3(self): pass + def test_1(self): pass + + test_names = ['test_2', 'test_3', 'test_1'] + self.assertEqual(loader.getTestCaseNames(Foo), sorted(test_names)) + + # "it can be set to None to disable the sort." # # XXX How is this different from reassigning cmp? Are the tests returned Index: Lib/test/test_copy.py =================================================================== --- Lib/test/test_copy.py (revision 68921) +++ Lib/test/test_copy.py (working copy) @@ -5,6 +5,7 @@ import unittest from test import support +from test.support import fcmp class TestCopy(unittest.TestCase): @@ -271,7 +272,7 @@ x = [] x.append(x) y = copy.deepcopy(x) - self.assertRaises(RuntimeError, cmp, y, x) + self.assertRaises(RuntimeError, fcmp, y, x) self.assert_(y is not x) self.assert_(y[0] is y) self.assertEqual(len(y), 1) @@ -287,7 +288,7 @@ x = ([],) x[0].append(x) y = copy.deepcopy(x) - self.assertRaises(RuntimeError, cmp, y, x) + self.assertRaises(RuntimeError, fcmp, y, x) self.assert_(y is not x) self.assert_(y[0] is not x[0]) self.assert_(y[0][0] is y) @@ -303,7 +304,7 @@ x = {} x['foo'] = x y = copy.deepcopy(x) - self.assertRaises(TypeError, cmp, y, x) + self.assertRaises(TypeError, fcmp, y, x) self.assert_(y is not x) self.assert_(y['foo'] is y) self.assertEqual(len(y), 1) Index: Lib/test/test_hash.py =================================================================== --- Lib/test/test_hash.py (revision 68921) +++ Lib/test/test_hash.py (working copy) @@ -55,13 +55,8 @@ def __ne__(self, other): return self is not other -class OnlyCmp(object): - def __cmp__(self, other): - return cmp(id(self), id(other)) - class InheritedHashWithEquality(FixedHash, OnlyEquality): pass class InheritedHashWithInequality(FixedHash, OnlyInequality): pass -class InheritedHashWithCmp(FixedHash, OnlyCmp): pass class NoHash(object): __hash__ = None @@ -74,7 +69,6 @@ fixed_expected = [FixedHash(), InheritedHashWithEquality(), InheritedHashWithInequality(), - InheritedHashWithCmp(), ] error_expected = [NoHash(), OnlyEquality(), Index: Lib/test/test_userdict.py =================================================================== --- Lib/test/test_userdict.py (revision 68921) +++ Lib/test/test_userdict.py (working copy) @@ -47,7 +47,7 @@ self.assertEqual(repr(u1), repr(d1)) self.assertEqual(repr(u2), repr(d2)) - # Test __cmp__ and __len__ + # Test rich comparison and __len__ all = [d0, d1, d2, u, u0, u1, u2, uu, uu0, uu1, uu2] for a in all: for b in all: Index: Lib/test/test_builtin.py =================================================================== --- Lib/test/test_builtin.py (revision 68921) +++ Lib/test/test_builtin.py (working copy) @@ -10,6 +10,7 @@ FutureWarning, __name__) warnings.filterwarnings("ignore", "integer argument expected", DeprecationWarning, "unittest") +import builtins class Squares: @@ -219,21 +220,9 @@ self.assertRaises((OverflowError, ValueError), chr, 2**32) def test_cmp(self): - self.assertEqual(cmp(-1, 1), -1) - self.assertEqual(cmp(1, -1), 1) - self.assertEqual(cmp(1, 1), 0) - # verify that circular objects are not handled - a = []; a.append(a) - b = []; b.append(b) - from collections import UserList - c = UserList(); c.append(c) - self.assertRaises(RuntimeError, cmp, a, b) - self.assertRaises(RuntimeError, cmp, b, c) - self.assertRaises(RuntimeError, cmp, c, a) - self.assertRaises(RuntimeError, cmp, a, c) - # okay, now break the cycles - a.pop(); b.pop(); c.pop() - self.assertRaises(TypeError, cmp) + # uncomment the following line once cmp has been removed + #self.assert_(not hasattr(builtins, "cmp")) + pass def test_compile(self): compile('print(1)\n', '', 'exec') @@ -736,10 +725,6 @@ def __getitem__(self, index): raise ValueError self.assertRaises(ValueError, min, BadSeq()) - class BadNumber: - def __cmp__(self, other): - raise ValueError - self.assertRaises(TypeError, min, (42, BadNumber())) for stmt in ( "min(key=int)", # no args Index: Lib/locale.py =================================================================== --- Lib/locale.py (revision 68921) +++ Lib/locale.py (working copy) @@ -31,7 +31,7 @@ """ strcoll(string,string) -> int. Compares two strings according to the locale. """ - return cmp(a,b) + return (a > b) - (a < b) def _strxfrm(s): """ strxfrm(string) -> string. Index: Lib/xml/dom/minidom.py =================================================================== --- Lib/xml/dom/minidom.py (revision 68921) +++ Lib/xml/dom/minidom.py (working copy) @@ -524,7 +524,7 @@ if self._attrs is getattr(other, "_attrs", None): return 0 else: - return cmp(id(self), id(other)) + return (id(self) > id(other)) - (id(self) < id(other)) def __getitem__(self, attname_or_tuple): if isinstance(attname_or_tuple, tuple): Index: Lib/xml/etree/ElementTree.py =================================================================== --- Lib/xml/etree/ElementTree.py (revision 68921) +++ Lib/xml/etree/ElementTree.py (working copy) @@ -500,8 +500,8 @@ return hash(self.text) def __cmp__(self, other): if isinstance(other, QName): - return cmp(self.text, other.text) - return cmp(self.text, other) + return (self.text > other.text) - (self.text < other.text) + return (self.text > other) - (self.text < other) ## # ElementTree wrapper class. This class represents an entire element