[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) :
    _noDM = _noDM()

    class QueryDM (TransactionComponent) :


        def __getitem__(self, oid, state=None):

            if self.resetStatesAfterTxn:
                # must always be used in a txn

            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._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:

            self.cache[oid] = ob
            return ob

        def setstate(self, ob):

            if self.resetStatesAfterTxn:
                # must always be used in a txn

            oid = ob._p_oid
            assert oid is not None
            state = self._load(oid,ob)
            ob._p_jar = _noDM
            ob._p_jar = self

All my unit tests passed without error so I don't expect some other problems.
Thanks for help.


More information about the PEAK mailing list