[ZODB-Dev] Is this a bug?

Tim Peters tim at zope.com
Sun Mar 21 01:43:57 EST 2004


[Chandra Tambrin]
> I've just tried out ZoDB. I was trying to do the following:
>
> from BTrees.OOBTree import OOBTree
> t = OOBTree()
>
> for i in range(10):
> 	t[i] = str(i)
>
> for each in t.keys():
> 	del t[each]
>
> len(t)
> --> 5
>
> should be 0 right? what happened here?

You're mutating a BTree while iterating over it, and the end result isn't
well defined.  It's a lot like doing

L = range(10)
for x in L:
    L.remove(x)

in Python, mutating a Python list while iterating over it (try that!  what
does L contain at the end?).

Don't be fooled into assuming that BTree.keys() is like a Python
dict.keys() -- it isn't.  BTree.keys() is more like a Python
dict.iterkeys():  you get back a tiny iterator object, not a potentially
giant list of keys.

If you have to mutate a BTree while iterating over it, you'll need to
materialize the full collection of keys first:

    for each in list(t.keys()):
        del t[each]

or

    for each in tuple(t.keys()):
        del t[each]

both leave t empty.  In either case, the thing you're iterating over is no
longer the BTree then, but a distinct data structure computed from the
original BTree.




More information about the ZODB-Dev mailing list