Found the answer on IRC.
t[0] += [1]
is several discrete actions:
- loading
t[0]
- building a new list with
1
in it
- adding that
[1]
to whatever t[0]
is
- reassigning
t[0]
It seems that x += y
is basically x = x + y
(but, is it?)
The tricky bit is that +=
implies assignment to both the tuple t
and to the list t[0]
t[0] += [1]
is not literally t[0] = t[0] + [1]
, it is: t[0] = t[0].__iadd__([1])
What really happens is:
__iadd__
both mutates the list and returns it. So the list (which is the first element in t
) has already got 1
appended to it.
- tuple's mutation is attempted in-place as well, but tuples are immutable, resulting in the exception.
Why is this not visible in plain sight? Because a n00b like me would expect t[0] += [1]
to either succeed all together or fail, because it's one short line of python. But that's not always the case.