[Zope-Checkins] CVS: Zope3/lib/python/Persistence/BTrees - BTreeTemplate.c:1.1.2.6 BucketTemplate.c:1.1.2.7 TreeSetTemplate.c:1.1.2.5

Jeremy Hylton jeremy@zope.com
Sat, 2 Mar 2002 00:21:55 -0500


Update of /cvs-repository/Zope3/lib/python/Persistence/BTrees
In directory cvs.zope.org:/tmp/cvs-serv25098

Modified Files:
      Tag: Zope-3x-branch
	BTreeTemplate.c BucketTemplate.c TreeSetTemplate.c 
Log Message:
Simplify BTree__p_resolveConflict() by using helper function caar().
Take advantage of METH_NOARGS and METH_O for BTree methods.
Rewrite doc strings for all BTree methods.

BTree__p_resolveConflict()

    Simplify argument processing logic by pushing tuple extraction and
    type checking to helper function named after the Lisp equivalent.

    Remove error munging on exit that turned all exceptions into
    ConflictErrors.  If a non-ConflictError occurs, it should
    propagate out far enough to cause the transaciton to fail, because
    there is a bug in the code.

Remove a bunch of unnecessary PyArg_ParseTuple() calls by using
METH_NOARGS and METH_ARGS.  I only made systematic changes to methods
on BTrees, but changes occasionally affected other modules that use
the same C functions.  Functions affected are:

    __getstate__()
    __setstate__()
    has_key()
    byValue()
    clear()
    update()
    _p_deactiveate()

Write more verbose doc strings for the BTrees methods, based on
ajung's new BTrees docs.  Reformat to be consistent with std Python
style.

Change merge_error() calls in BucketTemplate so that they never pass
negative numbers as the reason.  The new BTreesConflictError isn't
prepared for negative numbers.


=== Zope3/lib/python/Persistence/BTrees/BTreeTemplate.c 1.1.2.5 => 1.1.2.6 ===
 #ifdef PERSISTENT
 static PyObject *
-BTree__p_deactivate(BTree *self, PyObject *args)
+BTree__p_deactivate(BTree *self)
 {
   if (self->po_state == UPTODATE && self->po_dm)
     {
@@ -555,7 +555,7 @@
 #endif
 
 static PyObject *
-BTree_clear(BTree *self, PyObject *args)
+BTree_clear(BTree *self)
 {
   PER_USE_OR_RETURN(self, NULL);
 
@@ -578,7 +578,7 @@
 }
 
 static PyObject *
-BTree_getstate(BTree *self, PyObject *args)
+BTree_getstate(BTree *self)
 {
     PyObject *r = NULL, *o;
     int i, l;
@@ -716,15 +716,12 @@
 }
 
 static PyObject *
-BTree_setstate(BTree *self, PyObject *args)
+BTree_setstate(BTree *self, PyObject *arg)
 {
     int r;
 
-    if (!PyArg_ParseTuple(args,"O",&args)) 
-	return NULL;
- 
     PER_PREVENT_DEACTIVATION(self); 
-    r=_BTree_setstate(self, args, 0);
+    r = _BTree_setstate(self, arg, 0);
     PER_ALLOW_DEACTIVATION(self);
     PER_ACCESSED(self);
     
@@ -735,48 +732,75 @@
 }
 
 #ifdef PERSISTENT
-static PyObject *
-BTree__p_resolveConflict(BTree *self, PyObject *args)
+
+/* Return the caar of a tuple, where caar means t[0][0].
+   If t or t[0] is None, return None.
+   If caar is not None or a tuple, raise TypeError and return NULL.
+   Otherwise, raise TypeError and return NULL.
+
+   Always returns a borrowed reference.
+
+   Purpose: The state of a BTree should be a deeply nested tuple or
+   None.  Extract the caar and make sure it has the right type. 
+*/
+
+PyObject *
+caar(PyObject *t)
 {
-  PyObject *s[3], *r;
-  int i;
+    int i;
 
-  r = NULL;
+    if (t == Py_None)
+	return Py_None;
+    if (!PyTuple_Check(t)) {
+	PyErr_SetString(PyExc_TypeError, 
+		"_p_resolveConflict: expected tuple or None for state");
+	return NULL;
+    }
 
-  UNLESS (PyArg_ParseTuple(args, "OOO", s, s+1, s+2)) goto err;
+    for (i = 0; i < 2; i++) {
+	t = PyTuple_GET_ITEM(t, 0);
+	if (t == Py_None)
+	    return Py_None;
+	if (!PyTuple_Check(t)) {
+	    PyErr_SetString(PyExc_TypeError, 
+		"_p_resolveConflict: expected state to contain tuple or None");
+	    return NULL;
+	}
+    }
 
-                                /* for each state, detuplefy it twice */
-  for (i=0; i < 3; i++)
-    UNLESS (s[i]==Py_None || PyArg_ParseTuple(s[i], "O", s+i)) goto err;
-  for (i=0; i < 3; i++)
-    UNLESS (s[i]==Py_None || PyArg_ParseTuple(s[i], "O", s+i)) goto err;
+    return t;
+}
 
-  for (i=0; i < 3; i++)         /* Now make sure detupled thing is a tuple */
-    UNLESS (s[i]==Py_None || PyTuple_Check(s[i]))
-      return merge_error(-100, -100, -100, -100);
+static PyObject *
+BTree__p_resolveConflict(BTree *self, PyObject *args)
+{
+    PyObject *s[3], *r, *t;
 
-  if (PyObject_IsInstance((PyObject *)self, (PyObject *)&BTreeType))
-      r = _bucket__p_resolveConflict(OBJECT(&BucketType), s);
-  else
-      r = _bucket__p_resolveConflict(OBJECT(&SetType), s);
+    if (!PyArg_ParseTuple(args, "OOO", s, s+1, s+2))
+	return NULL;
 
-err:
+    s[0] = caar(s[0]);
+    if (s[0] == NULL)
+	return NULL;
+    s[1] = caar(s[1]);
+    if (s[1] == NULL)
+	return NULL;
+    s[2] = caar(s[2]);
+    if (s[2] == NULL)
+	return NULL;
 
-  if (r) {
-  	ASSIGN(r, Py_BuildValue("((O))", r));
-  } else {
-  	PyObject *error;
-	PyObject *value;
-	PyObject *traceback;
-  	/* Change any errors to ConflictErrors */
-
-	PyErr_Fetch(&error, &value, &traceback);
-	Py_INCREF(ConflictError);
-	Py_XDECREF(error);
-	PyErr_Restore(ConflictError, value, traceback);
-  }
 
-  return r;
+    if (PyObject_IsInstance((PyObject *)self, (PyObject *)&BTreeType))
+	r = _bucket__p_resolveConflict(OBJECT(&BucketType), s);
+    else
+	r = _bucket__p_resolveConflict(OBJECT(&SetType), s);
+
+    if (r == NULL)
+	return NULL;
+
+    t = Py_BuildValue("((O))", r);
+    Py_DECREF(r);
+    return t;
 }
 #endif
 
@@ -1046,9 +1070,9 @@
 }
 
 static PyObject *
-BTree_byValue(BTree *self, PyObject *args)
+BTree_byValue(BTree *self, PyObject *omin)
 {
-  PyObject *r=0, *o=0, *item=0, *omin;
+  PyObject *r=0, *o=0, *item=0;
   VALUE_TYPE min;
   VALUE_TYPE v;
   int copied=1;
@@ -1056,7 +1080,6 @@
 
   PER_USE_OR_RETURN(self, NULL);
 
-  UNLESS (PyArg_ParseTuple(args, "O", &omin)) return NULL;
   COPY_VALUE_FROM_ARG(min, omin, copied);
   UNLESS(copied) return NULL;
     
@@ -1134,12 +1157,9 @@
 ** BTree_has_key
 */
 static PyObject *
-BTree_has_key(BTree *self, PyObject *args)
+BTree_has_key(BTree *self, PyObject *key)
 {
-  PyObject *key;
-
-  UNLESS (PyArg_ParseTuple(args,"O",&key)) return NULL;  
-  return _BTree_get(self, key, 1);
+    return _BTree_get(self, key, 1);
 }
 
 static PyObject *
@@ -1156,45 +1176,57 @@
 
 
 static struct PyMethodDef BTree_methods[] = {
-  {"__getstate__", (PyCFunction) BTree_getstate,	METH_VARARGS,
-   "__getstate__() -- Return the picklable state of the object"},
-  {"__setstate__", (PyCFunction) BTree_setstate,	METH_VARARGS,
-   "__setstate__() -- Set the state of the object"},
-  {"has_key",	(PyCFunction) BTree_has_key,	METH_VARARGS,
-     "has_key(key) -- Test whether the bucket contains the given key"},
+  {"__getstate__", (PyCFunction) BTree_getstate,	METH_NOARGS,
+   "__getstate__() -> state\n\n"
+   "Return the picklable state of the BTree."},
+  {"__setstate__", (PyCFunction) BTree_setstate,	METH_O,
+   "__setstate__(state)\n\n"
+   "Set the state of the BTree."},
+  {"has_key",	(PyCFunction) BTree_has_key,	METH_O,
+   "has_key(key)\n\n"
+   "Return true if the BTree contains the given key."},
   {"keys",	(PyCFunction) BTree_keys,	METH_VARARGS,
-     "keys([min, max]) -- Return the keys"},
+   "keys([min, max]) -> list of keys\n\n"
+   "Returns the keys of the BTree.  If min and max are supplied, only\n"
+   "keys greater than min and less than max are returned."},
   {"values",	(PyCFunction) BTree_values,	METH_VARARGS,
-     "values([min, max]) -- Return the values"},
+   "values([min, max]) -> list of values\n\n"
+   "Returns the values of the BTree.  If min and max are supplied, only\n"
+   "values corresponding to keys greater than min and less than max are\n"
+   "returned."},
   {"items",	(PyCFunction) BTree_items,	METH_VARARGS,
-     "items([min, max]) -- Return the items"},
-  {"byValue",	(PyCFunction) BTree_byValue,	METH_VARARGS,
-   "byValue(min) -- "
-   "Return value-keys with values >= min and reverse sorted by values"
-  },
+   "items([min, max]) -> -- list of key, value pairs\n\n"
+   "Returns the items of the BTree.  If min and max are supplied, only\n"
+   "items with keys greater than min and less than max are returned."},
+  {"byValue",	(PyCFunction) BTree_byValue,	METH_O,
+   "byValue(min) ->  list of value, key pairs\n\n"
+   "Returns list of value, key pairs where the value is >= min.  The\n"
+   "list is sorted by value.  Note that items() returns keys in the\n"
+   "opposite order."},
   {"get",	(PyCFunction) BTree_getm,	METH_VARARGS,
-   "get(key[,default]) -- Look up a value\n\n"
-   "Return the default (or None) if the key is not found."
-  },
+   "get(key[, default=None]) -> Value for key or default\n\n"
+   "Return the value or the default if the key is not found."},
   {"maxKey", (PyCFunction) BTree_maxKey,	METH_VARARGS,
-   "maxKey([key]) -- Fine the maximum key\n\n"
-   "If an argument is given, find the maximum <= the argument"},
+   "maxKey([max]) -> key\n\n"
+   "Return the largest key in the BTree.  If max is specified, return\n"
+   "the largest key <= max."},
   {"minKey", (PyCFunction) BTree_minKey,	METH_VARARGS,
-   "minKey([key]) -- Fine the minimum key\n\n"
-   "If an argument is given, find the minimum >= the argument"},
-  {"clear",	(PyCFunction) BTree_clear,	METH_VARARGS,
-   "clear() -- Remove all of the items from the BTree"},  
+   "minKey([mi]) -> key\n\n"
+   "Return the smallest key in the BTree.  If min is specified, return\n"
+   "the smallest key >= min."},
+  {"clear",	(PyCFunction) BTree_clear,	METH_NOARGS,
+   "clear()\n\nRemove all of the items from the BTree."},  
   {"insert", (PyCFunction)BTree_addUnique, METH_VARARGS,
-   "insert(key, value) -- Add an item if the key is not already used.\n\n"
-   "Return 1 if the item was added, or 0 otherwise"
-  },
-  {"update",	(PyCFunction) Mapping_update,	METH_VARARGS,
-   "update(collection) -- Add the items from the given collection"},
+   "insert(key, value) -> 0 or 1\n\n"
+   "Add an item if the key is not already used. Return 1 if the item was\n"
+   "added, or 0 otherwise."},
+  {"update",	(PyCFunction) Mapping_update,	METH_O,
+   "update(collection)\n\n Add the items from the given collection."},
 #ifdef PERSISTENT
   {"_p_resolveConflict", (PyCFunction) BTree__p_resolveConflict, METH_VARARGS,
    "_p_resolveConflict() -- Reinitialize from a newly created copy"},
-  {"_p_deactivate", (PyCFunction) BTree__p_deactivate,	METH_VARARGS,
-   "_p_deactivate() -- Reinitialize from a newly created copy"},
+  {"_p_deactivate", (PyCFunction) BTree__p_deactivate,	METH_NOARGS,
+   "_p_deactivate()\n\nReinitialize from a newly created copy."},
 #endif
   {NULL,		NULL}		/* sentinel */
 };


=== Zope3/lib/python/Persistence/BTrees/BucketTemplate.c 1.1.2.6 => 1.1.2.7 ===
 
 static PyObject *
-Mapping_update(PyObject *self, PyObject *args)
+Mapping_update(PyObject *self, PyObject *seq)
 {
-    PyObject *seq = NULL;
-
-    if (!PyArg_ParseTuple(args, "|O:update", &seq)) 
+    if (update_from_seq(self, seq) < 0)
 	return NULL;
-
-    if (seq)
-	if (update_from_seq(self, seq) < 0)
-	    return NULL;
     Py_INCREF(Py_None);
     return Py_None;
 }
@@ -1068,7 +1062,7 @@
 
   if (b[0]->next != b[1]->next || b[0]->next != b[2]->next)
     {
-      merge_error(-1, -1, -1, -1);
+      merge_error(-1, -1, -1, 0);
       goto err;
     }
 
@@ -1105,7 +1099,7 @@
      "has_key(key) -- Test whether the bucket contains the given key"},
   {"clear",	(PyCFunction) bucket_clear,	METH_VARARGS,
    "clear() -- Remove all of the items from the bucket"},
-  {"update",	(PyCFunction) Mapping_update,	METH_VARARGS,
+  {"update",	(PyCFunction) Mapping_update,	METH_O,
    "update(collection) -- Add the items from the given collection"},
   {"maxKey", (PyCFunction) Bucket_maxKey,	METH_VARARGS,
    "maxKey([key]) -- Fine the maximum key\n\n"


=== Zope3/lib/python/Persistence/BTrees/TreeSetTemplate.c 1.1.2.4 => 1.1.2.5 ===
 
 static struct PyMethodDef TreeSet_methods[] = {
-  {"__getstate__", (PyCFunction) BTree_getstate,	METH_VARARGS,
-   "__getstate__() -- Return the picklable state of the object"},
+  {"__getstate__", (PyCFunction) BTree_getstate,	METH_NOARGS,
+   "__getstate__() -> state\n\n"
+   "Return the picklable state of the TreeSet."},
   {"__setstate__", (PyCFunction) TreeSet_setstate,	METH_VARARGS,
-   "__setstate__() -- Set the state of the object"},
-  {"has_key",	(PyCFunction) BTree_has_key,	METH_VARARGS,
-     "has_key(key) -- Test whether the bucket contains the given key"},
+   "__setstate__(state)\n\n"
+   "Set the state of the TreeSet."},
+  {"has_key",	(PyCFunction) BTree_has_key,	METH_O,
+   "has_key(key)\n\n"
+   "Return true if the TreeSet contains the given key."},
   {"keys",	(PyCFunction) BTree_keys,	METH_VARARGS,
-     "keys() -- Return the keys"},
+   "keys([min, max]) -> list of keys\n\n"
+   "Returns the keys of the TreeSet.  If min and max are supplied, only\n"
+   "keys greater than min and less than max are returned."},
   {"maxKey", (PyCFunction) BTree_maxKey,	METH_VARARGS,
-   "maxKey([key]) -- Fine the maximum key\n\n"
-   "If an argument is given, find the maximum <= the argument"},
+   "maxKey([max]) -> key\n\n"
+   "Return the largest key in the BTree.  If max is specified, return\n"
+   "the largest key <= max."},
   {"minKey", (PyCFunction) BTree_minKey,	METH_VARARGS,
-   "minKey([key]) -- Fine the minimum key\n\n"
-   "If an argument is given, find the minimum >= the argument"},
-  {"clear",	(PyCFunction) BTree_clear,	METH_VARARGS,
-   "clear() -- Remove all of the items from the BTree"},  
+   "minKey([mi]) -> key\n\n"
+   "Return the smallest key in the BTree.  If min is specified, return\n"
+   "the smallest key >= min."},
+  {"clear",	(PyCFunction) BTree_clear,	METH_NOARGS,
+   "clear()\n\nRemove all of the items from the BTree."},  
   {"insert",	(PyCFunction)TreeSet_insert,	METH_VARARGS,
    "insert(id,[ignored]) -- Add an id to the set"},
   {"update",	(PyCFunction)TreeSet_update,	METH_VARARGS,
-   "update(seq) -- Add the items from the given sequence to the set"},
+   "update(collection)\n\n Add the items from the given collection."},
   {"remove",	(PyCFunction)TreeSet_remove,	METH_VARARGS,
    "remove(id) -- Remove a key from the set"},
 #ifdef PERSISTENT
   {"_p_resolveConflict", (PyCFunction) BTree__p_resolveConflict, METH_VARARGS,
    "_p_resolveConflict() -- Reinitialize from a newly created copy"},
-  {"_p_deactivate", (PyCFunction) BTree__p_deactivate,	METH_VARARGS,
-   "_p_deactivate() -- Reinitialize from a newly created copy"},
+  {"_p_deactivate", (PyCFunction) BTree__p_deactivate,	METH_NOARGS,
+   "_p_deactivate()\n\nReinitialize from a newly created copy."},
 #endif
   {NULL,		NULL}		/* sentinel */
 };