Issue #1717: Remove cmp. Stage 1: remove all uses of cmp and __cmp__ from

the standard library and tests.
This commit is contained in:
Mark Dickinson 2009-01-27 18:17:45 +00:00
parent 191e850053
commit a56c467ac3
32 changed files with 210 additions and 216 deletions

View file

@ -436,8 +436,6 @@ class UserList(MutableSequence):
def __ge__(self, other): return self.data >= self.__cast(other) def __ge__(self, other): return self.data >= self.__cast(other)
def __cast(self, other): def __cast(self, other):
return other.data if isinstance(other, UserList) else 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 __contains__(self, item): return item in self.data
def __len__(self): return len(self.data) def __len__(self): return len(self.data)
def __getitem__(self, i): return self.data[i] def __getitem__(self, i): return self.data[i]

View file

@ -5,6 +5,10 @@ import _ctypes_test
lib = CDLL(_ctypes_test.__file__) lib = CDLL(_ctypes_test.__file__)
def three_way_cmp(x, y):
"""Return -1 if x < y, 0 if x == y and 1 if x > y"""
return (x > y) - (x < y)
class LibTest(unittest.TestCase): class LibTest(unittest.TestCase):
def test_sqrt(self): def test_sqrt(self):
lib.my_sqrt.argtypes = c_double, lib.my_sqrt.argtypes = c_double,
@ -19,7 +23,7 @@ class LibTest(unittest.TestCase):
lib.my_qsort.restype = None lib.my_qsort.restype = None
def sort(a, b): def sort(a, b):
return cmp(a[0], b[0]) return three_way_cmp(a[0], b[0])
chars = create_string_buffer("spam, spam, and spam") chars = create_string_buffer("spam, spam, and spam")
lib.my_qsort(chars, len(chars)-1, sizeof(c_char), comparefunc(sort)) lib.my_qsort(chars, len(chars)-1, sizeof(c_char), comparefunc(sort))

View file

@ -21,7 +21,7 @@ Every version number class implements the following interface:
an equivalent string -- ie. one that will generate an equivalent an equivalent string -- ie. one that will generate an equivalent
version number instance) version number instance)
* __repr__ generates Python code to recreate the 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 or a string (which will be parsed to an instance
of the same class, thus must follow the same rules) of the same class, thus must follow the same rules)
""" """
@ -32,7 +32,7 @@ class Version:
"""Abstract base class for version numbering classes. Just provides """Abstract base class for version numbering classes. Just provides
constructor (__init__) and reproducer (__repr__), because those constructor (__init__) and reproducer (__repr__), because those
seem to be the same for all version numbering classes; and route 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): def __init__ (self, vstring=None):
@ -43,37 +43,37 @@ class Version:
return "%s ('%s')" % (self.__class__.__name__, str(self)) return "%s ('%s')" % (self.__class__.__name__, str(self))
def __eq__(self, other): def __eq__(self, other):
c = self.__cmp__(other) c = self._cmp(other)
if c is NotImplemented: if c is NotImplemented:
return c return c
return c == 0 return c == 0
def __ne__(self, other): def __ne__(self, other):
c = self.__cmp__(other) c = self._cmp(other)
if c is NotImplemented: if c is NotImplemented:
return c return c
return c != 0 return c != 0
def __lt__(self, other): def __lt__(self, other):
c = self.__cmp__(other) c = self._cmp(other)
if c is NotImplemented: if c is NotImplemented:
return c return c
return c < 0 return c < 0
def __le__(self, other): def __le__(self, other):
c = self.__cmp__(other) c = self._cmp(other)
if c is NotImplemented: if c is NotImplemented:
return c return c
return c <= 0 return c <= 0
def __gt__(self, other): def __gt__(self, other):
c = self.__cmp__(other) c = self._cmp(other)
if c is NotImplemented: if c is NotImplemented:
return c return c
return c > 0 return c > 0
def __ge__(self, other): def __ge__(self, other):
c = self.__cmp__(other) c = self._cmp(other)
if c is NotImplemented: if c is NotImplemented:
return c return c
return c >= 0 return c >= 0
@ -91,7 +91,7 @@ class Version:
# (if not identical to) the string supplied to parse # (if not identical to) the string supplied to parse
# __repr__ (self) - generate Python code to recreate # __repr__ (self) - generate Python code to recreate
# the instance # 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 # be an unparsed version string, or another
# instance of your version class) # instance of your version class)
@ -169,30 +169,39 @@ class StrictVersion (Version):
return vstring return vstring
def __cmp__ (self, other): def _cmp (self, other):
if isinstance(other, str): if isinstance(other, str):
other = StrictVersion(other) other = StrictVersion(other)
compare = cmp(self.version, other.version) if self.version != other.version:
if (compare == 0): # have to compare prerelease # numeric versions don't match
# prerelease stuff doesn't matter
# case 1: neither has prerelease; they're equal if self.version < other.version:
# 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):
return 0
elif (self.prerelease and not other.prerelease):
return -1 return -1
elif (not self.prerelease and other.prerelease): else:
return 1 return 1
elif (self.prerelease and other.prerelease):
return cmp(self.prerelease, other.prerelease)
else: # numeric versions don't match -- # have to compare prerelease
return compare # prerelease stuff doesn't matter # 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):
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 < other.prerelease:
return -1
else:
return 1
else:
assert False, "never get here"
# end class StrictVersion # end class StrictVersion
@ -325,7 +334,7 @@ class LooseVersion (Version):
return "LooseVersion ('%s')" % str(self) return "LooseVersion ('%s')" % str(self)
def __cmp__ (self, other): def _cmp (self, other):
if isinstance(other, str): if isinstance(other, str):
other = LooseVersion(other) other = LooseVersion(other)

View file

@ -262,7 +262,7 @@ def _siftdown(heap, startpos, pos):
# #
# Cutting the # of comparisons is important, since these routines have no # Cutting the # of comparisons is important, since these routines have no
# way to extract "the priority" from an array element, so that intelligence # 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 # storing (priority, record) tuples. Comparisons are thus potentially
# expensive. # expensive.
# #

View file

@ -31,7 +31,7 @@ def _strcoll(a,b):
""" strcoll(string,string) -> int. """ strcoll(string,string) -> int.
Compares two strings according to the locale. Compares two strings according to the locale.
""" """
return cmp(a,b) return (a > b) - (a < b)
def _strxfrm(s): def _strxfrm(s):
""" strxfrm(string) -> string. """ strxfrm(string) -> string.

View file

@ -1643,7 +1643,7 @@ class Helper:
'SPECIALMETHODS': ('specialnames', 'BASICMETHODS ATTRIBUTEMETHODS ' 'SPECIALMETHODS': ('specialnames', 'BASICMETHODS ATTRIBUTEMETHODS '
'CALLABLEMETHODS SEQUENCEMETHODS1 MAPPINGMETHODS ' 'CALLABLEMETHODS SEQUENCEMETHODS1 MAPPINGMETHODS '
'SEQUENCEMETHODS2 NUMBERMETHODS CLASSES'), 'SEQUENCEMETHODS2 NUMBERMETHODS CLASSES'),
'BASICMETHODS': ('customization', 'cmp hash repr str SPECIALMETHODS'), 'BASICMETHODS': ('customization', 'hash repr str SPECIALMETHODS'),
'ATTRIBUTEMETHODS': ('attribute-access', 'ATTRIBUTES SPECIALMETHODS'), 'ATTRIBUTEMETHODS': ('attribute-access', 'ATTRIBUTES SPECIALMETHODS'),
'CALLABLEMETHODS': ('callable-types', 'CALLS SPECIALMETHODS'), 'CALLABLEMETHODS': ('callable-types', 'CALLS SPECIALMETHODS'),
'SEQUENCEMETHODS': ('sequence-types', 'SEQUENCES SEQUENCEMETHODS2 ' 'SEQUENCEMETHODS': ('sequence-types', 'SEQUENCES SEQUENCEMETHODS2 '

View file

@ -42,7 +42,7 @@ class CollationTests(unittest.TestCase):
def CheckCreateCollationNotAscii(self): def CheckCreateCollationNotAscii(self):
con = sqlite.connect(":memory:") con = sqlite.connect(":memory:")
try: try:
con.create_collation("collä", cmp) con.create_collation("collä", lambda x, y: (x > y) - (x < y))
self.fail("should have raised a ProgrammingError") self.fail("should have raised a ProgrammingError")
except sqlite.ProgrammingError as e: except sqlite.ProgrammingError as e:
pass pass
@ -52,7 +52,7 @@ class CollationTests(unittest.TestCase):
return return
def mycoll(x, y): def mycoll(x, y):
# reverse order # reverse order
return -cmp(x, y) return -((x > y) - (x < y))
con = sqlite.connect(":memory:") con = sqlite.connect(":memory:")
con.create_collation("mycoll", mycoll) con.create_collation("mycoll", mycoll)
@ -82,8 +82,8 @@ class CollationTests(unittest.TestCase):
Verify that the last one is actually used. Verify that the last one is actually used.
""" """
con = sqlite.connect(":memory:") con = sqlite.connect(":memory:")
con.create_collation("mycoll", cmp) con.create_collation("mycoll", lambda x, y: (x > y) - (x < y))
con.create_collation("mycoll", lambda x, y: -cmp(x, y)) con.create_collation("mycoll", lambda x, y: -((x > y) - (x < y)))
result = con.execute(""" result = con.execute("""
select x from (select 'a' as x union select 'b' as x) order by x collate mycoll select x from (select 'a' as x union select 'b' as x) order by x collate mycoll
""").fetchall() """).fetchall()
@ -96,7 +96,7 @@ class CollationTests(unittest.TestCase):
to use it. to use it.
""" """
con = sqlite.connect(":memory:") 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) con.create_collation("mycoll", None)
try: try:
con.execute("select 'a' as x union select 'b' as x order by x collate mycoll") con.execute("select 'a' as x union select 'b' as x order by x collate mycoll")

View file

@ -10,7 +10,7 @@ class MyKey(object):
def __hash__(self): def __hash__(self):
return hash('mykey') return hash('mykey')
def __cmp__(self, other): def __eq__(self, other):
# the following line decrefs the previous X.__mro__ # the following line decrefs the previous X.__mro__
X.__bases__ = (Base2,) X.__bases__ = (Base2,)
# trash all tuples of length 3, to make sure that the items of # trash all tuples of length 3, to make sure that the items of
@ -18,7 +18,7 @@ class MyKey(object):
z = [] z = []
for i in range(1000): for i in range(1000):
z.append((i, None, None)) z.append((i, None, None))
return -1 return 0
class Base(object): class Base(object):

View file

@ -439,13 +439,24 @@ class CommonTest(seq_tests.CommonTest):
self.assertRaises(TypeError, u.sort, 42, 42) self.assertRaises(TypeError, u.sort, 42, 42)
def revcmp(a, b): 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)) u.sort(key=CmpToKey(revcmp))
self.assertEqual(u, self.type2test([2,1,0,-1,-2])) self.assertEqual(u, self.type2test([2,1,0,-1,-2]))
# The following dumps core in unpatched Python 1.5: # The following dumps core in unpatched Python 1.5:
def myComparison(x,y): 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 = self.type2test(range(12))
z.sort(key=CmpToKey(myComparison)) z.sort(key=CmpToKey(myComparison))
@ -453,7 +464,12 @@ class CommonTest(seq_tests.CommonTest):
def selfmodifyingComparison(x,y): def selfmodifyingComparison(x,y):
z.append(1) 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(ValueError, z.sort, key=CmpToKey(selfmodifyingComparison))
self.assertRaises(TypeError, z.sort, 42, 42, 42, 42) self.assertRaises(TypeError, z.sort, 42, 42, 42, 42)

View file

@ -10,6 +10,7 @@ warnings.filterwarnings("ignore", "hex../oct.. of negative int",
FutureWarning, __name__) FutureWarning, __name__)
warnings.filterwarnings("ignore", "integer argument expected", warnings.filterwarnings("ignore", "integer argument expected",
DeprecationWarning, "unittest") DeprecationWarning, "unittest")
import builtins
class Squares: class Squares:
@ -219,21 +220,9 @@ class BuiltinTest(unittest.TestCase):
self.assertRaises((OverflowError, ValueError), chr, 2**32) self.assertRaises((OverflowError, ValueError), chr, 2**32)
def test_cmp(self): def test_cmp(self):
self.assertEqual(cmp(-1, 1), -1) # uncomment the following line once cmp has been removed
self.assertEqual(cmp(1, -1), 1) #self.assert_(not hasattr(builtins, "cmp"))
self.assertEqual(cmp(1, 1), 0) pass
# 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)
def test_compile(self): def test_compile(self):
compile('print(1)\n', '', 'exec') compile('print(1)\n', '', 'exec')
@ -736,10 +725,6 @@ class BuiltinTest(unittest.TestCase):
def __getitem__(self, index): def __getitem__(self, index):
raise ValueError raise ValueError
self.assertRaises(ValueError, min, BadSeq()) self.assertRaises(ValueError, min, BadSeq())
class BadNumber:
def __cmp__(self, other):
raise ValueError
self.assertRaises(TypeError, min, (42, BadNumber()))
for stmt in ( for stmt in (
"min(key=int)", # no args "min(key=int)", # no args

View file

@ -56,31 +56,16 @@ class TestContains(unittest.TestCase):
This class is designed to make sure that the contains code This class is designed to make sure that the contains code
works when the list is modified during the check. works when the list is modified during the check.
""" """
aList = range(15) aList = list(range(15))
def __cmp__(self, other): def __eq__(self, other):
if other == 12: if other == 12:
self.aList.remove(12) self.aList.remove(12)
self.aList.remove(13) self.aList.remove(13)
self.aList.remove(14) self.aList.remove(14)
return 1 return 0
self.assert_(Deviant1() not in Deviant1.aList) self.assert_(Deviant1() not in Deviant1.aList)
class Deviant2:
"""Behaves strangely when compared
This class raises an exception during comparison. That in
turn causes the comparison to fail with a TypeError.
"""
def __cmp__(self, other):
if other == 4:
raise RuntimeError("gotcha")
try:
self.assert_(Deviant2() not in a)
except TypeError:
pass
def test_nonreflexive(self): def test_nonreflexive(self):
# containment and equality tests involving elements that are # containment and equality tests involving elements that are
# not necessarily equal to themselves # not necessarily equal to themselves

View file

@ -2,10 +2,14 @@
import copy import copy
import copyreg import copyreg
from operator import le, lt, ge, gt, eq, ne
import unittest import unittest
from test import support from test import support
order_comparisons = le, lt, ge, gt
equality_comparisons = eq, ne
comparisons = order_comparisons + equality_comparisons
class TestCopy(unittest.TestCase): class TestCopy(unittest.TestCase):
# Attempt full line coverage of copy.py from top to bottom # Attempt full line coverage of copy.py from top to bottom
@ -271,7 +275,8 @@ class TestCopy(unittest.TestCase):
x = [] x = []
x.append(x) x.append(x)
y = copy.deepcopy(x) y = copy.deepcopy(x)
self.assertRaises(RuntimeError, cmp, y, x) for op in comparisons:
self.assertRaises(RuntimeError, op, y, x)
self.assert_(y is not x) self.assert_(y is not x)
self.assert_(y[0] is y) self.assert_(y[0] is y)
self.assertEqual(len(y), 1) self.assertEqual(len(y), 1)
@ -287,7 +292,8 @@ class TestCopy(unittest.TestCase):
x = ([],) x = ([],)
x[0].append(x) x[0].append(x)
y = copy.deepcopy(x) y = copy.deepcopy(x)
self.assertRaises(RuntimeError, cmp, y, x) for op in comparisons:
self.assertRaises(RuntimeError, op, y, x)
self.assert_(y is not x) self.assert_(y is not x)
self.assert_(y[0] is not x[0]) self.assert_(y[0] is not x[0])
self.assert_(y[0][0] is y) self.assert_(y[0][0] is y)
@ -303,7 +309,10 @@ class TestCopy(unittest.TestCase):
x = {} x = {}
x['foo'] = x x['foo'] = x
y = copy.deepcopy(x) y = copy.deepcopy(x)
self.assertRaises(TypeError, cmp, y, x) for op in order_comparisons:
self.assertRaises(TypeError, op, y, x)
for op in equality_comparisons:
self.assertRaises(RuntimeError, op, y, x)
self.assert_(y is not x) self.assert_(y is not x)
self.assert_(y['foo'] is y) self.assert_(y['foo'] is y)
self.assertEqual(len(y), 1) self.assertEqual(len(y), 1)

View file

@ -7,6 +7,8 @@ import os
import pickle import pickle
import unittest import unittest
from operator import lt, le, gt, ge, eq, ne
from test import support from test import support
from datetime import MINYEAR, MAXYEAR from datetime import MINYEAR, MAXYEAR
@ -156,9 +158,6 @@ class HarmlessMixedComparison:
self.assertRaises(TypeError, lambda: () > me) self.assertRaises(TypeError, lambda: () > me)
self.assertRaises(TypeError, lambda: () >= me) self.assertRaises(TypeError, lambda: () >= me)
self.assertRaises(TypeError, cmp, (), me)
self.assertRaises(TypeError, cmp, me, ())
############################################################################# #############################################################################
# timedelta tests # timedelta tests
@ -309,8 +308,6 @@ class TestTimeDelta(HarmlessMixedComparison, unittest.TestCase):
self.failUnless(not t1 != t2) self.failUnless(not t1 != t2)
self.failUnless(not t1 < t2) 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): for args in (3, 3, 3), (2, 4, 4), (2, 3, 5):
t2 = timedelta(*args) # this is larger than t1 t2 = timedelta(*args) # this is larger than t1
@ -326,8 +323,6 @@ class TestTimeDelta(HarmlessMixedComparison, unittest.TestCase):
self.failUnless(not t2 < t1) self.failUnless(not t2 < t1)
self.failUnless(not t1 >= t2) self.failUnless(not t1 >= t2)
self.failUnless(not t2 <= t1) self.failUnless(not t2 <= t1)
self.assertEqual(cmp(t1, t2), -1)
self.assertEqual(cmp(t2, t1), 1)
for badarg in OTHERSTUFF: for badarg in OTHERSTUFF:
self.assertEqual(t1 == badarg, False) self.assertEqual(t1 == badarg, False)
@ -953,8 +948,6 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase):
self.failUnless(not t1 != t2) self.failUnless(not t1 != t2)
self.failUnless(not t1 < t2) 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): for args in (3, 3, 3), (2, 4, 4), (2, 3, 5):
t2 = self.theclass(*args) # this is larger than t1 t2 = self.theclass(*args) # this is larger than t1
@ -970,8 +963,6 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase):
self.failUnless(not t2 < t1) self.failUnless(not t2 < t1)
self.failUnless(not t1 >= t2) self.failUnless(not t1 >= t2)
self.failUnless(not t2 <= t1) self.failUnless(not t2 <= t1)
self.assertEqual(cmp(t1, t2), -1)
self.assertEqual(cmp(t2, t1), 1)
for badarg in OTHERSTUFF: for badarg in OTHERSTUFF:
self.assertEqual(t1 == badarg, False) self.assertEqual(t1 == badarg, False)
@ -999,8 +990,6 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase):
# But the ordering is undefined # But the ordering is undefined
self.assertRaises(TypeError, lambda: our < 1) self.assertRaises(TypeError, lambda: our < 1)
self.assertRaises(TypeError, lambda: 1 < our) 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 # Repeat those tests with a different class
@ -1014,8 +1003,6 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase):
self.assertEqual(their != our, True) self.assertEqual(their != our, True)
self.assertRaises(TypeError, lambda: our < their) self.assertRaises(TypeError, lambda: our < their)
self.assertRaises(TypeError, lambda: their < our) 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 # However, if the other class explicitly defines ordering
# relative to our class, it is allowed to do so # relative to our class, it is allowed to do so
@ -1041,8 +1028,6 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase):
self.assertEqual(their != our, True) self.assertEqual(their != our, True)
self.assertEqual(our < their, True) self.assertEqual(our < their, True)
self.assertEqual(their < our, False) self.assertEqual(their < our, False)
self.assertEqual(cmp(our, their), -1)
self.assertEqual(cmp(their, our), 1)
def test_bool(self): def test_bool(self):
# All dates are considered true. # All dates are considered true.
@ -1440,8 +1425,6 @@ class TestDateTime(TestDate):
self.failUnless(not t1 != t2) self.failUnless(not t1 != t2)
self.failUnless(not t1 < t2) 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)): for i in range(len(args)):
newargs = args[:] newargs = args[:]
@ -1459,8 +1442,6 @@ class TestDateTime(TestDate):
self.failUnless(not t2 < t1) self.failUnless(not t2 < t1)
self.failUnless(not t1 >= t2) self.failUnless(not t1 >= t2)
self.failUnless(not t2 <= t1) self.failUnless(not t2 <= t1)
self.assertEqual(cmp(t1, t2), -1)
self.assertEqual(cmp(t2, t1), 1)
# A helper for timestamp constructor tests. # A helper for timestamp constructor tests.
@ -1728,8 +1709,6 @@ class TestTime(HarmlessMixedComparison, unittest.TestCase):
self.failUnless(not t1 != t2) self.failUnless(not t1 != t2)
self.failUnless(not t1 < t2) 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)): for i in range(len(args)):
newargs = args[:] newargs = args[:]
@ -1747,8 +1726,6 @@ class TestTime(HarmlessMixedComparison, unittest.TestCase):
self.failUnless(not t2 < t1) self.failUnless(not t2 < t1)
self.failUnless(not t1 >= t2) self.failUnless(not t1 >= t2)
self.failUnless(not t2 <= t1) self.failUnless(not t2 <= t1)
self.assertEqual(cmp(t1, t2), -1)
self.assertEqual(cmp(t2, t1), 1)
for badarg in OTHERSTUFF: for badarg in OTHERSTUFF:
self.assertEqual(t1 == badarg, False) self.assertEqual(t1 == badarg, False)
@ -2122,9 +2099,10 @@ class TZInfoBase:
d2 = base.replace(minute=11) d2 = base.replace(minute=11)
for x in d0, d1, d2: for x in d0, d1, d2:
for y in d0, d1, d2: for y in d0, d1, d2:
got = cmp(x, y) for op in lt, le, gt, ge, eq, ne:
expected = cmp(x.minute, y.minute) got = op(x, y)
self.assertEqual(got, expected) expected = op(x.minute, y.minute)
self.assertEqual(got, expected)
# However, if they're different members, uctoffset is not ignored. # However, if they're different members, uctoffset is not ignored.
# Note that a time can't actually have an operand-depedent offset, # Note that a time can't actually have an operand-depedent offset,
@ -2136,7 +2114,7 @@ class TZInfoBase:
d2 = base.replace(minute=11, tzinfo=OperandDependentOffset()) d2 = base.replace(minute=11, tzinfo=OperandDependentOffset())
for x in d0, d1, d2: for x in d0, d1, d2:
for y in d0, d1, d2: for y in d0, d1, d2:
got = cmp(x, y) got = (x > y) - (x < y)
if (x is d0 or x is d1) and (y is d0 or y is d1): if (x is d0 or x is d1) and (y is d0 or y is d1):
expected = 0 expected = 0
elif x is y is d2: elif x is y is d2:

View file

@ -1012,17 +1012,11 @@ class DecimalUsabilityTest(unittest.TestCase):
self.failUnless(da != dc) self.failUnless(da != dc)
self.failUnless(da <= db) self.failUnless(da <= db)
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 #a Decimal and an int
self.failUnless(dc > 23) self.failUnless(dc > 23)
self.failUnless(23 < dc) self.failUnless(23 < dc)
self.assertEqual(dc, 45) 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 #a Decimal and uncomparable
self.assertNotEqual(da, 'ugly') self.assertNotEqual(da, 'ugly')

View file

@ -103,7 +103,6 @@ class TestBasic(unittest.TestCase):
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(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): def test_extend(self):
d = deque('a') d = deque('a')

View file

@ -172,7 +172,6 @@ class OperatorsTest(unittest.TestCase):
def test_dicts(self): def test_dicts(self):
# Testing dict operations... # 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}, 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}, 2, 0, "b in a", "__contains__")
self.binop_test({1:2,3:4}, 1, 2, "a[b]", "__getitem__") self.binop_test({1:2,3:4}, 1, 2, "a[b]", "__getitem__")
@ -332,8 +331,6 @@ class OperatorsTest(unittest.TestCase):
# This is an ugly hack: # This is an ugly hack:
copy._deepcopy_dispatch[spam.spamdict] = spamdict 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}), 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}), 2, 0, "b in a", "__contains__")
self.binop_test(spamdict({1:2,3:4}), 1, 2, "a[b]", "__getitem__") self.binop_test(spamdict({1:2,3:4}), 1, 2, "a[b]", "__getitem__")
@ -1004,8 +1001,8 @@ order (MRO) for bases """
# Test lookup leaks [SF bug 572567] # Test lookup leaks [SF bug 572567]
import sys,gc import sys,gc
class G(object): class G(object):
def __cmp__(self, other): def __eq__(self, other):
return 0 return 1
g = G() g = G()
orig_objects = len(gc.get_objects()) orig_objects = len(gc.get_objects())
for i in range(10): for i in range(10):
@ -1525,7 +1522,6 @@ order (MRO) for bases """
self.assertNotEqual(id(c1), id(c2)) self.assertNotEqual(id(c1), id(c2))
hash(c1) hash(c1)
hash(c2) hash(c2)
## self.assertEqual(cmp(c1, c2), cmp(id(c1), id(c2)))
self.assertEqual(c1, c1) self.assertEqual(c1, c1)
self.assert_(c1 != c2) self.assert_(c1 != c2)
self.assert_(not c1 != c1) self.assert_(not c1 != c1)
@ -1549,7 +1545,6 @@ order (MRO) for bases """
self.assertNotEqual(id(d1), id(d2)) self.assertNotEqual(id(d1), id(d2))
hash(d1) hash(d1)
hash(d2) hash(d2)
## self.assertEqual(cmp(d1, d2), cmp(id(d1), id(d2)))
self.assertEqual(d1, d1) self.assertEqual(d1, d1)
self.assertNotEqual(d1, d2) self.assertNotEqual(d1, d2)
self.assert_(not d1 != d1) self.assert_(not d1 != d1)
@ -1610,23 +1605,6 @@ order (MRO) for bases """
self.assert_(i in p10) self.assert_(i in p10)
self.assertFalse(10 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): def test_weakrefs(self):
# Testing weak references... # Testing weak references...
import weakref import weakref
@ -2538,12 +2516,16 @@ order (MRO) for bases """
c = {1: c1, 2: c2, 3: c3} c = {1: c1, 2: c2, 3: c3}
for x in 1, 2, 3: for x in 1, 2, 3:
for y 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 "<", "<=", "==", "!=", ">", ">=": for op in "<", "<=", "==", "!=", ">", ">=":
self.assert_(eval("c[x] %s c[y]" % op) == eval("x %s y" % op), self.assert_(eval("c[x] %s c[y]" % op) ==
"x=%d, y=%d" % (x, y)) eval("x %s y" % op),
## self.assert_(cmp(c[x], y) == cmp(x, y), "x=%d, y=%d" % (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 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): def test_rich_comparisons(self):
# Testing rich comparisons... # Testing rich comparisons...

View file

@ -570,7 +570,7 @@ class DictTest(unittest.TestCase):
self.fail("missing KeyError") self.fail("missing KeyError")
def test_bad_key(self): 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): class CustomException(Exception):
pass pass

View file

@ -55,13 +55,8 @@ class OnlyInequality(object):
def __ne__(self, other): def __ne__(self, other):
return self is not 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 InheritedHashWithEquality(FixedHash, OnlyEquality): pass
class InheritedHashWithInequality(FixedHash, OnlyInequality): pass class InheritedHashWithInequality(FixedHash, OnlyInequality): pass
class InheritedHashWithCmp(FixedHash, OnlyCmp): pass
class NoHash(object): class NoHash(object):
__hash__ = None __hash__ = None
@ -74,7 +69,6 @@ class HashInheritanceTestCase(unittest.TestCase):
fixed_expected = [FixedHash(), fixed_expected = [FixedHash(),
InheritedHashWithEquality(), InheritedHashWithEquality(),
InheritedHashWithInequality(), InheritedHashWithInequality(),
InheritedHashWithCmp(),
] ]
error_expected = [NoHash(), error_expected = [NoHash(),
OnlyEquality(), OnlyEquality(),

View file

@ -234,9 +234,9 @@ class GetOnly:
class CmpErr: class CmpErr:
"Dummy element that always raises an error during comparison" "Dummy element that always raises an error during comparison"
def __cmp__(self, other): def __eq__(self, other):
raise ZeroDivisionError raise ZeroDivisionError
__eq__ = __ne__ = __lt__ = __le__ = __gt__ = __ge__ = __cmp__ __ne__ = __lt__ = __le__ = __gt__ = __ge__ = __eq__
def R(seqn): def R(seqn):
'Regular generator' 'Regular generator'

View file

@ -291,7 +291,7 @@ class CopyTestCase(unittest.TestCase):
# Testing if the copy method created a real copy. # Testing if the copy method created a real copy.
h1 = hmac.HMAC(b"key") h1 = hmac.HMAC(b"key")
h2 = h1.copy() 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) != id(h2), "No real copy of the HMAC instance.")
self.failUnless(id(h1.inner) != id(h2.inner), self.failUnless(id(h1.inner) != id(h2.inner),
"No real copy of the attribute 'inner'.") "No real copy of the attribute 'inner'.")

View file

@ -22,6 +22,7 @@ class TestKQueue(unittest.TestCase):
self.assertRaises(ValueError, kq.fileno) self.assertRaises(ValueError, kq.fileno)
def test_create_event(self): def test_create_event(self):
from operator import lt, le, gt, ge
fd = sys.stderr.fileno() fd = sys.stderr.fileno()
ev = select.kevent(fd) ev = select.kevent(fd)
other = select.kevent(1000) other = select.kevent(1000)
@ -33,12 +34,12 @@ class TestKQueue(unittest.TestCase):
self.assertEqual(ev.udata, 0) self.assertEqual(ev.udata, 0)
self.assertEqual(ev, ev) self.assertEqual(ev, ev)
self.assertNotEqual(ev, other) self.assertNotEqual(ev, other)
self.assertEqual(cmp(ev, other), -1)
self.assert_(ev < other) self.assert_(ev < other)
self.assert_(other >= ev) self.assert_(other >= ev)
self.assertRaises(TypeError, cmp, ev, None) for op in lt, le, gt, ge:
self.assertRaises(TypeError, cmp, ev, 1) self.assertRaises(TypeError, op, ev, None)
self.assertRaises(TypeError, cmp, ev, "ev") self.assertRaises(TypeError, op, ev, 1)
self.assertRaises(TypeError, op, ev, "ev")
ev = select.kevent(fd, select.KQ_FILTER_WRITE) ev = select.kevent(fd, select.KQ_FILTER_WRITE)
self.assertEqual(ev.ident, fd) self.assertEqual(ev.ident, fd)

View file

@ -697,7 +697,8 @@ class LongTest(unittest.TestCase):
def _cmp__(self, other): def _cmp__(self, other):
if not isinstance(other, Rat): if not isinstance(other, Rat):
other = Rat(other) 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): def __eq__(self, other):
return self._cmp__(other) == 0 return self._cmp__(other) == 0
def __ne__(self, other): def __ne__(self, other):
@ -727,8 +728,8 @@ class LongTest(unittest.TestCase):
Rx = Rat(x) Rx = Rat(x)
for y in cases: for y in cases:
Ry = Rat(y) Ry = Rat(y)
Rcmp = cmp(Rx, Ry) Rcmp = (Rx > Ry) - (Rx < Ry)
xycmp = cmp(x, y) xycmp = (x > y) - (x < y)
eq(Rcmp, xycmp, Frm("%r %r %d %d", x, y, Rcmp, xycmp)) 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))
eq(x != y, Rcmp != 0, Frm("%r != %r %d", x, y, Rcmp)) eq(x != y, Rcmp != 0, Frm("%r != %r %d", x, y, Rcmp))

View file

@ -1036,16 +1036,6 @@ class TestBinaryOps(unittest.TestCase):
result = self.set ^ set([8]) result = self.set ^ set([8])
self.assertEqual(result, set([2, 4, 6, 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): class TestUpdateOps(unittest.TestCase):

View file

@ -102,7 +102,7 @@ class TestBase(unittest.TestCase):
y = x[:] y = x[:]
y.reverse() y.reverse()
s = x[:] 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<a))
if verbose: if verbose:
print(" Checking against an insane comparison function.") print(" Checking against an insane comparison function.")
@ -157,13 +157,13 @@ class TestBugs(unittest.TestCase):
def mutating_cmp(x, y): def mutating_cmp(x, y):
L.append(3) L.append(3)
L.pop() L.pop()
return cmp(x, y) return (x > y) - (x < y)
L = [1,2] L = [1,2]
self.assertRaises(ValueError, L.sort, key=CmpToKey(mutating_cmp)) self.assertRaises(ValueError, L.sort, key=CmpToKey(mutating_cmp))
def mutating_cmp(x, y): def mutating_cmp(x, y):
L.append(3) L.append(3)
del L[:] del L[:]
return cmp(x, y) return (x > y) - (x < y)
self.assertRaises(ValueError, L.sort, key=CmpToKey(mutating_cmp)) self.assertRaises(ValueError, L.sort, key=CmpToKey(mutating_cmp))
memorywaster = [memorywaster] memorywaster = [memorywaster]
@ -176,7 +176,10 @@ class TestDecorateSortUndecorate(unittest.TestCase):
copy = data[:] copy = data[:]
random.shuffle(data) random.shuffle(data)
data.sort(key=str.lower) 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): def test_baddecorator(self):
data = 'The quick Brown fox Jumped over The lazy Dog'.split() data = 'The quick Brown fox Jumped over The lazy Dog'.split()
@ -246,8 +249,14 @@ class TestDecorateSortUndecorate(unittest.TestCase):
data = [(random.randrange(100), i) for i in range(200)] data = [(random.randrange(100), i) for i in range(200)]
copy1 = data[:] copy1 = data[:]
copy2 = data[:] copy2 = data[:]
data.sort(key=CmpToKey(lambda x,y: cmp(x[0],y[0])), reverse=True) def my_cmp(x, y):
copy1.sort(key=CmpToKey(lambda x,y: cmp(y[0],x[0]))) 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) self.assertEqual(data, copy1)
copy2.sort(key=lambda x: x[0], reverse=True) copy2.sort(key=lambda x: x[0], reverse=True)
self.assertEqual(data, copy2) self.assertEqual(data, copy2)

View file

@ -1103,7 +1103,7 @@ class Test_TestLoader(TestCase):
# getTestCaseNames() and all the loadTestsFromX() methods" # getTestCaseNames() and all the loadTestsFromX() methods"
def test_sortTestMethodsUsing__loadTestsFromTestCase(self): def test_sortTestMethodsUsing__loadTestsFromTestCase(self):
def reversed_cmp(x, y): def reversed_cmp(x, y):
return -cmp(x, y) return -((x > y) - (x < y))
class Foo(unittest.TestCase): class Foo(unittest.TestCase):
def test_1(self): pass def test_1(self): pass
@ -1119,7 +1119,7 @@ class Test_TestLoader(TestCase):
# getTestCaseNames() and all the loadTestsFromX() methods" # getTestCaseNames() and all the loadTestsFromX() methods"
def test_sortTestMethodsUsing__loadTestsFromModule(self): def test_sortTestMethodsUsing__loadTestsFromModule(self):
def reversed_cmp(x, y): def reversed_cmp(x, y):
return -cmp(x, y) return -((x > y) - (x < y))
m = types.ModuleType('m') m = types.ModuleType('m')
class Foo(unittest.TestCase): class Foo(unittest.TestCase):
@ -1137,7 +1137,7 @@ class Test_TestLoader(TestCase):
# getTestCaseNames() and all the loadTestsFromX() methods" # getTestCaseNames() and all the loadTestsFromX() methods"
def test_sortTestMethodsUsing__loadTestsFromName(self): def test_sortTestMethodsUsing__loadTestsFromName(self):
def reversed_cmp(x, y): def reversed_cmp(x, y):
return -cmp(x, y) return -((x > y) - (x < y))
m = types.ModuleType('m') m = types.ModuleType('m')
class Foo(unittest.TestCase): class Foo(unittest.TestCase):
@ -1155,7 +1155,7 @@ class Test_TestLoader(TestCase):
# getTestCaseNames() and all the loadTestsFromX() methods" # getTestCaseNames() and all the loadTestsFromX() methods"
def test_sortTestMethodsUsing__loadTestsFromNames(self): def test_sortTestMethodsUsing__loadTestsFromNames(self):
def reversed_cmp(x, y): def reversed_cmp(x, y):
return -cmp(x, y) return -((x > y) - (x < y))
m = types.ModuleType('m') m = types.ModuleType('m')
class Foo(unittest.TestCase): class Foo(unittest.TestCase):
@ -1175,7 +1175,7 @@ class Test_TestLoader(TestCase):
# Does it actually affect getTestCaseNames()? # Does it actually affect getTestCaseNames()?
def test_sortTestMethodsUsing__getTestCaseNames(self): def test_sortTestMethodsUsing__getTestCaseNames(self):
def reversed_cmp(x, y): def reversed_cmp(x, y):
return -cmp(x, y) return -((x > y) - (x < y))
class Foo(unittest.TestCase): class Foo(unittest.TestCase):
def test_1(self): pass def test_1(self): pass
@ -1188,9 +1188,19 @@ class Test_TestLoader(TestCase):
self.assertEqual(loader.getTestCaseNames(Foo), test_names) self.assertEqual(loader.getTestCaseNames(Foo), test_names)
# "The default value is the built-in cmp() function" # "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): def test_sortTestMethodsUsing__default_value(self):
loader = unittest.TestLoader() 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." # "it can be set to None to disable the sort."
# #

View file

@ -47,7 +47,7 @@ class UserDictTest(mapping_tests.TestHashMappingProtocol):
self.assertEqual(repr(u1), repr(d1)) self.assertEqual(repr(u1), repr(d1))
self.assertEqual(repr(u2), repr(d2)) 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] all = [d0, d1, d2, u, u0, u1, u2, uu, uu0, uu1, uu2]
for a in all: for a in all:
for b in all: for b in all:

View file

@ -181,7 +181,12 @@ class TestUUID(TestCase):
# Test comparison of UUIDs. # Test comparison of UUIDs.
for i in range(len(ascending)): for i in range(len(ascending)):
for j in range(len(ascending)): for j in range(len(ascending)):
equal(cmp(i, j), cmp(ascending[i], ascending[j])) equal(i < j, ascending[i] < ascending[j])
equal(i <= j, ascending[i] <= ascending[j])
equal(i == j, ascending[i] == ascending[j])
equal(i > j, ascending[i] > ascending[j])
equal(i >= j, ascending[i] >= ascending[j])
equal(i != j, ascending[i] != ascending[j])
# Test sorting of UUIDs (above list is in ascending order). # Test sorting of UUIDs (above list is in ascending order).
resorted = ascending[:] resorted = ascending[:]

View file

@ -539,12 +539,16 @@ def CmpToKey(mycmp):
return mycmp(self.obj, other.obj) == -1 return mycmp(self.obj, other.obj) == -1
return K return K
def three_way_cmp(x, y):
"""Return -1 if x < y, 0 if x == y and 1 if x > y"""
return (x > y) - (x < y)
class TestLoader(object): class TestLoader(object):
"""This class is responsible for loading tests according to various """This class is responsible for loading tests according to various
criteria and returning them wrapped in a TestSuite criteria and returning them wrapped in a TestSuite
""" """
testMethodPrefix = 'test' testMethodPrefix = 'test'
sortTestMethodsUsing = cmp sortTestMethodsUsing = staticmethod(three_way_cmp)
suiteClass = TestSuite suiteClass = TestSuite
def loadTestsFromTestCase(self, testCaseClass): def loadTestsFromTestCase(self, testCaseClass):

View file

@ -520,11 +520,29 @@ class NamedNodeMap(object):
__len__ = _get_length __len__ = _get_length
def __cmp__(self, other): def _cmp(self, other):
if self._attrs is getattr(other, "_attrs", None): if self._attrs is getattr(other, "_attrs", None):
return 0 return 0
else: else:
return cmp(id(self), id(other)) return (id(self) > id(other)) - (id(self) < id(other))
def __eq__(self, other):
return self._cmp(other) == 0
def __ge__(self, other):
return self._cmp(other) >= 0
def __gt__(self, other):
return self._cmp(other) > 0
def __le__(self, other):
return self._cmp(other) <= 0
def __lt__(self, other):
return self._cmp(other) < 0
def __ne__(self, other):
return self._cmp(other) != 0
def __getitem__(self, attname_or_tuple): def __getitem__(self, attname_or_tuple):
if isinstance(attname_or_tuple, tuple): if isinstance(attname_or_tuple, tuple):

View file

@ -498,10 +498,30 @@ class QName:
return self.text return self.text
def __hash__(self): def __hash__(self):
return hash(self.text) return hash(self.text)
def __cmp__(self, other): def __le__(self, other):
if isinstance(other, QName): if isinstance(other, QName):
return cmp(self.text, other.text) return self.text <= other.text
return cmp(self.text, other) return self.text <= other
def __lt__(self, other):
if isinstance(other, QName):
return self.text < other.text
return self.text < other
def __ge__(self, other):
if isinstance(other, QName):
return self.text >= other.text
return self.text >= other
def __gt__(self, other):
if isinstance(other, QName):
return self.text > other.text
return self.text > other
def __eq__(self, other):
if isinstance(other, QName):
return self.text == other.text
return self.text == other
def __ne__(self, other):
if isinstance(other, QName):
return self.text != other.text
return self.text != other
## ##
# ElementTree wrapper class. This class represents an entire element # ElementTree wrapper class. This class represents an entire element

View file

@ -349,10 +349,6 @@ class DateTime:
def timetuple(self): def timetuple(self):
return time.strptime(self.value, "%Y%m%dT%H:%M:%S") 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. # Get date/time value.
# #

View file

@ -457,15 +457,6 @@ def makeunicodetype(unicode, trace):
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# unicode name database # 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): def makeunicodename(unicode, trace):
FILE = "Modules/unicodename_db.h" FILE = "Modules/unicodename_db.h"
@ -508,14 +499,10 @@ def makeunicodename(unicode, trace):
wordlist = list(words.items()) wordlist = list(words.items())
# sort on falling frequency, then by name # sort on falling frequency, then by name
def cmpwords(a,b): def word_key(a):
aword, alist = a aword, alist = a
bword, blist = b return -len(alist), aword
r = -cmp(len(alist),len(blist)) wordlist.sort(key=word_key)
if r:
return r
return cmp(aword, bword)
wordlist.sort(key=CmpToKey(cmpwords))
# figure out how many phrasebook escapes we need # figure out how many phrasebook escapes we need
escapes = 0 escapes = 0