[Zope-Checkins] CVS: Zope3/lib/python/Persistence/BTrees - BTreeTemplate.c:1.1.2.2 BucketTemplate.c:1.1.2.2

Jeremy Hylton jeremy@zope.com
Mon, 25 Feb 2002 14:23:33 -0500


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

Modified Files:
      Tag: Zope-3x-branch
	BTreeTemplate.c BucketTemplate.c 
Log Message:
Add tp_init and new Mapping_update functions for BTrees and Buckets.

Add new function update_from_seq() that updates a mapping object using
a sequence of 2-tuples.  Re-implement Mapping_update() using this
function.

Add BTree_init() and Bucket_init() functions that call
update_from_seq().



=== Zope3/lib/python/Persistence/BTrees/BTreeTemplate.c 1.1.2.1 => 1.1.2.2 ===
 };
 
+static int
+BTree_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    PyObject *v = NULL;
+
+    if (!PyArg_ParseTuple(args, "|O:" MOD_NAME_PREFIX "BTree", &v))
+	return -1;
+
+    if (v)
+	return update_from_seq(self, v);
+    else
+	return 0;
+}
+
 static void
 BTree_dealloc(BTree *self)
 {
@@ -1376,7 +1390,7 @@
     0,					/* tp_descr_get */
     0,					/* tp_descr_set */
     0,					/* tp_dictoffset */
-    0,					/* tp_init */
+    BTree_init,				/* tp_init */
     0,					/* tp_alloc */
     PyType_GenericNew,			/* tp_new */
 };


=== Zope3/lib/python/Persistence/BTrees/BucketTemplate.c 1.1.2.1 => 1.1.2.2 ===
  */
 
-static PyObject *
-Mapping_update(PyObject *self, PyObject *args)
+static int
+update_from_seq(PyObject *map, PyObject *seq)
 {
-  PyObject *seq=0, *o, *t, *v, *tb, *k, *items = NULL;
-  int i, ind;
-
-  if (!PyArg_ParseTuple(args, "|O:update", &seq)) 
-      return NULL;
+    PyObject *iter, *o, *k, *v;
+    int err = -1;
 
-  if (!seq) {
-      Py_INCREF(Py_None);
-      return Py_None;
-  }
+    /* One path creates a new seq object.  The other path has an
+       INCREF of the seq argument.  So seq must always be DECREFed on
+       the way out.
+     */
+    if (!PySequence_Check(seq)) {
+	PyObject *items;
+	items = PyObject_GetAttrString(seq, "items");
+	if (items == NULL)
+	    return -1;
+	seq = PyObject_CallObject(items, NULL);
+	Py_DECREF(items);
+	if (seq == NULL) 
+	    return -1;
+    } else
+	Py_INCREF(seq);
     
-  if (!PySequence_Check(seq)) {
-      items = PyObject_GetAttrString(seq, "items");
-      if (items == NULL)
-	  return NULL;
-      seq = PyObject_CallObject(items, NULL);
-      if (seq == NULL) {
-	  Py_DECREF(items);
-	  return NULL;
-      }
-      /* HACK: items is DECREFed on exit, seq is not */
-      items = seq;
-    }
-
-  for (i=0; ; i++)
-    {
-      o = PySequence_GetItem(seq, i);
-      UNLESS (o)
-	{
-	  PyErr_Fetch(&t, &v, &tb);
-	  if (t != PyExc_IndexError)
-	    {
-	      PyErr_Restore(t, v, tb);
-	      goto err;
-	    }
-	  Py_XDECREF(t);
-	  Py_XDECREF(v);
-	  Py_XDECREF(tb);
-	  break;
+
+    iter = PyObject_GetIter(seq);
+    if (iter == NULL)
+	goto err;
+    while (1) {
+	o = PyIter_Next(iter);
+	if (o == NULL) {
+	    if (PyErr_Occurred())
+		goto err;
+	    else
+		break;
 	}
-      ind = PyArg_ParseTuple(o, "OO;items must be 2-item tuples", &k, &v);
-      if (ind)
-	ind = PyObject_SetItem(self, k, v);
-      else
-	ind = -1;
-      Py_DECREF(o);
-      if (ind < 0) {
-        PyErr_SetString(PyExc_TypeError,"Sequence must contain 2-item tuples");
-        goto err;
-        }
+	if (!PyTuple_Check(o) || !PyTuple_GET_SIZE(o) == 2) {
+	    PyErr_SetString(PyExc_TypeError,
+			    "Sequence must contain 2-item tuples");
+	    goto err;
+	}
+	k = PyTuple_GET_ITEM(o, 0);
+	v = PyTuple_GET_ITEM(o, 1);
+	if (PyObject_SetItem(map, k, v) < 0) {
+	    Py_DECREF(o);
+	    goto err;
+	}
+	Py_DECREF(o);
     }
 
-  Py_XDECREF(items);
-  Py_INCREF(Py_None);
-  return Py_None;
-
+    err = 0;
  err:
-  Py_XDECREF(items);
-  return NULL;
+    Py_DECREF(iter);
+    Py_DECREF(seq);
+    return err;
 }
 
+static PyObject *
+Mapping_update(PyObject *self, PyObject *args)
+{
+    PyObject *seq = NULL;
+
+    if (!PyArg_ParseTuple(args, "|O:update", &seq)) 
+	return NULL;
+
+    if (seq)
+	if (update_from_seq(self, seq) < 0)
+	    return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
 
 /*
 ** bucket_split
@@ -1103,8 +1108,8 @@
    "clear() -- Remove all of the items from the bucket"},
   {"update",	(PyCFunction) Mapping_update,	METH_VARARGS,
    "update(collection) -- Add the items from the given collection"},
-  {"__init__",	(PyCFunction) Mapping_update,	METH_VARARGS,
-   "__init__(collection) -- Initialize with items from the given collection"},
+  {"ateudp",	(PyCFunction) Mapping_update,	METH_VARARGS,
+   "update(collection) -- Add the items from the given collection"},
   {"maxKey", (PyCFunction) Bucket_maxKey,	METH_VARARGS,
    "maxKey([key]) -- Fine the maximum key\n\n"
    "If an argument is given, find the maximum <= the argument"},
@@ -1132,6 +1137,20 @@
   {NULL,		NULL}		/* sentinel */
 };
 
+static int
+Bucket_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    PyObject *v = NULL;
+
+    if (!PyArg_ParseTuple(args, "|O:" MOD_NAME_PREFIX "Bucket", &v))
+	return -1;
+
+    if (v)
+	return update_from_seq(self, v);
+    else
+	return 0;
+}
+
 static void
 bucket_dealloc(Bucket *self)
 {
@@ -1260,7 +1279,7 @@
     0,					/* tp_descr_get */
     0,					/* tp_descr_set */
     0,					/* tp_dictoffset */
-    0,					/* tp_init */
+    Bucket_init,			/* tp_init */
     0,					/* tp_alloc */
     PyType_GenericNew,			/* tp_new */
 };