
This sub-thread has long since drifted away from dicts, so I've changed the subject to make that clear. On Sat, Feb 14, 2015 at 11:41:52AM -0800, Chris Barker wrote:
The fact that you can't directly use augmented assignment on an object contained in an immutable is not a bug, but it certainly is a wart -- particuarly since it will raise an Exception AFTER it has, in fact, performed the operation requested.
Yes, but you can use augmented assignment on an object contained in an immutable under some circumstances. Here are three examples demonstrating outright failure, weird super-position of failed-but-succeeded, and success. py> t = (1, ) py> t[0] += 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment py> t (1,) py> t = ([1], ) py> t[0] += [1] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment py> t ([1, 1],) py> t[0][0] += 1 py> t ([2, 1],)
I have argued that this never would have come up if augmented assignment were only used for in-place operations,
And it would never happen if augmented assignment *never* was used for in-place operations. If it always required an assignment, then if the assignment failed, the object in question would be unchanged. Alas, there's no way to enforce the rule that __iadd__ doesn't modify objects in place, and it actually is a nice optimization when they can do so. [...]
I don't know enough about how this all works under the hood to know if it could be made to work, but it seems the intention is clear here:
object[index] += something.
is a shorthand for:
tmp = object[index] tmp += something
No, that doesn't work. If tmp is *immutable*, then object[index] never gets updated. The intention as I understand it is that: reference += expr should be syntactic sugar (possibly optimized) for: reference = reference + expr where "reference" means (for example) bare names, item references, key references, and chaining the same: n n[0] n[0]['spam'] n[0]['spam'].eggs etc. I wonder if we can make this work more clearly if augmented assignments checked whether the same object is returned and skipped the assignment in that case? -- Steve