On Tue, Mar 4, 2008 at 7:27 PM, Michael Bayer <[EMAIL PROTECTED]> wrote: > Well actually, in our particular case that's the behavior that we *do* > want; pretty much everywhere we've defined __eq__(), we've done it not > to redefine what it means for a==b, but to produce SQL expressions - > so in that sense __eq__() is entirely broken for its normal usage in > SQLAlchemy (as well as in all the other SQL tools out there using this > approach). For this reason, internally we can't do things like "d in > [a,b,c]" if those are SQL expressions, since __eq__() evaluates to > true in all cases - we use sets when we need a collection of SQL > expressions where we can test for presence, so that their hash value > is used. > > However, while Im not familiar with the internals of Python > dictionaries, depending on how they implemented it we still may need > to use IdentitySet and IdentityDict, two classes (well we have the > first one at least) which ignore the __hash__() and __eq__() methods > entirely and hash their contents strictly based on id(obj). This is > because a "hashtable" usually stores items in buckets based on a > modulus of the __hash__() value; if two items are in the same bucket, > an equality comparison is used to locate the correct object. If > Python's dict uses __eq__() for the equality comparison, we'd be in > trouble. I have a strong suspicion that they do not (since I think we > would have noticed by now), and that they use __hash__() for the > equality comparison as well, but I'm not sure; and also not sure if > this is slated to change in py2.6.
All hash table implementations (including one in Python) work the same way: first it looks up a list of key-value pairs by hash, and then iterate through the list to find a needed key by comparing it with "=" operator. Thus __eq__ method _is_ used to lookup values in dictionaries. So, this won't work in some cases: 1) when __eq__ may return False when comparing to identical (but not the same, since Python always checks with "is" first), 2) when __eq__ may return True for objects we want to be assumed different - in some rare cases when they produce the same hash. Although both are not our cases (we always return True, and using id() for hash guarantees they will never clash), I believe your suggestion to use IdentitySet and IdentityDict is a right direction. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---