blob: e6fb46e6e24dfb61f338f9dcaaf9b0f8660ca51a [file] [log] [blame]
Raymond Hettingerc991db22005-08-11 07:58:45 +00001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002/* set object implementation
Raymond Hettingerae7b00e2013-09-07 15:05:00 -07003
Raymond Hettingera9d99362005-08-05 00:01:15 +00004 Written and maintained by Raymond D. Hettinger <python@rcn.com>
5 Derived from Lib/sets.py and Objects/dictobject.c.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00006
Raymond Hettingerbd9b2002015-01-18 16:10:30 -08007 Copyright (c) 2003-2015 Python Software Foundation.
Raymond Hettingera9d99362005-08-05 00:01:15 +00008 All rights reserved.
Raymond Hettingerae7b00e2013-09-07 15:05:00 -07009
10 The basic lookup function used by all operations.
11 This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
12
13 The initial probe index is computed as hash mod the table size.
14 Subsequent probe indices are computed as explained in Objects/dictobject.c.
15
16 To improve cache locality, each probe inspects a series of consecutive
17 nearby entries before moving on to probes elsewhere in memory. This leaves
18 us with a hybrid of linear probing and open addressing. The linear probing
19 reduces the cost of hash collisions because consecutive memory accesses
20 tend to be much cheaper than scattered probes. After LINEAR_PROBES steps,
21 we then use open addressing with the upper bits from the hash value. This
22 helps break-up long chains of collisions.
23
24 All arithmetic on hash should ignore overflow.
25
Raymond Hettinger4d45c102015-01-25 16:27:40 -080026 Unlike the dictionary implementation, the lookkey function can return
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070027 NULL if the rich comparison returns an error.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000028*/
29
Raymond Hettingera690a992003-11-16 16:17:49 +000030#include "Python.h"
Raymond Hettingera9d99362005-08-05 00:01:15 +000031#include "structmember.h"
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000032
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000033/* Object used as dummy key to fill deleted entries */
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -050034static PyObject _dummy_struct;
35
36#define dummy (&_dummy_struct)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000037
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000038
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -070039/* ======================================================================== */
40/* ======= Begin logic for probing the hash table ========================= */
41
Raymond Hettinger710a67e2013-09-21 20:17:31 -070042/* Set this to zero to turn-off linear probing */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070043#ifndef LINEAR_PROBES
Raymond Hettinger742d8712013-09-08 00:25:57 -070044#define LINEAR_PROBES 9
Raymond Hettinger8408dc52013-09-15 14:57:15 -070045#endif
Raymond Hettinger742d8712013-09-08 00:25:57 -070046
47/* This must be >= 1 */
48#define PERTURB_SHIFT 5
49
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000050static setentry *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020051set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000052{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000053 setentry *table = so->table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020054 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070055 size_t perturb;
Raymond Hettingerafe89092013-08-28 20:59:31 -070056 size_t mask = so->mask;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -080057 size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070058 size_t j;
Raymond Hettinger4ef05282013-09-21 15:39:49 -070059 int cmp;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000060
Raymond Hettinger59ecabd2015-01-31 02:45:12 -080061 entry = &table[i];
Raymond Hettingerafe89092013-08-28 20:59:31 -070062 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000063 return entry;
Raymond Hettinger237b34b2013-08-17 02:31:53 -070064
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070065 perturb = hash;
66
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -070067 while (1) {
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080068 if (entry->hash == hash) {
Raymond Hettingerafe89092013-08-28 20:59:31 -070069 PyObject *startkey = entry->key;
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080070 /* startkey cannot be a dummy because the dummy hash field is -1 */
71 assert(startkey != dummy);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -080072 if (startkey == key)
73 return entry;
Raymond Hettinger93035c42015-01-25 16:12:49 -080074 if (PyUnicode_CheckExact(startkey)
75 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -070076 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger93035c42015-01-25 16:12:49 -080077 return entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000078 Py_INCREF(startkey);
79 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
80 Py_DECREF(startkey);
Raymond Hettinger426d9952014-05-18 21:40:20 +010081 if (cmp < 0) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000082 return NULL;
Raymond Hettinger426d9952014-05-18 21:40:20 +010083 if (table != so->table || entry->key != startkey) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 return set_lookkey(so, key, hash);
Raymond Hettinger426d9952014-05-18 21:40:20 +010085 if (cmp > 0) /* likely */
Raymond Hettingerafe89092013-08-28 20:59:31 -070086 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -060087 mask = so->mask; /* help avoid a register spill */
Raymond Hettingerafe89092013-08-28 20:59:31 -070088 }
Raymond Hettingerafe89092013-08-28 20:59:31 -070089
Raymond Hettingerc658d852015-02-02 08:35:00 -080090 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -080091 for (j = 0 ; j < LINEAR_PROBES ; j++) {
Raymond Hettingerc658d852015-02-02 08:35:00 -080092 entry++;
Raymond Hettinger8651a502015-05-27 10:37:20 -070093 if (entry->hash == 0 && entry->key == NULL)
94 return entry;
Raymond Hettingerc658d852015-02-02 08:35:00 -080095 if (entry->hash == hash) {
96 PyObject *startkey = entry->key;
97 assert(startkey != dummy);
98 if (startkey == key)
99 return entry;
100 if (PyUnicode_CheckExact(startkey)
101 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700102 && _PyUnicode_EQ(startkey, key))
Raymond Hettingerc658d852015-02-02 08:35:00 -0800103 return entry;
104 Py_INCREF(startkey);
105 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
106 Py_DECREF(startkey);
107 if (cmp < 0)
108 return NULL;
109 if (table != so->table || entry->key != startkey)
110 return set_lookkey(so, key, hash);
111 if (cmp > 0)
112 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -0600113 mask = so->mask;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800114 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700115 }
116 }
117
118 perturb >>= PERTURB_SHIFT;
119 i = (i * 5 + 1 + perturb) & mask;
120
121 entry = &table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700122 if (entry->key == NULL)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700123 return entry;
124 }
125}
126
Raymond Hettinger15f08692015-07-03 17:21:17 -0700127static int set_table_resize(PySetObject *, Py_ssize_t);
128
Raymond Hettinger8651a502015-05-27 10:37:20 -0700129static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700130set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700131{
132 setentry *table = so->table;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700133 setentry *freeslot;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700134 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700135 size_t perturb;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700136 size_t mask = so->mask;
137 size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */
138 size_t j;
139 int cmp;
140
141 entry = &table[i];
142 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700143 goto found_unused;
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700144
145 freeslot = NULL;
146 perturb = hash;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700147
148 while (1) {
149 if (entry->hash == hash) {
150 PyObject *startkey = entry->key;
151 /* startkey cannot be a dummy because the dummy hash field is -1 */
152 assert(startkey != dummy);
153 if (startkey == key)
154 goto found_active;
155 if (PyUnicode_CheckExact(startkey)
156 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700157 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700158 goto found_active;
159 Py_INCREF(startkey);
160 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
161 Py_DECREF(startkey);
162 if (cmp < 0) /* unlikely */
163 return -1;
164 if (table != so->table || entry->key != startkey) /* unlikely */
Raymond Hettinger73799b12015-07-05 16:06:10 -0700165 return set_add_entry(so, key, hash);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700166 if (cmp > 0) /* likely */
167 goto found_active;
168 mask = so->mask; /* help avoid a register spill */
169 }
170 if (entry->hash == -1 && freeslot == NULL)
171 freeslot = entry;
172
173 if (i + LINEAR_PROBES <= mask) {
174 for (j = 0 ; j < LINEAR_PROBES ; j++) {
175 entry++;
176 if (entry->hash == 0 && entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700177 goto found_unused_or_dummy;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700178 if (entry->hash == hash) {
179 PyObject *startkey = entry->key;
180 assert(startkey != dummy);
181 if (startkey == key)
182 goto found_active;
183 if (PyUnicode_CheckExact(startkey)
184 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700185 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700186 goto found_active;
187 Py_INCREF(startkey);
188 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
189 Py_DECREF(startkey);
190 if (cmp < 0)
191 return -1;
192 if (table != so->table || entry->key != startkey)
Raymond Hettinger73799b12015-07-05 16:06:10 -0700193 return set_add_entry(so, key, hash);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700194 if (cmp > 0)
195 goto found_active;
196 mask = so->mask;
197 }
Raymond Hettinger91672612015-06-26 02:50:21 -0700198 else if (entry->hash == -1 && freeslot == NULL)
Raymond Hettingerc658d852015-02-02 08:35:00 -0800199 freeslot = entry;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700200 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000201 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700202
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700203 perturb >>= PERTURB_SHIFT;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -0800204 i = (i * 5 + 1 + perturb) & mask;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700205
Raymond Hettinger59ecabd2015-01-31 02:45:12 -0800206 entry = &table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700207 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700208 goto found_unused_or_dummy;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700210
Raymond Hettinger15f08692015-07-03 17:21:17 -0700211 found_unused_or_dummy:
212 if (freeslot == NULL)
213 goto found_unused;
214 Py_INCREF(key);
215 so->used++;
216 freeslot->key = key;
217 freeslot->hash = hash;
218 return 0;
219
220 found_unused:
Raymond Hettinger2eff9e92015-06-27 22:03:35 -0700221 Py_INCREF(key);
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700222 so->fill++;
223 so->used++;
224 entry->key = key;
225 entry->hash = hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700226 if ((size_t)so->fill*3 < mask*2)
227 return 0;
Raymond Hettinger48973002015-07-03 20:00:03 -0700228 return set_table_resize(so, so->used);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700229
230 found_active:
Raymond Hettinger8651a502015-05-27 10:37:20 -0700231 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000232}
233
234/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000235Internal routine used by set_table_resize() to insert an item which is
236known to be absent from the set. This routine also assumes that
237the set contains no deleted entries. Besides the performance benefit,
238using set_insert_clean() in set_table_resize() is dangerous (SF bug #1456209).
239Note that no refcounts are changed by this routine; if needed, the caller
240is responsible for incref'ing `key`.
241*/
242static void
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200243set_insert_clean(PySetObject *so, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000244{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 setentry *table = so->table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200246 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700247 size_t perturb = hash;
248 size_t mask = (size_t)so->mask;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800249 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700250 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000251
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700252 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800253 entry = &table[i];
254 if (entry->key == NULL)
255 goto found_null;
256 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800257 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800258 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800259 if (entry->key == NULL)
260 goto found_null;
261 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700262 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700263 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800264 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000265 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700266 found_null:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 entry->key = key;
268 entry->hash = hash;
Raymond Hettinger4ef05282013-09-21 15:39:49 -0700269 so->fill++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 so->used++;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000271}
272
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700273/* ======== End logic for probing the hash table ========================== */
274/* ======================================================================== */
275
Thomas Wouters89f507f2006-12-13 04:49:30 +0000276/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000277Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000278keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000279actually be smaller than the old one.
280*/
281static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000282set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000283{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 Py_ssize_t newsize;
285 setentry *oldtable, *newtable, *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800286 Py_ssize_t oldfill = so->fill;
287 Py_ssize_t oldused = so->used;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 int is_oldtable_malloced;
289 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 assert(minused >= 0);
Raymond Hettinger48973002015-07-03 20:00:03 -0700292 minused = (minused > 50000) ? minused * 2 : minused * 4;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000294 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100295 /* XXX speed-up with intrinsics */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 for (newsize = PySet_MINSIZE;
297 newsize <= minused && newsize > 0;
298 newsize <<= 1)
299 ;
300 if (newsize <= 0) {
301 PyErr_NoMemory();
302 return -1;
303 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 /* Get space for a new table. */
306 oldtable = so->table;
307 assert(oldtable != NULL);
308 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 if (newsize == PySet_MINSIZE) {
311 /* A large table is shrinking, or we can't get any smaller. */
312 newtable = so->smalltable;
313 if (newtable == oldtable) {
314 if (so->fill == so->used) {
315 /* No dummies, so no point doing anything. */
316 return 0;
317 }
318 /* We're not going to resize it, but rebuild the
319 table anyway to purge old dummy entries.
320 Subtle: This is *necessary* if fill==size,
321 as set_lookkey needs at least one virgin slot to
322 terminate failing searches. If fill < size, it's
323 merely desirable, as dummies slow searches. */
324 assert(so->fill > so->used);
325 memcpy(small_copy, oldtable, sizeof(small_copy));
326 oldtable = small_copy;
327 }
328 }
329 else {
330 newtable = PyMem_NEW(setentry, newsize);
331 if (newtable == NULL) {
332 PyErr_NoMemory();
333 return -1;
334 }
335 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000337 /* Make the set empty, using the new table. */
338 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339 memset(newtable, 0, sizeof(setentry) * newsize);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000340 so->fill = 0;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800341 so->used = 0;
342 so->mask = newsize - 1;
343 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345 /* Copy the data over; this is refcount-neutral for active entries;
346 dummy entries aren't copied over, of course */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800347 if (oldfill == oldused) {
348 for (entry = oldtable; oldused > 0; entry++) {
349 if (entry->key != NULL) {
350 oldused--;
351 set_insert_clean(so, entry->key, entry->hash);
352 }
353 }
354 } else {
355 for (entry = oldtable; oldused > 0; entry++) {
356 if (entry->key != NULL && entry->key != dummy) {
357 oldused--;
358 set_insert_clean(so, entry->key, entry->hash);
359 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000360 }
361 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 if (is_oldtable_malloced)
364 PyMem_DEL(oldtable);
365 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000366}
367
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000368static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700369set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000370{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700371 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000372
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700373 entry = set_lookkey(so, key, hash);
374 if (entry != NULL)
375 return entry->key != NULL;
376 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000377}
378
379#define DISCARD_NOTFOUND 0
380#define DISCARD_FOUND 1
381
382static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700383set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800384{
385 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000387
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700388 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 if (entry == NULL)
390 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700391 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000392 return DISCARD_NOTFOUND;
393 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800395 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 so->used--;
397 Py_DECREF(old_key);
398 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000399}
400
401static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700402set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000403{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200404 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000405
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700406 if (!PyUnicode_CheckExact(key) ||
407 (hash = ((PyASCIIObject *) key)->hash) == -1) {
408 hash = PyObject_Hash(key);
409 if (hash == -1)
410 return -1;
411 }
412 return set_add_entry(so, key, hash);
413}
414
415static int
416set_contains_key(PySetObject *so, PyObject *key)
417{
418 Py_hash_t hash;
419
420 if (!PyUnicode_CheckExact(key) ||
421 (hash = ((PyASCIIObject *) key)->hash) == -1) {
422 hash = PyObject_Hash(key);
423 if (hash == -1)
424 return -1;
425 }
426 return set_contains_entry(so, key, hash);
427}
428
429static int
430set_discard_key(PySetObject *so, PyObject *key)
431{
432 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000433
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000434 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200435 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000436 hash = PyObject_Hash(key);
437 if (hash == -1)
438 return -1;
439 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700440 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000441}
442
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700443static void
444set_empty_to_minsize(PySetObject *so)
445{
446 memset(so->smalltable, 0, sizeof(so->smalltable));
447 so->fill = 0;
448 so->used = 0;
449 so->mask = PySet_MINSIZE - 1;
450 so->table = so->smalltable;
451 so->hash = -1;
452}
453
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000454static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000455set_clear_internal(PySetObject *so)
456{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800457 setentry *entry;
458 setentry *table = so->table;
459 Py_ssize_t fill = so->fill;
460 Py_ssize_t used = so->used;
461 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000463
Raymond Hettinger583cd032013-09-07 22:06:35 -0700464 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000465 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467 /* This is delicate. During the process of clearing the set,
468 * decrefs can cause the set to mutate. To avoid fatal confusion
469 * (voice of experience), we have to make the set empty before
470 * clearing the slots, and never refer to anything via so->ref while
471 * clearing.
472 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700474 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 else if (fill > 0) {
477 /* It's a small table with something that needs to be cleared.
478 * Afraid the only safe way is to copy the set entries into
479 * another small table first.
480 */
481 memcpy(small_copy, table, sizeof(small_copy));
482 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700483 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 }
485 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487 /* Now we can finally clear things. If C had refcounts, we could
488 * assert that the refcount on table is 1 now, i.e. that this function
489 * has unique access to it, so decref side-effects can't alter it.
490 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800491 for (entry = table; used > 0; entry++) {
492 if (entry->key && entry->key != dummy) {
493 used--;
494 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 if (table_is_malloced)
499 PyMem_DEL(table);
500 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000501}
502
503/*
504 * Iterate over a set table. Use like so:
505 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000506 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000507 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000508 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000509 * while (set_next(yourset, &pos, &entry)) {
510 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000511 * }
512 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000513 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000515 */
516static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000517set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000518{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 Py_ssize_t i;
520 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700521 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 assert (PyAnySet_Check(so));
524 i = *pos_ptr;
525 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700527 entry = &so->table[i];
528 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000529 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700530 entry++;
531 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 *pos_ptr = i+1;
533 if (i > mask)
534 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700535 assert(entry != NULL);
536 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000538}
539
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000540static void
541set_dealloc(PySetObject *so)
542{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200543 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800544 Py_ssize_t used = so->used;
545
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000546 PyObject_GC_UnTrack(so);
547 Py_TRASHCAN_SAFE_BEGIN(so)
548 if (so->weakreflist != NULL)
549 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000550
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800551 for (entry = so->table; used > 0; entry++) {
552 if (entry->key && entry->key != dummy) {
553 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700554 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000555 }
556 }
557 if (so->table != so->smalltable)
558 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700559 Py_TYPE(so)->tp_free(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000560 Py_TRASHCAN_SAFE_END(so)
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000561}
562
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000563static PyObject *
564set_repr(PySetObject *so)
565{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200566 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000567 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000568
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 if (status != 0) {
570 if (status < 0)
571 return NULL;
572 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
573 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000574
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000575 /* shortcut for the empty set */
576 if (!so->used) {
577 Py_ReprLeave((PyObject*)so);
578 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
579 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 keys = PySequence_List((PyObject *)so);
582 if (keys == NULL)
583 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000584
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200585 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 listrepr = PyObject_Repr(keys);
587 Py_DECREF(keys);
588 if (listrepr == NULL)
589 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200590 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000591 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200592 if (tmp == NULL)
593 goto done;
594 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200595
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200596 if (Py_TYPE(so) != &PySet_Type)
597 result = PyUnicode_FromFormat("%s({%U})",
598 Py_TYPE(so)->tp_name,
599 listrepr);
600 else
601 result = PyUnicode_FromFormat("{%U}", listrepr);
602 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000603done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604 Py_ReprLeave((PyObject*)so);
605 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000606}
607
Martin v. Löwis18e16552006-02-15 17:27:45 +0000608static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000609set_len(PyObject *so)
610{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000611 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000612}
613
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000614static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000615set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000616{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000618 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200619 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700620 setentry *so_entry;
621 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 assert (PyAnySet_Check(so));
624 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 other = (PySetObject*)otherset;
627 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700628 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 return 0;
630 /* Do one big resize at the start, rather than
631 * incrementally resizing as we insert new keys. Expect
632 * that there will be no (or few) overlapping keys.
633 */
Raymond Hettinger15f08692015-07-03 17:21:17 -0700634 if ((so->fill + other->used)*3 >= so->mask*2) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700635 if (set_table_resize(so, so->used + other->used) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000636 return -1;
637 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700638 so_entry = so->table;
639 other_entry = other->table;
640
641 /* If our table is empty, and both tables have the same size, and
642 there are no dummies to eliminate, then just copy the pointers. */
643 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
644 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
645 key = other_entry->key;
646 if (key != NULL) {
647 assert(so_entry->key == NULL);
648 Py_INCREF(key);
649 so_entry->key = key;
650 so_entry->hash = other_entry->hash;
651 }
652 }
653 so->fill = other->fill;
654 so->used = other->used;
655 return 0;
656 }
657
658 /* If our table is empty, we can use set_insert_clean() */
659 if (so->fill == 0) {
660 for (i = 0; i <= other->mask; i++, other_entry++) {
661 key = other_entry->key;
662 if (key != NULL && key != dummy) {
663 Py_INCREF(key);
664 set_insert_clean(so, key, other_entry->hash);
665 }
666 }
667 return 0;
668 }
669
670 /* We can't assure there are no duplicates, so do normal insertions */
671 for (i = 0; i <= other->mask; i++, other_entry++) {
672 key = other_entry->key;
673 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700674 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000675 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 }
677 }
678 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000679}
680
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000681static PyObject *
682set_pop(PySetObject *so)
683{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800684 /* Make sure the search finger is in bounds */
685 Py_ssize_t i = so->finger & so->mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200686 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000687 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000688
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000689 assert (PyAnySet_Check(so));
690 if (so->used == 0) {
691 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
692 return NULL;
693 }
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000694
Raymond Hettinger1202a472015-01-18 13:12:42 -0800695 while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
696 i++;
Raymond Hettingered741d42015-01-18 21:25:15 -0800697 if (i > so->mask)
698 i = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000699 }
700 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000701 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800702 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000703 so->used--;
Raymond Hettinger1202a472015-01-18 13:12:42 -0800704 so->finger = i + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000705 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000706}
707
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000708PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
709Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000710
711static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000712set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000713{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000714 Py_ssize_t pos = 0;
715 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000716
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 while (set_next(so, &pos, &entry))
718 Py_VISIT(entry->key);
719 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000720}
721
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000722static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000723frozenset_hash(PyObject *self)
724{
Raymond Hettinger74fc8c42014-01-05 12:00:31 -0800725 /* Most of the constants in this hash algorithm are randomly choosen
726 large primes with "interesting bit patterns" and that passed
727 tests for good collision statistics on a variety of problematic
728 datasets such as:
729
730 ps = []
731 for r in range(21):
732 ps += itertools.combinations(range(20), r)
733 num_distinct_hashes = len({hash(frozenset(s)) for s in ps})
734
735 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000736 PySetObject *so = (PySetObject *)self;
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800737 Py_uhash_t h, hash = 1927868237UL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 setentry *entry;
739 Py_ssize_t pos = 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000740
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000741 if (so->hash != -1)
742 return so->hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000743
Mark Dickinson57e683e2011-09-24 18:18:40 +0100744 hash *= (Py_uhash_t)PySet_GET_SIZE(self) + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000745 while (set_next(so, &pos, &entry)) {
746 /* Work to increase the bit dispersion for closely spaced hash
Raymond Hettinger06a1c8d2015-01-30 18:02:15 -0800747 values. This is important because some use cases have many
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000748 combinations of a small number of elements with nearby
749 hashes so that many distinct combinations collapse to only
750 a handful of distinct hash values. */
Antoine Pitroufbb1c612010-10-23 17:37:54 +0000751 h = entry->hash;
Raymond Hettinger74fc8c42014-01-05 12:00:31 -0800752 hash ^= ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000753 }
Raymond Hettinger74fc8c42014-01-05 12:00:31 -0800754 /* Make the final result spread-out in a different pattern
Eric V. Smith6ba56652014-01-14 08:15:03 -0500755 than the algorithm for tuples or other python objects. */
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800756 hash = hash * 69069U + 907133923UL;
Victor Stinner12174a52014-08-15 23:17:38 +0200757 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800758 hash = 590923713UL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759 so->hash = hash;
760 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000761}
762
Raymond Hettingera9d99362005-08-05 00:01:15 +0000763/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000764
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000765typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000766 PyObject_HEAD
767 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
768 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700769 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000770 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000771} setiterobject;
772
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000773static void
774setiter_dealloc(setiterobject *si)
775{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000776 Py_XDECREF(si->si_set);
777 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000778}
779
780static int
781setiter_traverse(setiterobject *si, visitproc visit, void *arg)
782{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000783 Py_VISIT(si->si_set);
784 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000785}
786
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000787static PyObject *
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000788setiter_len(setiterobject *si)
789{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000790 Py_ssize_t len = 0;
791 if (si->si_set != NULL && si->si_used == si->si_set->used)
792 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000793 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000794}
795
Armin Rigof5b3e362006-02-11 21:32:43 +0000796PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000797
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000798static PyObject *setiter_iternext(setiterobject *si);
799
800static PyObject *
801setiter_reduce(setiterobject *si)
802{
803 PyObject *list;
804 setiterobject tmp;
805
806 list = PyList_New(0);
807 if (!list)
808 return NULL;
809
Ezio Melotti0e1af282012-09-28 16:43:40 +0300810 /* copy the iterator state */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000811 tmp = *si;
812 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300813
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000814 /* iterate the temporary into a list */
815 for(;;) {
816 PyObject *element = setiter_iternext(&tmp);
817 if (element) {
818 if (PyList_Append(list, element)) {
819 Py_DECREF(element);
820 Py_DECREF(list);
821 Py_XDECREF(tmp.si_set);
822 return NULL;
823 }
824 Py_DECREF(element);
825 } else
826 break;
827 }
828 Py_XDECREF(tmp.si_set);
829 /* check for error */
830 if (tmp.si_set != NULL) {
831 /* we have an error */
832 Py_DECREF(list);
833 return NULL;
834 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200835 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000836}
837
838PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
839
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000840static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000842 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000843 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000844};
845
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000846static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000847{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700848 PyObject *key;
849 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200850 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000851 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000853 if (so == NULL)
854 return NULL;
855 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000856
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 if (si->si_used != so->used) {
858 PyErr_SetString(PyExc_RuntimeError,
859 "Set changed size during iteration");
860 si->si_used = -1; /* Make this state sticky */
861 return NULL;
862 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700863
864 i = si->si_pos;
865 assert(i>=0);
866 entry = so->table;
867 mask = so->mask;
868 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
869 i++;
870 si->si_pos = i+1;
871 if (i > mask)
872 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000873 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700874 key = entry[i].key;
875 Py_INCREF(key);
876 return key;
877
878fail:
879 Py_DECREF(so);
880 si->si_set = NULL;
881 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000882}
883
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000884PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000885 PyVarObject_HEAD_INIT(&PyType_Type, 0)
886 "set_iterator", /* tp_name */
887 sizeof(setiterobject), /* tp_basicsize */
888 0, /* tp_itemsize */
889 /* methods */
890 (destructor)setiter_dealloc, /* tp_dealloc */
891 0, /* tp_print */
892 0, /* tp_getattr */
893 0, /* tp_setattr */
894 0, /* tp_reserved */
895 0, /* tp_repr */
896 0, /* tp_as_number */
897 0, /* tp_as_sequence */
898 0, /* tp_as_mapping */
899 0, /* tp_hash */
900 0, /* tp_call */
901 0, /* tp_str */
902 PyObject_GenericGetAttr, /* tp_getattro */
903 0, /* tp_setattro */
904 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700905 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000906 0, /* tp_doc */
907 (traverseproc)setiter_traverse, /* tp_traverse */
908 0, /* tp_clear */
909 0, /* tp_richcompare */
910 0, /* tp_weaklistoffset */
911 PyObject_SelfIter, /* tp_iter */
912 (iternextfunc)setiter_iternext, /* tp_iternext */
913 setiter_methods, /* tp_methods */
914 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000915};
916
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000917static PyObject *
918set_iter(PySetObject *so)
919{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000920 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
921 if (si == NULL)
922 return NULL;
923 Py_INCREF(so);
924 si->si_set = so;
925 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700926 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000927 si->len = so->used;
928 _PyObject_GC_TRACK(si);
929 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000930}
931
Raymond Hettingerd7946662005-08-01 21:39:29 +0000932static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000933set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000934{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000935 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000937 if (PyAnySet_Check(other))
938 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000940 if (PyDict_CheckExact(other)) {
941 PyObject *value;
942 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000943 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000944 Py_ssize_t dictsize = PyDict_Size(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000945
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000946 /* Do one big resize at the start, rather than
947 * incrementally resizing as we insert new keys. Expect
948 * that there will be no (or few) overlapping keys.
949 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700950 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 return -1;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700952 if ((so->fill + dictsize)*3 >= so->mask*2) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700953 if (set_table_resize(so, so->used + dictsize) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 return -1;
955 }
956 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700957 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000958 return -1;
959 }
960 return 0;
961 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 it = PyObject_GetIter(other);
964 if (it == NULL)
965 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +0000966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700968 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 Py_DECREF(it);
970 Py_DECREF(key);
971 return -1;
972 }
973 Py_DECREF(key);
974 }
975 Py_DECREF(it);
976 if (PyErr_Occurred())
977 return -1;
978 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000979}
980
981static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000982set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +0000983{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000985
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000986 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
987 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700988 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 return NULL;
990 }
991 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +0000992}
993
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000994PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000995"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +0000996
Raymond Hettinger426d9952014-05-18 21:40:20 +0100997/* XXX Todo:
998 If aligned memory allocations become available, make the
999 set object 64 byte aligned so that most of the fields
1000 can be retrieved or updated in a single cache line.
1001*/
1002
Raymond Hettingera38123e2003-11-24 22:18:49 +00001003static PyObject *
1004make_new_set(PyTypeObject *type, PyObject *iterable)
1005{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001006 PySetObject *so = NULL;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 /* create PySetObject structure */
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001009 so = (PySetObject *)type->tp_alloc(type, 0);
1010 if (so == NULL)
1011 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001012
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001013 so->fill = 0;
1014 so->used = 0;
1015 so->mask = PySet_MINSIZE - 1;
1016 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001017 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001018 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001019 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001020
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001021 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001022 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 Py_DECREF(so);
1024 return NULL;
1025 }
1026 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001029}
1030
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001031static PyObject *
1032make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1033{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1035 if (PyType_IsSubtype(type, &PySet_Type))
1036 type = &PySet_Type;
1037 else
1038 type = &PyFrozenSet_Type;
1039 }
1040 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001041}
1042
Raymond Hettingerd7946662005-08-01 21:39:29 +00001043/* The empty frozenset is a singleton */
1044static PyObject *emptyfrozenset = NULL;
1045
Raymond Hettingera690a992003-11-16 16:17:49 +00001046static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001047frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001048{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001050
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001051 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset()", kwds))
1052 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001053
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1055 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001056
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001057 if (type != &PyFrozenSet_Type)
1058 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001059
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 if (iterable != NULL) {
1061 /* frozenset(f) is idempotent */
1062 if (PyFrozenSet_CheckExact(iterable)) {
1063 Py_INCREF(iterable);
1064 return iterable;
1065 }
1066 result = make_new_set(type, iterable);
1067 if (result == NULL || PySet_GET_SIZE(result))
1068 return result;
1069 Py_DECREF(result);
1070 }
1071 /* The empty frozenset is a singleton */
1072 if (emptyfrozenset == NULL)
1073 emptyfrozenset = make_new_set(type, NULL);
1074 Py_XINCREF(emptyfrozenset);
1075 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001076}
1077
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001078int
1079PySet_ClearFreeList(void)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001080{
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001081 return 0;
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001082}
1083
1084void
1085PySet_Fini(void)
1086{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 Py_CLEAR(emptyfrozenset);
Raymond Hettingera690a992003-11-16 16:17:49 +00001088}
1089
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001090static PyObject *
1091set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1092{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001093 if (type == &PySet_Type && !_PyArg_NoKeywords("set()", kwds))
1094 return NULL;
1095
1096 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001097}
1098
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001099/* set_swap_bodies() switches the contents of any two sets by moving their
1100 internal data pointers and, if needed, copying the internal smalltables.
1101 Semantically equivalent to:
1102
1103 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1104
1105 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001106 Useful for operations that update in-place (by allowing an intermediate
1107 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001108*/
1109
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001110static void
1111set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001112{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001113 Py_ssize_t t;
1114 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001115 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001116 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118 t = a->fill; a->fill = b->fill; b->fill = t;
1119 t = a->used; a->used = b->used; b->used = t;
1120 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122 u = a->table;
1123 if (a->table == a->smalltable)
1124 u = b->smalltable;
1125 a->table = b->table;
1126 if (b->table == b->smalltable)
1127 a->table = a->smalltable;
1128 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001130 if (a->table == a->smalltable || b->table == b->smalltable) {
1131 memcpy(tab, a->smalltable, sizeof(tab));
1132 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1133 memcpy(b->smalltable, tab, sizeof(tab));
1134 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1137 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1138 h = a->hash; a->hash = b->hash; b->hash = h;
1139 } else {
1140 a->hash = -1;
1141 b->hash = -1;
1142 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001143}
1144
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001145static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001146set_copy(PySetObject *so)
1147{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001148 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001149}
1150
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001151static PyObject *
1152frozenset_copy(PySetObject *so)
1153{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001154 if (PyFrozenSet_CheckExact(so)) {
1155 Py_INCREF(so);
1156 return (PyObject *)so;
1157 }
1158 return set_copy(so);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001159}
1160
Raymond Hettingera690a992003-11-16 16:17:49 +00001161PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1162
1163static PyObject *
Raymond Hettingerc991db22005-08-11 07:58:45 +00001164set_clear(PySetObject *so)
1165{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001166 set_clear_internal(so);
1167 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001168}
1169
1170PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1171
1172static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001173set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 PySetObject *result;
1176 PyObject *other;
1177 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001178
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001179 result = (PySetObject *)set_copy(so);
1180 if (result == NULL)
1181 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001182
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001183 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1184 other = PyTuple_GET_ITEM(args, i);
1185 if ((PyObject *)so == other)
1186 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001187 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001188 Py_DECREF(result);
1189 return NULL;
1190 }
1191 }
1192 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001193}
1194
1195PyDoc_STRVAR(union_doc,
1196 "Return the union of sets as a new set.\n\
1197\n\
1198(i.e. all elements that are in either set.)");
1199
1200static PyObject *
1201set_or(PySetObject *so, PyObject *other)
1202{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001203 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001204
Brian Curtindfc80e32011-08-10 20:28:54 -05001205 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1206 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001208 result = (PySetObject *)set_copy(so);
1209 if (result == NULL)
1210 return NULL;
1211 if ((PyObject *)so == other)
1212 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001213 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001214 Py_DECREF(result);
1215 return NULL;
1216 }
1217 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001218}
1219
Raymond Hettingera690a992003-11-16 16:17:49 +00001220static PyObject *
1221set_ior(PySetObject *so, PyObject *other)
1222{
Brian Curtindfc80e32011-08-10 20:28:54 -05001223 if (!PyAnySet_Check(other))
1224 Py_RETURN_NOTIMPLEMENTED;
1225
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001226 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001227 return NULL;
1228 Py_INCREF(so);
1229 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001230}
1231
1232static PyObject *
1233set_intersection(PySetObject *so, PyObject *other)
1234{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 PySetObject *result;
1236 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001237 Py_hash_t hash;
1238 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 if ((PyObject *)so == other)
1241 return set_copy(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001243 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1244 if (result == NULL)
1245 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 if (PyAnySet_Check(other)) {
1248 Py_ssize_t pos = 0;
1249 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001250
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1252 tmp = (PyObject *)so;
1253 so = (PySetObject *)other;
1254 other = tmp;
1255 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001258 key = entry->key;
1259 hash = entry->hash;
1260 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001261 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 Py_DECREF(result);
1263 return NULL;
1264 }
1265 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001266 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 Py_DECREF(result);
1268 return NULL;
1269 }
1270 }
1271 }
1272 return (PyObject *)result;
1273 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 it = PyObject_GetIter(other);
1276 if (it == NULL) {
1277 Py_DECREF(result);
1278 return NULL;
1279 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001282 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001283 if (hash == -1)
1284 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001285 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001286 if (rv < 0)
1287 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001289 if (set_add_entry(result, key, hash))
1290 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 }
1292 Py_DECREF(key);
1293 }
1294 Py_DECREF(it);
1295 if (PyErr_Occurred()) {
1296 Py_DECREF(result);
1297 return NULL;
1298 }
1299 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001300 error:
1301 Py_DECREF(it);
1302 Py_DECREF(result);
1303 Py_DECREF(key);
1304 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001305}
1306
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001307static PyObject *
1308set_intersection_multi(PySetObject *so, PyObject *args)
1309{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001310 Py_ssize_t i;
1311 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 if (PyTuple_GET_SIZE(args) == 0)
1314 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 Py_INCREF(so);
1317 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1318 PyObject *other = PyTuple_GET_ITEM(args, i);
1319 PyObject *newresult = set_intersection((PySetObject *)result, other);
1320 if (newresult == NULL) {
1321 Py_DECREF(result);
1322 return NULL;
1323 }
1324 Py_DECREF(result);
1325 result = newresult;
1326 }
1327 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001328}
1329
Raymond Hettingera690a992003-11-16 16:17:49 +00001330PyDoc_STRVAR(intersection_doc,
1331"Return the intersection of two sets as a new set.\n\
1332\n\
1333(i.e. all elements that are in both sets.)");
1334
1335static PyObject *
1336set_intersection_update(PySetObject *so, PyObject *other)
1337{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 tmp = set_intersection(so, other);
1341 if (tmp == NULL)
1342 return NULL;
1343 set_swap_bodies(so, (PySetObject *)tmp);
1344 Py_DECREF(tmp);
1345 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001346}
1347
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001348static PyObject *
1349set_intersection_update_multi(PySetObject *so, PyObject *args)
1350{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 tmp = set_intersection_multi(so, args);
1354 if (tmp == NULL)
1355 return NULL;
1356 set_swap_bodies(so, (PySetObject *)tmp);
1357 Py_DECREF(tmp);
1358 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001359}
1360
Raymond Hettingera690a992003-11-16 16:17:49 +00001361PyDoc_STRVAR(intersection_update_doc,
1362"Update a set with the intersection of itself and another.");
1363
1364static PyObject *
1365set_and(PySetObject *so, PyObject *other)
1366{
Brian Curtindfc80e32011-08-10 20:28:54 -05001367 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1368 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001370}
1371
1372static PyObject *
1373set_iand(PySetObject *so, PyObject *other)
1374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001376
Brian Curtindfc80e32011-08-10 20:28:54 -05001377 if (!PyAnySet_Check(other))
1378 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 result = set_intersection_update(so, other);
1380 if (result == NULL)
1381 return NULL;
1382 Py_DECREF(result);
1383 Py_INCREF(so);
1384 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001385}
1386
Guido van Rossum58da9312007-11-10 23:39:45 +00001387static PyObject *
1388set_isdisjoint(PySetObject *so, PyObject *other)
1389{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001391 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001392
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 if ((PyObject *)so == other) {
1394 if (PySet_GET_SIZE(so) == 0)
1395 Py_RETURN_TRUE;
1396 else
1397 Py_RETURN_FALSE;
1398 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001400 if (PyAnySet_CheckExact(other)) {
1401 Py_ssize_t pos = 0;
1402 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001404 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1405 tmp = (PyObject *)so;
1406 so = (PySetObject *)other;
1407 other = tmp;
1408 }
1409 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001410 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001411 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001412 return NULL;
1413 if (rv)
1414 Py_RETURN_FALSE;
1415 }
1416 Py_RETURN_TRUE;
1417 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001418
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 it = PyObject_GetIter(other);
1420 if (it == NULL)
1421 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001423 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001424 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 if (hash == -1) {
1427 Py_DECREF(key);
1428 Py_DECREF(it);
1429 return NULL;
1430 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001431 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001433 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001434 Py_DECREF(it);
1435 return NULL;
1436 }
1437 if (rv) {
1438 Py_DECREF(it);
1439 Py_RETURN_FALSE;
1440 }
1441 }
1442 Py_DECREF(it);
1443 if (PyErr_Occurred())
1444 return NULL;
1445 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001446}
1447
1448PyDoc_STRVAR(isdisjoint_doc,
1449"Return True if two sets have a null intersection.");
1450
Neal Norwitz6576bd82005-11-13 18:41:28 +00001451static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001452set_difference_update_internal(PySetObject *so, PyObject *other)
1453{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 if ((PyObject *)so == other)
1455 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 if (PyAnySet_Check(other)) {
1458 setentry *entry;
1459 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001462 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001463 return -1;
1464 } else {
1465 PyObject *key, *it;
1466 it = PyObject_GetIter(other);
1467 if (it == NULL)
1468 return -1;
1469
1470 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001471 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 Py_DECREF(it);
1473 Py_DECREF(key);
1474 return -1;
1475 }
1476 Py_DECREF(key);
1477 }
1478 Py_DECREF(it);
1479 if (PyErr_Occurred())
1480 return -1;
1481 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001482 /* If more than 1/4th are dummies, then resize them away. */
1483 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 return 0;
Raymond Hettinger48973002015-07-03 20:00:03 -07001485 return set_table_resize(so, so->used);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001486}
1487
Raymond Hettingera690a992003-11-16 16:17:49 +00001488static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001489set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001490{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001491 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001493 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1494 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001495 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 return NULL;
1497 }
1498 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001499}
1500
1501PyDoc_STRVAR(difference_update_doc,
1502"Remove all elements of another set from this set.");
1503
1504static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001505set_copy_and_difference(PySetObject *so, PyObject *other)
1506{
1507 PyObject *result;
1508
1509 result = set_copy(so);
1510 if (result == NULL)
1511 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001512 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001513 return result;
1514 Py_DECREF(result);
1515 return NULL;
1516}
1517
1518static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001519set_difference(PySetObject *so, PyObject *other)
1520{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001522 PyObject *key;
1523 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 setentry *entry;
1525 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001526 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001528 if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001529 return set_copy_and_difference(so, other);
1530 }
1531
1532 /* If len(so) much more than len(other), it's more efficient to simply copy
1533 * so and then iterate other looking for common elements. */
1534 if ((PySet_GET_SIZE(so) >> 2) > PyObject_Size(other)) {
1535 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001536 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001537
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 result = make_new_set_basetype(Py_TYPE(so), NULL);
1539 if (result == NULL)
1540 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542 if (PyDict_CheckExact(other)) {
1543 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001544 key = entry->key;
1545 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001546 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001547 if (rv < 0) {
1548 Py_DECREF(result);
1549 return NULL;
1550 }
1551 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001552 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001553 Py_DECREF(result);
1554 return NULL;
1555 }
1556 }
1557 }
1558 return result;
1559 }
1560
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001561 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001562 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001563 key = entry->key;
1564 hash = entry->hash;
1565 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001566 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001567 Py_DECREF(result);
1568 return NULL;
1569 }
1570 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001571 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 Py_DECREF(result);
1573 return NULL;
1574 }
1575 }
1576 }
1577 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001578}
1579
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001580static PyObject *
1581set_difference_multi(PySetObject *so, PyObject *args)
1582{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 Py_ssize_t i;
1584 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 if (PyTuple_GET_SIZE(args) == 0)
1587 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001588
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 other = PyTuple_GET_ITEM(args, 0);
1590 result = set_difference(so, other);
1591 if (result == NULL)
1592 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1595 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001596 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 Py_DECREF(result);
1598 return NULL;
1599 }
1600 }
1601 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001602}
1603
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001604PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001605"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001606\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001607(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001608static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001609set_sub(PySetObject *so, PyObject *other)
1610{
Brian Curtindfc80e32011-08-10 20:28:54 -05001611 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1612 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001614}
1615
1616static PyObject *
1617set_isub(PySetObject *so, PyObject *other)
1618{
Brian Curtindfc80e32011-08-10 20:28:54 -05001619 if (!PyAnySet_Check(other))
1620 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001621 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001622 return NULL;
1623 Py_INCREF(so);
1624 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001625}
1626
1627static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001628set_symmetric_difference_update(PySetObject *so, PyObject *other)
1629{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 PySetObject *otherset;
1631 PyObject *key;
1632 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001633 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001634 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001635 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001637 if ((PyObject *)so == other)
1638 return set_clear(so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001640 if (PyDict_CheckExact(other)) {
1641 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001643 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001644 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001645 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001646 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001648 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001649 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001650 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001651 Py_DECREF(key);
1652 return NULL;
1653 }
1654 }
Georg Brandl2d444492010-09-03 10:52:55 +00001655 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 }
1657 Py_RETURN_NONE;
1658 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 if (PyAnySet_Check(other)) {
1661 Py_INCREF(other);
1662 otherset = (PySetObject *)other;
1663 } else {
1664 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1665 if (otherset == NULL)
1666 return NULL;
1667 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001668
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001669 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001670 key = entry->key;
1671 hash = entry->hash;
1672 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001673 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001674 Py_DECREF(otherset);
1675 return NULL;
1676 }
1677 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001678 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001679 Py_DECREF(otherset);
1680 return NULL;
1681 }
1682 }
1683 }
1684 Py_DECREF(otherset);
1685 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001686}
1687
1688PyDoc_STRVAR(symmetric_difference_update_doc,
1689"Update a set with the symmetric difference of itself and another.");
1690
1691static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001692set_symmetric_difference(PySetObject *so, PyObject *other)
1693{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001694 PyObject *rv;
1695 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001696
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001697 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1698 if (otherset == NULL)
1699 return NULL;
1700 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
1701 if (rv == NULL)
1702 return NULL;
1703 Py_DECREF(rv);
1704 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001705}
1706
1707PyDoc_STRVAR(symmetric_difference_doc,
1708"Return the symmetric difference of two sets as a new set.\n\
1709\n\
1710(i.e. all elements that are in exactly one of the sets.)");
1711
1712static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001713set_xor(PySetObject *so, PyObject *other)
1714{
Brian Curtindfc80e32011-08-10 20:28:54 -05001715 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1716 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001717 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001718}
1719
1720static PyObject *
1721set_ixor(PySetObject *so, PyObject *other)
1722{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001723 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001724
Brian Curtindfc80e32011-08-10 20:28:54 -05001725 if (!PyAnySet_Check(other))
1726 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001727 result = set_symmetric_difference_update(so, other);
1728 if (result == NULL)
1729 return NULL;
1730 Py_DECREF(result);
1731 Py_INCREF(so);
1732 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001733}
1734
1735static PyObject *
1736set_issubset(PySetObject *so, PyObject *other)
1737{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001738 setentry *entry;
1739 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001740 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001741
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001742 if (!PyAnySet_Check(other)) {
1743 PyObject *tmp, *result;
1744 tmp = make_new_set(&PySet_Type, other);
1745 if (tmp == NULL)
1746 return NULL;
1747 result = set_issubset(so, tmp);
1748 Py_DECREF(tmp);
1749 return result;
1750 }
1751 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1752 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001753
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001754 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001755 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001756 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001757 return NULL;
1758 if (!rv)
1759 Py_RETURN_FALSE;
1760 }
1761 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001762}
1763
1764PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1765
1766static PyObject *
1767set_issuperset(PySetObject *so, PyObject *other)
1768{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001769 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001770
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001771 if (!PyAnySet_Check(other)) {
1772 tmp = make_new_set(&PySet_Type, other);
1773 if (tmp == NULL)
1774 return NULL;
1775 result = set_issuperset(so, tmp);
1776 Py_DECREF(tmp);
1777 return result;
1778 }
1779 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001780}
1781
1782PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1783
Raymond Hettingera690a992003-11-16 16:17:49 +00001784static PyObject *
1785set_richcompare(PySetObject *v, PyObject *w, int op)
1786{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001787 PyObject *r1;
1788 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001789
Brian Curtindfc80e32011-08-10 20:28:54 -05001790 if(!PyAnySet_Check(w))
1791 Py_RETURN_NOTIMPLEMENTED;
1792
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001793 switch (op) {
1794 case Py_EQ:
1795 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1796 Py_RETURN_FALSE;
1797 if (v->hash != -1 &&
1798 ((PySetObject *)w)->hash != -1 &&
1799 v->hash != ((PySetObject *)w)->hash)
1800 Py_RETURN_FALSE;
1801 return set_issubset(v, w);
1802 case Py_NE:
1803 r1 = set_richcompare(v, w, Py_EQ);
1804 if (r1 == NULL)
1805 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001806 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001807 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001808 if (r2 < 0)
1809 return NULL;
1810 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001811 case Py_LE:
1812 return set_issubset(v, w);
1813 case Py_GE:
1814 return set_issuperset(v, w);
1815 case Py_LT:
1816 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1817 Py_RETURN_FALSE;
1818 return set_issubset(v, w);
1819 case Py_GT:
1820 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1821 Py_RETURN_FALSE;
1822 return set_issuperset(v, w);
1823 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001824 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001825}
1826
Raymond Hettingera690a992003-11-16 16:17:49 +00001827static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001828set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001829{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001830 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001831 return NULL;
1832 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001833}
1834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001836"Add an element to a set.\n\
1837\n\
1838This has no effect if the element is already present.");
1839
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001840static int
1841set_contains(PySetObject *so, PyObject *key)
1842{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001843 PyObject *tmpkey;
1844 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001845
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001846 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001847 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1849 return -1;
1850 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001851 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 if (tmpkey == NULL)
1853 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001854 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855 Py_DECREF(tmpkey);
1856 }
1857 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001858}
1859
1860static PyObject *
1861set_direct_contains(PySetObject *so, PyObject *key)
1862{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001866 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 return NULL;
1868 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001869}
1870
1871PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1872
Raymond Hettingera690a992003-11-16 16:17:49 +00001873static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001874set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001875{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 PyObject *tmpkey;
1877 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001878
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001879 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001880 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1882 return NULL;
1883 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001884 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 if (tmpkey == NULL)
1886 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001889 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 return NULL;
1891 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001892
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001894 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 return NULL;
1896 }
1897 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001898}
1899
1900PyDoc_STRVAR(remove_doc,
1901"Remove an element from a set; it must be a member.\n\
1902\n\
1903If the element is not a member, raise a KeyError.");
1904
1905static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001906set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001907{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001908 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001912 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001913 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1914 return NULL;
1915 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001916 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001917 if (tmpkey == NULL)
1918 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001919 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001920 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001921 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001922 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923 }
1924 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001925}
1926
1927PyDoc_STRVAR(discard_doc,
1928"Remove an element from a set if it is a member.\n\
1929\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001931
1932static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001933set_reduce(PySetObject *so)
1934{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001935 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001936 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 keys = PySequence_List((PyObject *)so);
1939 if (keys == NULL)
1940 goto done;
1941 args = PyTuple_Pack(1, keys);
1942 if (args == NULL)
1943 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001944 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001945 if (dict == NULL) {
1946 PyErr_Clear();
1947 dict = Py_None;
1948 Py_INCREF(dict);
1949 }
1950 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001951done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 Py_XDECREF(args);
1953 Py_XDECREF(keys);
1954 Py_XDECREF(dict);
1955 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001956}
1957
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001958static PyObject *
1959set_sizeof(PySetObject *so)
1960{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001961 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001963 res = sizeof(PySetObject);
1964 if (so->table != so->smalltable)
1965 res = res + (so->mask + 1) * sizeof(setentry);
1966 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001967}
1968
1969PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001970static int
1971set_init(PySetObject *self, PyObject *args, PyObject *kwds)
1972{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001975 if (!PyAnySet_Check(self))
1976 return -1;
1977 if (PySet_Check(self) && !_PyArg_NoKeywords("set()", kwds))
1978 return -1;
1979 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
1980 return -1;
1981 set_clear_internal(self);
1982 self->hash = -1;
1983 if (iterable == NULL)
1984 return 0;
1985 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001986}
1987
Raymond Hettingera690a992003-11-16 16:17:49 +00001988static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001989 set_len, /* sq_length */
1990 0, /* sq_concat */
1991 0, /* sq_repeat */
1992 0, /* sq_item */
1993 0, /* sq_slice */
1994 0, /* sq_ass_item */
1995 0, /* sq_ass_slice */
1996 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00001997};
1998
1999/* set object ********************************************************/
2000
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002001#ifdef Py_DEBUG
2002static PyObject *test_c_api(PySetObject *so);
2003
2004PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2005All is well if assertions don't fail.");
2006#endif
2007
Raymond Hettingera690a992003-11-16 16:17:49 +00002008static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002009 {"add", (PyCFunction)set_add, METH_O,
2010 add_doc},
2011 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2012 clear_doc},
2013 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2014 contains_doc},
2015 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2016 copy_doc},
2017 {"discard", (PyCFunction)set_discard, METH_O,
2018 discard_doc},
2019 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2020 difference_doc},
2021 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2022 difference_update_doc},
2023 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2024 intersection_doc},
2025 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2026 intersection_update_doc},
2027 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2028 isdisjoint_doc},
2029 {"issubset", (PyCFunction)set_issubset, METH_O,
2030 issubset_doc},
2031 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2032 issuperset_doc},
2033 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2034 pop_doc},
2035 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2036 reduce_doc},
2037 {"remove", (PyCFunction)set_remove, METH_O,
2038 remove_doc},
2039 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2040 sizeof_doc},
2041 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2042 symmetric_difference_doc},
2043 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2044 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002045#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002046 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2047 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002048#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002049 {"union", (PyCFunction)set_union, METH_VARARGS,
2050 union_doc},
2051 {"update", (PyCFunction)set_update, METH_VARARGS,
2052 update_doc},
2053 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002054};
2055
2056static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002057 0, /*nb_add*/
2058 (binaryfunc)set_sub, /*nb_subtract*/
2059 0, /*nb_multiply*/
2060 0, /*nb_remainder*/
2061 0, /*nb_divmod*/
2062 0, /*nb_power*/
2063 0, /*nb_negative*/
2064 0, /*nb_positive*/
2065 0, /*nb_absolute*/
2066 0, /*nb_bool*/
2067 0, /*nb_invert*/
2068 0, /*nb_lshift*/
2069 0, /*nb_rshift*/
2070 (binaryfunc)set_and, /*nb_and*/
2071 (binaryfunc)set_xor, /*nb_xor*/
2072 (binaryfunc)set_or, /*nb_or*/
2073 0, /*nb_int*/
2074 0, /*nb_reserved*/
2075 0, /*nb_float*/
2076 0, /*nb_inplace_add*/
2077 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2078 0, /*nb_inplace_multiply*/
2079 0, /*nb_inplace_remainder*/
2080 0, /*nb_inplace_power*/
2081 0, /*nb_inplace_lshift*/
2082 0, /*nb_inplace_rshift*/
2083 (binaryfunc)set_iand, /*nb_inplace_and*/
2084 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2085 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002086};
2087
2088PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002089"set() -> new empty set object\n\
2090set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002091\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002092Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002093
2094PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002095 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2096 "set", /* tp_name */
2097 sizeof(PySetObject), /* tp_basicsize */
2098 0, /* tp_itemsize */
2099 /* methods */
2100 (destructor)set_dealloc, /* tp_dealloc */
2101 0, /* tp_print */
2102 0, /* tp_getattr */
2103 0, /* tp_setattr */
2104 0, /* tp_reserved */
2105 (reprfunc)set_repr, /* tp_repr */
2106 &set_as_number, /* tp_as_number */
2107 &set_as_sequence, /* tp_as_sequence */
2108 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002109 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002110 0, /* tp_call */
2111 0, /* tp_str */
2112 PyObject_GenericGetAttr, /* tp_getattro */
2113 0, /* tp_setattro */
2114 0, /* tp_as_buffer */
2115 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2116 Py_TPFLAGS_BASETYPE, /* tp_flags */
2117 set_doc, /* tp_doc */
2118 (traverseproc)set_traverse, /* tp_traverse */
2119 (inquiry)set_clear_internal, /* tp_clear */
2120 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002121 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2122 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 0, /* tp_iternext */
2124 set_methods, /* tp_methods */
2125 0, /* tp_members */
2126 0, /* tp_getset */
2127 0, /* tp_base */
2128 0, /* tp_dict */
2129 0, /* tp_descr_get */
2130 0, /* tp_descr_set */
2131 0, /* tp_dictoffset */
2132 (initproc)set_init, /* tp_init */
2133 PyType_GenericAlloc, /* tp_alloc */
2134 set_new, /* tp_new */
2135 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002136};
2137
2138/* frozenset object ********************************************************/
2139
2140
2141static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002142 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2143 contains_doc},
2144 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2145 copy_doc},
2146 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2147 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002148 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002149 intersection_doc},
2150 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2151 isdisjoint_doc},
2152 {"issubset", (PyCFunction)set_issubset, METH_O,
2153 issubset_doc},
2154 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2155 issuperset_doc},
2156 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2157 reduce_doc},
2158 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2159 sizeof_doc},
2160 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2161 symmetric_difference_doc},
2162 {"union", (PyCFunction)set_union, METH_VARARGS,
2163 union_doc},
2164 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002165};
2166
2167static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002168 0, /*nb_add*/
2169 (binaryfunc)set_sub, /*nb_subtract*/
2170 0, /*nb_multiply*/
2171 0, /*nb_remainder*/
2172 0, /*nb_divmod*/
2173 0, /*nb_power*/
2174 0, /*nb_negative*/
2175 0, /*nb_positive*/
2176 0, /*nb_absolute*/
2177 0, /*nb_bool*/
2178 0, /*nb_invert*/
2179 0, /*nb_lshift*/
2180 0, /*nb_rshift*/
2181 (binaryfunc)set_and, /*nb_and*/
2182 (binaryfunc)set_xor, /*nb_xor*/
2183 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002184};
2185
2186PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002187"frozenset() -> empty frozenset object\n\
2188frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002189\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002190Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002191
2192PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002193 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2194 "frozenset", /* tp_name */
2195 sizeof(PySetObject), /* tp_basicsize */
2196 0, /* tp_itemsize */
2197 /* methods */
2198 (destructor)set_dealloc, /* tp_dealloc */
2199 0, /* tp_print */
2200 0, /* tp_getattr */
2201 0, /* tp_setattr */
2202 0, /* tp_reserved */
2203 (reprfunc)set_repr, /* tp_repr */
2204 &frozenset_as_number, /* tp_as_number */
2205 &set_as_sequence, /* tp_as_sequence */
2206 0, /* tp_as_mapping */
2207 frozenset_hash, /* tp_hash */
2208 0, /* tp_call */
2209 0, /* tp_str */
2210 PyObject_GenericGetAttr, /* tp_getattro */
2211 0, /* tp_setattro */
2212 0, /* tp_as_buffer */
2213 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2214 Py_TPFLAGS_BASETYPE, /* tp_flags */
2215 frozenset_doc, /* tp_doc */
2216 (traverseproc)set_traverse, /* tp_traverse */
2217 (inquiry)set_clear_internal, /* tp_clear */
2218 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002219 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002220 (getiterfunc)set_iter, /* tp_iter */
2221 0, /* tp_iternext */
2222 frozenset_methods, /* tp_methods */
2223 0, /* tp_members */
2224 0, /* tp_getset */
2225 0, /* tp_base */
2226 0, /* tp_dict */
2227 0, /* tp_descr_get */
2228 0, /* tp_descr_set */
2229 0, /* tp_dictoffset */
2230 0, /* tp_init */
2231 PyType_GenericAlloc, /* tp_alloc */
2232 frozenset_new, /* tp_new */
2233 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002234};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002235
2236
2237/***** C API functions *************************************************/
2238
2239PyObject *
2240PySet_New(PyObject *iterable)
2241{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002242 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002243}
2244
2245PyObject *
2246PyFrozenSet_New(PyObject *iterable)
2247{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002248 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002249}
2250
Neal Norwitz8c49c822006-03-04 18:41:19 +00002251Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002252PySet_Size(PyObject *anyset)
2253{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002254 if (!PyAnySet_Check(anyset)) {
2255 PyErr_BadInternalCall();
2256 return -1;
2257 }
2258 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002259}
2260
2261int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002262PySet_Clear(PyObject *set)
2263{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002264 if (!PySet_Check(set)) {
2265 PyErr_BadInternalCall();
2266 return -1;
2267 }
2268 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002269}
2270
2271int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002272PySet_Contains(PyObject *anyset, PyObject *key)
2273{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002274 if (!PyAnySet_Check(anyset)) {
2275 PyErr_BadInternalCall();
2276 return -1;
2277 }
2278 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002279}
2280
2281int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002282PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002283{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002284 if (!PySet_Check(set)) {
2285 PyErr_BadInternalCall();
2286 return -1;
2287 }
2288 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002289}
2290
2291int
Christian Heimesfd66e512008-01-29 12:18:50 +00002292PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002293{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002294 if (!PySet_Check(anyset) &&
2295 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2296 PyErr_BadInternalCall();
2297 return -1;
2298 }
2299 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002300}
2301
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002302int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002303_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002304{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002305 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002307 if (!PyAnySet_Check(set)) {
2308 PyErr_BadInternalCall();
2309 return -1;
2310 }
2311 if (set_next((PySetObject *)set, pos, &entry) == 0)
2312 return 0;
2313 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002314 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002315 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002316}
2317
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002318PyObject *
2319PySet_Pop(PyObject *set)
2320{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002321 if (!PySet_Check(set)) {
2322 PyErr_BadInternalCall();
2323 return NULL;
2324 }
2325 return set_pop((PySetObject *)set);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002326}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002327
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002328int
2329_PySet_Update(PyObject *set, PyObject *iterable)
2330{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002331 if (!PySet_Check(set)) {
2332 PyErr_BadInternalCall();
2333 return -1;
2334 }
2335 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002336}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002337
Raymond Hettingere259f132013-12-15 11:56:14 -08002338/* Exported for the gdb plugin's benefit. */
2339PyObject *_PySet_Dummy = dummy;
2340
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002341#ifdef Py_DEBUG
2342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002343/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002344 Returns True and original set is restored. */
2345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002346#define assertRaises(call_return_value, exception) \
2347 do { \
2348 assert(call_return_value); \
2349 assert(PyErr_ExceptionMatches(exception)); \
2350 PyErr_Clear(); \
2351 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002352
2353static PyObject *
2354test_c_api(PySetObject *so)
2355{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002356 Py_ssize_t count;
2357 char *s;
2358 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002359 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002360 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002361 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002362 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002364 /* Verify preconditions */
2365 assert(PyAnySet_Check(ob));
2366 assert(PyAnySet_CheckExact(ob));
2367 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002369 /* so.clear(); so |= set("abc"); */
2370 str = PyUnicode_FromString("abc");
2371 if (str == NULL)
2372 return NULL;
2373 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002374 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002375 Py_DECREF(str);
2376 return NULL;
2377 }
2378 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002379
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002380 /* Exercise type/size checks */
2381 assert(PySet_Size(ob) == 3);
2382 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002384 /* Raise TypeError for non-iterable constructor arguments */
2385 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2386 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002388 /* Raise TypeError for unhashable key */
2389 dup = PySet_New(ob);
2390 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2391 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2392 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002394 /* Exercise successful pop, contains, add, and discard */
2395 elem = PySet_Pop(ob);
2396 assert(PySet_Contains(ob, elem) == 0);
2397 assert(PySet_GET_SIZE(ob) == 2);
2398 assert(PySet_Add(ob, elem) == 0);
2399 assert(PySet_Contains(ob, elem) == 1);
2400 assert(PySet_GET_SIZE(ob) == 3);
2401 assert(PySet_Discard(ob, elem) == 1);
2402 assert(PySet_GET_SIZE(ob) == 2);
2403 assert(PySet_Discard(ob, elem) == 0);
2404 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002406 /* Exercise clear */
2407 dup2 = PySet_New(dup);
2408 assert(PySet_Clear(dup2) == 0);
2409 assert(PySet_Size(dup2) == 0);
2410 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002412 /* Raise SystemError on clear or update of frozen set */
2413 f = PyFrozenSet_New(dup);
2414 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2415 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2416 assert(PySet_Add(f, elem) == 0);
2417 Py_INCREF(f);
2418 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2419 Py_DECREF(f);
2420 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002422 /* Exercise direct iteration */
2423 i = 0, count = 0;
2424 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
2425 s = _PyUnicode_AsString(x);
2426 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2427 count++;
2428 }
2429 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002431 /* Exercise updates */
2432 dup2 = PySet_New(NULL);
2433 assert(_PySet_Update(dup2, dup) == 0);
2434 assert(PySet_Size(dup2) == 3);
2435 assert(_PySet_Update(dup2, dup) == 0);
2436 assert(PySet_Size(dup2) == 3);
2437 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002439 /* Raise SystemError when self argument is not a set or frozenset. */
2440 t = PyTuple_New(0);
2441 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2442 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2443 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002444
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002445 /* Raise SystemError when self argument is not a set. */
2446 f = PyFrozenSet_New(dup);
2447 assert(PySet_Size(f) == 3);
2448 assert(PyFrozenSet_CheckExact(f));
2449 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2450 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2451 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002453 /* Raise KeyError when popping from an empty set */
2454 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2455 Py_DECREF(ob);
2456 assert(PySet_GET_SIZE(ob) == 0);
2457 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002458
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002459 /* Restore the set from the copy using the PyNumber API */
2460 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2461 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002462
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002463 /* Verify constructors accept NULL arguments */
2464 f = PySet_New(NULL);
2465 assert(f != NULL);
2466 assert(PySet_GET_SIZE(f) == 0);
2467 Py_DECREF(f);
2468 f = PyFrozenSet_New(NULL);
2469 assert(f != NULL);
2470 assert(PyFrozenSet_CheckExact(f));
2471 assert(PySet_GET_SIZE(f) == 0);
2472 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002474 Py_DECREF(elem);
2475 Py_DECREF(dup);
2476 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002477}
2478
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002479#undef assertRaises
2480
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002481#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002482
2483/***** Dummy Struct *************************************************/
2484
2485static PyObject *
2486dummy_repr(PyObject *op)
2487{
2488 return PyUnicode_FromString("<dummy key>");
2489}
2490
2491static void
2492dummy_dealloc(PyObject* ignore)
2493{
2494 Py_FatalError("deallocating <dummy key>");
2495}
2496
2497static PyTypeObject _PySetDummy_Type = {
2498 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2499 "<dummy key> type",
2500 0,
2501 0,
2502 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2503 0, /*tp_print*/
2504 0, /*tp_getattr*/
2505 0, /*tp_setattr*/
2506 0, /*tp_reserved*/
2507 dummy_repr, /*tp_repr*/
2508 0, /*tp_as_number*/
2509 0, /*tp_as_sequence*/
2510 0, /*tp_as_mapping*/
2511 0, /*tp_hash */
2512 0, /*tp_call */
2513 0, /*tp_str */
2514 0, /*tp_getattro */
2515 0, /*tp_setattro */
2516 0, /*tp_as_buffer */
2517 Py_TPFLAGS_DEFAULT, /*tp_flags */
2518};
2519
2520static PyObject _dummy_struct = {
2521 _PyObject_EXTRA_INIT
2522 2, &_PySetDummy_Type
2523};
2524