[Python-bugs-list] [ python-Bugs-475877 ] Mutable subtype instances are hashable

noreply@sourceforge.net noreply@sourceforge.net
Tue, 27 Nov 2001 13:33:22 -0800


Bugs item #475877, was opened at 2001-10-28 19:24
You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=475877&group_id=5470

Category: Type/class unification
Group: Python 2.2
Status: Open
Resolution: None
Priority: 7
Submitted By: Tim Peters (tim_one)
>Assigned to: Guido van Rossum (gvanrossum)
Summary: Mutable subtype instances are hashable

Initial Comment:
>>> class D(dictionary): pass
...
>>> d = D()
>>> hash(d)
7920544
>>> id(d)
7920544
>>>

Ditto for instances of list subclasses:

>>> class L(list): pass
...
>>> x = L(range(100))
>>> hash(x)
7928992
>>> id(x)
7928992
>>>

Among other nasties, this lets them get used as 
mutable dict keys.

Reported by Mark J on c.l.py:

"""
From: Mark J <maj64@hotmail.com>
Sent: Sunday, October 28, 2001 10:03 PM
To: python-list@python.org
Subject: Python 2.2b1 hashable dictionary bug?


Since I haven't had a good hit rate at detecting bugs 
vs. features, I thought I'd post here before filing a 
bug report at SourceForge.

Python 2.2b1 (#1, Oct 19 2001, 23:11:09) 
[GCC 2.96 20000731 (Red Hat Linux 7.1 2.96-81)] on 
linux2
Type "help", "copyright", "credits" or "license" for 
more information.
>>> class D(dictionary): pass
... 
>>> d = {}
>>> d2 = D()
>>> d[d2] = "dictionary used as key"
>>> d
{{}: 'dictionary used as key'}
>>> d[D()]="now have two keys that look the same"
>>> d
{{}: 'now have two keys that look the same', 
{}: 'dictionary used as
key'}
>>> d2["key"] = "mutable key in d"
>>> d
{{}: 'now have two keys that look the same', 
{'key': 'mutable key in
d'}: 'dictionary used as key'}
>>> d[d] = "plain dictionary not allowed as key"
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: unhashable type
>>> d2[d2] = "subclassed dictionary allowed though"
>>> d2
{{...}: 'subclassed dictionary allowed 
though', 'key': 'mutable keys'}
>>> #whoa: what just happened: {...} ??

Interesting....  So is this a feature or a bug?
"""

----------------------------------------------------------------------

>Comment By: Tim Peters (tim_one)
Date: 2001-11-27 13:33

Message:
Logged In: YES 
user_id=31435

Assigned to Guido, since he admitted to thinking about it.

----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2001-10-29 11:39

Message:
Logged In: YES 
user_id=6380

Interestingly, in Python list.__hash__ is the same as
object.__hash__, but in C, list.tp_hash is NULL while
object.tp_hash is not.

I think that the best solution is to somehow program an
exception into add_operators that adds a dummy __hash__
wrapper (which always raises an exception) when the tp_hash
field is found to be NULL. (Note that inherit_slots already
contains special-casing for tp_hash.)

----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2001-10-28 23:36

Message:
Logged In: YES 
user_id=6380

There's an admin setting that auto-assigns certain
categories.
Documentation gets auto-assugned to Fred; type/class to me;
Regular Expressions to Effbot I believe.

The hash(sys.stdin) result is expected; files are compared
by address and so their hash() is derived from their address
too.

I'll think about the real issue; this has to do with the way
the hash stub gets set. I'm not sure yet whether this is
best fixed by adding more code to slot_tp_hash or to the
code that sticks slot_to_hash in the tp_hash slot.

----------------------------------------------------------------------

Comment By: Tim Peters (tim_one)
Date: 2001-10-28 19:33

Message:
Logged In: YES 
user_id=31435

I swear I didn't assign this to Guido -- I intended to 
leave this unassigned for now.  That's the second time in 
two weeks I believe SF made up an assignment on one of my 
reports.

----------------------------------------------------------------------

Comment By: Tim Peters (tim_one)
Date: 2001-10-28 19:28

Message:
Logged In: YES 
user_id=31435

Jeez, hash() has gone off the deep end:

>>> import sys
>>> hash(sys.stdin)
7690032
>>>


----------------------------------------------------------------------

You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=475877&group_id=5470