[Python-Dev] setdefault's second argument

Tim Peters tim.peters at gmail.com
Fri Sep 2 19:45:34 CEST 2005


[Tim Peters]
>> Dang!  I may have just found a use, in Zope's
>> lib/python/docutils/parsers/rst/directives/images.py (which is part
>> of docutils, not really part of Zope):
>>
>>     figwidth = options.setdefault('figwidth')
>>     figclass = options.setdefault('figclass')
>>     del options['figwidth']
>>     del options['figclass']

[David Goodger]
> If a feature is available, it *will* eventually be used!
> Whose law is that?

This is a different law, about design mistakes getting used by people
who should know better ;-)

> The code needs to store the values of certain dict entries, then
> delete them.  This is because the "options" dict is passed on to
> another function, where those entries are not welcome.  The code above
> is simply shorter than this:
>
>    if options.has_key('figwidth'):
>        figwidth = options['figwidth']
>        del options['figwidth']
>    # again for 'figclass'
>
> Alternatively,
>
>    try:
>        figwidth = options['figwidth']
>        del options['figwidth']
>    except KeyError:
>        pass

Those wouldn't work in context, because they leave figwidth unbound if
it's not a key in options.  Later code unconditionally references
fidgwidth.

> It saves between one line and three lines of code per entry.  But
> since those entries are probably not so common, it would actually be
> faster to use one of the above patterns.

Changing

    figwidth = options.setdefault('figwidth')
    figclass = options.setdefault('figclass')

to

    figwidth = options.setdefault('figwidth', None)
    figclass = options.setdefault('figclass', None)

is a minimal semantics-neutral edit to avoid the unloved 1-argument case.

>> Assuming options is a dict-like thingie, it probably meant to do:
>>
>>     figwidth = options.pop('figwidth', None)
>>     figclass = options.pop('figclass', None)

> Yes, but the "pop" method was only added in Python 2.3.  Docutils
> currently maintains compatibility with Python 2.1, so that's RIGHT
> OUT!

Oh, stop torturing yourself.  Nobody uses Python 2.1 anymore ;-)

>> David, are you married to that bizarre use of setdefault <wink>?

> No, not at all.  In fact, I will vehemently deny that I ever wrote
> such code, and will continue to do so until someone looks up its
> history and proves that I'm guilty, which I probably am.

No, I checked, and this code was actually added by an Asian spammer,
who polluted the docutils codebase with thousandsd of porn links
hidden in triple-quoted strings.  Google reveals that 1-argument
setdefault() is a favorite of Asian porn spammers.  So you should add
a second argument just to avoid getting in trouble with Interpol ;-)


More information about the Python-Dev mailing list