copy on write

MRAB python at mrabarnett.plus.com
Thu Feb 2 17:28:28 CET 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