diff options
Diffstat (limited to 'Objects/setobject.c')
-rw-r--r-- | Objects/setobject.c | 191 |
1 files changed, 113 insertions, 78 deletions
diff --git a/Objects/setobject.c b/Objects/setobject.c index 3abeefb..723679a 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -77,7 +77,7 @@ NULL if the rich comparison returns an error. static setentry * set_lookkey(PySetObject *so, PyObject *key, register Py_hash_t hash) { - register Py_ssize_t i; + register size_t i; register size_t perturb; register setentry *freeslot; register size_t mask = so->mask; @@ -86,7 +86,7 @@ set_lookkey(PySetObject *so, PyObject *key, register Py_hash_t hash) register int cmp; PyObject *startkey; - i = hash & mask; + i = (size_t)hash & mask; entry = &table[i]; if (entry->key == NULL || entry->key == key) return entry; @@ -159,7 +159,7 @@ set_lookkey(PySetObject *so, PyObject *key, register Py_hash_t hash) static setentry * set_lookkey_unicode(PySetObject *so, PyObject *key, register Py_hash_t hash) { - register Py_ssize_t i; + register size_t i; register size_t perturb; register setentry *freeslot; register size_t mask = so->mask; @@ -174,7 +174,7 @@ set_lookkey_unicode(PySetObject *so, PyObject *key, register Py_hash_t hash) so->lookup = set_lookkey; return set_lookkey(so, key, hash); } - i = hash & mask; + i = (size_t)hash & mask; entry = &table[i]; if (entry->key == NULL || entry->key == key) return entry; @@ -256,7 +256,7 @@ set_insert_clean(register PySetObject *so, PyObject *key, Py_hash_t hash) setentry *table = so->table; register setentry *entry; - i = hash & mask; + i = (size_t)hash & mask; entry = &table[i]; for (perturb = hash; entry->key != NULL; perturb >>= PERTURB_SHIFT) { i = (i << 2) + i + perturb + 1; @@ -386,7 +386,7 @@ set_add_key(register PySetObject *so, PyObject *key) register Py_ssize_t n_used; if (!PyUnicode_CheckExact(key) || - (hash = ((PyUnicodeObject *) key)->hash) == -1) { + (hash = ((PyASCIIObject *) key)->hash) == -1) { hash = PyObject_Hash(key); if (hash == -1) return -1; @@ -434,7 +434,7 @@ set_discard_key(PySetObject *so, PyObject *key) assert (PyAnySet_Check(so)); if (!PyUnicode_CheckExact(key) || - (hash = ((PyUnicodeObject *) key)->hash) == -1) { + (hash = ((PyASCIIObject *) key)->hash) == -1) { hash = PyObject_Hash(key); if (hash == -1) return -1; @@ -579,11 +579,8 @@ set_dealloc(PySetObject *so) static PyObject * set_repr(PySetObject *so) { - PyObject *keys, *result=NULL; - Py_UNICODE *u; + PyObject *result=NULL, *keys, *listrepr, *tmp; int status = Py_ReprEnter((PyObject*)so); - PyObject *listrepr; - Py_ssize_t newsize; if (status != 0) { if (status < 0) @@ -601,29 +598,24 @@ set_repr(PySetObject *so) if (keys == NULL) goto done; + /* repr(keys)[1:-1] */ listrepr = PyObject_Repr(keys); Py_DECREF(keys); if (listrepr == NULL) goto done; - newsize = PyUnicode_GET_SIZE(listrepr); - result = PyUnicode_FromUnicode(NULL, newsize); - if (result) { - u = PyUnicode_AS_UNICODE(result); - *u++ = '{'; - /* Omit the brackets from the listrepr */ - Py_UNICODE_COPY(u, PyUnicode_AS_UNICODE(listrepr)+1, - PyUnicode_GET_SIZE(listrepr)-2); - u += newsize-2; - *u++ = '}'; - } + tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1); + Py_DECREF(listrepr); + if (tmp == NULL) + goto done; + listrepr = tmp; + + if (Py_TYPE(so) != &PySet_Type) + result = PyUnicode_FromFormat("%s({%U})", + Py_TYPE(so)->tp_name, + listrepr); + else + result = PyUnicode_FromFormat("{%U}", listrepr); Py_DECREF(listrepr); - if (Py_TYPE(so) != &PySet_Type) { - PyObject *tmp = PyUnicode_FromFormat("%s(%U)", - Py_TYPE(so)->tp_name, - result); - Py_DECREF(result); - result = tmp; - } done: Py_ReprLeave((PyObject*)so); return result; @@ -682,7 +674,7 @@ set_contains_key(PySetObject *so, PyObject *key) setentry *entry; if (!PyUnicode_CheckExact(key) || - (hash = ((PyUnicodeObject *) key)->hash) == -1) { + (hash = ((PyASCIIObject *) key)->hash) == -1) { hash = PyObject_Hash(key); if (hash == -1) return -1; @@ -768,14 +760,14 @@ static Py_hash_t frozenset_hash(PyObject *self) { PySetObject *so = (PySetObject *)self; - Py_hash_t h, hash = 1927868237L; + Py_uhash_t h, hash = 1927868237U; setentry *entry; Py_ssize_t pos = 0; if (so->hash != -1) return so->hash; - hash *= PySet_GET_SIZE(self) + 1; + hash *= (Py_uhash_t)PySet_GET_SIZE(self) + 1; while (set_next(so, &pos, &entry)) { /* Work to increase the bit dispersion for closely spaced hash values. The is important because some use cases have many @@ -783,11 +775,11 @@ frozenset_hash(PyObject *self) hashes so that many distinct combinations collapse to only a handful of distinct hash values. */ h = entry->hash; - hash ^= (h ^ (h << 16) ^ 89869747L) * 3644798167u; + hash ^= (h ^ (h << 16) ^ 89869747U) * 3644798167U; } - hash = hash * 69069L + 907133923L; + hash = hash * 69069U + 907133923U; if (hash == -1) - hash = 590923713L; + hash = 590923713U; so->hash = hash; return hash; } @@ -827,8 +819,51 @@ setiter_len(setiterobject *si) PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); +static PyObject *setiter_iternext(setiterobject *si); + +static PyObject * +setiter_reduce(setiterobject *si) +{ + PyObject *list; + setiterobject tmp; + + list = PyList_New(0); + if (!list) + return NULL; + + /* copy the iterator state */ + tmp = *si; + Py_XINCREF(tmp.si_set); + + /* iterate the temporary into a list */ + for(;;) { + PyObject *element = setiter_iternext(&tmp); + if (element) { + if (PyList_Append(list, element)) { + Py_DECREF(element); + Py_DECREF(list); + Py_XDECREF(tmp.si_set); + return NULL; + } + Py_DECREF(element); + } else + break; + } + Py_XDECREF(tmp.si_set); + /* check for error */ + if (tmp.si_set != NULL) { + /* we have an error */ + Py_DECREF(list); + return NULL; + } + return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list); +} + +PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); + static PyMethodDef setiter_methods[] = { {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc}, + {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc}, {NULL, NULL} /* sentinel */ }; @@ -1076,9 +1111,10 @@ frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return emptyfrozenset; } -void -PySet_Fini(void) +int +PySet_ClearFreeList(void) { + int freelist_size = numfree; PySetObject *so; while (numfree) { @@ -1086,10 +1122,27 @@ PySet_Fini(void) so = free_list[numfree]; PyObject_GC_Del(so); } + return freelist_size; +} + +void +PySet_Fini(void) +{ + PySet_ClearFreeList(); Py_CLEAR(dummy); Py_CLEAR(emptyfrozenset); } +/* Print summary info about the state of the optimized allocator */ +void +_PySet_DebugMallocStats(FILE *out) +{ + _PyDebugAllocatorStats(out, + "free PySetObject", + numfree, sizeof(PySetObject)); +} + + static PyObject * set_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -1210,10 +1263,8 @@ set_or(PySetObject *so, PyObject *other) { PySetObject *result; - if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } + if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) + Py_RETURN_NOTIMPLEMENTED; result = (PySetObject *)set_copy(so); if (result == NULL) @@ -1230,10 +1281,9 @@ set_or(PySetObject *so, PyObject *other) static PyObject * set_ior(PySetObject *so, PyObject *other) { - if (!PyAnySet_Check(other)) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } + if (!PyAnySet_Check(other)) + Py_RETURN_NOTIMPLEMENTED; + if (set_update_internal(so, other) == -1) return NULL; Py_INCREF(so); @@ -1383,10 +1433,8 @@ PyDoc_STRVAR(intersection_update_doc, static PyObject * set_and(PySetObject *so, PyObject *other) { - if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } + if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) + Py_RETURN_NOTIMPLEMENTED; return set_intersection(so, other); } @@ -1395,10 +1443,8 @@ set_iand(PySetObject *so, PyObject *other) { PyObject *result; - if (!PyAnySet_Check(other)) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } + if (!PyAnySet_Check(other)) + Py_RETURN_NOTIMPLEMENTED; result = set_intersection_update(so, other); if (result == NULL) return NULL; @@ -1625,20 +1671,16 @@ PyDoc_STRVAR(difference_doc, static PyObject * set_sub(PySetObject *so, PyObject *other) { - if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } + if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) + Py_RETURN_NOTIMPLEMENTED; return set_difference(so, other); } static PyObject * set_isub(PySetObject *so, PyObject *other) { - if (!PyAnySet_Check(other)) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } + if (!PyAnySet_Check(other)) + Py_RETURN_NOTIMPLEMENTED; if (set_difference_update_internal(so, other) == -1) return NULL; Py_INCREF(so); @@ -1736,10 +1778,8 @@ PyDoc_STRVAR(symmetric_difference_doc, static PyObject * set_xor(PySetObject *so, PyObject *other) { - if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } + if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) + Py_RETURN_NOTIMPLEMENTED; return set_symmetric_difference(so, other); } @@ -1748,10 +1788,8 @@ set_ixor(PySetObject *so, PyObject *other) { PyObject *result; - if (!PyAnySet_Check(other)) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } + if (!PyAnySet_Check(other)) + Py_RETURN_NOTIMPLEMENTED; result = set_symmetric_difference_update(so, other); if (result == NULL) return NULL; @@ -1813,10 +1851,9 @@ set_richcompare(PySetObject *v, PyObject *w, int op) { PyObject *r1, *r2; - if(!PyAnySet_Check(w)) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } + if(!PyAnySet_Check(w)) + Py_RETURN_NOTIMPLEMENTED; + switch (op) { case Py_EQ: if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w)) @@ -1846,8 +1883,7 @@ set_richcompare(PySetObject *v, PyObject *w, int op) Py_RETURN_FALSE; return set_issuperset(v, w); } - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; + Py_RETURN_NOTIMPLEMENTED; } static PyObject * @@ -1959,6 +1995,7 @@ static PyObject * set_reduce(PySetObject *so) { PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL; + _Py_IDENTIFIER(__dict__); keys = PySequence_List((PyObject *)so); if (keys == NULL) @@ -1966,7 +2003,7 @@ set_reduce(PySetObject *so) args = PyTuple_Pack(1, keys); if (args == NULL) goto done; - dict = PyObject_GetAttrString((PyObject *)so, "__dict__"); + dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__); if (dict == NULL) { PyErr_Clear(); dict = Py_None; @@ -1980,8 +2017,6 @@ done: return result; } -PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); - static PyObject * set_sizeof(PySetObject *so) { |