Commit ac80ceec authored by Raymond Hettinger's avatar Raymond Hettinger

* Fix SF #1257731. Make __contains__(), remove(), and discard() only do

  a frozenset conversion when the initial search attempt fails with a
  TypeError and the key is some type of set.  Add a testcase.

* Eliminate a duplicate if-stmt.
parent edc200f7
...@@ -932,20 +932,22 @@ static int ...@@ -932,20 +932,22 @@ static int
set_contains(PySetObject *so, PyObject *key) set_contains(PySetObject *so, PyObject *key)
{ {
PyObject *tmpkey; PyObject *tmpkey;
int result; int rv;
result = set_contains_key(so, key); rv = set_contains_key(so, key);
if (result == -1 && PyAnySet_Check(key)) { if (rv == -1) {
if (!PyAnySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
return -1;
PyErr_Clear(); PyErr_Clear();
tmpkey = make_new_set(&PyFrozenSet_Type, NULL); tmpkey = make_new_set(&PyFrozenSet_Type, NULL);
if (tmpkey == NULL) if (tmpkey == NULL)
return -1; return -1;
set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key);
result = set_contains_key(so, tmpkey); rv = set_contains(so, tmpkey);
set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key);
Py_DECREF(tmpkey); Py_DECREF(tmpkey);
} }
return result; return rv;
} }
static PyObject * static PyObject *
...@@ -1046,15 +1048,16 @@ set_intersection(PySetObject *so, PyObject *other) ...@@ -1046,15 +1048,16 @@ set_intersection(PySetObject *so, PyObject *other)
if (result == NULL) if (result == NULL)
return NULL; return NULL;
if (PyAnySet_Check(other) && set_len(other) > set_len((PyObject *)so)) { if (PyAnySet_Check(other)) {
int pos = 0;
setentry *entry;
if (set_len(other) > set_len((PyObject *)so)) {
tmp = (PyObject *)so; tmp = (PyObject *)so;
so = (PySetObject *)other; so = (PySetObject *)other;
other = tmp; other = tmp;
} }
if (PyAnySet_Check(other)) {
int pos = 0;
setentry *entry;
while (set_next((PySetObject *)other, &pos, &entry)) { while (set_next((PySetObject *)other, &pos, &entry)) {
if (set_contains_entry(so, entry)) { if (set_contains_entry(so, entry)) {
if (set_add_entry(result, entry) == -1) { if (set_add_entry(result, entry) == -1) {
...@@ -1556,21 +1559,20 @@ set_remove(PySetObject *so, PyObject *key) ...@@ -1556,21 +1559,20 @@ set_remove(PySetObject *so, PyObject *key)
PyObject *tmpkey, *result; PyObject *tmpkey, *result;
int rv; int rv;
if (PyType_IsSubtype(key->ob_type, &PySet_Type)) { rv = set_discard_key(so, key);
if (rv == -1) {
if (!PyAnySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
return NULL;
PyErr_Clear();
tmpkey = make_new_set(&PyFrozenSet_Type, NULL); tmpkey = make_new_set(&PyFrozenSet_Type, NULL);
if (tmpkey == NULL) if (tmpkey == NULL)
return NULL; return NULL;
set_swap_bodies((PySetObject *)key, (PySetObject *)tmpkey); set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key);
result = set_remove(so, tmpkey); result = set_remove(so, tmpkey);
set_swap_bodies((PySetObject *)key, (PySetObject *)tmpkey); set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key);
Py_DECREF(tmpkey); Py_DECREF(tmpkey);
return result; return result;
} } else if (rv == DISCARD_NOTFOUND) {
rv = set_discard_key(so, key);
if (rv == -1)
return NULL;
else if (rv == DISCARD_NOTFOUND) {
PyErr_SetObject(PyExc_KeyError, key); PyErr_SetObject(PyExc_KeyError, key);
return NULL; return NULL;
} }
...@@ -1586,20 +1588,22 @@ static PyObject * ...@@ -1586,20 +1588,22 @@ static PyObject *
set_discard(PySetObject *so, PyObject *key) set_discard(PySetObject *so, PyObject *key)
{ {
PyObject *tmpkey, *result; PyObject *tmpkey, *result;
int rv;
if (PyType_IsSubtype(key->ob_type, &PySet_Type)) { rv = set_discard_key(so, key);
if (rv == -1) {
if (!PyAnySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
return NULL;
PyErr_Clear();
tmpkey = make_new_set(&PyFrozenSet_Type, NULL); tmpkey = make_new_set(&PyFrozenSet_Type, NULL);
if (tmpkey == NULL) if (tmpkey == NULL)
return NULL; return NULL;
set_swap_bodies((PySetObject *)key, (PySetObject *)tmpkey); set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key);
result = set_discard(so, tmpkey); result = set_discard(so, tmpkey);
set_swap_bodies((PySetObject *)key, (PySetObject *)tmpkey); set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key);
Py_DECREF(tmpkey); Py_DECREF(tmpkey);
return result; return result;
} }
if (set_discard_key(so, key) == -1)
return NULL;
Py_RETURN_NONE; Py_RETURN_NONE;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment