summaryrefslogtreecommitdiffstats
path: root/Objects/dictobject.c
diff options
context:
space:
mode:
authorDaniel Stutzbach <daniel@stutzbachenterprises.com>2010-09-02 15:06:06 (GMT)
committerDaniel Stutzbach <daniel@stutzbachenterprises.com>2010-09-02 15:06:06 (GMT)
commit045b3ba184f78a1ff0ca96561d8b5651c22233c0 (patch)
tree837b1fd156b77afa8cd44904bb1a9ce28be08df2 /Objects/dictobject.c
parent928d4eeee8e92ca44899108e297437392102aaa4 (diff)
downloadcpython-045b3ba184f78a1ff0ca96561d8b5651c22233c0.zip
cpython-045b3ba184f78a1ff0ca96561d8b5651c22233c0.tar.gz
cpython-045b3ba184f78a1ff0ca96561d8b5651c22233c0.tar.bz2
Issue #9212: Added the missing isdisjoint method to the dict_keys and
dict_items views. The method is required by the collections.Set ABC, which the views register as supporting.
Diffstat (limited to 'Objects/dictobject.c')
-rw-r--r--Objects/dictobject.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 745e2dc..241790c 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -2807,7 +2807,63 @@ static PyNumberMethods dictviews_as_number = {
(binaryfunc)dictviews_or, /*nb_or*/
};
+static PyObject*
+dictviews_isdisjoint(PyObject *self, PyObject *other)
+{
+ PyObject *it;
+ PyObject *item = NULL;
+
+ if (self == other) {
+ if (dictview_len((dictviewobject *)self) == 0)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+ }
+
+ /* Iterate over the shorter object (only if other is a set,
+ * because PySequence_Contains may be expensive otherwise): */
+ if (PyAnySet_Check(other) || PyDictViewSet_Check(other)) {
+ Py_ssize_t len_self = dictview_len((dictviewobject *)self);
+ Py_ssize_t len_other = PyObject_Size(other);
+ if (len_other == -1)
+ return NULL;
+
+ if ((len_other > len_self)) {
+ PyObject *tmp = other;
+ other = self;
+ self = tmp;
+ }
+ }
+
+ it = PyObject_GetIter(other);
+ if (it == NULL)
+ return NULL;
+
+ while ((item = PyIter_Next(it)) != NULL) {
+ int contains = PySequence_Contains(self, item);
+ Py_DECREF(item);
+ if (contains == -1) {
+ Py_DECREF(it);
+ return NULL;
+ }
+
+ if (contains) {
+ Py_DECREF(it);
+ Py_RETURN_FALSE;
+ }
+ }
+ Py_DECREF(it);
+ if (PyErr_Occurred())
+ return NULL; /* PyIter_Next raised an exception. */
+ Py_RETURN_TRUE;
+}
+
+PyDoc_STRVAR(isdisjoint_doc,
+"Return True if the view and the given iterable have a null intersection.");
+
static PyMethodDef dictkeys_methods[] = {
+ {"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O,
+ isdisjoint_doc},
{NULL, NULL} /* sentinel */
};
@@ -2892,6 +2948,8 @@ static PySequenceMethods dictitems_as_sequence = {
};
static PyMethodDef dictitems_methods[] = {
+ {"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O,
+ isdisjoint_doc},
{NULL, NULL} /* sentinel */
};