[Python-Dev] inplace operators and __setitem__

Phillip J. Eby pje at telecommunity.com
Wed Sep 28 16:39:42 CEST 2005

At 03:12 PM 9/28/2005 +0200, Reinhold Birkenfeld wrote:
>a general question. Consider:
>class A(list):
>     def __setitem__(self, index, item):
>         # do something with index and item
>         return list.__setitem__(self, index, item)
>lst = A([1,set()])
>lst[0] |= 1
>lst[1] |= set([1])
>Do we want lst.__setitem__ to be called in the second inplace assignment?

Yes.  See:


The purpose of the augmented assignment forms is to allow for the 
possibility that the item's __i*__ method may or may not exist, and may or 
may not return the same object.  In the case where there is no __i*__ form, 
or it does not return the same object, the lvalue *must* be re-bound to the 
new value, or the semantics break.

>A case where this matters is here: http://python.org/sf/1306777

I've closed it as invalid; the behavior is as-defined.

In principle, there *could* be an optimization to avoid rebinding the 
lvalue in the case where the __i*__ form did return self.  But using it for 
the purpose of allowing augmented assignment to tuple members seems dubious 
at best, and likely to create confusion about the mutability or lack 
thereof of tuples.  IMO it's better to have augmented assignment to tuple 
members always fail, so that the code has to be a little more specific 
about its intent.

More information about the Python-Dev mailing list