[ZODB-Dev] Re: false write conflicts

Casey Duncan casey at zope.com
Tue Mar 2 11:25:51 EST 2004


On Tue, 02 Mar 2004 11:15:42 -0500
John Belmonte <john at neggie.net> wrote:

> 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.
> 
> To be more accurate, it seems like
> 
>     foo.bar += 1
> 
> becomes the equivalent of
> 
>     x = foo.bar; x += 1; foo.bar = x

Ok, I'm not sure how that's more accurate ;^) My example don't create a
local variable 'x'.
 
> That is arguably a Python wart.  With regard to the containing object,
> 
> it seems unfortunate to consider "foo.bar +=1" different than 
> "foo.bar[a] = b".

It's not a wart. Augmented assignment is an assignment operation. If it
is an assignent to an attribute, that changes the containing object. A
positive side-affect of this wrt persistence is that augmented assigment
of mutable non-persistent attributes actually does the "right thing".
i.e.::

Where:
  self.x = []

  self.x += 'foo'

marks self as changed which actually "helps" you since
self.x.append('foo') wouldn't.

> 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)

Ugh. This is bound to bite you somewhere down the line. I'd say its
simpler to avoid augmented assignment when you don't want the container
marked as changed. But that's me.

-Casey



More information about the ZODB-Dev mailing list