Skip to content

Commit acc618c

Browse files
author
nick.coghlan
committed
Issue 2235: Py3k warnings are now emitted for classes that will no longer inherit a__hash__ implementation from a parent class in Python 3.x. The standard library and test suite have been updated to not emit these warnings.
git-svn-id: http://svn.python.org/projects/python/trunk@65642 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent 765219b commit acc618c

18 files changed

Lines changed: 165 additions & 18 deletions

Lib/UserList.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ def __cast(self, other):
2525
else: return other
2626
def __cmp__(self, other):
2727
return cmp(self.data, self.__cast(other))
28+
__hash__ = None # Mutable sequence, so not hashable
2829
def __contains__(self, item): return item in self.data
2930
def __len__(self): return len(self.data)
3031
def __getitem__(self, i): return self.data[i]

Lib/_abcoll.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ def __xor__(self, other):
207207
other = self._from_iterable(other)
208208
return (self - other) | (other - self)
209209

210+
# Sets are not hashable by default, but subclasses can change this
211+
__hash__ = None
212+
210213
def _hash(self):
211214
"""Compute the hash value of a set.
212215
@@ -350,6 +353,9 @@ def items(self):
350353
def values(self):
351354
return [self[key] for key in self]
352355

356+
# Mappings are not hashable by default, but subclasses can change this
357+
__hash__ = None
358+
353359
def __eq__(self, other):
354360
return isinstance(other, Mapping) and \
355361
dict(self.items()) == dict(other.items())

Lib/ctypes/test/test_simplesubclasses.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ def __cmp__(self, other):
66
if type(other) != MyInt:
77
return -1
88
return cmp(self.value, other.value)
9+
def __hash__(self): # Silence Py3k warning
10+
return hash(self.value)
911

1012
class Test(unittest.TestCase):
1113

Lib/numbers.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ class Number(object):
1818
"""
1919
__metaclass__ = ABCMeta
2020

21+
# Concrete numeric types must provide their own hash implementation
22+
__hash__ = None
23+
2124

2225
## Notes on Decimal
2326
## ----------------

Lib/test/test_builtin.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,7 @@ def test_range(self):
10641064
class badzero(int):
10651065
def __cmp__(self, other):
10661066
raise RuntimeError
1067+
__hash__ = None # Invalid cmp makes this unhashable
10671068
self.assertRaises(RuntimeError, range, a, a + 1, badzero(1))
10681069

10691070
# Reject floats when it would require PyLongs to represent.

Lib/test/test_coercion.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ class WackyComparer(object):
309309
def __cmp__(slf, other):
310310
self.assert_(other == 42, 'expected evil_coercer, got %r' % other)
311311
return 0
312+
__hash__ = None # Invalid cmp makes this unhashable
312313
self.assertEquals(cmp(WackyComparer(), evil_coercer), 0)
313314
# ...and classic classes too, since that code path is a little different
314315
class ClassicWackyComparer:

Lib/test/test_collections.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ def test_Hashable(self):
172172
class H(Hashable):
173173
def __hash__(self):
174174
return super(H, self).__hash__()
175+
__eq__ = Hashable.__eq__ # Silence Py3k warning
175176
self.assertEqual(hash(H()), 0)
176177
self.failIf(issubclass(int, H))
177178

Lib/test/test_copy.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,7 @@ def __reduce__(self):
435435
return (C, (), self.__dict__)
436436
def __cmp__(self, other):
437437
return cmp(self.__dict__, other.__dict__)
438+
__hash__ = None # Silence Py3k warning
438439
x = C()
439440
x.foo = [42]
440441
y = copy.copy(x)
@@ -451,6 +452,7 @@ def __setstate__(self, state):
451452
self.__dict__.update(state)
452453
def __cmp__(self, other):
453454
return cmp(self.__dict__, other.__dict__)
455+
__hash__ = None # Silence Py3k warning
454456
x = C()
455457
x.foo = [42]
456458
y = copy.copy(x)
@@ -477,6 +479,7 @@ def __reduce__(self):
477479
def __cmp__(self, other):
478480
return (cmp(list(self), list(other)) or
479481
cmp(self.__dict__, other.__dict__))
482+
__hash__ = None # Silence Py3k warning
480483
x = C([[1, 2], 3])
481484
y = copy.copy(x)
482485
self.assertEqual(x, y)
@@ -494,6 +497,7 @@ def __reduce__(self):
494497
def __cmp__(self, other):
495498
return (cmp(dict(self), list(dict)) or
496499
cmp(self.__dict__, other.__dict__))
500+
__hash__ = None # Silence Py3k warning
497501
x = C([("foo", [1, 2]), ("bar", 3)])
498502
y = copy.copy(x)
499503
self.assertEqual(x, y)

Lib/test/test_datetime.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,7 @@ def __cmp__(self, other):
986986
# compare-by-address (which never says "equal" for distinct
987987
# objects).
988988
return 0
989+
__hash__ = None # Silence Py3k warning
989990

990991
# This still errors, because date and datetime comparison raise
991992
# TypeError instead of NotImplemented when they don't know what to

Lib/test/test_descr.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,7 @@ class F(object):
11211121
class G(object):
11221122
def __cmp__(self, other):
11231123
return 0
1124+
__hash__ = None # Silence Py3k warning
11241125
g = G()
11251126
orig_objects = len(gc.get_objects())
11261127
for i in xrange(10):
@@ -2727,6 +2728,7 @@ def __cmp__(self, other):
27272728
if isinstance(other, int) or isinstance(other, long):
27282729
return cmp(self.value, other)
27292730
return NotImplemented
2731+
__hash__ = None # Silence Py3k warning
27302732

27312733
c1 = C(1)
27322734
c2 = C(2)
@@ -2755,6 +2757,7 @@ def __eq__(self, other):
27552757
return abs(self - other) <= 1e-6
27562758
except:
27572759
return NotImplemented
2760+
__hash__ = None # Silence Py3k warning
27582761
zz = ZZ(1.0000003)
27592762
self.assertEqual(zz, 1+0j)
27602763
self.assertEqual(1+0j, zz)
@@ -2767,6 +2770,7 @@ def __init__(self, value):
27672770
self.value = int(value)
27682771
def __cmp__(self_, other):
27692772
self.fail("shouldn't call __cmp__")
2773+
__hash__ = None # Silence Py3k warning
27702774
def __eq__(self, other):
27712775
if isinstance(other, C):
27722776
return self.value == other.value
@@ -3262,6 +3266,7 @@ def __rpow__(self, other, mod=None):
32623266
class S(str):
32633267
def __eq__(self, other):
32643268
return self.lower() == other.lower()
3269+
__hash__ = None # Silence Py3k warning
32653270

32663271
def test_subclass_propagation(self):
32673272
# Testing propagation of slot functions to subclasses...

0 commit comments

Comments
 (0)