Like I said, it is clear *why* this happens, what I am concerned is if this what we *want* to happen, i.e., if the current situation is satisfying. Your mytuple class would be something that resembles a solution, my question is what the people on this group think about it.
On Dec 24, 5:08 pm, Arnaud Delobelle <[EMAIL PROTECTED]> wrote: > On Dec 24, 3:22 pm, [EMAIL PROTECTED] wrote: > > > > > Recently, I got into a debate on programming.reddit.com about > > what should happen in the following case: > > > >>> a = ([1], 2) > > >>> a[0] += [3] > > > Currently, Python raises an error *and* changes the first element of > > the tuple. Now, this seems like something one would want to > > change - why raise an error *and* execute the thing it > > was complaining about? The discussion seems to have no end, and > > that is why I'm posting here. I would like to know what is the opinion > > of the people on this group... Am I really mistaking for thinking that > > this is strange and unwanted behavior? Btw I understand *why* is this > > happening, I just think it should change... > > And here is the post that started this > > discussion:http://filoxus.blogspot.com/2007/12/python-3000-how-mutable-is-immuta... > > > Thanks for your replies > > For the sake of clarity, say you have typed: > > >>> L = [1] > >>> a = (L, 2) > >>> a[0] += [3] > > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > TypeError: 'tuple' object does not support item assignment>>> a > > ([1, 3], 2) > > I think that this is what happens when a[0] += [3] is executed: > > 1. list.__iadd__(L, [3]) is called, modifying L in place and returning > L. > 2. tuple.__setitem__(a, L) is tried, raising the TypeError. > > Notice that this problem doesn't arise when replacing lists with > tuples: > > >>> a = ( (1,), 2) > >>> a[0] += (3, ) > > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > TypeError: 'tuple' object does not support item assignment>>> a > > ((1,), 2) > > This is because tuple object don't have an __iadd__ method so a new > object tuple.__add__((1,),(3,)) is created and returned. > > AFAICS, the only way to avoid the error message would be to check if > the new object is the same as the old one before raising the > TypeError: > > class mytuple(tuple): > "It's ok to do t[i] = obj as long as t[i] was already obj" > def __setitem__(self, i, val): > if self[i] is not val: > raise TypeError("'mytuple' object is immutable") > > So: > > >>> a = mytuple(([1], 2)) > >>> a[0] += [3] # This now works > >>> a[1] += 4 # This won't work as ints are immutable > > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > File "tuple.py", line 4, in __setitem__ > raise TypeError("'mytuple' object is immutable") > TypeError: 'mytuple' object is immutable>>> a > > ([1, 3], 2) > > It wouldn't slow anything down I suppose, just make some currently > failing code succeed. > > -- > Arnaud -- http://mail.python.org/mailman/listinfo/python-list