[ZODB-Dev] BTrees and PersistentDict keys: bug or feature

Tim Peters tim at zope.com
Thu Aug 14 23:00:03 EDT 2003


[Christian Reis]
> (I suppose I push these things in annoying ways.)

I don't think so.  I think it's more that you're playing in dark corners
that nobody else wants to visit.  For example, it's unlikely my boss will
tell me to devote days to this <wink>.

The docs I pointed you at before strongly recommend using simple, immutable
values, with well-defined __cmp__ methods, as BTree keys.  When you go
beyond that, you're trying things nobody understands.  For example, I have
no idea how a PersistentMapping will or won't compare itself against a
Python dict, and I wager nobody else does either.

> [various examples of trying to use Python dicts and PersistentMapping
>  objects as BTree keys, and of trying to use one of those types as
>  a key when setting a value, then retrieving via the other type]
> ...

You don't need BTrees to find confusion here.  For example, this is enough:

>>> d = {1:1, 2:2}
>>> p = PersistentMapping(d)

>>> p == d
1
>>> d == p
0
>>>

I expect you'll see the same two results, and (of course) they're
inconsistent.  (They're also inconsistent under the covers, then, when the
BTree code invokes comparison operations.)

>>> p < d
0
>>> d > p
1
>>>

I expect you'll see 0 for the first result there, but that the second result
may vary across platforms.  It's obvious <wink> to me that when the dict is
on the left-hand side of a comparison, it compares itself against a
PersistentMapping by memory address.  When the PersistentMapping is on the
left-hand side, it compares its hidden Python dict to the other dict, and
Python dict comparison is well-defined.

> The check() module indicates it works okay.

check.check() can only confirm that the BTree hasn't become internally
insane.

> I've tried to track this down but I'm not having a large measure of
> success. It *seems* to me that the problem is PersistentMapping's
> __cmp__ method is not being called consistently, but ever since Tim
> warned me of mixed-type comparisons I've been reluctant to spend a
> long time staring at code when I see these issues.
>
> Should I just try and band-aid it in my code?

I suspect you'd have more luck if you explained what you're trying to
accomplish, so that people could suggest other ways to get there.

Since mixed-type comparisons here are demonstrably inconsistent, you would
have to rely on brand new releases of ZODB and/or of Python too(!) to
straighten those out.  You would also have to convince someone it's worth
their time to try to repair the inconsistencies in ZODB and/or in Python.
That would be an even harder sell than you're imagining, because the
implementation of comparisons right now is so bloody complicated that
there's a very strong chance any change will break someone else's
currently-working code.

So, IMO, the only realistic choice is to find a different way to solve your
real problem (I don't know what that is, I only know you're not going to
solve it via what you're trying to do now).




More information about the ZODB-Dev mailing list