On Mon, 03 May 2010 06:37:49 +0200, Alf P. Steinbach wrote: > * Terry Reedy: >> * Alf P. Steinbach: >>> * Aahz: >> >>>> and sometimes >>>> they rebind the original target to the same object. >>> >>> At the Python level that seems to be an undetectable null-operation. >> >> If you try t=(1,2,3); t[1]+=3, if very much matters that a rebind >> occurs. > > Testing: > > <test lang="py3"> > >>> t = ([], [], []) > >>> t > ([], [], []) > >>> t[0] += ["blah"] > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > TypeError: 'tuple' object does not support item assignment > >>> t > (['blah'], [], []) > >>> _ > </test> > > Yep, it matters. > > Is this change-but-raise-exception a bug? > > I seem to have a knack for running into bugs. :-)
No, I don't believe so -- I believe that it is behaving exactly as advertised. But it is absolutely a gotcha. Consider: >>> class K(object): ... def __init__(self, value=0): ... self.value = value ... def __add__(self, other): ... self.value = self.value + other ... return self ... def __str__(self): ... return "%s" % self.value ... __repr__ = __str__ ... >>> x = K(42) >>> x + 5 47 >>> t = (None, x) >>> t (None, 47) >>> >>> t[1] + 3 50 >>> t (None, 50) >>> t[1] += 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment >>> t (None, 51) Unintuitive, yes. Possibly a bad design, maybe. Surprising, absolutely. But not a bug, as it's working exactly as promised. += is conceptually two steps: perform an addition, and perform an assignment afterward. That addition is sometimes performed in-place, but regardless of whether it is or not, the assignment is always attempted. -- Steven -- http://mail.python.org/mailman/listinfo/python-list