BTrees and setdefault

Working on Z3ECM code base i met following code construction:
try:
    return self.__applications[key]
except KeyError:
    self.__applications[key] = PersistentList()
    return self.__applications[key]
where __applications is OOBTree.
My immediate reaction was to use standard python's mapping protocol method – setdefault as «Readability counts» (C) and rewrite above long code to following:
return self.__applications.setdefault(key, PersistentList())
nice, isn't it? and i was a bit surprised to get
AttributeError: 'BTrees._OOBTree.OOBTree' object has no attribute 'setdefault'
Of course setdefault can be easily emulated, but i want to have short code :) You need to be aware that default argument instance will be created each time you call setdefault, even if it won't be used.

So i raised question in zodb-dev mailing list about adding setdefault method to ZODB and was kindly pointed by Dmitry Vasiliev that this question was raised nearly a year ago - http://mail.zope.org/pipermail/zodb-dev/2004-October/008040.html and as a result it was frozen and no implementation was provided.

Currently some people came up that it's a good idea to have this method for btrees, some had objections. Tim Peters showed how setdefault could be emulated:
This one is obvious:
result = self.__applications.get(key, None)
if result is None:
    result = self.__applications[key] = PersistentList()
return result
While this one uses special btree's method insert:
self.__applications.insert(key, PersistentList())
return self.__applications[key]
This time Jim Fulton gave +1 and as Tim noted: - «Jim's +1 wipes out any number of -0 votes :) .»
So i made my hands dirty, created separate branch in ZODB and implemented setdefault (of course in C :) Bit lately when reviewing my branch Tim noted the behaviour(specific) of python's setdefault doesn't fit well with BTree:
>>> d = {}
>>> d.setdefault(666)
>>> d
{666: None}
You see what's the point?
It will work only with OOBTree and IO, but not with OI, II, IF.
Tim proposed to have 2 required parameters to setdefault and that's how it's now – you should explicitely pass default to method and this was raised on python-dev too and seems like this behaviour will go into standard python, because usage of setdefault without explicit default is confusing and useless.

So, Tim mercilesly refactored my code, of course to make it better :), thanks Tim.
As a result branch is now merged and we have setdefault method in ZODB3.5 final, so you can use it with Zope3 now (currently with 3.1 branch and soon with trunk) and write short, readable code, though, of course, someone may argue :)

More to come...

Important announcement: Join the Nuxeo team and contribute to the Nuxeo project! We have open positions in France and the UK for open source Java EE developers and sales engineers, both junior and senior.

Like this post? Share it:


Trackback Pings

Trackback URL for this entry:
http://blogs.nuxeo.com/sections/blogs/ruslan_spivak/2005_09_01_btrees-setdefault/tbping
Posted by Ruslan Spivak @ 09/02/2005 06:12 PM. - Categories: zope3 -  0 comments

Nuxeo Bloggers: Log in!
Nuxeo - Indesko - Nuxeo 5 Project
All content is copyrighted by their author.
CPSSkins is Copyright © 2003-2006 by Jean-Marc Orliaguet. | CPS is Copyright © 2002-2006 by Nuxeo SAS.