After some tought I must agree that this is a wart more than a bug and that it will probably be best not to mess with it. However, what do you guys think about the print wart in Py3k described at http://filoxus.blogspot.com/2007/12/python-3000-how-mutable-is-immutable.html#links (im not trying to advertise my blog, I just don't feel like typing the whole problem all over again)?
On 26 pro, 19:11, Arnaud Delobelle <[EMAIL PROTECTED]> wrote: > On Dec 26, 1:08 am, Steven D'Aprano <[EMAIL PROTECTED] > > cybersource.com.au> wrote: > > On Mon, 24 Dec 2007 18:01:53 -0800, Raymond Hettinger wrote: > [...] > > > The first succeeds and the second fails. > > > And this is a good idea? > > > Shouldn't the tuple assignment raise the exception BEFORE calling > > __iadd__ on the item, instead of after? > > If you look at the bytecode generated, this doesn't seem possible: > > >>> def f(): > > ... a = ([1],) > ... a[0] += [2] > ...>>> import dis > >>> dis.dis(f) > > 2 0 LOAD_CONST 1 (1) > 3 BUILD_LIST 1 > 6 BUILD_TUPLE 1 > 9 STORE_FAST 0 (a) > > 3 12 LOAD_FAST 0 (a) > 15 LOAD_CONST 2 (0) > 18 DUP_TOPX 2 > 21 BINARY_SUBSCR > 22 LOAD_CONST 3 (2) > 25 BUILD_LIST 1 > 28 INPLACE_ADD > 29 ROT_THREE > 30 STORE_SUBSCR > 31 LOAD_CONST 0 (None) > 34 RETURN_VALUE > > BINARY_SUBSCR puts a[0] on the stack, it has no way to know that a[0] > will be changed in place. To allow an exception to be thrown before > the in-place modification of a[0], there should be a new bytecode > instruction, say BINARY_SUBSCR_WITH_A_VIEW_TO_CHANGE_IN_PLACE, which > checks that the subscriptable object supports STORE_SUBSCR (;-). > > [...] > > > I was never a big fan of augmented assignments. I think it goes against > > the Python grain: it's an implied operation, using punctuation, for the > > sole (?) benefit of saving a keystroke or three. > > > But I think this behaviour counts as a wart on the language, rather than > > a bug. > > Yes. I didn't realise this before you mentioned it, but the culprit > here seems to be the augmented assignment which acts differently on > mutable and immutable objects: > > b = a # say a is immutable > a += c # equivalent to a = a + c > b is a # -> False > > b = a # Now say a is mutable > a += c # equivalent to a.__iadd__(c) > b is a # -> True > > OTOH augmented assignent are a slight optimisation: > > a[i] += 1 > > will look for the value of a and i only once and duplicate them on the > stack, whereas > > a[i] = a[i] + 1 > > will need to resolve a and i twice (which can be costly if a and i are > globals) > > -- > Arnaud -- http://mail.python.org/mailman/listinfo/python-list