Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a56c467

Browse files
committed
Issue #1717: Remove cmp. Stage 1: remove all uses of cmp and __cmp__ from
the standard library and tests.
1 parent 191e850 commit a56c467

32 files changed

Lines changed: 210 additions & 216 deletions

Lib/collections.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,8 +436,6 @@ def __gt__(self, other): return self.data > self.__cast(other)
436436
def __ge__(self, other): return self.data >= self.__cast(other)
437437
def __cast(self, other):
438438
return other.data if isinstance(other, UserList) else other
439-
def __cmp__(self, other):
440-
return cmp(self.data, self.__cast(other))
441439
def __contains__(self, item): return item in self.data
442440
def __len__(self): return len(self.data)
443441
def __getitem__(self, i): return self.data[i]

Lib/ctypes/test/test_libc.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55

66
lib = CDLL(_ctypes_test.__file__)
77

8+
def three_way_cmp(x, y):
9+
"""Return -1 if x < y, 0 if x == y and 1 if x > y"""
10+
return (x > y) - (x < y)
11+
812
class LibTest(unittest.TestCase):
913
def test_sqrt(self):
1014
lib.my_sqrt.argtypes = c_double,
@@ -19,7 +23,7 @@ def test_qsort(self):
1923
lib.my_qsort.restype = None
2024

2125
def sort(a, b):
22-
return cmp(a[0], b[0])
26+
return three_way_cmp(a[0], b[0])
2327

2428
chars = create_string_buffer("spam, spam, and spam")
2529
lib.my_qsort(chars, len(chars)-1, sizeof(c_char), comparefunc(sort))

Lib/distutils/version.py

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
an equivalent string -- ie. one that will generate an equivalent
2222
version number instance)
2323
* __repr__ generates Python code to recreate the version number instance
24-
* __cmp__ compares the current instance with either another instance
24+
* _cmp compares the current instance with either another instance
2525
of the same class or a string (which will be parsed to an instance
2626
of the same class, thus must follow the same rules)
2727
"""
@@ -32,7 +32,7 @@ class Version:
3232
"""Abstract base class for version numbering classes. Just provides
3333
constructor (__init__) and reproducer (__repr__), because those
3434
seem to be the same for all version numbering classes; and route
35-
rich comparisons to __cmp__.
35+
rich comparisons to _cmp.
3636
"""
3737

3838
def __init__ (self, vstring=None):
@@ -43,37 +43,37 @@ def __repr__ (self):
4343
return "%s ('%s')" % (self.__class__.__name__, str(self))
4444

4545
def __eq__(self, other):
46-
c = self.__cmp__(other)
46+
c = self._cmp(other)
4747
if c is NotImplemented:
4848
return c
4949
return c == 0
5050

5151
def __ne__(self, other):
52-
c = self.__cmp__(other)
52+
c = self._cmp(other)
5353
if c is NotImplemented:
5454
return c
5555
return c != 0
5656

5757
def __lt__(self, other):
58-
c = self.__cmp__(other)
58+
c = self._cmp(other)
5959
if c is NotImplemented:
6060
return c
6161
return c < 0
6262

6363
def __le__(self, other):
64-
c = self.__cmp__(other)
64+
c = self._cmp(other)
6565
if c is NotImplemented:
6666
return c
6767
return c <= 0
6868

6969
def __gt__(self, other):
70-
c = self.__cmp__(other)
70+
c = self._cmp(other)
7171
if c is NotImplemented:
7272
return c
7373
return c > 0
7474

7575
def __ge__(self, other):
76-
c = self.__cmp__(other)
76+
c = self._cmp(other)
7777
if c is NotImplemented:
7878
return c
7979
return c >= 0
@@ -91,7 +91,7 @@ def __ge__(self, other):
9191
# (if not identical to) the string supplied to parse
9292
# __repr__ (self) - generate Python code to recreate
9393
# the instance
94-
# __cmp__ (self, other) - compare two version numbers ('other' may
94+
# _cmp (self, other) - compare two version numbers ('other' may
9595
# be an unparsed version string, or another
9696
# instance of your version class)
9797

@@ -169,30 +169,39 @@ def __str__ (self):
169169
return vstring
170170

171171

172-
def __cmp__ (self, other):
172+
def _cmp (self, other):
173173
if isinstance(other, str):
174174
other = StrictVersion(other)
175175

176-
compare = cmp(self.version, other.version)
177-
if (compare == 0): # have to compare prerelease
178-
179-
# case 1: neither has prerelease; they're equal
180-
# case 2: self has prerelease, other doesn't; other is greater
181-
# case 3: self doesn't have prerelease, other does: self is greater
182-
# case 4: both have prerelease: must compare them!
176+
if self.version != other.version:
177+
# numeric versions don't match
178+
# prerelease stuff doesn't matter
179+
if self.version < other.version:
180+
return -1
181+
else:
182+
return 1
183183

184-
if (not self.prerelease and not other.prerelease):
184+
# have to compare prerelease
185+
# case 1: neither has prerelease; they're equal
186+
# case 2: self has prerelease, other doesn't; other is greater
187+
# case 3: self doesn't have prerelease, other does: self is greater
188+
# case 4: both have prerelease: must compare them!
189+
190+
if (not self.prerelease and not other.prerelease):
191+
return 0
192+
elif (self.prerelease and not other.prerelease):
193+
return -1
194+
elif (not self.prerelease and other.prerelease):
195+
return 1
196+
elif (self.prerelease and other.prerelease):
197+
if self.prerelease == other.prerelease:
185198
return 0
186-
elif (self.prerelease and not other.prerelease):
199+
elif self.prerelease < other.prerelease:
187200
return -1
188-
elif (not self.prerelease and other.prerelease):
201+
else:
189202
return 1
190-
elif (self.prerelease and other.prerelease):
191-
return cmp(self.prerelease, other.prerelease)
192-
193-
else: # numeric versions don't match --
194-
return compare # prerelease stuff doesn't matter
195-
203+
else:
204+
assert False, "never get here"
196205

197206
# end class StrictVersion
198207

@@ -325,7 +334,7 @@ def __repr__ (self):
325334
return "LooseVersion ('%s')" % str(self)
326335

327336

328-
def __cmp__ (self, other):
337+
def _cmp (self, other):
329338
if isinstance(other, str):
330339
other = LooseVersion(other)
331340

Lib/heapq.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ def _siftdown(heap, startpos, pos):
262262
#
263263
# Cutting the # of comparisons is important, since these routines have no
264264
# way to extract "the priority" from an array element, so that intelligence
265-
# is likely to be hiding in custom __cmp__ methods, or in array elements
265+
# is likely to be hiding in custom comparison methods, or in array elements
266266
# storing (priority, record) tuples. Comparisons are thus potentially
267267
# expensive.
268268
#

Lib/locale.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def _strcoll(a,b):
3131
""" strcoll(string,string) -> int.
3232
Compares two strings according to the locale.
3333
"""
34-
return cmp(a,b)
34+
return (a > b) - (a < b)
3535

3636
def _strxfrm(s):
3737
""" strxfrm(string) -> string.

Lib/pydoc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1643,7 +1643,7 @@ class Helper:
16431643
'SPECIALMETHODS': ('specialnames', 'BASICMETHODS ATTRIBUTEMETHODS '
16441644
'CALLABLEMETHODS SEQUENCEMETHODS1 MAPPINGMETHODS '
16451645
'SEQUENCEMETHODS2 NUMBERMETHODS CLASSES'),
1646-
'BASICMETHODS': ('customization', 'cmp hash repr str SPECIALMETHODS'),
1646+
'BASICMETHODS': ('customization', 'hash repr str SPECIALMETHODS'),
16471647
'ATTRIBUTEMETHODS': ('attribute-access', 'ATTRIBUTES SPECIALMETHODS'),
16481648
'CALLABLEMETHODS': ('callable-types', 'CALLS SPECIALMETHODS'),
16491649
'SEQUENCEMETHODS': ('sequence-types', 'SEQUENCES SEQUENCEMETHODS2 '

Lib/sqlite3/test/hooks.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def CheckCreateCollationNotCallable(self):
4242
def CheckCreateCollationNotAscii(self):
4343
con = sqlite.connect(":memory:")
4444
try:
45-
con.create_collation("collä", cmp)
45+
con.create_collation("collä", lambda x, y: (x > y) - (x < y))
4646
self.fail("should have raised a ProgrammingError")
4747
except sqlite.ProgrammingError as e:
4848
pass
@@ -52,7 +52,7 @@ def CheckCollationIsUsed(self):
5252
return
5353
def mycoll(x, y):
5454
# reverse order
55-
return -cmp(x, y)
55+
return -((x > y) - (x < y))
5656

5757
con = sqlite.connect(":memory:")
5858
con.create_collation("mycoll", mycoll)
@@ -82,8 +82,8 @@ def CheckCollationRegisterTwice(self):
8282
Verify that the last one is actually used.
8383
"""
8484
con = sqlite.connect(":memory:")
85-
con.create_collation("mycoll", cmp)
86-
con.create_collation("mycoll", lambda x, y: -cmp(x, y))
85+
con.create_collation("mycoll", lambda x, y: (x > y) - (x < y))
86+
con.create_collation("mycoll", lambda x, y: -((x > y) - (x < y)))
8787
result = con.execute("""
8888
select x from (select 'a' as x union select 'b' as x) order by x collate mycoll
8989
""").fetchall()
@@ -96,7 +96,7 @@ def CheckDeregisterCollation(self):
9696
to use it.
9797
"""
9898
con = sqlite.connect(":memory:")
99-
con.create_collation("mycoll", cmp)
99+
con.create_collation("mycoll", lambda x, y: (x > y) - (x < y))
100100
con.create_collation("mycoll", None)
101101
try:
102102
con.execute("select 'a' as x union select 'b' as x order by x collate mycoll")

Lib/test/crashers/loosing_mro_ref.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ class MyKey(object):
1010
def __hash__(self):
1111
return hash('mykey')
1212

13-
def __cmp__(self, other):
13+
def __eq__(self, other):
1414
# the following line decrefs the previous X.__mro__
1515
X.__bases__ = (Base2,)
1616
# trash all tuples of length 3, to make sure that the items of
1717
# the previous X.__mro__ are really garbage
1818
z = []
1919
for i in range(1000):
2020
z.append((i, None, None))
21-
return -1
21+
return 0
2222

2323

2424
class Base(object):

Lib/test/list_tests.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -439,21 +439,37 @@ def test_sort(self):
439439
self.assertRaises(TypeError, u.sort, 42, 42)
440440

441441
def revcmp(a, b):
442-
return cmp(b, a)
442+
if a == b:
443+
return 0
444+
elif a < b:
445+
return 1
446+
else: # a > b
447+
return -1
443448
u.sort(key=CmpToKey(revcmp))
444449
self.assertEqual(u, self.type2test([2,1,0,-1,-2]))
445450

446451
# The following dumps core in unpatched Python 1.5:
447452
def myComparison(x,y):
448-
return cmp(x%3, y%7)
453+
xmod, ymod = x%3, y%7
454+
if xmod == ymod:
455+
return 0
456+
elif xmod < ymod:
457+
return -1
458+
else: # xmod > ymod
459+
return 1
449460
z = self.type2test(range(12))
450461
z.sort(key=CmpToKey(myComparison))
451462

452463
self.assertRaises(TypeError, z.sort, 2)
453464

454465
def selfmodifyingComparison(x,y):
455466
z.append(1)
456-
return cmp(x, y)
467+
if x == y:
468+
return 0
469+
elif x < y:
470+
return -1
471+
else: # x > y
472+
return 1
457473
self.assertRaises(ValueError, z.sort, key=CmpToKey(selfmodifyingComparison))
458474

459475
self.assertRaises(TypeError, z.sort, 42, 42, 42, 42)

Lib/test/test_builtin.py

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
FutureWarning, __name__)
1111
warnings.filterwarnings("ignore", "integer argument expected",
1212
DeprecationWarning, "unittest")
13+
import builtins
1314

1415
class Squares:
1516

@@ -219,21 +220,9 @@ def test_chr(self):
219220
self.assertRaises((OverflowError, ValueError), chr, 2**32)
220221

221222
def test_cmp(self):
222-
self.assertEqual(cmp(-1, 1), -1)
223-
self.assertEqual(cmp(1, -1), 1)
224-
self.assertEqual(cmp(1, 1), 0)
225-
# verify that circular objects are not handled
226-
a = []; a.append(a)
227-
b = []; b.append(b)
228-
from collections import UserList
229-
c = UserList(); c.append(c)
230-
self.assertRaises(RuntimeError, cmp, a, b)
231-
self.assertRaises(RuntimeError, cmp, b, c)
232-
self.assertRaises(RuntimeError, cmp, c, a)
233-
self.assertRaises(RuntimeError, cmp, a, c)
234-
# okay, now break the cycles
235-
a.pop(); b.pop(); c.pop()
236-
self.assertRaises(TypeError, cmp)
223+
# uncomment the following line once cmp has been removed
224+
#self.assert_(not hasattr(builtins, "cmp"))
225+
pass
237226

238227
def test_compile(self):
239228
compile('print(1)\n', '', 'exec')
@@ -736,10 +725,6 @@ class BadSeq:
736725
def __getitem__(self, index):
737726
raise ValueError
738727
self.assertRaises(ValueError, min, BadSeq())
739-
class BadNumber:
740-
def __cmp__(self, other):
741-
raise ValueError
742-
self.assertRaises(TypeError, min, (42, BadNumber()))
743728

744729
for stmt in (
745730
"min(key=int)", # no args

0 commit comments

Comments
 (0)