On Mar 3, 2008, at 11:23 AM, Michael Bayer wrote:



On Mar 3, 2008, at 11:56 AM, Patrick Hartling wrote:


hash(Works())
hash(Works2())
# Raises TypeError with Python 2.6 because Fails is deemed unhashable.
hash(Fails())

Does anyone know of a workaround for this issue? So far,
sqlalchemy.schema.PrimaryKeyConstraint and sqlalchemy.schema.Column
are the two classes that have tripped me up. I have added __hash__()
methods to both, but I cannot vouch for the correctness of the
implementations.


hmm, subtle difference between the 2.5 docs:

        If a class does not define a __cmp__() method it should not define a
__hash__() operation either; if it defines __cmp__() or __eq__() but
not __hash__(), its instances will not be usable as dictionary keys.
If a class defines mutable objects and implements a __cmp__() or
__eq__() method, it should not implement __hash__(), since the
dictionary implementation requires that a key's hash value is
immutable (if the object's hash value changes, it will be in the wrong
hash bucket).

and the 2.6 docs:

        If a class does not define a __cmp__() or __eq__() method it should
not define a __hash__() operation either; if it defines __cmp__() or
__eq__() but not __hash__(), its instances will not be usable as
dictionary keys. If a class defines mutable objects and implements a
__cmp__() or __eq__() method, it should not implement __hash__(),
since the dictionary implementation requires that a key’s hash value
is immutable (if the object’s hash value changes, it will be in the
wrong hash bucket).

both claim that if we define __eq__() but not __hash__(), it wont be
useable as a dictionary key.  but in the case of 2.5 this seems to be
incorrect, or at least not enforced.  The only difference here is that
2.6 says " if we dont define __cmp__() or __eq__(), then we shouldn't
define __hash__() either" whereas 2.5 only mentions __cmp__() in that
regard.

Subtle indeed.

We define __eq__() all over the place so that would be a lot of
__hash__() methods to add, all of which return id(self).  I wonder if
we shouldn't just make a util.Mixin called "Hashable" so that we can
centralize the idea.


That sounds like a reasonable approach. I have not looked much at the SQLAlchemy internals before today, but if I follow your idea correctly, I could apply that solution wherever I run into problems during testing.

 -Patrick


--
Patrick L. Hartling
Senior Software Engineer, Priority 5
http://www.priority5.com/

Attachment: PGP.sig
Description: This is a digitally signed message part

Reply via email to