[Zodb-checkins] CVS: Zope3/src/zodb/code - class_.py:1.6.2.1

Jeremy Hylton jeremy@zope.com
Tue, 21 Jan 2003 17:35:50 -0500


Update of /cvs-repository/Zope3/src/zodb/code
In directory cvs.zope.org:/tmp/cvs-serv32398

Modified Files:
      Tag: new-pickle-branch
	class_.py 
Log Message:
Many small changes, including several significant ones.

Make sure that a persistent class is always unghostified.  A
persistent class can never be a ghost, because there are too many
places where Python will attempt to inspect the class without using
getattr().  As a result, it would be impossible to guarantee that the
class would be unghostified at the right time.

When a persistent class is created, extend the __getstate__() and
__setate__() methods so that they can be defined on class and
metaclass.

Add XXX about the need to do something with _p_changed.  Not really
sure what needs to be done.

Remove unused class ExtClassObject.


=== Zope3/src/zodb/code/class_.py 1.6 => 1.6.2.1 ===
--- Zope3/src/zodb/code/class_.py:1.6	Tue Dec 31 13:27:49 2002
+++ Zope3/src/zodb/code/class_.py	Tue Jan 21 17:35:45 2003
@@ -102,36 +102,6 @@
     def clsdelete(self):
         del self.val
 
-class ExtClassObject:
-
-    _missing = object()
-
-    def __init__(self, name, instdescr):
-        self.name = name
-        self.instdescr = instdescr
-
-    def __get__(self, obj, cls):
-        if obj is None:
-            return self.clsget(cls)
-        else:
-            return self.instdescr.__get__(obj, cls)
-
-    def __set__(self, obj, cls):
-        if obj is None:
-            return self.clsset(cls)
-        else:
-            if self.instdescr is None:
-                raise AttributeError, self.name
-            return self.instdescr.__set__(obj, cls)
-
-    def __delete__(self, obj, cls):
-        if obj is None:
-            return self.clsdelete(cls)
-        else:
-            if self.instdescr is None:
-                raise AttributeError, self.name
-            return self.instdescr.__delete__(obj, cls)
-
 class ExtClassMethodDescr(MethodMixin, ExtClassDescr):
     pass
 
@@ -224,6 +194,7 @@
     # GHOST instead of UPTODATE.  See __getnewargs__().
 
     def __new__(meta, name, bases, dict, state=UPTODATE):
+        # XXX make sure bases are not ghosts?
         cls = super(PersistentClassMetaClass, meta).__new__(
             meta, name, bases, dict)
         # helper functions
@@ -239,17 +210,32 @@
         extend_attr("_p_jar", None)
         extend_attr("_p_atime", time.time() % 86400)
         extend_attr("_p_state", state)
+        # XXX A persistent class needs a proprety for _p_changed
+        # so that it can be used to register with the transaction
+        # manager.
+        extend_attr("_p_changed", None)
         extend_meth("_p_activate", meta._p_activate)
         extend_meth("_p_deactivate", meta._p_activate)
-        extend_meth("__getstate__", meta.__getstate__)
-        extend_meth("__setstate__", meta.__setstate__)
-        extend_attr("__implements__", meta.__implements__)
 
         for k, v in dict.items():
             if isinstance(v, PersistentFunction):
                 setattr(cls, k, PersistentDescriptor(cls, v))
 
+        # A class could define any of these attributes, thus we
+        # need to create extended descriptors so that the class
+        # and its instances have separate versions.
+        extend_meth("__getstate__", meta.__getstate__)
+        extend_meth("__setstate__", meta.__setstate__)
+        extend_attr("__implements__", meta.__implements__)
+
         cls._pc_init = True
+        # A persistent class can never be a ghost, because there are too
+        # many places where Python will attempt to inspect the class
+        # without using getattr().  As a result, it would be impossible
+        # to guarantee that the class would be unghostified at the
+        # right time.
+        if state == GHOST:
+            cls._p_activate()
         return cls
 
     def __getattribute__(cls, name):