[ZODB-Dev] Re: false write conflicts

Tim Peters tim at zope.com
Tue Mar 2 11:48:02 EST 2004


> Casey Duncan wrote:
>> Augmented assignment causes a setattr on the containing object. This
>> is the way Python works. These examples are semantically equivilant::
>
>>   self.x += 1
>>   self.x = self.x + 1
>>   setattr(self, 'x', self.x + 1)
>>
>> They all cause self to be modified through __setattr__. If self is a
>> persistent instance then it will be marked changed in all three cases
>> above.

[John Belmonte]
> To be more accurate, it seems like
>
>     foo.bar += 1
>
> becomes the equivalent of
>
>     x = foo.bar; x += 1; foo.bar = x

Right.

> That is arguably a Python wart.

Why?  The setattr is generally necessary when foo.bar is of an immutable
type.  For example, if foo.bar started life as the int 42, it's impossible
to mutate the int object "in place"; foo.bar must be bound to a different
object (43) then.  The __iadd__ method of an object makes this decision (it
can return self if it wants to do in-place mutation, or return any object if
it can't or won't mutate in-place).  The code *generated* for += can't guess
what any specific __iadd__ will do, so caters to the (in some sense) "worst"
case (where the LHS object's __iadd__ decides to return an object other than
self).

> With regard to the containing object, it seems unfortunate to consider
> "foo.bar +=1" different than "foo.bar[a] = b".

In "foo.bar[a] = b", the containing object (wrt what changes) is foo.bar,
not foo.

> This wrapper for Persistent.__setattr__ looks like it will suit my
> needs:
>
> class MyPersistent(Persistent):
>   def __setattr__(self, key, val):
>     if not (self.__dict__.has_key(key) and self.__dict__[key] is val):
>       Persistent.__setattr__(self, key, val)

That looks safe to me.  Note that there's no guarantee that, e.g., in

   foo.bar += 0

you won't end up calling Persistent.__setattr__() anyway (immutable objects
generally don't promise to reuse self whenever semantically possible).




More information about the ZODB-Dev mailing list