[Zodb-checkins] CVS: ZODB3/Persistence - cPersistence.c:1.72.8.10

Jeremy Hylton jeremy at zope.com
Thu Jul 3 16:21:15 EDT 2003


Update of /cvs-repository/ZODB3/Persistence
In directory cvs.zope.org:/tmp/cvs-serv3687

Modified Files:
      Tag: zodb33-devel-branch
	cPersistence.c 
Log Message:
Rewrite tp_getattro slot implementation.

Implement _p_mtime using getset.
Use unghost_getattr() helper to decide whether to unghost.
Remove unused orNothing() helper.


=== ZODB3/Persistence/cPersistence.c 1.72.8.9 => 1.72.8.10 ===
--- ZODB3/Persistence/cPersistence.c:1.72.8.9	Thu Jul  3 14:19:11 2003
+++ ZODB3/Persistence/cPersistence.c	Thu Jul  3 15:21:08 2003
@@ -410,14 +410,6 @@
   self->ob_type->tp_free(self);
 }
 
-static PyObject *
-orNothing(PyObject *v)
-{
-  if (! v) v=Py_None;
-  Py_INCREF(v);
-  return v;
-}
-
 /* convert_name() returns a new reference to a string name
    or sets an exception and returns NULL.
 */
@@ -442,83 +434,72 @@
     return name;
 }
 
-static PyObject *
-Per_getattr(cPersistentObject *self, PyObject *oname)
-{
-  char *n, *name;
-  name = PyString_AS_STRING(oname);
-  n = name;
-  assert(n);
-
-  if (n && *n++=='_')
-      if (*n++=='p' && *n++=='_') {
-	switch(*n++)
-	  {
-	  case 's':
-	    if (strcmp(n,"elf")==0) 
-	      return orNothing((PyObject *)self);
-	    break;
-	  case 'm':
-	    if (strcmp(n,"time")==0)
-	      {
-                  if (!unghostify(self))
-                      return NULL;
-
-		accessed(self);
-
-		if (self->serial[7]=='\0' && self->serial[6]=='\0' &&
-		    self->serial[5]=='\0' && self->serial[4]=='\0' &&
-		    self->serial[3]=='\0' && self->serial[2]=='\0' &&
-		    self->serial[1]=='\0' && self->serial[0]=='\0')
-		  {
-		    Py_INCREF(Py_None);
-		    return Py_None;
-		  }
-		
-		oname=PyString_FromStringAndSize(self->serial, 8);
-		if (! oname) return oname;
-
-		ASSIGN(oname, PyObject_CallFunction(TimeStamp, "O", oname));
-		if (! oname) return oname;
-		ASSIGN(oname, PyObject_GetAttr(oname, py_timeTime));
-		if (! oname) return oname;
-		ASSIGN(oname, PyObject_CallObject(oname, NULL));
-		return oname;
-	      }
-	    break;
-	  }
-
-	return PyObject_GenericGetAttr((PyObject *)self, oname);
-      }
+/* Returns true if the object requires unghostification.
 
-  /* If the name is not __dict__, __del__, __class__, or __of__,
-     unghostify the object.
-  */
-  if (! (*name++ == '_' && *name++ == '_' &&
-	(strcmp(name,"dict__") == 0 || strcmp(name,"class__") == 0
-	 || strcmp(name, "of__") == 0 || strcmp(name, "del__") == 0))) {
-      if (!unghostify(self))
-	  return NULL;
-      accessed(self);
-  }
+   There are several special attributes that we allow access to without
+   requiring that the object be unghostified:
+   __class__
+   __del__
+   __dict__
+   __of__
+   __setstate__
+*/
 
-  return PyObject_GenericGetAttr((PyObject *)self, oname);
+static int
+unghost_getattr(const char *s)
+{
+    if (*s++ != '_')
+	return 1;
+    if (*s == 'p') {
+	s++;
+	if (*s == '_')  
+	    return 0; /* _p_ */
+	else
+	    return 1; 
+    }
+    else if (*s == '_') {
+	s++;
+	switch (*s) {
+	case 'c':
+	    return strcmp(s, "class__");
+	case 'd':
+	    s++;
+	    if (!strcmp(s, "el__"))
+		return 0; /* __del__ */
+	    if (!strcmp(s, "ict__"))
+		return 0; /* __dict__ */
+	    return 1;
+	case 'o':
+	    return strcmp(s, "of__");
+	case 's':
+	    return strcmp(s, "setstate__");
+	default:
+	    return 1;
+	}
+    }
+    return 1;
 }
 
 static PyObject*
 Per_getattro(cPersistentObject *self, PyObject *name)
 {
-  PyObject *r;
+    PyObject *r;
+    char *s;
 
-  
-  name = convert_name(name);
-  if (!name)
-      return NULL;
+    name = convert_name(name);
+    if (!name)
+	return NULL;
+    s = PyString_AS_STRING(name);
 
-  r = Per_getattr(self, name);
+    if (*s != '_' || unghost_getattr(s)) {
+	if (!unghostify(self))
+	    return NULL;
+	accessed(self);
+    }
+    r = PyObject_GenericGetAttr((PyObject *)self, name);
  
-  Py_DECREF(name);
-  return r;  
+    Py_DECREF(name);
+    return r;
 }
 
 static int
@@ -758,9 +739,33 @@
     return 0;
 }
 
+static PyObject *
+Per_get_mtime(cPersistentObject *self)
+{
+    PyObject *t, *v;
+
+    if (!unghostify(self))
+	return NULL;
+
+    accessed(self);
+
+    if (memcmp(self->serial, "\0\0\0\0\0\0\0\0", 8) == 0) {
+	Py_INCREF(Py_None);
+	return Py_None;
+    }
+    
+    t = PyObject_CallFunction(TimeStamp, "s#", self->serial, 8);
+    if (!t)
+	return NULL;
+    v = PyObject_CallMethod(t, "timeTime", "");
+    Py_DECREF(t);
+    return v;
+}
+
 static PyGetSetDef Per_getsets[] = {
     {"_p_changed", (getter)Per_get_changed, (setter)Per_set_changed},
     {"_p_jar", (getter)Per_get_jar, (setter)Per_set_jar},
+    {"_p_mtime", (getter)Per_get_mtime},
     {"_p_oid", (getter)Per_get_oid, (setter)Per_set_oid},
     {"_p_serial", (getter)Per_get_serial, (setter)Per_set_serial},
     {NULL}
@@ -829,7 +834,7 @@
     ghostify,
     deallocated,
     (intfunctionwithpythonarg)Per_setstate,
-    (pergetattr)Per_getattr,
+    (pergetattr)Per_getattro,
     (persetattr)_setattro,
     NULL /* The percachedel slot is initialized in cPickleCache.c when
 	    the module is loaded.  It uses a function in a different




More information about the Zodb-checkins mailing list