[Python-3000] A request to keep dict.setdefault() in 3.0

Phillip J. Eby pje at telecommunity.com
Mon Jul 9 20:44:09 CEST 2007

PEP 3100 suggests dict.setdefault() may be removed in Python 3, since 
it is in principle no longer necessary (due to the new defaultdict type).

However, there is another class of use cases which use setdefault for 
its limited atomic properties - the initialization of non-mutated 
data structures that are shared among threads.  (And defaultdict 
cannot achieve the same thing.)

I currently have three places where I use this, off the top of my head:

1. a "synchronized" decorator that initializes an object's __lock__ 
attribute (if not found) using ob.__dict__.setdefault('__lock__', 

2. an Aspect implementation that does almost exactly the same thing, 
so that if multiple threads ask for an Aspect that doesn't exist for 
a given object, they will not end up using different instances.

3. a configuration library that supports "write many, read once" 
configurations shared across threads.  A key may have its value 
written to any number of times, so long as it has never been 
read.  As soon as the value has been read by any thread, it becomes 
fixed and it cannot be set to any other value.  (Setting it to the 
same value has no effect.)  This is essentially a simple way of 
having a provably race-condition-free data structure -- if you have a 
race condition, you will get an error.  As a bonus, it is completely 
non-blocking and single threaded code does not pay any overhead for 
the use of the data structures.

Of course, to take advantage of setdefault's atomic properties, one 
must be using CPython, and all the dictionary keys must have __hash__ 
and __eq__ methods implemented entirely in C (recursively to their 
contents, if tuples are involved).  However, for all three of the 
above applications this latter condition is actually quite trivial to ensure.

I realize, however, that this is an "impure" usage, in that other 
Python implementations usually do not have any atomicity guarantees, 
period.  But it would save me having to write a setdefault function 
in C when porting any of the above code to 3.0.  ;-)

More information about the Python-3000 mailing list