[Zope-Checkins] CVS: Zope3/lib/python/Persistence - _persistent.py:1.1.2.6 _persistentmech.py:NONE

Guido van Rossum guido@python.org
Fri, 30 Nov 2001 12:08:06 -0500


Update of /cvs-repository/Zope3/lib/python/Persistence
In directory cvs.zope.org:/tmp/cvs-serv21139

Modified Files:
      Tag: Zope-3x-branch
	_persistent.py 
Removed Files:
      Tag: Zope-3x-branch
	_persistentmech.py 
Log Message:
Changes to the Persistent class with Jim's approval:

- implement _p_changed using property() and three local methods rather
  than a new object in a separate file

- remove premature optimizations (oget, oset)

- change oget(self, '_p_foo') into self._p_foo

- setting a _v_ attribute doesn't mark the object as changed

This passes all test in lib/python/{Persistence,ZODB}.



=== Zope3/lib/python/Persistence/_persistent.py 1.1.2.5 => 1.1.2.6 ===
 from IPersistent import IPersistent
 
-oget=object.__getattribute__
-oset=object.__setattr__
-
 class Persistent(object):
     """Mix-in class providing IPersistent support
     """
 
     __implements__ = IPersistent
 
-    from _persistentmech import _p_changed
-    _p_changed=_p_changed()
+    def _p_get_changed(self):
+        return self._p_state
+
+    def _p_set_changed(self, val):
+        if self._p_jar is None or self._p_oid is None:
+            return
+
+        state = self._p_state
+        if state is val: return
 
-    _p_state=0
+        if state:
+            # changed
+            if val==0:
+                self._p_state = 0
+        elif state==0:
+            # unchanged, but not a ghost
+            if val:
+                self._p_state = 1
+                self._p_jar.register(self)
+            elif val is None:
+                self._p_deactivate()
+                self._p_state = None
+        else:
+            # Ghost. Note val can't be None, cuz then val would equal state.
+            self._p_jar.setstate(self)
+            self._p_state = not not state
+
+    def _p_del_changed(self):
+        if self._p_jar is None or self._p_oid is None:
+            return
+
+        state = self._p_state
+        if state is not None:
+            self._p_state = 0
+            self._p_deactivate()
+            self._p_state = None
+
+    _p_changed = property(_p_get_changed, _p_set_changed, _p_del_changed,
+                          "set _p_changed to 1 to indicate a change")
+
+    _p_state = 0
 
     _p_oid = _p_jar = _p_serial = None
-    
+
     def __getstate__(self):
         r={}
-        for k, v in oget(self, '__dict__').items():
+        for k, v in self.__dict__.items():
             if k[:3] not in ('_p_', '_v_'):
                 r[k]=v
         return r
 
     def __setstate__(self, state):
-        d=oget(self, '__dict__')
+        d=self.__dict__
         for k, v in d.items():
             if k[:3] != '_p_':
                 del d[k]
         d.update(state)
 
     def _p_deactivate(self):
-        state=oget(self, '_p_state')
+        state=self._p_state
         if state:
             return
-        if oget(self, '_p_jar') is None or oget(self, '_p_oid') is None:
+        if self._p_jar is None or self._p_oid is None:
             return
-        
-        d=oget(self, '__dict__')
+
+        d=self.__dict__
         for k, v in d.items():
             if k[:3] != '_p_':
                 del d[k]
-        oset(self, '_p_state', None)
+        self._p_state = None
 
     def __getattribute__(self, name):
-        oget=object.__getattribute__
-                
         if name[:3] != '_p_' and name != '__dict__':
-            oset=object.__setattr__
-
-            state=oget(self, '_p_state')
+            state=self._p_state
             if state is None:
-                dm=oget(self, '_p_jar')
+                dm=self._p_jar
                 if dm is not None:
                     setstate(self, dm, 0)
-                
-            oset(self, '_p_atime', int(time() % 86400))
-            
-        return oget(self, name)
+
+            object.__setattr__(self, '_p_atime', int(time() % 86400))
+
+        return object.__getattribute__(self, name)
 
     def __setattr__(self, name, v):
-        oget=object.__getattribute__
-        oset=object.__setattr__
-                
-        if name[:3] != '_p_' and name != '__dict__':
-            state=oget(self, '_p_state')
+        if name[:3] not in ('_p_', '_v_') and name != '__dict__':
+            state=self._p_state
             if state is None:
-                dm=oget(self, '_p_jar')
-                if dm is None or oget(self, '_p_oid') is None:
+                dm=self._p_jar
+                if dm is None or self._p_oid is None:
                     raise TypeError('Attempt to modify a unreviveable ghost')
                 # revivable ghost
                 setstate(self, dm, 1)
                 dm.register(self)
             elif not state:
-                dm=oget(self, '_p_jar')
+                dm=self._p_jar
                 if dm is not None:
-                    oset(self, '_p_state', 1)
+                    self._p_state = 1
                     dm.register(self)
-                
-            oset(self, '_p_atime', int(time() % 86400))
-            
-        return oset(self, name, v)
-        
-    
+
+            self._p_atime = int(time() % 86400)
+
+        return object.__setattr__(self, name, v)
+
+
 def setstate(ob, dm, state):
     # Put in modified state so we don't mark ourselves as modified
     # when our state is updated.
-    oset(ob, '_p_state', 1)
+    ob._p_state = 1
 
     try:
         # Get out data manager to updates us.
         dm.setstate(ob)
 
         # Now set the final state.
-        oset(ob, '_p_state', state)
-    
+        ob._p_state = state
+
     except: # We are going to reraise!
         # Something went wrong. We need to end up in the ghost state:
         del ob._p_changed

=== Removed File Zope3/lib/python/Persistence/_persistentmech.py ===