list in a tuple

montyphyton at gmail.com montyphyton at gmail.com
Thu Dec 27 12:38:01 EST 2007


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 <arno... at googlemail.com> wrote:
> On Dec 26, 1:08 am, Steven D'Aprano <st... at REMOVE-THIS-
>
> 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




More information about the Python-list mailing list