[ python-Bugs-851449 ] New-style classes with __eq__ but not __hash__ are hashable

SourceForge.net noreply at sourceforge.net
Sun Nov 30 00:40:02 EST 2003


Bugs item #851449, was opened at 2003-11-30 00:40
Message generated for change (Tracker Item Submitted) made by Item Submitter
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=851449&group_id=5470

Category: Python Interpreter Core
Group: Python 2.3
Status: Open
Resolution: None
Priority: 5
Submitted By: Edward Loper (edloper)
Assigned to: Nobody/Anonymous (nobody)
Summary: New-style classes with __eq__ but not __hash__ are hashable

Initial Comment:
According to the current reference docs, "If [a class] 
defines
__cmp__() or __eq__() but not __hash__(), its 
instances will not be
usable as dictionary keys. [1]  But this doesn't work 
quite like you'd
think for new-style classes:

    Python 2.3 (#1, Sep 13 2003, 00:49:11) 
    [GCC 3.3 20030304 (Apple Computer, Inc. build 
1495)] on darwin
    Type "help", "copyright", "credits" or "license" for 
more information.
    >>> class A(object):
    ...     def __cmp__(self, other): return -1
    >>> print {A():1}
    {<__main__.A object at 0x71cf0>: 1}

The problem is that object defines a default __hash__ 
method:

    >>> print A.__hash__
    <slot wrapper '__hash__' of 'object' objects>

So the dictionary class thinks that the object is 
hashable.  But given
that we've overridden cmp, there's no reason to believe 
that __hash__
is still valid.  The only workaround I've found is to 
manually add a
__hash__ method that raises the appropriate 
exception:

    >>> class A(object):
    ...     def __cmp__(self, other): return -1
    ...     def __hash__(self): 
    ...         raise TypeError, ('%s objects are unhashable' 
% 
    ...                           self.__class__)

But it seems like this should be fixed in Python itself.  I 
can think
of 2 reasonable ways to fix it:

  - change object.__hash__() to raise a TypeError if 
__cmp__ or
    __eq__ is overridden.
  - change hash() to raise a TypeError if given an object 
that
    overrides __cmp__ or __eq__ but not __hash__.

So..  Is this a real bug, or am I missing something?  And 
if so,
what's the prefered place to fix it?  (I'd be happy to try 
to put
together a patch for it, if it is indeed broken.)

-Edward

[1] http://www.python.org/doc/current/ref/
customization.html


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

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



More information about the Python-bugs-list mailing list