[Zodb-checkins] CVS: Zope3/lib/python/Persistence/BTrees - SetTemplate.c:1.1.2.2 TreeSetTemplate.c:1.1.2.2

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


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

Modified Files:
      Tag: Zope-3x-branch
	SetTemplate.c TreeSetTemplate.c 
Log Message:
Add tp_init implements and update functions based on PyObject_GetIter().

_XXX_update (where XXX is TreeSet or Set) takes any iterable object
and adds all the elements in it to the set.  It returns an int
indicating number of elements added or -1 on error.

XXX_update() and XXX_init() call this _XXX_update() function.
Otherwise they're just Python C API intermediaries.


=== Zope3/lib/python/Persistence/BTrees/SetTemplate.c 1.1.2.1 => 1.1.2.2 ===
 }
 
+/* _Set_update and _TreeSet_update are identical except for the
+   function they call to add the element to the set.
+*/
+
+static int
+_Set_update(Bucket *self, PyObject *seq)
+{
+    int n = 0;
+    PyObject *iter, *v;
+    int ind;
+
+    iter = PyObject_GetIter(seq);
+    if (iter == NULL)
+	return -1;
+
+    while (1) {
+	v = PyIter_Next(iter);
+	if (v == NULL) {
+	    if (PyErr_Occurred()) {
+		Py_DECREF(iter);
+		return -1;
+	    } else
+		break;
+	}
+	ind = _bucket_set(self, v, Py_None, 1, 1, 0);
+	Py_DECREF(v);
+	if (ind < 0) {
+	    Py_DECREF(iter);
+	    return -1;
+	} else
+	    n += ind;
+    }
+    return n;
+}
+
 static PyObject *
-Set_update(Bucket *self, PyObject *args)
+Set_update(BTree *self, PyObject *args)
 {
-  PyObject *seq=0, *o, *t, *v, *tb;
-  int i, n=0, ind;
+    PyObject *seq = NULL;
+    int n = 0;
 
-  UNLESS(PyArg_ParseTuple(args, "|O:update", &seq)) return NULL;
+    if (!PyArg_ParseTuple(args, "|O:update", &seq))
+	return NULL;
 
-  if (seq)
-    {
-      for (i=0; ; i++)
-        {
-          UNLESS (o=PySequence_GetItem(seq, i))
-            {
-              PyErr_Fetch(&t, &v, &tb);
-              if (t != PyExc_IndexError)
-                {
-                  PyErr_Restore(t, v, tb);
-                  return NULL;
-                }
-              Py_XDECREF(t);
-              Py_XDECREF(v);
-              Py_XDECREF(tb);
-              break;
-            }
-          ind=_bucket_set(self, o, Py_None, 1, 1, 0);
-          Py_DECREF(o);
-          if (ind < 0) return NULL;
-          n += ind;
-        }
+    if (seq) {
+	n = _Set_update(self, seq);
+	if (n < 0)
+	    return NULL;
     }
 
-  return PyInt_FromLong(n);
+    return PyInt_FromLong(n);
 }
 
 static PyObject *
@@ -175,6 +193,22 @@
   {NULL,		NULL}		/* sentinel */
 };
 
+static int
+Set_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    PyObject *v = NULL;
+
+    if (!PyArg_ParseTuple(args, "|O:" MOD_NAME_PREFIX "Set", &v))
+	return -1;
+
+    if (v)
+	return _Set_update((BTree *)self, v);
+    else
+	return 0;
+}
+
+
+
 static PyObject *
 set_repr(Bucket *self)
 {
@@ -275,7 +309,7 @@
     0,					/* tp_descr_get */
     0,					/* tp_descr_set */
     0,					/* tp_dictoffset */
-    0,					/* tp_init */
+    Set_init,				/* tp_init */
     0,					/* tp_alloc */
     PyType_GenericNew,			/* tp_new */
 };


=== Zope3/lib/python/Persistence/BTrees/TreeSetTemplate.c 1.1.2.1 => 1.1.2.2 ===
 }
 
+/* _Set_update and _TreeSet_update are identical except for the
+   function they call to add the element to the set.
+*/
+
+static int
+_TreeSet_update(BTree *self, PyObject *seq)
+{
+    int n = 0;
+    PyObject *iter, *v;
+    int ind;
+
+    iter = PyObject_GetIter(seq);
+    if (iter == NULL)
+	return -1;
+
+    while (1) {
+	v = PyIter_Next(iter);
+	if (v == NULL) {
+	    if (PyErr_Occurred()) {
+		Py_DECREF(iter);
+		return -1;
+	    } else
+		break;
+	}
+	ind = _BTree_set(self, v, Py_None, 1, 1);
+	Py_DECREF(v);
+	if (ind < 0) {
+	    Py_DECREF(iter);
+	    return -1;
+	} else
+	    n += ind;
+    }
+    return n;
+}
+
 static PyObject *
 TreeSet_update(BTree *self, PyObject *args)
 {
-  PyObject *seq=0, *o, *t, *v, *tb;
-  int i, n=0, ind;
+    PyObject *seq = NULL;
+    int n = 0;
 
-  UNLESS(PyArg_ParseTuple(args, "|O:update", &seq)) return NULL;
+    if (!PyArg_ParseTuple(args, "|O:update", &seq))
+	return NULL;
 
-  if (seq)
-    {
-      for (i=0; ; i++)
-        {
-          UNLESS (o=PySequence_GetItem(seq, i))
-            {
-              PyErr_Fetch(&t, &v, &tb);
-              if (t != PyExc_IndexError)
-                {
-                  PyErr_Restore(t, v, tb);
-                  return NULL;
-                }
-              Py_XDECREF(t);
-              Py_XDECREF(v);
-              Py_XDECREF(tb);
-              break;
-            }
-          ind=_BTree_set(self, o, Py_None, 1, 1);
-          Py_DECREF(o);
-          if (ind < 0) return NULL;
-          n += ind;
-        }
+    if (seq) {
+	n = _TreeSet_update(self, seq);
+	if (n < 0)
+	    return NULL;
     }
 
-  return PyInt_FromLong(n);
+    return PyInt_FromLong(n);
 }
 
 
@@ -127,6 +145,20 @@
   (inquiry)BTree_length,		/*mp_length*/
 };
 
+static int
+TreeSet_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    PyObject *v = NULL;
+
+    if (!PyArg_ParseTuple(args, "|O:" MOD_NAME_PREFIX "TreeSet", &v))
+	return -1;
+
+    if (v)
+	return _TreeSet_update((BTree *)self, v);
+    else
+	return 0;
+}
+
 static PyTypeObject TreeSetType = {
     PyObject_HEAD_INIT(NULL) /* PyPersist_Type */
     0,					/* ob_size */
@@ -165,7 +197,7 @@
     0,					/* tp_descr_get */
     0,					/* tp_descr_set */
     0,					/* tp_dictoffset */
-    0,					/* tp_init */
+    TreeSet_init,			/* tp_init */
     0,					/* tp_alloc */
     PyType_GenericNew,			/* tp_new */
 };