Index: Lib/decimal.py =================================================================== --- Lib/decimal.py (revision 85835) +++ Lib/decimal.py (working copy) @@ -943,7 +943,7 @@ # in the documentation. (See library docs, 'Built-in Types'). if self._is_special: if self.is_snan(): - raise TypeError('Cannot hash a signaling NaN value.') + raise ValueError('Cannot hash a signaling NaN value.') elif self.is_nan(): return _PyHASH_NAN else: @@ -957,7 +957,8 @@ else: exp_hash = pow(_PyHASH_10INV, -self._exp, _PyHASH_MODULUS) hash_ = int(self._int) * exp_hash % _PyHASH_MODULUS - return hash_ if self >= 0 else -hash_ + ans = hash_ if self >= 0 else -hash_ + return -2 if ans == -1 else ans def as_tuple(self): """Represents the number as a triple tuple. Index: Lib/test/test_decimal.py =================================================================== --- Lib/test/test_decimal.py (revision 85835) +++ Lib/test/test_decimal.py (working copy) @@ -1299,19 +1299,26 @@ self.assertEqual(id(dc), id(d)) def test_hash_method(self): + def hashit(d): + a = hash(d) + b = d.__hash__() + self.assertEqual(a, b) + return a + #just that it's hashable - hash(Decimal(23)) - hash(Decimal('Infinity')) - hash(Decimal('-Infinity')) - hash(Decimal('nan123')) - hash(Decimal('-NaN')) + hashit(Decimal(23)) + hashit(Decimal('Infinity')) + hashit(Decimal('-Infinity')) + hashit(Decimal('nan123')) + hashit(Decimal('-NaN')) test_values = [Decimal(sign*(2**m + n)) for m in [0, 14, 15, 16, 17, 30, 31, - 32, 33, 62, 63, 64, 65, 66] + 32, 33, 61, 62, 63, 64, 65, 66] for n in range(-10, 10) for sign in [-1, 1]] test_values.extend([ + Decimal("-1"), # ==> -2 Decimal("-0"), # zeros Decimal("0.00"), Decimal("-0.000"), @@ -1335,13 +1342,13 @@ # check that hash(d) == hash(int(d)) for integral values for value in test_values: - self.assertEqual(hash(value), hash(int(value))) + self.assertEqual(hashit(value), hashit(int(value))) #the same hash that to an int - self.assertEqual(hash(Decimal(23)), hash(23)) - self.assertRaises(TypeError, hash, Decimal('sNaN')) - self.assertTrue(hash(Decimal('Inf'))) - self.assertTrue(hash(Decimal('-Inf'))) + self.assertEqual(hashit(Decimal(23)), hashit(23)) + self.assertRaises(ValueError, hash, Decimal('sNaN')) + self.assertTrue(hashit(Decimal('Inf'))) + self.assertTrue(hashit(Decimal('-Inf'))) # check that the hashes of a Decimal float match when they # represent exactly the same values @@ -1350,7 +1357,7 @@ for s in test_strings: f = float(s) d = Decimal(s) - self.assertEqual(hash(f), hash(d)) + self.assertEqual(hashit(f), hashit(d)) # check that the value of the hash doesn't depend on the # current context (issue #1757) @@ -1359,11 +1366,11 @@ x = Decimal("123456789.1") c.prec = 6 - h1 = hash(x) + h1 = hashit(x) c.prec = 10 - h2 = hash(x) + h2 = hashit(x) c.prec = 16 - h3 = hash(x) + h3 = hashit(x) self.assertEqual(h1, h2) self.assertEqual(h1, h3)