summaryrefslogtreecommitdiffstats
path: root/Objects/setobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/setobject.c')
-rw-r--r--Objects/setobject.c286
1 files changed, 136 insertions, 150 deletions
diff --git a/Objects/setobject.c b/Objects/setobject.c
index af1ce16..d8401f4 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -3,12 +3,13 @@
Written and maintained by Raymond D. Hettinger <python@rcn.com>
Derived from Lib/sets.py and Objects/dictobject.c.
- Copyright (c) 2003-2007 Python Software Foundation.
+ Copyright (c) 2003-2008 Python Software Foundation.
All rights reserved.
*/
#include "Python.h"
#include "structmember.h"
+#include "stringlib/eq.h"
/* Set a key error with the specified argument, wrapping it in a
* tuple automatically so that tuple keys are not unpacked as the
@@ -57,6 +58,7 @@ _PySet_Dummy(void)
static PySetObject *free_list[PySet_MAXFREELIST];
static int numfree = 0;
+
/*
The basic lookup function used by all operations.
This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
@@ -73,9 +75,9 @@ NULL if the rich comparison returns an error.
*/
static setentry *
-set_lookkey(PySetObject *so, PyObject *key, register long hash)
+set_lookkey(PySetObject *so, PyObject *key, register Py_hash_t hash)
{
- register Py_ssize_t i;
+ register size_t i; /* Unsigned for defined overflow behavior. */
register size_t perturb;
register setentry *freeslot;
register size_t mask = so->mask;
@@ -150,25 +152,25 @@ set_lookkey(PySetObject *so, PyObject *key, register long hash)
}
/*
- * Hacked up version of set_lookkey which can assume keys are always strings;
- * This means we can always use _PyString_Eq directly and not have to check to
+ * Hacked up version of set_lookkey which can assume keys are always unicode;
+ * This means we can always use unicode_eq directly and not have to check to
* see if the comparison altered the table.
*/
static setentry *
-set_lookkey_string(PySetObject *so, PyObject *key, register long hash)
+set_lookkey_unicode(PySetObject *so, PyObject *key, register Py_hash_t hash)
{
- register Py_ssize_t i;
+ register size_t i; /* Unsigned for defined overflow behavior. */
register size_t perturb;
register setentry *freeslot;
register size_t mask = so->mask;
setentry *table = so->table;
register setentry *entry;
- /* Make sure this function doesn't have to handle non-string keys,
+ /* Make sure this function doesn't have to handle non-unicode keys,
including subclasses of str; e.g., one reason to subclass
strings is to override __eq__, and for speed we don't cater to
that here. */
- if (!PyString_CheckExact(key)) {
+ if (!PyUnicode_CheckExact(key)) {
so->lookup = set_lookkey;
return set_lookkey(so, key, hash);
}
@@ -179,7 +181,7 @@ set_lookkey_string(PySetObject *so, PyObject *key, register long hash)
if (entry->key == dummy)
freeslot = entry;
else {
- if (entry->hash == hash && _PyString_Eq(entry->key, key))
+ if (entry->hash == hash && unicode_eq(entry->key, key))
return entry;
freeslot = NULL;
}
@@ -194,7 +196,7 @@ set_lookkey_string(PySetObject *so, PyObject *key, register long hash)
if (entry->key == key
|| (entry->hash == hash
&& entry->key != dummy
- && _PyString_Eq(entry->key, key)))
+ && unicode_eq(entry->key, key)))
return entry;
if (entry->key == dummy && freeslot == NULL)
freeslot = entry;
@@ -209,10 +211,10 @@ Used by the public insert routine.
Eats a reference to key.
*/
static int
-set_insert_key(register PySetObject *so, PyObject *key, long hash)
+set_insert_key(register PySetObject *so, PyObject *key, Py_hash_t hash)
{
register setentry *entry;
- typedef setentry *(*lookupfunc)(PySetObject *, PyObject *, long);
+ typedef setentry *(*lookupfunc)(PySetObject *, PyObject *, Py_hash_t);
assert(so->lookup != NULL);
entry = so->lookup(so, key, hash);
@@ -246,7 +248,7 @@ Note that no refcounts are changed by this routine; if needed, the caller
is responsible for incref'ing `key`.
*/
static void
-set_insert_clean(register PySetObject *so, PyObject *key, long hash)
+set_insert_clean(register PySetObject *so, PyObject *key, Py_hash_t hash)
{
register size_t i;
register size_t perturb;
@@ -363,7 +365,7 @@ set_add_entry(register PySetObject *so, setentry *entry)
{
register Py_ssize_t n_used;
PyObject *key = entry->key;
- long hash = entry->hash;
+ Py_hash_t hash = entry->hash;
assert(so->fill <= so->mask); /* at least one empty slot */
n_used = so->used;
@@ -380,11 +382,11 @@ set_add_entry(register PySetObject *so, setentry *entry)
static int
set_add_key(register PySetObject *so, PyObject *key)
{
- register long hash;
+ register Py_hash_t hash;
register Py_ssize_t n_used;
- if (!PyString_CheckExact(key) ||
- (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+ if (!PyUnicode_CheckExact(key) ||
+ (hash = ((PyUnicodeObject *) key)->hash) == -1) {
hash = PyObject_Hash(key);
if (hash == -1)
return -1;
@@ -425,13 +427,14 @@ set_discard_entry(PySetObject *so, setentry *oldentry)
static int
set_discard_key(PySetObject *so, PyObject *key)
{
- register long hash;
+ register Py_hash_t hash;
register setentry *entry;
PyObject *old_key;
assert (PyAnySet_Check(so));
- if (!PyString_CheckExact(key) ||
- (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+
+ if (!PyUnicode_CheckExact(key) ||
+ (hash = ((PyUnicodeObject *) key)->hash) == -1) {
hash = PyObject_Hash(key);
if (hash == -1)
return -1;
@@ -573,67 +576,54 @@ set_dealloc(PySetObject *so)
Py_TRASHCAN_SAFE_END(so)
}
-static int
-set_tp_print(PySetObject *so, FILE *fp, int flags)
-{
- setentry *entry;
- Py_ssize_t pos=0;
- char *emit = ""; /* No separator emitted on first pass */
- char *separator = ", ";
- int status = Py_ReprEnter((PyObject*)so);
-
- if (status != 0) {
- if (status < 0)
- return status;
- Py_BEGIN_ALLOW_THREADS
- fprintf(fp, "%s(...)", so->ob_type->tp_name);
- Py_END_ALLOW_THREADS
- return 0;
- }
-
- Py_BEGIN_ALLOW_THREADS
- fprintf(fp, "%s([", so->ob_type->tp_name);
- Py_END_ALLOW_THREADS
- while (set_next(so, &pos, &entry)) {
- Py_BEGIN_ALLOW_THREADS
- fputs(emit, fp);
- Py_END_ALLOW_THREADS
- emit = separator;
- if (PyObject_Print(entry->key, fp, 0) != 0) {
- Py_ReprLeave((PyObject*)so);
- return -1;
- }
- }
- Py_BEGIN_ALLOW_THREADS
- fputs("])", fp);
- Py_END_ALLOW_THREADS
- Py_ReprLeave((PyObject*)so);
- return 0;
-}
-
static PyObject *
set_repr(PySetObject *so)
{
- PyObject *keys, *result=NULL, *listrepr;
+ PyObject *keys, *result=NULL;
+ Py_UNICODE *u;
int status = Py_ReprEnter((PyObject*)so);
+ PyObject *listrepr;
+ Py_ssize_t newsize;
if (status != 0) {
if (status < 0)
return NULL;
- return PyString_FromFormat("%s(...)", so->ob_type->tp_name);
+ return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
+ }
+
+ /* shortcut for the empty set */
+ if (!so->used) {
+ Py_ReprLeave((PyObject*)so);
+ return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
}
keys = PySequence_List((PyObject *)so);
if (keys == NULL)
goto done;
+
listrepr = PyObject_Repr(keys);
Py_DECREF(keys);
if (listrepr == NULL)
goto done;
-
- result = PyString_FromFormat("%s(%s)", so->ob_type->tp_name,
- PyString_AS_STRING(listrepr));
+ 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++ = '}';
+ }
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;
@@ -650,7 +640,7 @@ set_merge(PySetObject *so, PyObject *otherset)
{
PySetObject *other;
PyObject *key;
- long hash;
+ Py_hash_t hash;
register Py_ssize_t i;
register setentry *entry;
@@ -688,11 +678,11 @@ set_merge(PySetObject *so, PyObject *otherset)
static int
set_contains_key(PySetObject *so, PyObject *key)
{
- long hash;
+ Py_hash_t hash;
setentry *entry;
- if (!PyString_CheckExact(key) ||
- (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+ if (!PyUnicode_CheckExact(key) ||
+ (hash = ((PyUnicodeObject *) key)->hash) == -1) {
hash = PyObject_Hash(key);
if (hash == -1)
return -1;
@@ -774,11 +764,11 @@ set_traverse(PySetObject *so, visitproc visit, void *arg)
return 0;
}
-static long
+static Py_hash_t
frozenset_hash(PyObject *self)
{
PySetObject *so = (PySetObject *)self;
- long h, hash = 1927868237L;
+ Py_uhash_t h, hash = 1927868237UL;
setentry *entry;
Py_ssize_t pos = 0;
@@ -793,11 +783,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) ^ 89869747UL) * 3644798167UL;
}
- hash = hash * 69069L + 907133923L;
+ hash = hash * 69069UL + 907133923UL;
if (hash == -1)
- hash = 590923713L;
+ hash = 590923713UL;
so->hash = hash;
return hash;
}
@@ -832,7 +822,7 @@ setiter_len(setiterobject *si)
Py_ssize_t len = 0;
if (si->si_set != NULL && si->si_used == si->si_set->used)
len = si->len;
- return PyInt_FromLong(len);
+ return PyLong_FromSsize_t(len);
}
PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
@@ -880,9 +870,9 @@ fail:
return NULL;
}
-static PyTypeObject PySetIter_Type = {
+PyTypeObject PySetIter_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
- "setiterator", /* tp_name */
+ "set_iterator", /* tp_name */
sizeof(setiterobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
@@ -890,7 +880,7 @@ static PyTypeObject PySetIter_Type = {
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
- 0, /* tp_compare */
+ 0, /* tp_reserved */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
@@ -939,7 +929,7 @@ set_update_internal(PySetObject *so, PyObject *other)
if (PyDict_CheckExact(other)) {
PyObject *value;
Py_ssize_t pos = 0;
- long hash;
+ Py_hash_t hash;
Py_ssize_t dictsize = PyDict_Size(other);
/* Do one big resize at the start, rather than
@@ -1003,7 +993,7 @@ make_new_set(PyTypeObject *type, PyObject *iterable)
register PySetObject *so = NULL;
if (dummy == NULL) { /* Auto-initialize dummy */
- dummy = PyString_FromString("<dummy key>");
+ dummy = PyUnicode_FromString("<dummy key>");
if (dummy == NULL)
return NULL;
}
@@ -1026,7 +1016,7 @@ make_new_set(PyTypeObject *type, PyObject *iterable)
INIT_NONZERO_SET_SLOTS(so);
}
- so->lookup = set_lookkey_string;
+ so->lookup = set_lookkey_unicode;
so->weakreflist = NULL;
if (iterable != NULL) {
@@ -1039,6 +1029,18 @@ make_new_set(PyTypeObject *type, PyObject *iterable)
return (PyObject *)so;
}
+static PyObject *
+make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
+{
+ if (type != &PySet_Type && type != &PyFrozenSet_Type) {
+ if (PyType_IsSubtype(type, &PySet_Type))
+ type = &PySet_Type;
+ else
+ type = &PyFrozenSet_Type;
+ }
+ return make_new_set(type, iterable);
+}
+
/* The empty frozenset is a singleton */
static PyObject *emptyfrozenset = NULL;
@@ -1115,9 +1117,9 @@ set_swap_bodies(PySetObject *a, PySetObject *b)
{
Py_ssize_t t;
setentry *u;
- setentry *(*f)(PySetObject *so, PyObject *key, long hash);
+ setentry *(*f)(PySetObject *so, PyObject *key, Py_ssize_t hash);
setentry tab[PySet_MINSIZE];
- long h;
+ Py_hash_t h;
t = a->fill; a->fill = b->fill; b->fill = t;
t = a->used; a->used = b->used; b->used = t;
@@ -1151,7 +1153,7 @@ set_swap_bodies(PySetObject *a, PySetObject *b)
static PyObject *
set_copy(PySetObject *so)
{
- return make_new_set(Py_TYPE(so), (PyObject *)so);
+ return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
}
static PyObject *
@@ -1247,7 +1249,7 @@ set_intersection(PySetObject *so, PyObject *other)
if ((PyObject *)so == other)
return set_copy(so);
- result = (PySetObject *)make_new_set(Py_TYPE(so), NULL);
+ result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
if (result == NULL)
return NULL;
@@ -1286,7 +1288,7 @@ set_intersection(PySetObject *so, PyObject *other)
while ((key = PyIter_Next(it)) != NULL) {
int rv;
setentry entry;
- long hash = PyObject_Hash(key);
+ Py_hash_t hash = PyObject_Hash(key);
if (hash == -1) {
Py_DECREF(it);
@@ -1345,9 +1347,9 @@ set_intersection_multi(PySetObject *so, PyObject *args)
}
PyDoc_STRVAR(intersection_doc,
-"Return the intersection of two or more sets as a new set.\n\
+"Return the intersection of two sets as a new set.\n\
\n\
-(i.e. elements that are common to all of the sets.)");
+(i.e. all elements that are in both sets.)");
static PyObject *
set_intersection_update(PySetObject *so, PyObject *other)
@@ -1443,7 +1445,7 @@ set_isdisjoint(PySetObject *so, PyObject *other)
while ((key = PyIter_Next(it)) != NULL) {
int rv;
setentry entry;
- long hash = PyObject_Hash(key);
+ Py_hash_t hash = PyObject_Hash(key);
if (hash == -1) {
Py_DECREF(key);
@@ -1526,6 +1528,20 @@ PyDoc_STRVAR(difference_update_doc,
"Remove all elements of another set from this set.");
static PyObject *
+set_copy_and_difference(PySetObject *so, PyObject *other)
+{
+ PyObject *result;
+
+ result = set_copy(so);
+ if (result == NULL)
+ return NULL;
+ if (set_difference_update_internal((PySetObject *) result, other) != -1)
+ return result;
+ Py_DECREF(result);
+ return NULL;
+}
+
+static PyObject *
set_difference(PySetObject *so, PyObject *other)
{
PyObject *result;
@@ -1533,16 +1549,16 @@ set_difference(PySetObject *so, PyObject *other)
Py_ssize_t pos = 0;
if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) {
- result = set_copy(so);
- if (result == NULL)
- return NULL;
- if (set_difference_update_internal((PySetObject *)result, other) != -1)
- return result;
- Py_DECREF(result);
- return NULL;
+ return set_copy_and_difference(so, other);
+ }
+
+ /* If len(so) much more than len(other), it's more efficient to simply copy
+ * so and then iterate other looking for common elements. */
+ if ((PySet_GET_SIZE(so) >> 2) > PyObject_Size(other)) {
+ return set_copy_and_difference(so, other);
}
- result = make_new_set(Py_TYPE(so), NULL);
+ result = make_new_set_basetype(Py_TYPE(so), NULL);
if (result == NULL)
return NULL;
@@ -1561,6 +1577,7 @@ set_difference(PySetObject *so, PyObject *other)
return result;
}
+ /* Iterate over so, checking for common elements in other. */
while (set_next(so, &pos, &entry)) {
int rv = set_contains_entry((PySetObject *)other, entry);
if (rv == -1) {
@@ -1642,7 +1659,7 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other)
if (PyDict_CheckExact(other)) {
PyObject *value;
int rv;
- long hash;
+ Py_hash_t hash;
while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
setentry an_entry;
@@ -1670,7 +1687,7 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other)
Py_INCREF(other);
otherset = (PySetObject *)other;
} else {
- otherset = (PySetObject *)make_new_set(Py_TYPE(so), other);
+ otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
if (otherset == NULL)
return NULL;
}
@@ -1701,7 +1718,7 @@ set_symmetric_difference(PySetObject *so, PyObject *other)
PyObject *rv;
PySetObject *otherset;
- otherset = (PySetObject *)make_new_set(Py_TYPE(so), other);
+ otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
if (otherset == NULL)
return NULL;
rv = set_symmetric_difference_update(otherset, (PyObject *)so);
@@ -1797,12 +1814,8 @@ set_richcompare(PySetObject *v, PyObject *w, int op)
PyObject *r1, *r2;
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;
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
}
switch (op) {
case Py_EQ:
@@ -1837,13 +1850,6 @@ set_richcompare(PySetObject *v, PyObject *w, int op)
return Py_NotImplemented;
}
-static int
-set_nocmp(PyObject *self, PyObject *other)
-{
- PyErr_SetString(PyExc_TypeError, "cannot compare sets using cmp()");
- return -1;
-}
-
static PyObject *
set_add(PySetObject *so, PyObject *key)
{
@@ -1984,7 +1990,7 @@ set_sizeof(PySetObject *so)
res = sizeof(PySetObject);
if (so->table != so->smalltable)
res = res + (so->mask + 1) * sizeof(setentry);
- return PyInt_FromSsize_t(res);
+ return PyLong_FromSsize_t(res);
}
PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
@@ -2078,30 +2084,25 @@ static PyNumberMethods set_as_number = {
0, /*nb_add*/
(binaryfunc)set_sub, /*nb_subtract*/
0, /*nb_multiply*/
- 0, /*nb_divide*/
0, /*nb_remainder*/
0, /*nb_divmod*/
0, /*nb_power*/
0, /*nb_negative*/
0, /*nb_positive*/
0, /*nb_absolute*/
- 0, /*nb_nonzero*/
+ 0, /*nb_bool*/
0, /*nb_invert*/
0, /*nb_lshift*/
0, /*nb_rshift*/
(binaryfunc)set_and, /*nb_and*/
(binaryfunc)set_xor, /*nb_xor*/
(binaryfunc)set_or, /*nb_or*/
- 0, /*nb_coerce*/
0, /*nb_int*/
- 0, /*nb_long*/
+ 0, /*nb_reserved*/
0, /*nb_float*/
- 0, /*nb_oct*/
- 0, /*nb_hex*/
0, /*nb_inplace_add*/
(binaryfunc)set_isub, /*nb_inplace_subtract*/
0, /*nb_inplace_multiply*/
- 0, /*nb_inplace_divide*/
0, /*nb_inplace_remainder*/
0, /*nb_inplace_power*/
0, /*nb_inplace_lshift*/
@@ -2124,28 +2125,28 @@ PyTypeObject PySet_Type = {
0, /* tp_itemsize */
/* methods */
(destructor)set_dealloc, /* tp_dealloc */
- (printfunc)set_tp_print, /* tp_print */
+ 0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
- set_nocmp, /* tp_compare */
+ 0, /* tp_reserved */
(reprfunc)set_repr, /* tp_repr */
&set_as_number, /* tp_as_number */
&set_as_sequence, /* tp_as_sequence */
0, /* tp_as_mapping */
- (hashfunc)PyObject_HashNotImplemented, /* tp_hash */
+ PyObject_HashNotImplemented, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES |
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
set_doc, /* tp_doc */
(traverseproc)set_traverse, /* tp_traverse */
(inquiry)set_clear_internal, /* tp_clear */
(richcmpfunc)set_richcompare, /* tp_richcompare */
- offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
- (getiterfunc)set_iter, /* tp_iter */
+ offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
+ (getiterfunc)set_iter, /* tp_iter */
0, /* tp_iternext */
set_methods, /* tp_methods */
0, /* tp_members */
@@ -2194,14 +2195,13 @@ static PyNumberMethods frozenset_as_number = {
0, /*nb_add*/
(binaryfunc)set_sub, /*nb_subtract*/
0, /*nb_multiply*/
- 0, /*nb_divide*/
0, /*nb_remainder*/
0, /*nb_divmod*/
0, /*nb_power*/
0, /*nb_negative*/
0, /*nb_positive*/
0, /*nb_absolute*/
- 0, /*nb_nonzero*/
+ 0, /*nb_bool*/
0, /*nb_invert*/
0, /*nb_lshift*/
0, /*nb_rshift*/
@@ -2223,10 +2223,10 @@ PyTypeObject PyFrozenSet_Type = {
0, /* tp_itemsize */
/* methods */
(destructor)set_dealloc, /* tp_dealloc */
- (printfunc)set_tp_print, /* tp_print */
+ 0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
- set_nocmp, /* tp_compare */
+ 0, /* tp_reserved */
(reprfunc)set_repr, /* tp_repr */
&frozenset_as_number, /* tp_as_number */
&set_as_sequence, /* tp_as_sequence */
@@ -2237,7 +2237,7 @@ PyTypeObject PyFrozenSet_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES |
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
frozenset_doc, /* tp_doc */
(traverseproc)set_traverse, /* tp_traverse */
@@ -2327,22 +2327,7 @@ PySet_Add(PyObject *anyset, PyObject *key)
}
int
-_PySet_Next(PyObject *set, Py_ssize_t *pos, PyObject **key)
-{
- setentry *entry_ptr;
-
- if (!PyAnySet_Check(set)) {
- PyErr_BadInternalCall();
- return -1;
- }
- if (set_next((PySetObject *)set, pos, &entry_ptr) == 0)
- return 0;
- *key = entry_ptr->key;
- return 1;
-}
-
-int
-_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash)
+_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
{
setentry *entry;
@@ -2397,6 +2382,7 @@ test_c_api(PySetObject *so)
Py_ssize_t i;
PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x;
PyObject *ob = (PyObject *)so;
+ Py_hash_t hash;
PyObject *str;
/* Verify preconditions */
@@ -2405,7 +2391,7 @@ test_c_api(PySetObject *so)
assert(!PyFrozenSet_CheckExact(ob));
/* so.clear(); so |= set("abc"); */
- str = PyString_FromString("abc");
+ str = PyUnicode_FromString("abc");
if (str == NULL)
return NULL;
set_clear_internal(so);
@@ -2459,8 +2445,8 @@ test_c_api(PySetObject *so)
/* Exercise direct iteration */
i = 0, count = 0;
- while (_PySet_Next((PyObject *)dup, &i, &x)) {
- s = PyString_AsString(x);
+ while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
+ s = _PyUnicode_AsString(x);
assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
count++;
}