[ZODB-Dev] BTree mutating iteration

Tim Peters tim at zope.com
Fri Feb 20 17:17:57 EST 2004


[John Belmonte]
> I found through experience that it's not ok to delete keys from a
> BTree while iterating.  I take it the same goes for adding keys?

More generally, mutating any container C while iterating over C's containees
is usually a Bad Idea.  The mutations will take effect, and nothing should
(e.g.) segfault as a result, but the sequence of elements the iteration sees
generally isn't defined then.  It is for Python lists, but obscurely, and
few people have read (or understood) that part of the language reference
manual.

> It might be useful to mention this in the ZODB guide,

Probably.

> as it might catch someone used to Python dictionary behavior.

That makes me wonder what you think Python dictionary behavior is <wink>.
Recent Pythons reliably complain if a dict changes size while you iterate
over it:

>>> d = {1: 1}
>>> for k in d:
...     d[k+k] = k+k
...
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
RuntimeError: dictionary changed size during iteration
>>>

Recent BTrees also *try* to complain similarly, but only eighth-heartedly.
The difference is that a dict knows how many keys it contains, but a BTree
doesn't, and it's expensive for a BTree to find out.  As a result, a BTree
may or may not complain if you mutate it while iterating over it, but
probably won't (the only things it checks for are things it needs to check
anyway to prevent segfaults, which amounts to checking whether you deleted
the key the iterator was pointing at).




More information about the ZODB-Dev mailing list