[ZODB-Dev] Re: setdefault branch

Tim Peters tim at zope.com
Mon Aug 29 21:41:23 EDT 2005


[Tim Peters]
>> I'm trying to straighten out the new BTree.setdefault() code, on
>> ZODB/branches/alienoid-btrees_setdefault.
>>
>> Turns out this can't work like Python's dict.setdefault() in all cases.
>> This is why:
>>
>> >>> d = {}
>> >>> d.setdefault(666)
>> >>> d
>> {666: None}

[Ruslan Spivak]
> Yes, currrently in branch in this case i simply return None without
> setting item, though of course it's not ideal.

You're out of date ;-)  Currently the branch raises TypeError if an explicit
default isn't passed.

>> That is, the default for the optional ``default`` argument is None, so
>> when the key is missing and no explicit default is given (or an explicit
>> default of None is given), the corrected code tries to associate None
>> with the key.
>>
>> That's fine for OO and IO trees, but can't work for II or OI or IF
>> trees: None isn't a possible value in the latter kinds of trees.
>>
>> Proposal:  make BTree/Bucket setdefault() a two-argument function (3 if
>> you count ``self`` too).  In practice, an explicit default is always
>> passed, and not even in theory could we come up with a sane
>> default-default that works across all tree types.

> I think we can handle that without additional argument:

Why even try?  Nobody presented a use case for leaving out the default, and,
indeed, Python's default of None seems essentially useless even in Python.

> if default is not set try to insert None,

Who would want to insert None as the value associated with a key in an OO or
IO tree?  Almost all use cases for setdefault() explicitly pass an empty
container object (usually an empty list, dict, or BTree) as the default, and
all the rest I've seen have no use for setting it to None.

> if we get TypeError exception then try to insert 0 as it's suitable
> both for int and floats(for floats it will be converted to 0.0 by
> default) Return type will be None, 0 or 0.0 or maybe just None?

I just don't think a default-default is useful, period.  Especially not when
it's an inherently meaningless, arbitrary default that varies across tree
and bucket types.  If None could have been used across all tree and bucket
types here, I was willing to live with that just for slavish compatibility
with Python dict endcases.  But since that's not possible, I don't want to
endure unique obscurities just to be "kind of compatible, if you squint hard
enough" with something nobody actually wants anyway.

> As for float type return i guess handling one more TypeError exception
> may be required to correctly differentiate between int and floats. Dunno
> if this is a good way, but at least it seems to be possible option.

I'm happy with the branch now.

If people feel that insane <wink> defaults are useful, the right way to do
it is to add new "and this is the default value used for setdefault()"
macros to the {float,int,object}valuemacros.h files.



More information about the ZODB-Dev mailing list