Mercurial > cpython-lru_cache-weakref
diff Objects/setobject.c @ 35333:dc8ae499efcf 2.4
* SF bug #1257731: Fix logic in set.__contains__(), set.remove(),
and set.discard for handling keys that both inherite from set and
define their own __hash__() function.
* Fixed O(n) performance issue with set.pop() which should have been
an O(1) process.
| author | Raymond Hettinger <python@rcn.com> |
|---|---|
| date | Fri, 12 Aug 2005 23:47:50 +0000 |
| parents | f3d3151f8417 |
| children | 503c3697578f |
line wrap: on
line diff
--- a/Objects/setobject.c Fri Aug 12 14:08:10 2005 +0000 +++ b/Objects/setobject.c Fri Aug 12 23:47:50 2005 +0000 @@ -145,18 +145,20 @@ set_contains(PySetObject *so, PyObject *key) { PyObject *tmp; - int result; + int rv; - result = PyDict_Contains(so->data, key); - if (result == -1 && PyAnySet_Check(key)) { + rv = PyDict_Contains(so->data, key); + if (rv == -1) { + if (!PyAnySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError)) + return -1; PyErr_Clear(); tmp = frozenset_dict_wrapper(((PySetObject *)(key))->data); if (tmp == NULL) return -1; - result = PyDict_Contains(so->data, tmp); + rv = PyDict_Contains(so->data, tmp); Py_DECREF(tmp); } - return result; + return rv; } static PyObject * @@ -791,19 +793,20 @@ set_remove(PySetObject *so, PyObject *item) { PyObject *tmp, *result; + int rv; - if (PyType_IsSubtype(item->ob_type, &PySet_Type)) { - tmp = frozenset_dict_wrapper(((PySetObject *)(item))->data); - if (tmp == NULL) - return NULL; - result = set_remove(so, tmp); - Py_DECREF(tmp); - return result; - } - - if (PyDict_DelItem(so->data, item) == -1) + rv = PyDict_DelItem(so->data, item); + if (rv == 0) + Py_RETURN_NONE; + if (!PyAnySet_Check(item) || !PyErr_ExceptionMatches(PyExc_TypeError)) return NULL; - Py_RETURN_NONE; + PyErr_Clear(); + tmp = frozenset_dict_wrapper(((PySetObject *)(item))->data); + if (tmp == NULL) + return NULL; + result = set_remove(so, tmp); + Py_DECREF(tmp); + return result; } PyDoc_STRVAR(remove_doc, @@ -815,22 +818,24 @@ set_discard(PySetObject *so, PyObject *item) { PyObject *tmp, *result; + int rv; - if (PyType_IsSubtype(item->ob_type, &PySet_Type)) { - tmp = frozenset_dict_wrapper(((PySetObject *)(item))->data); - if (tmp == NULL) - return NULL; - result = set_discard(so, tmp); - Py_DECREF(tmp); - return result; + rv = PyDict_DelItem(so->data, item); + if (rv == 0) + Py_RETURN_NONE; + if (PyErr_ExceptionMatches(PyExc_KeyError)) { + PyErr_Clear(); + Py_RETURN_NONE; } - - if (PyDict_DelItem(so->data, item) == -1) { - if (!PyErr_ExceptionMatches(PyExc_KeyError)) - return NULL; - PyErr_Clear(); - } - Py_RETURN_NONE; + if (!PyAnySet_Check(item) || !PyErr_ExceptionMatches(PyExc_TypeError)) + return NULL; + PyErr_Clear(); + tmp = frozenset_dict_wrapper(((PySetObject *)(item))->data); + if (tmp == NULL) + return NULL; + result = set_discard(so, tmp); + Py_DECREF(tmp); + return result; } PyDoc_STRVAR(discard_doc, @@ -841,18 +846,18 @@ static PyObject * set_pop(PySetObject *so) { - PyObject *key, *value; - int pos = 0; + PyObject *item, *key; - if (!PyDict_Next(so->data, &pos, &key, &value)) { + if (set_len(so) == 0) { PyErr_SetString(PyExc_KeyError, "pop from an empty set"); return NULL; } + item = PyObject_CallMethod(so->data, "popitem", NULL); + if (item == NULL) + return NULL; + key = PyTuple_GET_ITEM(item, 0); Py_INCREF(key); - if (PyDict_DelItem(so->data, key) == -1) { - Py_DECREF(key); - return NULL; - } + Py_DECREF(item); return key; }
