blob: 9753c8d22f46db0ede3a680d27d47639179418fe [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;
769 Py_ssize_t si_pos;
770 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{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000848 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200849 Py_ssize_t i, mask;
850 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 Hettinger9f1a6792005-07-31 01:16:36 +0000863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000864 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;
873 si->len--;
874 key = entry[i].key;
875 Py_INCREF(key);
876 return key;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000877
878fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000879 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 */
905 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
906 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;
926 si->si_pos = 0;
927 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);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 if (hash == -1) {
1284 Py_DECREF(it);
1285 Py_DECREF(result);
1286 Py_DECREF(key);
1287 return NULL;
1288 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001289 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001290 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 Py_DECREF(it);
1292 Py_DECREF(result);
1293 Py_DECREF(key);
1294 return NULL;
1295 }
1296 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001297 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 Py_DECREF(it);
1299 Py_DECREF(result);
1300 Py_DECREF(key);
1301 return NULL;
1302 }
1303 }
1304 Py_DECREF(key);
1305 }
1306 Py_DECREF(it);
1307 if (PyErr_Occurred()) {
1308 Py_DECREF(result);
1309 return NULL;
1310 }
1311 return (PyObject *)result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001312}
1313
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001314static PyObject *
1315set_intersection_multi(PySetObject *so, PyObject *args)
1316{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 Py_ssize_t i;
1318 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 if (PyTuple_GET_SIZE(args) == 0)
1321 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 Py_INCREF(so);
1324 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1325 PyObject *other = PyTuple_GET_ITEM(args, i);
1326 PyObject *newresult = set_intersection((PySetObject *)result, other);
1327 if (newresult == NULL) {
1328 Py_DECREF(result);
1329 return NULL;
1330 }
1331 Py_DECREF(result);
1332 result = newresult;
1333 }
1334 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001335}
1336
Raymond Hettingera690a992003-11-16 16:17:49 +00001337PyDoc_STRVAR(intersection_doc,
1338"Return the intersection of two sets as a new set.\n\
1339\n\
1340(i.e. all elements that are in both sets.)");
1341
1342static PyObject *
1343set_intersection_update(PySetObject *so, PyObject *other)
1344{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001347 tmp = set_intersection(so, other);
1348 if (tmp == NULL)
1349 return NULL;
1350 set_swap_bodies(so, (PySetObject *)tmp);
1351 Py_DECREF(tmp);
1352 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001353}
1354
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001355static PyObject *
1356set_intersection_update_multi(PySetObject *so, PyObject *args)
1357{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001360 tmp = set_intersection_multi(so, args);
1361 if (tmp == NULL)
1362 return NULL;
1363 set_swap_bodies(so, (PySetObject *)tmp);
1364 Py_DECREF(tmp);
1365 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001366}
1367
Raymond Hettingera690a992003-11-16 16:17:49 +00001368PyDoc_STRVAR(intersection_update_doc,
1369"Update a set with the intersection of itself and another.");
1370
1371static PyObject *
1372set_and(PySetObject *so, PyObject *other)
1373{
Brian Curtindfc80e32011-08-10 20:28:54 -05001374 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1375 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001377}
1378
1379static PyObject *
1380set_iand(PySetObject *so, PyObject *other)
1381{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001383
Brian Curtindfc80e32011-08-10 20:28:54 -05001384 if (!PyAnySet_Check(other))
1385 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 result = set_intersection_update(so, other);
1387 if (result == NULL)
1388 return NULL;
1389 Py_DECREF(result);
1390 Py_INCREF(so);
1391 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001392}
1393
Guido van Rossum58da9312007-11-10 23:39:45 +00001394static PyObject *
1395set_isdisjoint(PySetObject *so, PyObject *other)
1396{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001397 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001398 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001400 if ((PyObject *)so == other) {
1401 if (PySet_GET_SIZE(so) == 0)
1402 Py_RETURN_TRUE;
1403 else
1404 Py_RETURN_FALSE;
1405 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001406
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001407 if (PyAnySet_CheckExact(other)) {
1408 Py_ssize_t pos = 0;
1409 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1412 tmp = (PyObject *)so;
1413 so = (PySetObject *)other;
1414 other = tmp;
1415 }
1416 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001417 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001418 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 return NULL;
1420 if (rv)
1421 Py_RETURN_FALSE;
1422 }
1423 Py_RETURN_TRUE;
1424 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 it = PyObject_GetIter(other);
1427 if (it == NULL)
1428 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001431 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 if (hash == -1) {
1434 Py_DECREF(key);
1435 Py_DECREF(it);
1436 return NULL;
1437 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001438 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001440 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 Py_DECREF(it);
1442 return NULL;
1443 }
1444 if (rv) {
1445 Py_DECREF(it);
1446 Py_RETURN_FALSE;
1447 }
1448 }
1449 Py_DECREF(it);
1450 if (PyErr_Occurred())
1451 return NULL;
1452 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001453}
1454
1455PyDoc_STRVAR(isdisjoint_doc,
1456"Return True if two sets have a null intersection.");
1457
Neal Norwitz6576bd82005-11-13 18:41:28 +00001458static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001459set_difference_update_internal(PySetObject *so, PyObject *other)
1460{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 if ((PyObject *)so == other)
1462 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 if (PyAnySet_Check(other)) {
1465 setentry *entry;
1466 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001467
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001468 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001469 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 return -1;
1471 } else {
1472 PyObject *key, *it;
1473 it = PyObject_GetIter(other);
1474 if (it == NULL)
1475 return -1;
1476
1477 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001478 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001479 Py_DECREF(it);
1480 Py_DECREF(key);
1481 return -1;
1482 }
1483 Py_DECREF(key);
1484 }
1485 Py_DECREF(it);
1486 if (PyErr_Occurred())
1487 return -1;
1488 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001489 /* If more than 1/4th are dummies, then resize them away. */
1490 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001491 return 0;
Raymond Hettinger48973002015-07-03 20:00:03 -07001492 return set_table_resize(so, so->used);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001493}
1494
Raymond Hettingera690a992003-11-16 16:17:49 +00001495static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001496set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001497{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1501 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001502 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 return NULL;
1504 }
1505 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001506}
1507
1508PyDoc_STRVAR(difference_update_doc,
1509"Remove all elements of another set from this set.");
1510
1511static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001512set_copy_and_difference(PySetObject *so, PyObject *other)
1513{
1514 PyObject *result;
1515
1516 result = set_copy(so);
1517 if (result == NULL)
1518 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001519 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001520 return result;
1521 Py_DECREF(result);
1522 return NULL;
1523}
1524
1525static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001526set_difference(PySetObject *so, PyObject *other)
1527{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001528 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001529 PyObject *key;
1530 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 setentry *entry;
1532 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001533 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001536 return set_copy_and_difference(so, other);
1537 }
1538
1539 /* If len(so) much more than len(other), it's more efficient to simply copy
1540 * so and then iterate other looking for common elements. */
1541 if ((PySet_GET_SIZE(so) >> 2) > PyObject_Size(other)) {
1542 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 result = make_new_set_basetype(Py_TYPE(so), NULL);
1546 if (result == NULL)
1547 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001548
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 if (PyDict_CheckExact(other)) {
1550 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001551 key = entry->key;
1552 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001553 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001554 if (rv < 0) {
1555 Py_DECREF(result);
1556 return NULL;
1557 }
1558 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001559 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001560 Py_DECREF(result);
1561 return NULL;
1562 }
1563 }
1564 }
1565 return result;
1566 }
1567
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001568 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001569 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001570 key = entry->key;
1571 hash = entry->hash;
1572 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001573 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001574 Py_DECREF(result);
1575 return NULL;
1576 }
1577 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001578 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 Py_DECREF(result);
1580 return NULL;
1581 }
1582 }
1583 }
1584 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001585}
1586
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001587static PyObject *
1588set_difference_multi(PySetObject *so, PyObject *args)
1589{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001590 Py_ssize_t i;
1591 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001592
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593 if (PyTuple_GET_SIZE(args) == 0)
1594 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001595
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001596 other = PyTuple_GET_ITEM(args, 0);
1597 result = set_difference(so, other);
1598 if (result == NULL)
1599 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001600
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1602 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001603 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 Py_DECREF(result);
1605 return NULL;
1606 }
1607 }
1608 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001609}
1610
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001611PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001612"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001613\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001614(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001615static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001616set_sub(PySetObject *so, PyObject *other)
1617{
Brian Curtindfc80e32011-08-10 20:28:54 -05001618 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1619 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001621}
1622
1623static PyObject *
1624set_isub(PySetObject *so, PyObject *other)
1625{
Brian Curtindfc80e32011-08-10 20:28:54 -05001626 if (!PyAnySet_Check(other))
1627 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001628 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 return NULL;
1630 Py_INCREF(so);
1631 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001632}
1633
1634static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001635set_symmetric_difference_update(PySetObject *so, PyObject *other)
1636{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001637 PySetObject *otherset;
1638 PyObject *key;
1639 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001640 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001641 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001642 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001643
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001644 if ((PyObject *)so == other)
1645 return set_clear(so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001646
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 if (PyDict_CheckExact(other)) {
1648 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001649 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001650 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001651 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001652 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001653 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001655 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001656 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001657 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001658 Py_DECREF(key);
1659 return NULL;
1660 }
1661 }
Georg Brandl2d444492010-09-03 10:52:55 +00001662 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001663 }
1664 Py_RETURN_NONE;
1665 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001666
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001667 if (PyAnySet_Check(other)) {
1668 Py_INCREF(other);
1669 otherset = (PySetObject *)other;
1670 } else {
1671 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1672 if (otherset == NULL)
1673 return NULL;
1674 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001675
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001676 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001677 key = entry->key;
1678 hash = entry->hash;
1679 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001680 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001681 Py_DECREF(otherset);
1682 return NULL;
1683 }
1684 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001685 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001686 Py_DECREF(otherset);
1687 return NULL;
1688 }
1689 }
1690 }
1691 Py_DECREF(otherset);
1692 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001693}
1694
1695PyDoc_STRVAR(symmetric_difference_update_doc,
1696"Update a set with the symmetric difference of itself and another.");
1697
1698static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001699set_symmetric_difference(PySetObject *so, PyObject *other)
1700{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001701 PyObject *rv;
1702 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001703
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001704 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1705 if (otherset == NULL)
1706 return NULL;
1707 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
1708 if (rv == NULL)
1709 return NULL;
1710 Py_DECREF(rv);
1711 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001712}
1713
1714PyDoc_STRVAR(symmetric_difference_doc,
1715"Return the symmetric difference of two sets as a new set.\n\
1716\n\
1717(i.e. all elements that are in exactly one of the sets.)");
1718
1719static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001720set_xor(PySetObject *so, PyObject *other)
1721{
Brian Curtindfc80e32011-08-10 20:28:54 -05001722 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1723 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001724 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001725}
1726
1727static PyObject *
1728set_ixor(PySetObject *so, PyObject *other)
1729{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001730 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001731
Brian Curtindfc80e32011-08-10 20:28:54 -05001732 if (!PyAnySet_Check(other))
1733 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001734 result = set_symmetric_difference_update(so, other);
1735 if (result == NULL)
1736 return NULL;
1737 Py_DECREF(result);
1738 Py_INCREF(so);
1739 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001740}
1741
1742static PyObject *
1743set_issubset(PySetObject *so, PyObject *other)
1744{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001745 setentry *entry;
1746 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001747 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001748
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001749 if (!PyAnySet_Check(other)) {
1750 PyObject *tmp, *result;
1751 tmp = make_new_set(&PySet_Type, other);
1752 if (tmp == NULL)
1753 return NULL;
1754 result = set_issubset(so, tmp);
1755 Py_DECREF(tmp);
1756 return result;
1757 }
1758 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1759 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001762 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001763 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001764 return NULL;
1765 if (!rv)
1766 Py_RETURN_FALSE;
1767 }
1768 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001769}
1770
1771PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1772
1773static PyObject *
1774set_issuperset(PySetObject *so, PyObject *other)
1775{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001777
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001778 if (!PyAnySet_Check(other)) {
1779 tmp = make_new_set(&PySet_Type, other);
1780 if (tmp == NULL)
1781 return NULL;
1782 result = set_issuperset(so, tmp);
1783 Py_DECREF(tmp);
1784 return result;
1785 }
1786 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001787}
1788
1789PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1790
Raymond Hettingera690a992003-11-16 16:17:49 +00001791static PyObject *
1792set_richcompare(PySetObject *v, PyObject *w, int op)
1793{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001794 PyObject *r1;
1795 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001796
Brian Curtindfc80e32011-08-10 20:28:54 -05001797 if(!PyAnySet_Check(w))
1798 Py_RETURN_NOTIMPLEMENTED;
1799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001800 switch (op) {
1801 case Py_EQ:
1802 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1803 Py_RETURN_FALSE;
1804 if (v->hash != -1 &&
1805 ((PySetObject *)w)->hash != -1 &&
1806 v->hash != ((PySetObject *)w)->hash)
1807 Py_RETURN_FALSE;
1808 return set_issubset(v, w);
1809 case Py_NE:
1810 r1 = set_richcompare(v, w, Py_EQ);
1811 if (r1 == NULL)
1812 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001813 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001814 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001815 if (r2 < 0)
1816 return NULL;
1817 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001818 case Py_LE:
1819 return set_issubset(v, w);
1820 case Py_GE:
1821 return set_issuperset(v, w);
1822 case Py_LT:
1823 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1824 Py_RETURN_FALSE;
1825 return set_issubset(v, w);
1826 case Py_GT:
1827 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1828 Py_RETURN_FALSE;
1829 return set_issuperset(v, w);
1830 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001831 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001832}
1833
Raymond Hettingera690a992003-11-16 16:17:49 +00001834static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001835set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001836{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001837 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 return NULL;
1839 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001840}
1841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001842PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001843"Add an element to a set.\n\
1844\n\
1845This has no effect if the element is already present.");
1846
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001847static int
1848set_contains(PySetObject *so, PyObject *key)
1849{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 PyObject *tmpkey;
1851 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001853 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001854 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1856 return -1;
1857 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001858 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 if (tmpkey == NULL)
1860 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001861 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001862 Py_DECREF(tmpkey);
1863 }
1864 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001865}
1866
1867static PyObject *
1868set_direct_contains(PySetObject *so, PyObject *key)
1869{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001870 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001873 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001874 return NULL;
1875 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001876}
1877
1878PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1879
Raymond Hettingera690a992003-11-16 16:17:49 +00001880static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001881set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001882{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001883 PyObject *tmpkey;
1884 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001887 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1889 return NULL;
1890 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001891 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 if (tmpkey == NULL)
1893 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001896 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 return NULL;
1898 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001901 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 return NULL;
1903 }
1904 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001905}
1906
1907PyDoc_STRVAR(remove_doc,
1908"Remove an element from a set; it must be a member.\n\
1909\n\
1910If the element is not a member, raise a KeyError.");
1911
1912static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001913set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001914{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001915 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001916 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001917
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001918 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001919 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001920 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1921 return NULL;
1922 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001923 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 if (tmpkey == NULL)
1925 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001926 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001928 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001929 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 }
1931 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001932}
1933
1934PyDoc_STRVAR(discard_doc,
1935"Remove an element from a set if it is a member.\n\
1936\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001938
1939static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001940set_reduce(PySetObject *so)
1941{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001942 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001943 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001944
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001945 keys = PySequence_List((PyObject *)so);
1946 if (keys == NULL)
1947 goto done;
1948 args = PyTuple_Pack(1, keys);
1949 if (args == NULL)
1950 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001951 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 if (dict == NULL) {
1953 PyErr_Clear();
1954 dict = Py_None;
1955 Py_INCREF(dict);
1956 }
1957 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001958done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001959 Py_XDECREF(args);
1960 Py_XDECREF(keys);
1961 Py_XDECREF(dict);
1962 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001963}
1964
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001965static PyObject *
1966set_sizeof(PySetObject *so)
1967{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001969
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001970 res = sizeof(PySetObject);
1971 if (so->table != so->smalltable)
1972 res = res + (so->mask + 1) * sizeof(setentry);
1973 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001974}
1975
1976PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001977static int
1978set_init(PySetObject *self, PyObject *args, PyObject *kwds)
1979{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001981
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001982 if (!PyAnySet_Check(self))
1983 return -1;
1984 if (PySet_Check(self) && !_PyArg_NoKeywords("set()", kwds))
1985 return -1;
1986 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
1987 return -1;
1988 set_clear_internal(self);
1989 self->hash = -1;
1990 if (iterable == NULL)
1991 return 0;
1992 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001993}
1994
Raymond Hettingera690a992003-11-16 16:17:49 +00001995static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001996 set_len, /* sq_length */
1997 0, /* sq_concat */
1998 0, /* sq_repeat */
1999 0, /* sq_item */
2000 0, /* sq_slice */
2001 0, /* sq_ass_item */
2002 0, /* sq_ass_slice */
2003 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002004};
2005
2006/* set object ********************************************************/
2007
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002008#ifdef Py_DEBUG
2009static PyObject *test_c_api(PySetObject *so);
2010
2011PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2012All is well if assertions don't fail.");
2013#endif
2014
Raymond Hettingera690a992003-11-16 16:17:49 +00002015static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002016 {"add", (PyCFunction)set_add, METH_O,
2017 add_doc},
2018 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2019 clear_doc},
2020 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2021 contains_doc},
2022 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2023 copy_doc},
2024 {"discard", (PyCFunction)set_discard, METH_O,
2025 discard_doc},
2026 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2027 difference_doc},
2028 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2029 difference_update_doc},
2030 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2031 intersection_doc},
2032 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2033 intersection_update_doc},
2034 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2035 isdisjoint_doc},
2036 {"issubset", (PyCFunction)set_issubset, METH_O,
2037 issubset_doc},
2038 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2039 issuperset_doc},
2040 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2041 pop_doc},
2042 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2043 reduce_doc},
2044 {"remove", (PyCFunction)set_remove, METH_O,
2045 remove_doc},
2046 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2047 sizeof_doc},
2048 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2049 symmetric_difference_doc},
2050 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2051 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002052#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002053 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2054 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002055#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002056 {"union", (PyCFunction)set_union, METH_VARARGS,
2057 union_doc},
2058 {"update", (PyCFunction)set_update, METH_VARARGS,
2059 update_doc},
2060 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002061};
2062
2063static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002064 0, /*nb_add*/
2065 (binaryfunc)set_sub, /*nb_subtract*/
2066 0, /*nb_multiply*/
2067 0, /*nb_remainder*/
2068 0, /*nb_divmod*/
2069 0, /*nb_power*/
2070 0, /*nb_negative*/
2071 0, /*nb_positive*/
2072 0, /*nb_absolute*/
2073 0, /*nb_bool*/
2074 0, /*nb_invert*/
2075 0, /*nb_lshift*/
2076 0, /*nb_rshift*/
2077 (binaryfunc)set_and, /*nb_and*/
2078 (binaryfunc)set_xor, /*nb_xor*/
2079 (binaryfunc)set_or, /*nb_or*/
2080 0, /*nb_int*/
2081 0, /*nb_reserved*/
2082 0, /*nb_float*/
2083 0, /*nb_inplace_add*/
2084 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2085 0, /*nb_inplace_multiply*/
2086 0, /*nb_inplace_remainder*/
2087 0, /*nb_inplace_power*/
2088 0, /*nb_inplace_lshift*/
2089 0, /*nb_inplace_rshift*/
2090 (binaryfunc)set_iand, /*nb_inplace_and*/
2091 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2092 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002093};
2094
2095PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002096"set() -> new empty set object\n\
2097set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002098\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002099Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002100
2101PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002102 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2103 "set", /* tp_name */
2104 sizeof(PySetObject), /* tp_basicsize */
2105 0, /* tp_itemsize */
2106 /* methods */
2107 (destructor)set_dealloc, /* tp_dealloc */
2108 0, /* tp_print */
2109 0, /* tp_getattr */
2110 0, /* tp_setattr */
2111 0, /* tp_reserved */
2112 (reprfunc)set_repr, /* tp_repr */
2113 &set_as_number, /* tp_as_number */
2114 &set_as_sequence, /* tp_as_sequence */
2115 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002116 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002117 0, /* tp_call */
2118 0, /* tp_str */
2119 PyObject_GenericGetAttr, /* tp_getattro */
2120 0, /* tp_setattro */
2121 0, /* tp_as_buffer */
2122 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2123 Py_TPFLAGS_BASETYPE, /* tp_flags */
2124 set_doc, /* tp_doc */
2125 (traverseproc)set_traverse, /* tp_traverse */
2126 (inquiry)set_clear_internal, /* tp_clear */
2127 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002128 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2129 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002130 0, /* tp_iternext */
2131 set_methods, /* tp_methods */
2132 0, /* tp_members */
2133 0, /* tp_getset */
2134 0, /* tp_base */
2135 0, /* tp_dict */
2136 0, /* tp_descr_get */
2137 0, /* tp_descr_set */
2138 0, /* tp_dictoffset */
2139 (initproc)set_init, /* tp_init */
2140 PyType_GenericAlloc, /* tp_alloc */
2141 set_new, /* tp_new */
2142 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002143};
2144
2145/* frozenset object ********************************************************/
2146
2147
2148static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002149 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2150 contains_doc},
2151 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2152 copy_doc},
2153 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2154 difference_doc},
2155 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2156 intersection_doc},
2157 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2158 isdisjoint_doc},
2159 {"issubset", (PyCFunction)set_issubset, METH_O,
2160 issubset_doc},
2161 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2162 issuperset_doc},
2163 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2164 reduce_doc},
2165 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2166 sizeof_doc},
2167 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2168 symmetric_difference_doc},
2169 {"union", (PyCFunction)set_union, METH_VARARGS,
2170 union_doc},
2171 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002172};
2173
2174static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002175 0, /*nb_add*/
2176 (binaryfunc)set_sub, /*nb_subtract*/
2177 0, /*nb_multiply*/
2178 0, /*nb_remainder*/
2179 0, /*nb_divmod*/
2180 0, /*nb_power*/
2181 0, /*nb_negative*/
2182 0, /*nb_positive*/
2183 0, /*nb_absolute*/
2184 0, /*nb_bool*/
2185 0, /*nb_invert*/
2186 0, /*nb_lshift*/
2187 0, /*nb_rshift*/
2188 (binaryfunc)set_and, /*nb_and*/
2189 (binaryfunc)set_xor, /*nb_xor*/
2190 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002191};
2192
2193PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002194"frozenset() -> empty frozenset object\n\
2195frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002196\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002197Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002198
2199PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002200 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2201 "frozenset", /* tp_name */
2202 sizeof(PySetObject), /* tp_basicsize */
2203 0, /* tp_itemsize */
2204 /* methods */
2205 (destructor)set_dealloc, /* tp_dealloc */
2206 0, /* tp_print */
2207 0, /* tp_getattr */
2208 0, /* tp_setattr */
2209 0, /* tp_reserved */
2210 (reprfunc)set_repr, /* tp_repr */
2211 &frozenset_as_number, /* tp_as_number */
2212 &set_as_sequence, /* tp_as_sequence */
2213 0, /* tp_as_mapping */
2214 frozenset_hash, /* tp_hash */
2215 0, /* tp_call */
2216 0, /* tp_str */
2217 PyObject_GenericGetAttr, /* tp_getattro */
2218 0, /* tp_setattro */
2219 0, /* tp_as_buffer */
2220 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2221 Py_TPFLAGS_BASETYPE, /* tp_flags */
2222 frozenset_doc, /* tp_doc */
2223 (traverseproc)set_traverse, /* tp_traverse */
2224 (inquiry)set_clear_internal, /* tp_clear */
2225 (richcmpfunc)set_richcompare, /* tp_richcompare */
2226 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2227 (getiterfunc)set_iter, /* tp_iter */
2228 0, /* tp_iternext */
2229 frozenset_methods, /* tp_methods */
2230 0, /* tp_members */
2231 0, /* tp_getset */
2232 0, /* tp_base */
2233 0, /* tp_dict */
2234 0, /* tp_descr_get */
2235 0, /* tp_descr_set */
2236 0, /* tp_dictoffset */
2237 0, /* tp_init */
2238 PyType_GenericAlloc, /* tp_alloc */
2239 frozenset_new, /* tp_new */
2240 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002241};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002242
2243
2244/***** C API functions *************************************************/
2245
2246PyObject *
2247PySet_New(PyObject *iterable)
2248{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002249 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002250}
2251
2252PyObject *
2253PyFrozenSet_New(PyObject *iterable)
2254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002255 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002256}
2257
Neal Norwitz8c49c822006-03-04 18:41:19 +00002258Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002259PySet_Size(PyObject *anyset)
2260{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002261 if (!PyAnySet_Check(anyset)) {
2262 PyErr_BadInternalCall();
2263 return -1;
2264 }
2265 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002266}
2267
2268int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002269PySet_Clear(PyObject *set)
2270{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002271 if (!PySet_Check(set)) {
2272 PyErr_BadInternalCall();
2273 return -1;
2274 }
2275 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002276}
2277
2278int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002279PySet_Contains(PyObject *anyset, PyObject *key)
2280{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002281 if (!PyAnySet_Check(anyset)) {
2282 PyErr_BadInternalCall();
2283 return -1;
2284 }
2285 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002286}
2287
2288int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002289PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002290{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002291 if (!PySet_Check(set)) {
2292 PyErr_BadInternalCall();
2293 return -1;
2294 }
2295 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002296}
2297
2298int
Christian Heimesfd66e512008-01-29 12:18:50 +00002299PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002300{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002301 if (!PySet_Check(anyset) &&
2302 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2303 PyErr_BadInternalCall();
2304 return -1;
2305 }
2306 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002307}
2308
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002309int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002310_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002311{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002312 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002314 if (!PyAnySet_Check(set)) {
2315 PyErr_BadInternalCall();
2316 return -1;
2317 }
2318 if (set_next((PySetObject *)set, pos, &entry) == 0)
2319 return 0;
2320 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002321 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002322 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002323}
2324
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002325PyObject *
2326PySet_Pop(PyObject *set)
2327{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002328 if (!PySet_Check(set)) {
2329 PyErr_BadInternalCall();
2330 return NULL;
2331 }
2332 return set_pop((PySetObject *)set);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002333}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002334
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002335int
2336_PySet_Update(PyObject *set, PyObject *iterable)
2337{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002338 if (!PySet_Check(set)) {
2339 PyErr_BadInternalCall();
2340 return -1;
2341 }
2342 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002343}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002344
Raymond Hettingere259f132013-12-15 11:56:14 -08002345/* Exported for the gdb plugin's benefit. */
2346PyObject *_PySet_Dummy = dummy;
2347
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002348#ifdef Py_DEBUG
2349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002350/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002351 Returns True and original set is restored. */
2352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002353#define assertRaises(call_return_value, exception) \
2354 do { \
2355 assert(call_return_value); \
2356 assert(PyErr_ExceptionMatches(exception)); \
2357 PyErr_Clear(); \
2358 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002359
2360static PyObject *
2361test_c_api(PySetObject *so)
2362{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002363 Py_ssize_t count;
2364 char *s;
2365 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002366 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002367 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002368 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002369 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002371 /* Verify preconditions */
2372 assert(PyAnySet_Check(ob));
2373 assert(PyAnySet_CheckExact(ob));
2374 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002376 /* so.clear(); so |= set("abc"); */
2377 str = PyUnicode_FromString("abc");
2378 if (str == NULL)
2379 return NULL;
2380 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002381 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002382 Py_DECREF(str);
2383 return NULL;
2384 }
2385 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002387 /* Exercise type/size checks */
2388 assert(PySet_Size(ob) == 3);
2389 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002391 /* Raise TypeError for non-iterable constructor arguments */
2392 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2393 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002395 /* Raise TypeError for unhashable key */
2396 dup = PySet_New(ob);
2397 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2398 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2399 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002400
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002401 /* Exercise successful pop, contains, add, and discard */
2402 elem = PySet_Pop(ob);
2403 assert(PySet_Contains(ob, elem) == 0);
2404 assert(PySet_GET_SIZE(ob) == 2);
2405 assert(PySet_Add(ob, elem) == 0);
2406 assert(PySet_Contains(ob, elem) == 1);
2407 assert(PySet_GET_SIZE(ob) == 3);
2408 assert(PySet_Discard(ob, elem) == 1);
2409 assert(PySet_GET_SIZE(ob) == 2);
2410 assert(PySet_Discard(ob, elem) == 0);
2411 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002413 /* Exercise clear */
2414 dup2 = PySet_New(dup);
2415 assert(PySet_Clear(dup2) == 0);
2416 assert(PySet_Size(dup2) == 0);
2417 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002418
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002419 /* Raise SystemError on clear or update of frozen set */
2420 f = PyFrozenSet_New(dup);
2421 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2422 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2423 assert(PySet_Add(f, elem) == 0);
2424 Py_INCREF(f);
2425 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2426 Py_DECREF(f);
2427 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002429 /* Exercise direct iteration */
2430 i = 0, count = 0;
2431 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
2432 s = _PyUnicode_AsString(x);
2433 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2434 count++;
2435 }
2436 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002438 /* Exercise updates */
2439 dup2 = PySet_New(NULL);
2440 assert(_PySet_Update(dup2, dup) == 0);
2441 assert(PySet_Size(dup2) == 3);
2442 assert(_PySet_Update(dup2, dup) == 0);
2443 assert(PySet_Size(dup2) == 3);
2444 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002446 /* Raise SystemError when self argument is not a set or frozenset. */
2447 t = PyTuple_New(0);
2448 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2449 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2450 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002452 /* Raise SystemError when self argument is not a set. */
2453 f = PyFrozenSet_New(dup);
2454 assert(PySet_Size(f) == 3);
2455 assert(PyFrozenSet_CheckExact(f));
2456 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2457 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2458 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002460 /* Raise KeyError when popping from an empty set */
2461 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2462 Py_DECREF(ob);
2463 assert(PySet_GET_SIZE(ob) == 0);
2464 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002466 /* Restore the set from the copy using the PyNumber API */
2467 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2468 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002470 /* Verify constructors accept NULL arguments */
2471 f = PySet_New(NULL);
2472 assert(f != NULL);
2473 assert(PySet_GET_SIZE(f) == 0);
2474 Py_DECREF(f);
2475 f = PyFrozenSet_New(NULL);
2476 assert(f != NULL);
2477 assert(PyFrozenSet_CheckExact(f));
2478 assert(PySet_GET_SIZE(f) == 0);
2479 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002481 Py_DECREF(elem);
2482 Py_DECREF(dup);
2483 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002484}
2485
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002486#undef assertRaises
2487
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002488#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002489
2490/***** Dummy Struct *************************************************/
2491
2492static PyObject *
2493dummy_repr(PyObject *op)
2494{
2495 return PyUnicode_FromString("<dummy key>");
2496}
2497
2498static void
2499dummy_dealloc(PyObject* ignore)
2500{
2501 Py_FatalError("deallocating <dummy key>");
2502}
2503
2504static PyTypeObject _PySetDummy_Type = {
2505 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2506 "<dummy key> type",
2507 0,
2508 0,
2509 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2510 0, /*tp_print*/
2511 0, /*tp_getattr*/
2512 0, /*tp_setattr*/
2513 0, /*tp_reserved*/
2514 dummy_repr, /*tp_repr*/
2515 0, /*tp_as_number*/
2516 0, /*tp_as_sequence*/
2517 0, /*tp_as_mapping*/
2518 0, /*tp_hash */
2519 0, /*tp_call */
2520 0, /*tp_str */
2521 0, /*tp_getattro */
2522 0, /*tp_setattro */
2523 0, /*tp_as_buffer */
2524 Py_TPFLAGS_DEFAULT, /*tp_flags */
2525};
2526
2527static PyObject _dummy_struct = {
2528 _PyObject_EXTRA_INIT
2529 2, &_PySetDummy_Type
2530};
2531