[Zope-Checkins] SVN: Zope/trunk/lib/python/ZClasses/_pmc.py Import what we can from ZODB.persistentclass to avoid duplication.

Jim Fulton jim at zope.com
Sun Apr 10 09:42:01 EDT 2005


Log message for revision 29939:
  Import what we can from ZODB.persistentclass to avoid duplication.
  

Changed:
  U   Zope/trunk/lib/python/ZClasses/_pmc.py

-=-
Modified: Zope/trunk/lib/python/ZClasses/_pmc.py
===================================================================
--- Zope/trunk/lib/python/ZClasses/_pmc.py	2005-04-10 13:15:31 UTC (rev 29938)
+++ Zope/trunk/lib/python/ZClasses/_pmc.py	2005-04-10 13:42:00 UTC (rev 29939)
@@ -18,136 +18,24 @@
 
 $Id$
 """
-
-
-# Notes:
-# 
-# Persistent classes are non-ghostable.  This has some interesting
-# ramifications:
-# 
-# - When an object is invalidated, it must reload it's state
-# 
-# - When an object is loaded from the database, it's state must be
-#   loaded.  Unfortunately, there isn't a clear signal when an object is
-#   loaded from the database.  This should probably be fixed.
-# 
-#   In the mean time, we need to infer.  This should be viewed as a
-#   short term hack.
-# 
-#   Here's the strategy we'll use:
-# 
-#   - We'll have a need to be loaded flag that we'll set in
-#     __new__, through an extra argument.
-# 
-#   - When setting _p_oid and _p_jar, if both are set and we need to be
-#     loaded, then we'll load out state.
-# 
-#   - We'll use _p_changed is None to indicate that we're in this state.
-# 
-
 import ExtensionClass
+import ZODB.persistentclass
 
-class _p_DataDescr(object):
-    # Descr used as base for _p_ data. Data are stored in
-    # _p_class_dict.
+# See the comments in ZODB.persistentclass
 
-    def __init__(self, name):
-        self.__name__ = name
-
-    def __get__(self, inst, cls):
-        if inst is None:
-            return self
-
-        if '__global_persistent_class_not_stored_in_DB__' in inst.__dict__:
-            raise AttributeError, self.__name__
-        return inst._p_class_dict.get(self.__name__)
-    
-    def __set__(self, inst, v):
-        inst._p_class_dict[self.__name__] = v
-
-    def __delete__(self, inst):
-        raise AttributeError, self.__name__
-
-class _p_oid_or_jar_Descr(_p_DataDescr):
-    # Special descr for _p_oid and _p_jar that loads
-    # state when set if both are set and and _p_changed is None
-    #
-    # See notes above
-    
-    def __set__(self, inst, v):
-        get = inst._p_class_dict.get
-        if v == get(self.__name__):
-            return
-        
-        inst._p_class_dict[self.__name__] = v
-        
-        jar = get('_p_jar')
-        if (jar is not None
-            and get('_p_oid') is not None
-            and get('_p_changed') is None
-            ):
-            jar.setstate(inst)
-
-class _p_ChangedDescr(object):
-    # descriptor to handle special weird emantics of _p_changed
-    
-    def __get__(self, inst, cls):
-        if inst is None:
-            return self
-        return inst._p_class_dict['_p_changed']
-        
-    def __set__(self, inst, v):
-        if v is None:
-            return
-        inst._p_class_dict['_p_changed'] = bool(v)
-
-    def __delete__(self, inst):
-        inst._p_invalidate()
-
-class _p_MethodDescr(object):
-    """Provide unassignable class attributes
-    """
-
-    def __init__(self, func):
-        self.func = func
-
-    def __get__(self, inst, cls):
-        if inst is None:
-            return cls
-        return self.func.__get__(inst, cls)
-
-    def __set__(self, inst, v):
-        raise AttributeError, self.__name__
-
-    def __delete__(self, inst):
-        raise AttributeError, self.__name__
-    
-
-special_class_descrs = '__dict__', '__weakref__'
-
-
-def _p_maybeupdate(self, name):
-    get = self._p_class_dict.get
-    data_manager = get('_p_jar')
-
-    if (
-        (data_manager is not None)
-        and          
-        (get('_p_oid') is not None)
-        and
-        (get('_p_changed') == False)
-        ):
-        
-        self._p_changed = True
-        data_manager.register(self)
-
 class ZClassPersistentMetaClass(ExtensionClass.ExtensionClass):
 
-    _p_jar = _p_oid_or_jar_Descr('_p_jar')
-    _p_oid = _p_oid_or_jar_Descr('_p_oid')
-    _p_changed = _p_ChangedDescr()
-    _p_serial = _p_DataDescr('_p_serial')
+    # For weird reasons having to do with restrictions on built-in
+    # types, we can't subclass
+    # ZODB.persistentclass.PersistentMetaClass, so we do the next best
+    # thing:
 
+    for name in ('_p_jar', '_p_oid', '_p_changed', '_p_serial',
+                 '__getnewargs__', '_p_maybeupdate', '_p_deactivate',
+                 '_p_invalidate', '__getstate__', '_p_activate', ):
+        locals()[name] = ZODB.persistentclass.PersistentMetaClass.__dict__[
+            name]
+
     def __new__(self, name, bases, cdict, _p_changed=False):
 
         # _p_changed will be None if we are being loaded from the
@@ -168,46 +56,15 @@
         ExtensionClass.pmc_init_of(result)
         return result
 
-    def __getnewargs__(self):
-        return self.__name__, self.__bases__, {}, None
-
-    __getnewargs__ = _p_MethodDescr(__getnewargs__)
-
     def __setattr__(self, name, v):
         if not ((name.startswith('_p_') or name.startswith('_v'))):
-            _p_maybeupdate(self, name)
+            self._p_maybeupdate(name)
         super(ZClassPersistentMetaClass, self).__setattr__(name, v)
 
     def __delattr__(self, name):
         if not ((name.startswith('_p_') or name.startswith('_v'))):
-            _p_maybeupdate(self, name)
+            self._p_maybeupdate(name)
         super(ZClassPersistentMetaClass, self).__delattr__(name)
-
-    def _p_deactivate(self):
-        # persistent classes can't be ghosts
-        pass
-
-    _p_deactivate = _p_MethodDescr(_p_deactivate)
-
-    def _p_invalidate(self):
-        # reset state
-        self._p_class_dict['_p_changed'] = None
-        self._p_jar.setstate(self)
-
-    _p_invalidate = _p_MethodDescr(_p_invalidate)
-
-
-    def __getstate__(self):
-        return (self.__bases__, 
-                dict([(k, v) for (k, v) in self.__dict__.items()
-                      if not (k.startswith('_p_')
-                              or k.startswith('_v_')
-                              or k in special_class_descrs
-                              )
-                     ]),
-                )
-
-    __getstate__ = _p_MethodDescr(__getstate__)
     
     def __setstate__(self, state):
         try:
@@ -224,13 +81,14 @@
             _p_class_dict = self._p_class_dict
             self._p_class_dict = {}
 
-            to_remove = [k for k in self.__dict__
-                         if ((k not in cdict)
-                             and
-                             (k not in special_class_descrs)
-                             and
-                             (k != '_p_class_dict')
-                             )]
+            to_remove = [
+                k for k in self.__dict__
+                if ((k not in cdict)
+                    and
+                    (k not in ZODB.persistentclass.special_class_descrs)
+                    and
+                    (k != '_p_class_dict')
+                    )]
 
             for k in to_remove:
                 delattr(self, k)
@@ -244,9 +102,4 @@
 
         self._p_changed = False
         
-    __setstate__ = _p_MethodDescr(__setstate__)
-
-    def _p_activate(self):
-        self._p_jar.setstate(self)
-
-    _p_activate = _p_MethodDescr(_p_activate)
+    __setstate__ = ZODB.persistentclass._p_MethodDescr(__setstate__)



More information about the Zope-Checkins mailing list