[PEAK] Recursive __setstate__ call
    Radek Kanovsky 
    rk at dat.cz
       
    Sat Apr 17 10:19:32 EDT 2004
    
    
  
On Fri, Apr 16, 2004 at 09:25:22PM -0400, Phillip J. Eby wrote:
> At 02:58 PM 4/16/04 +0200, Radek Kanovsky wrote:
> >On Thu, Mar 25, 2004 at 11:52:02AM -0500, Phillip J. Eby wrote:
> >
> >> So, it's almost certainly something wrong with the state management logic
> >> in _persistence.c.  It might be possible to workaround by having
> >> 'setstate()' force ob._p_changed to a particular state before calling
> >> __setstate__, but I'm not sure.
> >
> >Investigating persistence code I am almost sure that it is not
> >possible to revive ghost object without setstate invocation as
> >undesirable side effect. Any operation on ghost causes immediate
> >_PyPersist_Load() -> setstate() calling.
> 
> What would happen if you temporarily set ob._p_jar to an object with a 
> 'setstate()' method that set the desired state?
Yes! It is the right trick that doesn't strike me. I have changed
QueryDM.__getitem__ and QueryDM.setstate methods following way:
    class _noDM :
        def setstate (self, ob) :
            pass
    _noDM = _noDM()
   
    class QueryDM (TransactionComponent) :
        [...]
        def __getitem__(self, oid, state=None):
            if self.resetStatesAfterTxn:
                # must always be used in a txn
                self.joinedTxn
            ob = self.cache.get(oid,self)
            if ob is not self:
                if state is not None and ob._p_state == 3 :
                    # Revive ghost
                    ob._p_jar = _noDM
                    ob.__setstate__(state)
                    ob._p_jar = self
                return ob
            ob = self._ghost(oid,state)
            if isinstance(ob,Persistent):
                ob._p_jar = self
                ob._p_oid = oid
                if state is None:
                    ob._p_deactivate()
                else:
                    ob.__setstate__(state)
            self.cache[oid] = ob
            return ob
        
        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.
RadekK
    
    
More information about the PEAK
mailing list