[Zodb-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 Zodb-checkins
mailing list