[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