Has anyone tried SQLAlchemy with a recent build of Python 2.6 up to  
and including the Alpha 1 release? It seems that something has changed  
about the behavior of the built-in hash() function. In particular, I  
am getting the following exception when trying to construct a Column  
object:

   File "init_hook.py", line 33, in initMappers
     Column('url', String())
   File "...\SQLAlchemy\lib\sqlalchemy\schema.py", line 105, in __call__
     return type.__call__(self, name, metadata, *args, **kwargs)
   File "...\SQLAlchemy\lib\sqlalchemy\schema.py", line 203, in __init__
     self.primary_key = PrimaryKeyConstraint()
   File "...\SQLAlchemy\lib\sqlalchemy\schema.py", line 283, in  
_set_primary_key
     self.constraints.add(pk)
TypeError: unhashable type: 'PrimaryKeyConstraint'

The above line numbers are for SQLAlchemy 0.4.3. The same error occurs  
with version 0.3.11. This appears to be a change in the strictness of  
hashability for objects. According to the Python 2.5 description of  
__hash__(), the class for a mutable object can define __eq__() or  
__cmp__(), but it should not define __hash__(). With Python 2.6, it  
seems to me that the presence of __eq__() and the absence of  
__hash__() is interpreted as the type being unhashable, which was not  
the case with Python 2.5. The following code, when executed with  
Python 2.5 and 2.6a1, demonstrates the difference:

class Works(object):
    def __init__(self):
       self._value = 'works'

class Works2(object):
    def __init__(self):
       self._value = 'works2'

    def __eq__(self, other):
       return self._value == other._value

    def __hash__(self):
       return hash(self._value)

class Fails(object):
    def __init__(self):
       self._value = 'false'

    def __eq__(self, other):
       return self._value == other.value

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.

  -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