[PEAK] Recursive __setstate__ call

Radek Kanovsky rk at dat.cz
Sun Apr 18 09:35:35 EDT 2004

On Sun, Apr 18, 2004 at 12:55:20AM -0400, Phillip J. Eby wrote:

> At 04:19 PM 4/17/04 +0200, Radek Kanovsky wrote:
> >        def setstate(self, ob):
> >
> >            if self.resetStatesAfterTxn:
> >                # must always be used in a txn
> >                self.joinedTxn
> >
> >            oid = ob._p_oid
> >            assert oid is not None
> >            state = self._load(oid,ob)
> >            ob._p_jar = _noDM
> >            ob.__setstate__(state)
> >            ob._p_jar = self
> >
> >
> >
> >All my unit tests passed without error so I don't expect some other 
> >problems.
> >Thanks for help.
> Hm.  Do they pass without the modification to setstate()?  I'm just curious 
> because I seem to recall that every place the DM' setstate() is called from 
> persistence.c, it first temporarily sets the object's state to "CHANGED", 
> and then puts it back to "UPTODATE" afterwards.  So it seems like the code 
> above in setstate() should be unnecessary.  But I haven't rechecked this.

I have made changes to setstate() because of my first complain. Original
code ``ob.__setstate__(self._load(oid, ob))'' caused twofold loading
when setting attribute of GHOST object:

    user = dm[1]           
    assert user._p_state == 3 # ghost
    user.login = "fred"

Dereferencing ob.__setstate__ on GHOST invokes setstate() again. Seccond
pass doesn't invoke setstate() third time because object's state is
temporarily changed from GHOST to CHANGED.

IMO setstate() modification is necessary for avoiding this problem.
__getitem__() modifications only solve problems with ghosts preloading.
I haven't found any contraexapmle that shouldn't work because of these
changes. Only if one redefine __setstate__() method and relies on
original DM in _p_jar attribute. But I should note that I am working
only with PostgreSQL data managers.


More information about the PEAK mailing list