« OOo2 standalone from rpm files | Main | BTrees and pop() »

Sep 02, 2005

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...

(Post originally written by Ruslan Spivak on the old Nuxeo blogs.)

Comments

About Us

We're the friendly employees of Nuxeo, a leading open source software vendor, which develops a complete Enterprise Content Management (ECM) software platform to help companies better produce, process, publish, archive, expose and find their information from digital assets to transactional documents.

» Follow us @nuxeo (Twitter)

» Connect on LinkedIn

» Visit Nuxeo.com

 

Customize & Configure
Nuxeo • Studio

Nuxeo • DM
Online Trial

Nuxeo • DM
Download

Nuxeo • DAM
Download

Nuxeo Connect support