diff options
author | Raymond Hettinger <python@rcn.com> | 2003-11-17 16:42:33 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2003-11-17 16:42:33 (GMT) |
commit | 50a4bb325c29e7ac2e4727787cb5a40f995ea204 (patch) | |
tree | 240ba663fb4d87bd8b8d951cf97f08ddc74c2785 /Objects | |
parent | e2c277a69f86480ce950399a2e8a215a48ee60cd (diff) | |
download | cpython-50a4bb325c29e7ac2e4727787cb5a40f995ea204.zip cpython-50a4bb325c29e7ac2e4727787cb5a40f995ea204.tar.gz cpython-50a4bb325c29e7ac2e4727787cb5a40f995ea204.tar.bz2 |
Various fixups (most suggested by Armin Rigo).
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/setobject.c | 106 |
1 files changed, 66 insertions, 40 deletions
diff --git a/Objects/setobject.c b/Objects/setobject.c index 61ba853..7ad8af0 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -12,7 +12,6 @@ /* Fast access macros */ #define DICT_CONTAINS(d, k) (d->ob_type->tp_as_sequence->sq_contains(d, k)) -#define IS_SET(so) (so->ob_type == &PySet_Type || so->ob_type == &PyFrozenSet_Type) /* set object **********************************************************/ @@ -42,8 +41,6 @@ make_new_set(PyTypeObject *type, PyObject *iterable) Py_DECREF(it); Py_DECREF(data); Py_DECREF(item); - PyErr_SetString(PyExc_TypeError, - "all set entries must be immutable"); return NULL; } Py_DECREF(item); @@ -67,7 +64,7 @@ make_new_set(PyTypeObject *type, PyObject *iterable) } static PyObject * -set_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *iterable = NULL; @@ -76,6 +73,14 @@ set_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return make_new_set(type, iterable); } +static PyObject * +set_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *iterable = NULL; + + return make_new_set(type, NULL); +} + static void set_dealloc(PySetObject *so) { @@ -139,6 +144,8 @@ set_union(PySetObject *so, PyObject *other) PyObject *item, *data, *it; result = (PySetObject *)set_copy(so); + if (result == NULL) + return NULL; it = PyObject_GetIter(other); if (it == NULL) { Py_DECREF(result); @@ -150,8 +157,6 @@ set_union(PySetObject *so, PyObject *other) Py_DECREF(it); Py_DECREF(result); Py_DECREF(item); - PyErr_SetString(PyExc_TypeError, - "all set entries must be immutable"); return NULL; } Py_DECREF(item); @@ -183,8 +188,6 @@ set_union_update(PySetObject *so, PyObject *other) if (PyDict_SetItem(data, item, Py_True) == -1) { Py_DECREF(it); Py_DECREF(item); - PyErr_SetString(PyExc_TypeError, - "all set entries must be immutable"); return NULL; } Py_DECREF(item); @@ -201,7 +204,7 @@ PyDoc_STRVAR(union_update_doc, static PyObject * set_or(PySetObject *so, PyObject *other) { - if (!IS_SET(so) || !IS_SET(other)) { + if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } @@ -213,7 +216,7 @@ set_ior(PySetObject *so, PyObject *other) { PyObject *result; - if (!IS_SET(other)) { + if (!PyAnySet_Check(other)) { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } @@ -249,8 +252,6 @@ set_intersection(PySetObject *so, PyObject *other) Py_DECREF(it); Py_DECREF(result); Py_DECREF(item); - PyErr_SetString(PyExc_TypeError, - "all set entries must be immutable"); return NULL; } } @@ -291,8 +292,6 @@ set_intersection_update(PySetObject *so, PyObject *other) Py_DECREF(newdict); Py_DECREF(it); Py_DECREF(item); - PyErr_SetString(PyExc_TypeError, - "all set entries must be immutable"); return NULL; } } @@ -315,7 +314,7 @@ PyDoc_STRVAR(intersection_update_doc, static PyObject * set_and(PySetObject *so, PyObject *other) { - if (!IS_SET(so) || !IS_SET(other)) { + if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } @@ -327,7 +326,7 @@ set_iand(PySetObject *so, PyObject *other) { PyObject *result; - if (!IS_SET(other)) { + if (!PyAnySet_Check(other)) { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } @@ -416,7 +415,7 @@ PyDoc_STRVAR(difference_update_doc, static PyObject * set_sub(PySetObject *so, PyObject *other) { - if (!IS_SET(so) || !IS_SET(other)) { + if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } @@ -428,7 +427,7 @@ set_isub(PySetObject *so, PyObject *other) { PyObject *result; - if (!IS_SET(other)) { + if (!PyAnySet_Check(other)) { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } @@ -475,8 +474,6 @@ set_symmetric_difference(PySetObject *so, PyObject *other) Py_DECREF(otherset); Py_DECREF(result); Py_DECREF(item); - PyErr_SetString(PyExc_TypeError, - "all set entries must be immutable"); return NULL; } } @@ -506,7 +503,7 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other) if (PyDict_Check(other)) otherdata = other; - else if (IS_SET(other)) + else if (PyAnySet_Check(other)) otherdata = ((PySetObject *)other)->data; else { otherset = (PySetObject *)make_new_set(so->ob_type, other); @@ -525,8 +522,6 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other) Py_XDECREF(otherset); Py_DECREF(it); Py_DECREF(item); - PyErr_SetString(PyExc_TypeError, - "all set entries must be immutable"); return NULL; } } else { @@ -534,8 +529,6 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other) Py_XDECREF(otherset); Py_DECREF(it); Py_DECREF(item); - PyErr_SetString(PyExc_TypeError, - "all set entries must be immutable"); return NULL; } } @@ -554,7 +547,7 @@ PyDoc_STRVAR(symmetric_difference_update_doc, static PyObject * set_xor(PySetObject *so, PyObject *other) { - if (!IS_SET(so) || !IS_SET(other)) { + if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } @@ -566,7 +559,7 @@ set_ixor(PySetObject *so, PyObject *other) { PyObject *result; - if (!IS_SET(other)) { + if (!PyAnySet_Check(other)) { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } @@ -583,7 +576,7 @@ set_issubset(PySetObject *so, PyObject *other) { PyObject *otherdata, *it, *item; - if (!IS_SET(other)) { + if (!PyAnySet_Check(other)) { PyErr_SetString(PyExc_TypeError, "can only compare to a set"); return NULL; } @@ -604,6 +597,8 @@ set_issubset(PySetObject *so, PyObject *other) Py_DECREF(item); } Py_DECREF(it); + if (PyErr_Occurred()) + return NULL; Py_RETURN_TRUE; } @@ -612,7 +607,7 @@ PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set."); static PyObject * set_issuperset(PySetObject *so, PyObject *other) { - if (!IS_SET(other)) { + if (!PyAnySet_Check(other)) { PyErr_SetString(PyExc_TypeError, "can only compare to a set"); return NULL; } @@ -653,20 +648,21 @@ frozenset_hash(PyObject *self) hash ^= PyObject_Hash(item); Py_DECREF(item); } - so->hash = hash; Py_DECREF(it); + if (PyErr_Occurred()) + return -1; + so->hash = hash; return hash; } static PyObject * set_richcompare(PySetObject *v, PyObject *w, int op) { - /* XXX factor out is_set test */ - if (op == Py_EQ && !IS_SET(w)) - Py_RETURN_FALSE; - else if (op == Py_NE && !IS_SET(w)) - Py_RETURN_TRUE; - if (!IS_SET(w)) { + if(!PyAnySet_Check(w)) { + if (op == Py_EQ) + Py_RETURN_FALSE; + if (op == Py_NE) + Py_RETURN_TRUE; PyErr_SetString(PyExc_TypeError, "can only compare to a set"); return NULL; } @@ -698,8 +694,12 @@ set_repr(PySetObject *so) PyObject *keys, *result, *listrepr; keys = PyDict_Keys(so->data); + if (keys == NULL) + return NULL; listrepr = PyObject_Repr(keys); Py_DECREF(keys); + if (listrepr == NULL) + return NULL; result = PyString_FromFormat("%s(%s)", so->ob_type->tp_name, PyString_AS_STRING(listrepr)); @@ -732,6 +732,8 @@ set_tp_print(PySetObject *so, FILE *fp, int flags) } Py_DECREF(it); fprintf(fp, "])"); + if (PyErr_Occurred()) + return -1; return 0; } @@ -810,8 +812,10 @@ set_pop(PySetObject *so) return NULL; } Py_INCREF(key); - if (PyDict_DelItem(so->data, key) == -1) - PyErr_Clear(); + if (PyDict_DelItem(so->data, key) == -1) { + Py_DECREF(key); + return NULL; + } return key; } @@ -837,6 +841,28 @@ done: PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); +static int +set_init(PySetObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *iterable = NULL; + PyObject *result; + + if (!PyAnySet_Check(self)) + return -1; + if (!PyArg_UnpackTuple(args, self->ob_type->tp_name, 0, 1, &iterable)) + return -1; + PyDict_Clear(self->data); + self->hash = -1; + if (iterable == NULL) + return 0; + result = set_union_update(self, iterable); + if (result != NULL) { + Py_DECREF(result); + return 0; + } + return -1; +} + static PySequenceMethods set_as_sequence = { (inquiry)set_len, /* sq_length */ 0, /* sq_concat */ @@ -971,7 +997,7 @@ PyTypeObject PySet_Type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - 0, /* tp_init */ + (initproc)set_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ set_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ @@ -1068,6 +1094,6 @@ PyTypeObject PyFrozenSet_Type = { 0, /* tp_dictoffset */ 0, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ - set_new, /* tp_new */ + frozenset_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ }; |