[Zope-Checkins] CVS: ZODB3/ZODB - coptimizations.c:1.20.2.1
Jeremy Hylton
jeremy@zope.com
Fri, 13 Dec 2002 16:57:05 -0500
Update of /cvs-repository/ZODB3/ZODB
In directory cvs.zope.org:/tmp/cvs-serv25075
Modified Files:
Tag: ZODB3-3_1-branch
coptimizations.c
Log Message:
Sideport changes from Zope 2.6 branch.
Get ZClasses working. (Tested this time.)
Add some more comments and add XDECREFs to avoid leaks.
Remove redundant check of ExtensionClass in get_class().
Apparent fix for ZClass persistent_id problem.
(Also add comment from ZODB trunk.)
=== ZODB3/ZODB/coptimizations.c 1.20 => 1.20.2.1 ===
--- ZODB3/ZODB/coptimizations.c:1.20 Mon Sep 30 12:02:32 2002
+++ ZODB3/ZODB/coptimizations.c Fri Dec 13 16:57:05 2002
@@ -69,8 +69,8 @@
/* Returns the klass of a persistent object.
Returns NULL for other objects.
*/
-static PyObject *
-get_class(PyObject *object)
+int
+get_class(PyObject *object, PyObject **out_class)
{
PyObject *class = NULL;
@@ -79,19 +79,23 @@
class = PyObject_GetAttr(object, py___class__);
if (!class) {
PyErr_Clear();
- return NULL;
+ return 0;
}
- if (!PyExtensionClass_Check(class) ||
- !(((PyExtensionClass*)class)->class_flags
+ /* The __class__ must be an extension class. */
+ if (!(((PyExtensionClass*)class)->class_flags
& PERSISTENT_TYPE_FLAG)) {
Py_DECREF(class);
- return NULL;
+ return 0;
}
}
else
- return NULL;
+ /* Most objects will exit via this path. They are neither
+ extension classes nor instances of them.
+ */
+ return 0;
}
- return class;
+ *out_class = class;
+ return 1;
}
/* Return a two-tuple of the class's module and name.
@@ -106,7 +110,7 @@
goto err;
if (!PyObject_IsTrue(module)) {
Py_DECREF(module);
- /* XXX Handle degenerate 1.x ZClass case. */
+ /* If the class has no __module__, it must be a degnerate ZClass. */
return oid;
}
@@ -152,24 +156,39 @@
return NULL;
}
+/* persistent_id_call()
+
+ Returns a reference to a persistent object, appending it to the the
+ persistent_id's list of objects. If a non-persistent object is
+ found, return None.
+
+ The returned reference can be either class info, oid pair or a
+ plain old oid. If it is a pair, the class info is the module and
+ the name of the class. The class info can be used to create a
+ ghost without loading the class.
+
+ 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__().
+*/
+
static PyObject *
persistent_id_call(persistent_id *self, PyObject *args, PyObject *kwargs)
{
- PyObject *object, *oid, *klass=NULL;
+ PyObject *object, *oid=NULL, *klass=NULL;
PyObject *t1, *t2;
int setjar = 0;
if (!PyArg_ParseTuple(args, "O", &object))
return NULL;
- klass = get_class(object);
- if (!klass)
+ /* If it is not an extension class, get the object's class. */
+ if (!get_class(object, &klass))
goto return_none;
oid = PyObject_GetAttr(object, py__p_oid);
if (!oid) {
PyErr_Clear();
- Py_DECREF(klass);
goto return_none;
}
@@ -205,7 +224,7 @@
t2 = get_class_tuple(klass, oid);
if (!t2)
goto err;
- if (t2 == oid) /* pass through ZClass special case */
+ if (t2 == oid) /* Couldn't find class info, just used oid. */
goto return_oid;
t1 = PyTuple_New(2);
if (!t1) {
@@ -229,6 +248,8 @@
return oid;
return_none:
+ Py_XDECREF(oid);
+ Py_XDECREF(klass);
Py_INCREF(Py_None);
return Py_None;
}