Issue #1757: The hash of a Decimal instance is no longer affected
by the current context. Thanks Mark Dickinson.
This commit is contained in:
parent
f66f95d419
commit
52b25795c0
|
@ -788,8 +788,10 @@ class Decimal(object):
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
"""x.__hash__() <==> hash(x)"""
|
"""x.__hash__() <==> hash(x)"""
|
||||||
# Decimal integers must hash the same as the ints
|
# Decimal integers must hash the same as the ints
|
||||||
# Non-integer decimals are normalized and hashed as strings
|
#
|
||||||
# Normalization assures that hash(100E-1) == hash(10)
|
# The hash of a nonspecial noninteger Decimal must depend only
|
||||||
|
# on the value of that Decimal, and not on its representation.
|
||||||
|
# For example: hash(Decimal("100E-1")) == hash(Decimal("10")).
|
||||||
if self._is_special:
|
if self._is_special:
|
||||||
if self._isnan():
|
if self._isnan():
|
||||||
raise TypeError('Cannot hash a NaN value.')
|
raise TypeError('Cannot hash a NaN value.')
|
||||||
|
@ -805,7 +807,13 @@ class Decimal(object):
|
||||||
# 2**64-1. So we can replace hash((-1)**s*c*10**e) with
|
# 2**64-1. So we can replace hash((-1)**s*c*10**e) with
|
||||||
# hash((-1)**s*c*pow(10, e, 2**64-1).
|
# hash((-1)**s*c*pow(10, e, 2**64-1).
|
||||||
return hash((-1)**op.sign*op.int*pow(10, op.exp, 2**64-1))
|
return hash((-1)**op.sign*op.int*pow(10, op.exp, 2**64-1))
|
||||||
return hash(str(self.normalize()))
|
# The value of a nonzero nonspecial Decimal instance is
|
||||||
|
# faithfully represented by the triple consisting of its sign,
|
||||||
|
# its adjusted exponent, and its coefficient with trailing
|
||||||
|
# zeros removed.
|
||||||
|
return hash((self._sign,
|
||||||
|
self._exp+len(self._int),
|
||||||
|
self._int.rstrip('0')))
|
||||||
|
|
||||||
def as_tuple(self):
|
def as_tuple(self):
|
||||||
"""Represents the number as a triple tuple.
|
"""Represents the number as a triple tuple.
|
||||||
|
|
|
@ -980,6 +980,23 @@ class DecimalUsabilityTest(unittest.TestCase):
|
||||||
self.assert_(hash(Decimal('Inf')))
|
self.assert_(hash(Decimal('Inf')))
|
||||||
self.assert_(hash(Decimal('-Inf')))
|
self.assert_(hash(Decimal('-Inf')))
|
||||||
|
|
||||||
|
# check that the value of the hash doesn't depend on the
|
||||||
|
# current context (issue #1757)
|
||||||
|
c = getcontext()
|
||||||
|
old_precision = c.prec
|
||||||
|
x = Decimal("123456789.1")
|
||||||
|
|
||||||
|
c.prec = 6
|
||||||
|
h1 = hash(x)
|
||||||
|
c.prec = 10
|
||||||
|
h2 = hash(x)
|
||||||
|
c.prec = 16
|
||||||
|
h3 = hash(x)
|
||||||
|
|
||||||
|
self.assertEqual(h1, h2)
|
||||||
|
self.assertEqual(h1, h3)
|
||||||
|
c.prec = old_precision
|
||||||
|
|
||||||
def test_min_and_max_methods(self):
|
def test_min_and_max_methods(self):
|
||||||
|
|
||||||
d1 = Decimal('15.32')
|
d1 = Decimal('15.32')
|
||||||
|
|
|
@ -348,6 +348,9 @@ Core and builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #1757: The hash of a Decimal instance is no longer affected by
|
||||||
|
the current context.
|
||||||
|
|
||||||
- Patch #467924: add ZipFile.extract() and ZipFile.extractall() in the
|
- Patch #467924: add ZipFile.extract() and ZipFile.extractall() in the
|
||||||
zipfile module.
|
zipfile module.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue