copy on write
MRAB
python at mrabarnett.plus.com
Thu Feb 2 11:28:28 EST 2012
On 02/02/2012 10:53, Hrvoje Niksic wrote:
> Steven D'Aprano<steve+comp.lang.python at pearwood.info> writes:
>
>> Perhaps you are thinking that Python could determine ahead of time
>> whether x[1] += y involved a list or a tuple, and not perform the
>> finally assignment if x was a tuple. Well, maybe, but such an approach
>> (if possible!) is fraught with danger and mysterious errors even
>> harder to debug than the current situation. And besides, what should
>> Python do about non-built-in types? There is no way in general to
>> predict whether x[1] = something will succeed except to actually try
>> it.
>
> An alternative approach is to simply not perform the final assignment if
> the in-place method is available on the contained object. No prediction
> is needed to do it, because the contained object has to be examined
> anyway. No prediction is needed, just don't. Currently,
> lhs[ind] += rhs is implemented like this:
>
> item = lhs[ind]
> if hasattr(item, '__iadd__'):
> lhs.__setitem__(ind, item.__iadd__(rhs))
> else:
> lhs.__setitem__(ind, item + rhs)
> # (Note item assignment in both "if" branches.)
>
> It could, however, be implemented like this:
>
> item = lhs[ind]
> if hasattr(item, '__iadd__'):
> item += rhs # no assignment, item supports in-place change
> else:
> lhs.__setitem__(ind, lhs[ind] + rhs)
>
> This would raise the exact same exception in the tuple case, but without
> executing the in-place assignment. On the other hand, some_list[ind] += 1
> would continue working exactly the same as it does now.
>
> In the same vein, in-place methods should not have a return value
> (i.e. they should return None), as per Python convention that functions
> called for side effect don't return values.
>
> The alternative behavior is unfortunately not backward-compatible (it
> ignores the return value of augmented methods), so I'm not seriously
> proposing it, but I believe it would have been a better implementation
> of augmented assignments than the current one.
>
[snip]
Could it not perform the assignment if the reference returned by
__iadd__ is the same as the current reference?
For example:
t[0] += x
would do:
r = t[0].__iadd__(x)
if t[0] is not r:
t[0] = r
Should failed assignment be raising TypeError? Is it really a type
error?
More information about the Python-list
mailing list