[Zope3-checkins] CVS: Zope3/src/ZODB - Connection.py:1.114.2.1 coptimizations.c:1.26.6.1 serialize.py:1.2.10.1

Fred L. Drake, Jr. fred at zope.com
Fri Jan 9 14:48:55 EST 2004


Update of /cvs-repository/Zope3/src/ZODB
In directory cvs.zope.org:/tmp/cvs-serv30152

Modified Files:
      Tag: zope3-zodb3-devel-branch
	Connection.py coptimizations.c serialize.py 
Log Message:
checkpoint changes to change the ZODB format


=== Zope3/src/ZODB/Connection.py 1.114 => 1.114.2.1 ===
--- Zope3/src/ZODB/Connection.py:1.114	Tue Jan  6 13:10:43 2004
+++ Zope3/src/ZODB/Connection.py	Fri Jan  9 14:48:53 2004
@@ -19,28 +19,20 @@
 import sys
 import threading
 from time import time
-from types import ClassType
 from utils import u64
 
-_marker = object()
-
-def myhasattr(obj, attr):
-    # builtin hasattr() swallows exceptions
-    return getattr(obj, attr, _marker) is not _marker
-
 from persistent import PickleCache
 from zLOG import LOG, ERROR, BLATHER, WARNING
 
 from ZODB.ConflictResolution import ResolvedSerial
-from ZODB.coptimizations import new_persistent_id
 from ZODB.ExportImport import ExportImport
 from ZODB.POSException \
-     import ConflictError, ReadConflictError, TransactionError
+     import ConflictError, ReadConflictError
 from ZODB.TmpStore import TmpStore
 from ZODB.Transaction import Transaction, get_transaction
 from ZODB.utils import oid_repr, z64
 from ZODB.serialize \
-     import ObjectWriter, getClassMetadata, ConnectionObjectReader
+     import ObjectWriter, ConnectionObjectReader
 
 global_reset_counter = 0
 
@@ -475,7 +467,7 @@
         # dict update could go on in another thread, but we don't care
         # because we have to check again after the load anyway.
         if (obj._p_oid in self._invalidated
-            and not myhasattr(obj, "_p_independent")):
+            and not hasattr(obj, "_p_independent")):
             # If the object has _p_independent(), we will handle it below.
             self._load_before_or_conflict(obj)
             return
@@ -490,7 +482,7 @@
             self._inv_lock.release()
 
         if invalid:
-            if myhasattr(obj, "_p_independent"):
+            if hasattr(obj, "_p_independent"):
                 # This call will raise a ReadConflictError if something
                 # goes wrong
                 self._handle_independent(obj)


=== Zope3/src/ZODB/coptimizations.c 1.26 => 1.26.6.1 ===
--- Zope3/src/ZODB/coptimizations.c:1.26	Thu Dec 11 11:02:56 2003
+++ Zope3/src/ZODB/coptimizations.c	Fri Jan  9 14:48:53 2004
@@ -18,7 +18,7 @@
 
 #include "cPersistence.h"
 
-static PyObject *py__p_oid, *py__p_jar, *py___getinitargs__, *py___module__;
+static PyObject *py__p_oid, *py__p_jar, *py___getnewargs__, *py___module__;
 static PyObject *py_new_oid, *py___class__, *py___name__;
 
 static PyObject *InvalidObjectReference;
@@ -36,8 +36,12 @@
     persistent_id *self;
     PyObject *jar, *stack;
 
-    if (!PyArg_ParseTuple(args, "OO!", &jar, &PyList_Type, &stack)) 
+    if (!PyArg_UnpackTuple(args, "new_persistent_id", 2, 2, &jar, &stack)) 
 	return NULL;
+    if (!PyList_Check(stack)) {
+        PyErr_SetString(PyExc_TypeError, "stack argument must be a list");
+        return NULL;
+    }
     self = PyObject_NEW(persistent_id, &persistent_idType);
     if (!self)
 	return NULL;
@@ -58,28 +62,6 @@
     PyObject_DEL(self);
 }
 
-/* Returns the klass of a persistent object.
-   Returns NULL for other objects.
-*/
-int
-get_class(PyObject *object, PyObject **out_class)
-{
-    PyObject *class = NULL;
-
-    if (!PyType_Check(object)) {
-	if (!PER_TypeCheck(object)) 
-	    return 0;
-
-	class = PyObject_GetAttr(object, py___class__);
-	if (!class) {
-	    PyErr_Clear();
-	    return 0;
-	}
-    }
-    *out_class = class;
-    return 1;
-}
-
 /* Return a two-tuple of the class's module and name.
  */
 static PyObject *
@@ -151,32 +133,38 @@
 
    For unusual objects, e.g. ZClasses, return just the oid.  An object
    is unusual if it isn't an ExtensionClass, because that means it
-   doesn't inherit from Persistence, or if it has __getinitargs__().
+   doesn't inherit from Persistence, or if it has __getnewargs__().
 */
 
 static PyObject *
 persistent_id_call(persistent_id *self, PyObject *args, PyObject *kwargs)
 {
-    PyObject *object, *oid=NULL, *klass=NULL;
-    PyObject *t1, *t2;
+    PyObject *object, *oid = NULL, *klass = NULL;
+    PyObject *t1;
     int setjar = 0;
 
-    if (!PyArg_ParseTuple(args, "O", &object))
+    if (! PyArg_UnpackTuple(args, "__call__", 1, 1, &object))
 	return NULL;
 
-    /* If it is not an extension class, get the object's class. */
-    if (!get_class(object, &klass))
-	goto return_none;
+    /* Most objects are not persistent. The following cheap test
+       identifies most of them.  For these, we return None,
+       signalling that the object should be pickled normally.
+    */
+    if (! PyType_Check(object) && ! PER_TypeCheck(object))
+        goto return_none;
 
+    /* We have a persistent object or a non-persistent class. */
+    
     oid = PyObject_GetAttr(object, py__p_oid);
     if (!oid) {
 	PyErr_Clear();
 	goto return_none;
     }
+    
     if (oid != Py_None) {
 	PyObject *jar;
 
-	if (!PyString_Check(oid)) {
+	if (! PyString_Check(oid)) {
 	    /* If the object is a class, then asking for _p_oid or
 	       _p_jar will return a descriptor.  There is no API to
 	       ask whether something is a descriptor; the best you
@@ -207,6 +195,16 @@
 	    /* XXX should check that this was an AttributeError */
 	    PyErr_Clear();
 	}
+
+
+        /* Since we have an oid, we have either a persistent instance
+           (an instance of Persistent), or a persistent class.
+
+           NOTE! Persistent classes don't (and can't) subclass persistent.
+
+        */
+
+        
 	jar = PyObject_GetAttr(object, py__p_jar);
 	if (!jar)
 	    PyErr_Clear();
@@ -231,24 +229,18 @@
 	    goto err;
     }
 
-    if (PyType_Check(object) || PyObject_HasAttr(klass, py___getinitargs__))
+    klass = (PyObject *)object->ob_type;
+    if (PyObject_HasAttr(klass, py___getnewargs__))
 	goto return_oid;
 
-    t2 = get_class_tuple(klass, oid);
-    if (!t2)
-	goto err;
-    if (t2 == oid) /* Couldn't find class info, just used oid. */
-	goto return_oid;
     t1 = PyTuple_New(2);
-    if (!t1) {
-	Py_DECREF(t2);
+    if (!t1)
 	goto err;
-    }
-    /* use borrowed references to oid and t2 */
-    PyTuple_SET_ITEM(t1, 0, oid);
-    PyTuple_SET_ITEM(t1, 1, t2);
 
-    Py_DECREF(klass);
+    /* use borrowed reference to oid */
+    Py_INCREF(klass);
+    PyTuple_SET_ITEM(t1, 0, oid);
+    PyTuple_SET_ITEM(t1, 1, klass);
 
     return t1;
 
@@ -314,7 +306,7 @@
 #define make_string(S) if (! (py_ ## S=PyString_FromString(#S))) return
     make_string(_p_oid);
     make_string(_p_jar);
-    make_string(__getinitargs__);
+    make_string(__getnewargs__);
     make_string(__module__);
     make_string(__class__);
     make_string(__name__);


=== Zope3/src/ZODB/serialize.py 1.2 => 1.2.10.1 ===
--- Zope3/src/ZODB/serialize.py:1.2	Fri Nov 28 11:44:49 2003
+++ Zope3/src/ZODB/serialize.py	Fri Jan  9 14:48:53 2004
@@ -60,32 +60,13 @@
 
 from ZODB.coptimizations import new_persistent_id
 
-_marker = object()
-
-def myhasattr(obj, attr):
-    """Returns True or False or raises an exception."""
-    val = getattr(obj, attr, _marker)
-    return val is not _marker
-
 def getClassMetadata(obj):
     klass = obj.__class__
-    if issubclass(klass, type):
-        # Handle ZClasses.
-        d = obj.__dict__.copy()
-        del d["_p_jar"]
-        args = obj.__name__, obj.__bases__, d
-        return klass, args
+    newargs = getattr(klass, "__getnewargs__", None)
+    if newargs is None:
+        return klass
     else:
-        getinitargs = getattr(klass, "__getinitargs__", None)
-        if getinitargs is None:
-            args = None
-        else:
-            args = getinitargs()
-        mod = getattr(klass, "__module__", None)
-        if mod is None:
-            return klass, args
-        else:
-            return (mod, klass.__name__), args
+        return klass, newargs(obj)
 
 class BaseObjectWriter:
     """Serializes objects for storage in the database.
@@ -107,7 +88,7 @@
         self._stack = []
         self._p.persistent_id = new_persistent_id(jar, self._stack)
         if jar is not None:
-            assert myhasattr(jar, "new_oid")
+            assert hasattr(jar, "new_oid")
         self._jar = jar
 
     def serialize(self, obj):
@@ -168,7 +149,7 @@
         return unpickler
 
     def _new_object(self, klass, args):
-        if not args and not myhasattr(klass, "__getinitargs__"):
+        if not args and not hasattr(klass, "__getnewargs__"):
             obj = klass.__new__(klass)
         else:
             obj = klass(*args)
@@ -179,19 +160,32 @@
 
     def getClassName(self, pickle):
         unpickler = self._get_unpickler(pickle)
-        klass, newargs = unpickler.load()
+        klass = unpickler.load()
         if isinstance(klass, tuple):
-            return "%s.%s" % klass
-        else:
-            return klass.__name__
+            klass, args = klass
+            if isinstance(klass, tuple):
+                # old style reference
+                return "%s.%s" % klass
+        return "%s.%s" % (klass.__module__, klass.__name__)
 
     def getGhost(self, pickle):
         unpickler = self._get_unpickler(pickle)
-        klass, args = unpickler.load()
+        klass = unpickler.load()
         if isinstance(klass, tuple):
-            klass = self._get_class(*klass)
-
-        return self._new_object(klass, args)
+            # Here we have a separate class and args.
+            # This could be an old record, so the class module ne a named
+            # refernce
+            klass, args = klass
+            if isinstance(klass, tuple):
+                # Old module_name, class_name tuple
+                klass = self._get_class(*klass)
+            if args is None:
+                return klass.__new__(klass)
+            else:
+                return klass.__new__(klass, *args)
+        else:
+            # Definately new style direct class reference
+            return klass.__new__(klass)
 
     def getState(self, pickle):
         unpickler = self._get_unpickler(pickle)
@@ -202,13 +196,6 @@
         state = self.getState(pickle)
         obj.__setstate__(state)
 
-    def getObject(self, pickle):
-        unpickler = self._get_unpickler(pickle)
-        klass, args = unpickler.load()
-        obj = self._new_object(klass, args)
-        state = unpickler.load()
-        obj.__setstate__(state)
-        return obj
 
 class ExternalReference(object):
     pass
@@ -242,19 +229,18 @@
         if isinstance(oid, tuple):
             # Quick instance reference.  We know all we need to know
             # to create the instance w/o hitting the db, so go for it!
-            oid, klass_info = oid
+            oid, klass = oid
             obj = self._cache.get(oid, None) # XXX it's not a dict
             if obj is not None:
                 return obj
-
-            klass = self._get_class(*klass_info)
-            # XXX Why doesn't this have args?
-            obj = self._new_object(klass, None)
-            # XXX This doesn't address the last fallback that used to
-            # exist:
-##                    # Eek, we couldn't get the class. Hm.  Maybe there's
-##                    # more current data in the object's actual record!
-##                    return self._conn[oid]
+            if isinstance(klass, tuple):
+                klass = self._get_class(*klass)
+            try:
+                obj = klass.__new__(klass)
+            except TypeError:
+                # Couldn't create the instance.  Maybe there's more
+                # current data in the object's actual record!
+                return self._conn[oid]
 
             # XXX should be done by connection
             obj._p_oid = oid
@@ -267,7 +253,7 @@
             self._cache[oid] = obj
             return obj
 
-        obj = self._cache.get(oid)
+        obj = self._cache.get(oid, None)
         if obj is not None:
             return obj
         return self._conn[oid]




More information about the Zope3-Checkins mailing list