mirror of https://github.com/python/cpython
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.
This commit is contained in:
parent
928d4eeee8
commit
045b3ba184
|
@ -2216,6 +2216,11 @@ available ("other" refers either to another view or a set):
|
||||||
Return the symmetric difference (all elements either in *dictview* or
|
Return the symmetric difference (all elements either in *dictview* or
|
||||||
*other*, but not in both) of the dictview and the other object as a new set.
|
*other*, but not in both) of the dictview and the other object as a new set.
|
||||||
|
|
||||||
|
.. method:: dictview.isdisjoint(other)
|
||||||
|
|
||||||
|
Return True if the view has no elements in common with *other*. Sets are
|
||||||
|
disjoint if and only if their intersection is the empty set.
|
||||||
|
|
||||||
|
|
||||||
An example of dictionary view usage::
|
An example of dictionary view usage::
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,24 @@ class DictSetTest(unittest.TestCase):
|
||||||
self.assertEqual(d1.keys() ^ set(d3.keys()),
|
self.assertEqual(d1.keys() ^ set(d3.keys()),
|
||||||
{'a', 'b', 'd', 'e'})
|
{'a', 'b', 'd', 'e'})
|
||||||
|
|
||||||
|
self.assertFalse(d1.keys().isdisjoint(d1.keys()))
|
||||||
|
self.assertFalse(d1.keys().isdisjoint(d2.keys()))
|
||||||
|
self.assertFalse(d1.keys().isdisjoint(list(d2.keys())))
|
||||||
|
self.assertFalse(d1.keys().isdisjoint(set(d2.keys())))
|
||||||
|
self.assertTrue(d1.keys().isdisjoint({'x', 'y', 'z'}))
|
||||||
|
self.assertTrue(d1.keys().isdisjoint(['x', 'y', 'z']))
|
||||||
|
self.assertTrue(d1.keys().isdisjoint(set(['x', 'y', 'z'])))
|
||||||
|
self.assertTrue(d1.keys().isdisjoint(set(['x', 'y'])))
|
||||||
|
self.assertTrue(d1.keys().isdisjoint(['x', 'y']))
|
||||||
|
self.assertTrue(d1.keys().isdisjoint({}))
|
||||||
|
self.assertTrue(d1.keys().isdisjoint(d3.keys()))
|
||||||
|
|
||||||
|
de = {}
|
||||||
|
self.assertTrue(de.keys().isdisjoint(set()))
|
||||||
|
self.assertTrue(de.keys().isdisjoint([]))
|
||||||
|
self.assertTrue(de.keys().isdisjoint(de.keys()))
|
||||||
|
self.assertTrue(de.keys().isdisjoint([1]))
|
||||||
|
|
||||||
def test_items_set_operations(self):
|
def test_items_set_operations(self):
|
||||||
d1 = {'a': 1, 'b': 2}
|
d1 = {'a': 1, 'b': 2}
|
||||||
d2 = {'a': 2, 'b': 2}
|
d2 = {'a': 2, 'b': 2}
|
||||||
|
@ -144,6 +162,23 @@ class DictSetTest(unittest.TestCase):
|
||||||
self.assertEqual(d1.items() ^ d3.items(),
|
self.assertEqual(d1.items() ^ d3.items(),
|
||||||
{('a', 1), ('b', 2), ('d', 4), ('e', 5)})
|
{('a', 1), ('b', 2), ('d', 4), ('e', 5)})
|
||||||
|
|
||||||
|
self.assertFalse(d1.items().isdisjoint(d1.items()))
|
||||||
|
self.assertFalse(d1.items().isdisjoint(d2.items()))
|
||||||
|
self.assertFalse(d1.items().isdisjoint(list(d2.items())))
|
||||||
|
self.assertFalse(d1.items().isdisjoint(set(d2.items())))
|
||||||
|
self.assertTrue(d1.items().isdisjoint({'x', 'y', 'z'}))
|
||||||
|
self.assertTrue(d1.items().isdisjoint(['x', 'y', 'z']))
|
||||||
|
self.assertTrue(d1.items().isdisjoint(set(['x', 'y', 'z'])))
|
||||||
|
self.assertTrue(d1.items().isdisjoint(set(['x', 'y'])))
|
||||||
|
self.assertTrue(d1.items().isdisjoint({}))
|
||||||
|
self.assertTrue(d1.items().isdisjoint(d3.items()))
|
||||||
|
|
||||||
|
de = {}
|
||||||
|
self.assertTrue(de.items().isdisjoint(set()))
|
||||||
|
self.assertTrue(de.items().isdisjoint([]))
|
||||||
|
self.assertTrue(de.items().isdisjoint(de.items()))
|
||||||
|
self.assertTrue(de.items().isdisjoint([1]))
|
||||||
|
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
support.run_unittest(DictSetTest)
|
support.run_unittest(DictSetTest)
|
||||||
|
|
|
@ -12,6 +12,9 @@ What's New in Python 3.2 Alpha 2?
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #9212: dict_keys and dict_items now provide the isdisjoint()
|
||||||
|
method, to conform to the Set ABC.
|
||||||
|
|
||||||
- Issue #9737: Fix a crash when trying to delete a slice or an item from
|
- Issue #9737: Fix a crash when trying to delete a slice or an item from
|
||||||
a memoryview object.
|
a memoryview object.
|
||||||
|
|
||||||
|
|
|
@ -2807,7 +2807,63 @@ static PyNumberMethods dictviews_as_number = {
|
||||||
(binaryfunc)dictviews_or, /*nb_or*/
|
(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[] = {
|
static PyMethodDef dictkeys_methods[] = {
|
||||||
|
{"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O,
|
||||||
|
isdisjoint_doc},
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2892,6 +2948,8 @@ static PySequenceMethods dictitems_as_sequence = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyMethodDef dictitems_methods[] = {
|
static PyMethodDef dictitems_methods[] = {
|
||||||
|
{"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O,
|
||||||
|
isdisjoint_doc},
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue