This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: "special" decimals aren't hashable
Type: Stage:
Components: Library (Lib) Versions: Python 2.4
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: anthonybaxter, foom, marienz, rhettinger, tim.peters
Priority: normal Keywords:

Created on 2005-03-14 22:37 by marienz, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (7)
msg24603 - (view) Author: Marien Zwart (marienz) * Date: 2005-03-14 22:37
Python 2.4 (#1, Feb 22 2005, 15:02:34) 
[GCC 3.4.3-20050110 (Gentoo Linux 3.4.3.20050110,
ssp-3.4.3.20050110-0, pie-8.7 on linux2
Type "help", "copyright", "credits" or "license" for
more information.
>>> import decimal
>>> hash(decimal.NaN)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/usr/lib/python2.4/decimal.py", line 720, in
__hash__
    i = int(self)
  File "/usr/lib/python2.4/decimal.py", line 1410, in
__int__
    return context._raise_error(InvalidContext)
  File "/usr/lib/python2.4/decimal.py", line 2215, in
_raise_error
    raise error, explanation
decimal.InvalidOperation

This behaviour doesn't match the comment in
decimal.py's __hash__:
# Decimal integers must hash the same as the ints
# Non-integer decimals are normalized and hashed as strings
# Normalization assures that hast(100E-1) == hash(10)

Would it make sense to wrap the int(self) in an except
block and return hash(str(self.normalize())) if this
raises?
msg24604 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2005-03-14 22:42
Logged In: YES 
user_id=80475

Since two NaNs are never equal to one another, I would think
that it doesn't make sense to hash them.  Tim, do you have
another thoughts on the subject?
msg24605 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2005-03-15 00:04
Logged In: YES 
user_id=31435

Well, I'm not really a fan of Python's tying hashability 
to "usable as a dict key", but given that's what Python 
_does_, ya, hashing a NaN doesn't make sense.

marienz, by "special" decimals did you mean only NaNs, or 
do you have other cases in mind too?
msg24606 - (view) Author: James Y Knight (foom) Date: 2005-03-15 04:15
Logged In: YES 
user_id=1104715

NaN, Inf, and negInf all fail to hash. 

Inf and negInf are equal to themselves, so they don't have any problem 
being used as a dict key. 

As for NaN, I don't see any harm in allowing it to return a hashcode 
anyways, but perhaps you're right. 

However, in that case, it would be nice to have the exception raised be 
somewhat more regular and expected-looking than a InvalidOperation 
from int(). Perhaps it should raise TypeError('Decimal("NaN") is 
unhashable').
msg24607 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2005-03-15 05:00
Logged In: YES 
user_id=80475

Fixed.  See Lib/decimal.py 1.35.

Anthony, can this be backported to 2.4.1 or does it need to
wait for 2.4.2?
msg24608 - (view) Author: Anthony Baxter (anthonybaxter) (Python triager) Date: 2005-03-15 14:10
Logged In: YES 
user_id=29957

If you can check it in in the next 24 hours, yes.
otherwise, it can wait til 2.4.2
msg24609 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2005-03-16 11:07
Logged In: YES 
user_id=80475

Okay, it's backported.
History
Date User Action Args
2022-04-11 14:56:10adminsetgithub: 41700
2005-03-14 22:37:14marienzcreate