[Zope3-checkins] CVS: Zope3/src/zope/app/container - _zope_app_container_contained.c:1.3

Fred L. Drake, Jr. fred at zope.com
Fri Feb 20 11:56:44 EST 2004


Update of /cvs-repository/Zope3/src/zope/app/container
In directory cvs.zope.org:/tmp/cvs-serv22350/src/zope/app/container

Modified Files:
	_zope_app_container_contained.c 
Log Message:


revision 1.2.10.5
date: 2004/02/12 18:23:32;  author: jeremy;  state: Exp;  lines: +8 -8
Fix references to the C persistent type.
----------------------------
revision 1.2.10.4
date: 2004/01/30 16:31:27;  author: jim;  state: Exp;  lines: +16 -9
Fixed a leak in the implementation of __setstate__.



Rewrote the CLEAR macro to hide the necessary temporary variable.
----------------------------
revision 1.2.10.3
date: 2004/01/30 16:16:56;  author: jim;  state: Exp;  lines: +10 -4
Fixed a bug in tp_dealloc.  The slot needs to call the base-class,
Persistent, tp_dealloc, so that the object gets removed from the
zodb object cache.




=== Zope3/src/zope/app/container/_zope_app_container_contained.c 1.2 => 1.3 ===
--- Zope3/src/zope/app/container/_zope_app_container_contained.c:1.2	Sun Sep 21 13:31:28 2003
+++ Zope3/src/zope/app/container/_zope_app_container_contained.c	Fri Feb 20 11:56:44 2004
@@ -12,12 +12,30 @@
 #
 ############################################################################*/
 
+/* Contained Proxy Base class
+
+ Contained proxies provide __parent__ and __name__ attributes for
+ objects without them.
+
+ There is something strange and, possibly cool, going on here, wrt
+ persistence.  To reuse the base proxy implementation we don't treat
+ the proxied object as part of the persistent state of the proxy.
+ This means that the proxy still operates as a proxy even if it is a
+ ghost.  
+
+ The proxy will only be unghostified if you need to access one of the
+ attributes provided by the proxy.
+
+ */
+
+
 #include "Python.h"
-#include "persistence/persistence.h"
-#include "persistence/persistenceAPI.h"
+#include "persistent/cPersistence.h"
+
+static PyObject *str_p_deactivate;
 
 typedef struct {
-  PyPersist_HEAD                 
+  cPersistent_HEAD               
   PyObject *po_serial;            
   PyObject *po_weaklist;          
   PyObject *proxy_object;
@@ -32,8 +50,12 @@
     PyObject *(*getobject)(PyObject *proxy);
 } ProxyInterface;
 
+#define OBJECT(O) ((PyObject*)(O))
 #define Proxy_GET_OBJECT(ob)   (((ProxyObject *)(ob))->proxy_object)
 
+#define CLEAR(O) \
+  if (O) {PyObject *clr__tmp = O; O = NULL; Py_DECREF(clr__tmp); }
+
 /* Supress inclusion of the original proxy.h */
 #define _proxy_H_ 1
 
@@ -72,7 +94,7 @@
 
   if (SPECIAL(cname))
     /* delegate to persistent */
-    return PyPersist_TYPE->tp_getattro(self, name);
+    return cPersistenceCAPI->pertype->tp_getattro(self, name);
 
   /* Use the wrapper version to delegate */
   return wrap_getattro(self, name);
@@ -89,7 +111,7 @@
 
   if (SPECIAL(cname))
     /* delegate to persistent */
-    return PyPersist_TYPE->tp_setattro(self, name, v);
+    return cPersistenceCAPI->pertype->tp_setattro(self, name, v);
 
   /* Use the wrapper version to delegate */
   return wrap_setattro(self, name, v);
@@ -113,10 +135,20 @@
 static PyObject *
 CP_setstate(ProxyObject *self, PyObject *state)
 {
-  if(! PyArg_ParseTuple(state, "OO", &self->__parent__, &self->__name__))
+  PyObject *parent, *name;
+
+  if(! PyArg_ParseTuple(state, "OO", &parent, &name))
     return NULL;
-  Py_INCREF(self->__parent__);
-  Py_INCREF(self->__name__);
+
+  CLEAR(self->__parent__);
+  CLEAR(self->__name__);
+
+  Py_INCREF(parent);
+  Py_INCREF(name);
+
+  self->__parent__ = parent;
+  self->__name__ = name;
+
   Py_INCREF(Py_None);
   return Py_None;
 }
@@ -124,12 +156,17 @@
 static PyObject *
 CP_reduce(ProxyObject *self)
 {
-  return Py_BuildValue("O(O)(OO)",
-                       self->ob_type,
-                       self->proxy_object,
-                       self->__parent__ ? self->__parent__ : Py_None,
-                       self->__name__   ? self->__name__   : Py_None
-                       );
+  PyObject *result;
+  if (! PER_USE(self))
+    return NULL;
+  result = Py_BuildValue("O(O)(OO)",
+                         self->ob_type,
+                         self->proxy_object,
+                         self->__parent__ ? self->__parent__ : Py_None,
+                         self->__name__   ? self->__name__   : Py_None
+                         );
+  PER_ALLOW_DEACTIVATION(self);
+  return result;
 }
 
 static PyObject *
@@ -139,48 +176,25 @@
 }
 
 static PyObject *
-CP__p_deactivate(ProxyObject *self, PyObject *args, PyObject *keywords)
+CP__p_deactivate(ProxyObject *self)
 {
-    int ghostify = 1;
-    PyObject *force = NULL;
-
-    if (args && PyTuple_GET_SIZE(args) > 0) {
-	PyErr_SetString(PyExc_TypeError, 
-			"_p_deactivate takes not positional arguments");
-	return NULL;
-    }
-    if (keywords) {
-	int size = PyDict_Size(keywords);
-	force = PyDict_GetItemString(keywords, "force");
-	if (force)
-	    size--;
-	if (size) {
-	    PyErr_SetString(PyExc_TypeError, 
-			    "_p_deactivate only accepts keyword arg force");
-	    return NULL;
-	}
-    }
+  PyObject *result;
 
-    if (self->po_dm && self->po_oid) {
-	ghostify = self->po_state == UPTODATE;
-	if (!ghostify && force) {
-	    if (PyObject_IsTrue(force))
-		ghostify = 1;
-	    if (PyErr_Occurred())
-		return NULL;
-	}
-	if (ghostify) {
-            Py_XDECREF(self->__parent__);
-            self->__parent__ = NULL;
-            Py_XDECREF(self->__name__);
-            self->__name__ = NULL;
+  result = PyObject_CallMethodObjArgs(OBJECT(cPersistenceCAPI->pertype), 
+                                      str_p_deactivate,
+                                      self, NULL);
+  if (result == NULL)
+    return NULL;
 
-	    self->po_state = GHOST;
-	}
+  if (self->jar && self->oid && self->state == cPersistent_UPTODATE_STATE)
+    {
+      Py_XDECREF(self->__parent__);
+      self->__parent__ = NULL;
+      Py_XDECREF(self->__name__);
+      self->__name__ = NULL;
     }
 
-    Py_INCREF(Py_None);
-    return Py_None;
+    return result;
 }
 
 
@@ -196,7 +210,7 @@
    "Reduce the object to constituent parts."},
   {"__reduce_ex__", (PyCFunction)CP_reduce_ex, METH_O, 
    "Reduce the object to constituent parts."},
-  {"_p_deactivate", (PyCFunction)CP__p_deactivate, METH_KEYWORDS, 
+  {"_p_deactivate", (PyCFunction)CP__p_deactivate, METH_NOARGS, 
    "Deactivate the object."},
   {NULL, NULL},
 };
@@ -216,7 +230,7 @@
 static int
 CP_traverse(ProxyObject *self, visitproc visit, void *arg)
 {
-  if (PyPersist_TYPE->tp_traverse((PyObject *)self, visit, arg) < 0)
+  if (cPersistenceCAPI->pertype->tp_traverse((PyObject *)self, visit, arg) < 0)
     return -1;
   if (self->po_serial != NULL && visit(self->po_serial, arg) < 0)
     return -1;
@@ -241,16 +255,14 @@
      collector will call this method if it detects that this
      object is involved in a reference cycle.
   */
-  PyPersist_TYPE->tp_clear((PyObject*)self);
+  if (cPersistenceCAPI->pertype->tp_clear != NULL)
+    cPersistenceCAPI->pertype->tp_clear((PyObject*)self);
+  
+  CLEAR(self->po_serial);
+  CLEAR(self->proxy_object);
+  CLEAR(self->__parent__);
+  CLEAR(self->__name__);
 
-  Py_XDECREF(self->po_serial);
-  self->po_serial = NULL;
-  Py_XDECREF(self->proxy_object);
-  self->proxy_object = NULL;
-  Py_XDECREF(self->__parent__);
-  self->__parent__ = NULL;
-  Py_XDECREF(self->__name__);
-  self->__name__ = NULL;
   return 0;
 }
 
@@ -260,9 +272,12 @@
   if (self->po_weaklist != NULL)
     PyObject_ClearWeakRefs((PyObject *)self);
 
-  PyObject_GC_UnTrack((PyObject *)self);
-  CP_clear(self);
-  self->ob_type->tp_free((PyObject*)self);
+  CLEAR(self->po_serial);
+  CLEAR(self->proxy_object);
+  CLEAR(self->__parent__);
+  CLEAR(self->__name__);
+
+  cPersistenceCAPI->pertype->tp_dealloc((PyObject*)self);
 }
 
 #ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
@@ -272,6 +287,10 @@
 init_zope_app_container_contained(void)
 {
   PyObject *m;
+
+  str_p_deactivate = PyString_FromString("_p_deactivate");
+  if (str_p_deactivate == NULL)
+    return;
         
   /* Try to fake out compiler nag function */
   if (0) init_zope_proxy_proxy();
@@ -286,14 +305,13 @@
     empty_tuple = PyTuple_New(0);
 
   /* Initialize the PyPersist_C_API and the type objects. */
-  PyPersist_C_API = PyCObject_Import("persistence._persistence", "C_API");
-  if (PyPersist_C_API == NULL)
+  cPersistenceCAPI = PyCObject_Import("persistent.cPersistence", "CAPI");
+  if (cPersistenceCAPI == NULL)
     return;
 
-  
   ProxyType.tp_name = "zope.app.container.contained.ContainedProxyBase";
   ProxyType.ob_type = &PyType_Type;
-  ProxyType.tp_base = PyPersist_TYPE;
+  ProxyType.tp_base = cPersistenceCAPI->pertype;
   ProxyType.tp_getattro = CP_getattro;
   ProxyType.tp_setattro = CP_setattro;
   ProxyType.tp_members = CP_members;




More information about the Zope3-Checkins mailing list