blob: 12f82f339862423bcea5867c1e889830b1b5c8bc [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;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769 Py_ssize_t len;
Raymond Hettinger3dbc11c2015-07-06 19:03:01 -0700770 setentry *entry;
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 Pitrou9ed5f272013-08-13 20:18:52 +0200848 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000849 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000851 if (so == NULL)
852 return NULL;
853 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000855 if (si->si_used != so->used) {
856 PyErr_SetString(PyExc_RuntimeError,
857 "Set changed size during iteration");
858 si->si_used = -1; /* Make this state sticky */
859 return NULL;
860 }
Raymond Hettinger3dbc11c2015-07-06 19:03:01 -0700861 if (si->len <= 0) {
862 Py_DECREF(so);
863 si->si_set = NULL;
864 return NULL;
865 }
866 entry = si->entry;
867 while (entry->key == NULL || entry->key == dummy)
868 entry++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000869 si->len--;
Raymond Hettinger3dbc11c2015-07-06 19:03:01 -0700870 si->entry = entry + 1;
871 Py_INCREF(entry->key);
872 return entry->key;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000873}
874
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000875PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000876 PyVarObject_HEAD_INIT(&PyType_Type, 0)
877 "set_iterator", /* tp_name */
878 sizeof(setiterobject), /* tp_basicsize */
879 0, /* tp_itemsize */
880 /* methods */
881 (destructor)setiter_dealloc, /* tp_dealloc */
882 0, /* tp_print */
883 0, /* tp_getattr */
884 0, /* tp_setattr */
885 0, /* tp_reserved */
886 0, /* tp_repr */
887 0, /* tp_as_number */
888 0, /* tp_as_sequence */
889 0, /* tp_as_mapping */
890 0, /* tp_hash */
891 0, /* tp_call */
892 0, /* tp_str */
893 PyObject_GenericGetAttr, /* tp_getattro */
894 0, /* tp_setattro */
895 0, /* tp_as_buffer */
896 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
897 0, /* tp_doc */
898 (traverseproc)setiter_traverse, /* tp_traverse */
899 0, /* tp_clear */
900 0, /* tp_richcompare */
901 0, /* tp_weaklistoffset */
902 PyObject_SelfIter, /* tp_iter */
903 (iternextfunc)setiter_iternext, /* tp_iternext */
904 setiter_methods, /* tp_methods */
905 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000906};
907
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000908static PyObject *
909set_iter(PySetObject *so)
910{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
912 if (si == NULL)
913 return NULL;
914 Py_INCREF(so);
915 si->si_set = so;
916 si->si_used = so->used;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000917 si->len = so->used;
Raymond Hettinger3dbc11c2015-07-06 19:03:01 -0700918 si->entry = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000919 _PyObject_GC_TRACK(si);
920 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000921}
922
Raymond Hettingerd7946662005-08-01 21:39:29 +0000923static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000924set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000925{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000928 if (PyAnySet_Check(other))
929 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000931 if (PyDict_CheckExact(other)) {
932 PyObject *value;
933 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000934 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000935 Py_ssize_t dictsize = PyDict_Size(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000937 /* Do one big resize at the start, rather than
938 * incrementally resizing as we insert new keys. Expect
939 * that there will be no (or few) overlapping keys.
940 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700941 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000942 return -1;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700943 if ((so->fill + dictsize)*3 >= so->mask*2) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700944 if (set_table_resize(so, so->used + dictsize) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000945 return -1;
946 }
947 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700948 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 return -1;
950 }
951 return 0;
952 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 it = PyObject_GetIter(other);
955 if (it == NULL)
956 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +0000957
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000958 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700959 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000960 Py_DECREF(it);
961 Py_DECREF(key);
962 return -1;
963 }
964 Py_DECREF(key);
965 }
966 Py_DECREF(it);
967 if (PyErr_Occurred())
968 return -1;
969 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000970}
971
972static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000973set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +0000974{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000975 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000976
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
978 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700979 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000980 return NULL;
981 }
982 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +0000983}
984
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000986"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +0000987
Raymond Hettinger426d9952014-05-18 21:40:20 +0100988/* XXX Todo:
989 If aligned memory allocations become available, make the
990 set object 64 byte aligned so that most of the fields
991 can be retrieved or updated in a single cache line.
992*/
993
Raymond Hettingera38123e2003-11-24 22:18:49 +0000994static PyObject *
995make_new_set(PyTypeObject *type, PyObject *iterable)
996{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200997 PySetObject *so = NULL;
Raymond Hettingera38123e2003-11-24 22:18:49 +0000998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 /* create PySetObject structure */
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001000 so = (PySetObject *)type->tp_alloc(type, 0);
1001 if (so == NULL)
1002 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001003
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001004 so->fill = 0;
1005 so->used = 0;
1006 so->mask = PySet_MINSIZE - 1;
1007 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001008 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001009 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001010 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001013 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 Py_DECREF(so);
1015 return NULL;
1016 }
1017 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001018
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001019 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001020}
1021
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001022static PyObject *
1023make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1024{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001025 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1026 if (PyType_IsSubtype(type, &PySet_Type))
1027 type = &PySet_Type;
1028 else
1029 type = &PyFrozenSet_Type;
1030 }
1031 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001032}
1033
Raymond Hettingerd7946662005-08-01 21:39:29 +00001034/* The empty frozenset is a singleton */
1035static PyObject *emptyfrozenset = NULL;
1036
Raymond Hettingera690a992003-11-16 16:17:49 +00001037static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001038frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001039{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001040 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset()", kwds))
1043 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001045 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1046 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001047
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001048 if (type != &PyFrozenSet_Type)
1049 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001050
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001051 if (iterable != NULL) {
1052 /* frozenset(f) is idempotent */
1053 if (PyFrozenSet_CheckExact(iterable)) {
1054 Py_INCREF(iterable);
1055 return iterable;
1056 }
1057 result = make_new_set(type, iterable);
1058 if (result == NULL || PySet_GET_SIZE(result))
1059 return result;
1060 Py_DECREF(result);
1061 }
1062 /* The empty frozenset is a singleton */
1063 if (emptyfrozenset == NULL)
1064 emptyfrozenset = make_new_set(type, NULL);
1065 Py_XINCREF(emptyfrozenset);
1066 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001067}
1068
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001069int
1070PySet_ClearFreeList(void)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001071{
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001072 return 0;
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001073}
1074
1075void
1076PySet_Fini(void)
1077{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001078 Py_CLEAR(emptyfrozenset);
Raymond Hettingera690a992003-11-16 16:17:49 +00001079}
1080
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001081static PyObject *
1082set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001084 if (type == &PySet_Type && !_PyArg_NoKeywords("set()", kwds))
1085 return NULL;
1086
1087 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001088}
1089
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001090/* set_swap_bodies() switches the contents of any two sets by moving their
1091 internal data pointers and, if needed, copying the internal smalltables.
1092 Semantically equivalent to:
1093
1094 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1095
1096 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001097 Useful for operations that update in-place (by allowing an intermediate
1098 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001099*/
1100
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001101static void
1102set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001103{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 Py_ssize_t t;
1105 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001106 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001107 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001109 t = a->fill; a->fill = b->fill; b->fill = t;
1110 t = a->used; a->used = b->used; b->used = t;
1111 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001113 u = a->table;
1114 if (a->table == a->smalltable)
1115 u = b->smalltable;
1116 a->table = b->table;
1117 if (b->table == b->smalltable)
1118 a->table = a->smalltable;
1119 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001121 if (a->table == a->smalltable || b->table == b->smalltable) {
1122 memcpy(tab, a->smalltable, sizeof(tab));
1123 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1124 memcpy(b->smalltable, tab, sizeof(tab));
1125 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001127 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1128 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1129 h = a->hash; a->hash = b->hash; b->hash = h;
1130 } else {
1131 a->hash = -1;
1132 b->hash = -1;
1133 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001134}
1135
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001136static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001137set_copy(PySetObject *so)
1138{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001139 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001140}
1141
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001142static PyObject *
1143frozenset_copy(PySetObject *so)
1144{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 if (PyFrozenSet_CheckExact(so)) {
1146 Py_INCREF(so);
1147 return (PyObject *)so;
1148 }
1149 return set_copy(so);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001150}
1151
Raymond Hettingera690a992003-11-16 16:17:49 +00001152PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1153
1154static PyObject *
Raymond Hettingerc991db22005-08-11 07:58:45 +00001155set_clear(PySetObject *so)
1156{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001157 set_clear_internal(so);
1158 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001159}
1160
1161PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1162
1163static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001164set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001165{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001166 PySetObject *result;
1167 PyObject *other;
1168 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 result = (PySetObject *)set_copy(so);
1171 if (result == NULL)
1172 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001174 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1175 other = PyTuple_GET_ITEM(args, i);
1176 if ((PyObject *)so == other)
1177 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001178 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001179 Py_DECREF(result);
1180 return NULL;
1181 }
1182 }
1183 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001184}
1185
1186PyDoc_STRVAR(union_doc,
1187 "Return the union of sets as a new set.\n\
1188\n\
1189(i.e. all elements that are in either set.)");
1190
1191static PyObject *
1192set_or(PySetObject *so, PyObject *other)
1193{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001194 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001195
Brian Curtindfc80e32011-08-10 20:28:54 -05001196 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1197 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 result = (PySetObject *)set_copy(so);
1200 if (result == NULL)
1201 return NULL;
1202 if ((PyObject *)so == other)
1203 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001204 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001205 Py_DECREF(result);
1206 return NULL;
1207 }
1208 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001209}
1210
Raymond Hettingera690a992003-11-16 16:17:49 +00001211static PyObject *
1212set_ior(PySetObject *so, PyObject *other)
1213{
Brian Curtindfc80e32011-08-10 20:28:54 -05001214 if (!PyAnySet_Check(other))
1215 Py_RETURN_NOTIMPLEMENTED;
1216
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001217 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001218 return NULL;
1219 Py_INCREF(so);
1220 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001221}
1222
1223static PyObject *
1224set_intersection(PySetObject *so, PyObject *other)
1225{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001226 PySetObject *result;
1227 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001228 Py_hash_t hash;
1229 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001231 if ((PyObject *)so == other)
1232 return set_copy(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1235 if (result == NULL)
1236 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 if (PyAnySet_Check(other)) {
1239 Py_ssize_t pos = 0;
1240 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1243 tmp = (PyObject *)so;
1244 so = (PySetObject *)other;
1245 other = tmp;
1246 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001249 key = entry->key;
1250 hash = entry->hash;
1251 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001252 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 Py_DECREF(result);
1254 return NULL;
1255 }
1256 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001257 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 Py_DECREF(result);
1259 return NULL;
1260 }
1261 }
1262 }
1263 return (PyObject *)result;
1264 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 it = PyObject_GetIter(other);
1267 if (it == NULL) {
1268 Py_DECREF(result);
1269 return NULL;
1270 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001272 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001273 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001274 if (hash == -1)
1275 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001276 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001277 if (rv < 0)
1278 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001280 if (set_add_entry(result, key, hash))
1281 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 }
1283 Py_DECREF(key);
1284 }
1285 Py_DECREF(it);
1286 if (PyErr_Occurred()) {
1287 Py_DECREF(result);
1288 return NULL;
1289 }
1290 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001291 error:
1292 Py_DECREF(it);
1293 Py_DECREF(result);
1294 Py_DECREF(key);
1295 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001296}
1297
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001298static PyObject *
1299set_intersection_multi(PySetObject *so, PyObject *args)
1300{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 Py_ssize_t i;
1302 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 if (PyTuple_GET_SIZE(args) == 0)
1305 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 Py_INCREF(so);
1308 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1309 PyObject *other = PyTuple_GET_ITEM(args, i);
1310 PyObject *newresult = set_intersection((PySetObject *)result, other);
1311 if (newresult == NULL) {
1312 Py_DECREF(result);
1313 return NULL;
1314 }
1315 Py_DECREF(result);
1316 result = newresult;
1317 }
1318 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001319}
1320
Raymond Hettingera690a992003-11-16 16:17:49 +00001321PyDoc_STRVAR(intersection_doc,
1322"Return the intersection of two sets as a new set.\n\
1323\n\
1324(i.e. all elements that are in both sets.)");
1325
1326static PyObject *
1327set_intersection_update(PySetObject *so, PyObject *other)
1328{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001331 tmp = set_intersection(so, other);
1332 if (tmp == NULL)
1333 return NULL;
1334 set_swap_bodies(so, (PySetObject *)tmp);
1335 Py_DECREF(tmp);
1336 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001337}
1338
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001339static PyObject *
1340set_intersection_update_multi(PySetObject *so, PyObject *args)
1341{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001342 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 tmp = set_intersection_multi(so, args);
1345 if (tmp == NULL)
1346 return NULL;
1347 set_swap_bodies(so, (PySetObject *)tmp);
1348 Py_DECREF(tmp);
1349 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001350}
1351
Raymond Hettingera690a992003-11-16 16:17:49 +00001352PyDoc_STRVAR(intersection_update_doc,
1353"Update a set with the intersection of itself and another.");
1354
1355static PyObject *
1356set_and(PySetObject *so, PyObject *other)
1357{
Brian Curtindfc80e32011-08-10 20:28:54 -05001358 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1359 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001360 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001361}
1362
1363static PyObject *
1364set_iand(PySetObject *so, PyObject *other)
1365{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001367
Brian Curtindfc80e32011-08-10 20:28:54 -05001368 if (!PyAnySet_Check(other))
1369 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 result = set_intersection_update(so, other);
1371 if (result == NULL)
1372 return NULL;
1373 Py_DECREF(result);
1374 Py_INCREF(so);
1375 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001376}
1377
Guido van Rossum58da9312007-11-10 23:39:45 +00001378static PyObject *
1379set_isdisjoint(PySetObject *so, PyObject *other)
1380{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001382 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 if ((PyObject *)so == other) {
1385 if (PySet_GET_SIZE(so) == 0)
1386 Py_RETURN_TRUE;
1387 else
1388 Py_RETURN_FALSE;
1389 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 if (PyAnySet_CheckExact(other)) {
1392 Py_ssize_t pos = 0;
1393 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001395 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1396 tmp = (PyObject *)so;
1397 so = (PySetObject *)other;
1398 other = tmp;
1399 }
1400 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001401 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001402 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001403 return NULL;
1404 if (rv)
1405 Py_RETURN_FALSE;
1406 }
1407 Py_RETURN_TRUE;
1408 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001410 it = PyObject_GetIter(other);
1411 if (it == NULL)
1412 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001415 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 if (hash == -1) {
1418 Py_DECREF(key);
1419 Py_DECREF(it);
1420 return NULL;
1421 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001422 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001423 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001424 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 Py_DECREF(it);
1426 return NULL;
1427 }
1428 if (rv) {
1429 Py_DECREF(it);
1430 Py_RETURN_FALSE;
1431 }
1432 }
1433 Py_DECREF(it);
1434 if (PyErr_Occurred())
1435 return NULL;
1436 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001437}
1438
1439PyDoc_STRVAR(isdisjoint_doc,
1440"Return True if two sets have a null intersection.");
1441
Neal Norwitz6576bd82005-11-13 18:41:28 +00001442static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001443set_difference_update_internal(PySetObject *so, PyObject *other)
1444{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001445 if ((PyObject *)so == other)
1446 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 if (PyAnySet_Check(other)) {
1449 setentry *entry;
1450 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001452 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001453 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 return -1;
1455 } else {
1456 PyObject *key, *it;
1457 it = PyObject_GetIter(other);
1458 if (it == NULL)
1459 return -1;
1460
1461 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001462 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001463 Py_DECREF(it);
1464 Py_DECREF(key);
1465 return -1;
1466 }
1467 Py_DECREF(key);
1468 }
1469 Py_DECREF(it);
1470 if (PyErr_Occurred())
1471 return -1;
1472 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001473 /* If more than 1/4th are dummies, then resize them away. */
1474 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 return 0;
Raymond Hettinger48973002015-07-03 20:00:03 -07001476 return set_table_resize(so, so->used);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001477}
1478
Raymond Hettingera690a992003-11-16 16:17:49 +00001479static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001480set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001481{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001482 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1485 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001486 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 return NULL;
1488 }
1489 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001490}
1491
1492PyDoc_STRVAR(difference_update_doc,
1493"Remove all elements of another set from this set.");
1494
1495static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001496set_copy_and_difference(PySetObject *so, PyObject *other)
1497{
1498 PyObject *result;
1499
1500 result = set_copy(so);
1501 if (result == NULL)
1502 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001503 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001504 return result;
1505 Py_DECREF(result);
1506 return NULL;
1507}
1508
1509static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001510set_difference(PySetObject *so, PyObject *other)
1511{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001513 PyObject *key;
1514 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 setentry *entry;
1516 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001517 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001520 return set_copy_and_difference(so, other);
1521 }
1522
1523 /* If len(so) much more than len(other), it's more efficient to simply copy
1524 * so and then iterate other looking for common elements. */
1525 if ((PySet_GET_SIZE(so) >> 2) > PyObject_Size(other)) {
1526 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001527 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 result = make_new_set_basetype(Py_TYPE(so), NULL);
1530 if (result == NULL)
1531 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001532
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001533 if (PyDict_CheckExact(other)) {
1534 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001535 key = entry->key;
1536 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001537 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001538 if (rv < 0) {
1539 Py_DECREF(result);
1540 return NULL;
1541 }
1542 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001543 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001544 Py_DECREF(result);
1545 return NULL;
1546 }
1547 }
1548 }
1549 return result;
1550 }
1551
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001552 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001553 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001554 key = entry->key;
1555 hash = entry->hash;
1556 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001557 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 Py_DECREF(result);
1559 return NULL;
1560 }
1561 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001562 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001563 Py_DECREF(result);
1564 return NULL;
1565 }
1566 }
1567 }
1568 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001569}
1570
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001571static PyObject *
1572set_difference_multi(PySetObject *so, PyObject *args)
1573{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001574 Py_ssize_t i;
1575 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001576
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 if (PyTuple_GET_SIZE(args) == 0)
1578 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 other = PyTuple_GET_ITEM(args, 0);
1581 result = set_difference(so, other);
1582 if (result == NULL)
1583 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001584
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1586 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001587 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 Py_DECREF(result);
1589 return NULL;
1590 }
1591 }
1592 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001593}
1594
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001595PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001596"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001597\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001598(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001599static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001600set_sub(PySetObject *so, PyObject *other)
1601{
Brian Curtindfc80e32011-08-10 20:28:54 -05001602 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1603 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001605}
1606
1607static PyObject *
1608set_isub(PySetObject *so, PyObject *other)
1609{
Brian Curtindfc80e32011-08-10 20:28:54 -05001610 if (!PyAnySet_Check(other))
1611 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001612 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 return NULL;
1614 Py_INCREF(so);
1615 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001616}
1617
1618static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001619set_symmetric_difference_update(PySetObject *so, PyObject *other)
1620{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 PySetObject *otherset;
1622 PyObject *key;
1623 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001624 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001626 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628 if ((PyObject *)so == other)
1629 return set_clear(so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 if (PyDict_CheckExact(other)) {
1632 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001634 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001635 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001636 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001637 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001638 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001640 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001641 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001642 Py_DECREF(key);
1643 return NULL;
1644 }
1645 }
Georg Brandl2d444492010-09-03 10:52:55 +00001646 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 }
1648 Py_RETURN_NONE;
1649 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001650
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 if (PyAnySet_Check(other)) {
1652 Py_INCREF(other);
1653 otherset = (PySetObject *)other;
1654 } else {
1655 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1656 if (otherset == NULL)
1657 return NULL;
1658 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001661 key = entry->key;
1662 hash = entry->hash;
1663 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001664 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001665 Py_DECREF(otherset);
1666 return NULL;
1667 }
1668 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001669 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001670 Py_DECREF(otherset);
1671 return NULL;
1672 }
1673 }
1674 }
1675 Py_DECREF(otherset);
1676 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001677}
1678
1679PyDoc_STRVAR(symmetric_difference_update_doc,
1680"Update a set with the symmetric difference of itself and another.");
1681
1682static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001683set_symmetric_difference(PySetObject *so, PyObject *other)
1684{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001685 PyObject *rv;
1686 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001687
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001688 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1689 if (otherset == NULL)
1690 return NULL;
1691 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
1692 if (rv == NULL)
1693 return NULL;
1694 Py_DECREF(rv);
1695 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001696}
1697
1698PyDoc_STRVAR(symmetric_difference_doc,
1699"Return the symmetric difference of two sets as a new set.\n\
1700\n\
1701(i.e. all elements that are in exactly one of the sets.)");
1702
1703static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001704set_xor(PySetObject *so, PyObject *other)
1705{
Brian Curtindfc80e32011-08-10 20:28:54 -05001706 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1707 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001708 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001709}
1710
1711static PyObject *
1712set_ixor(PySetObject *so, PyObject *other)
1713{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001714 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001715
Brian Curtindfc80e32011-08-10 20:28:54 -05001716 if (!PyAnySet_Check(other))
1717 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001718 result = set_symmetric_difference_update(so, other);
1719 if (result == NULL)
1720 return NULL;
1721 Py_DECREF(result);
1722 Py_INCREF(so);
1723 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001724}
1725
1726static PyObject *
1727set_issubset(PySetObject *so, PyObject *other)
1728{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001729 setentry *entry;
1730 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001731 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001732
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001733 if (!PyAnySet_Check(other)) {
1734 PyObject *tmp, *result;
1735 tmp = make_new_set(&PySet_Type, other);
1736 if (tmp == NULL)
1737 return NULL;
1738 result = set_issubset(so, tmp);
1739 Py_DECREF(tmp);
1740 return result;
1741 }
1742 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1743 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001745 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001746 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001747 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001748 return NULL;
1749 if (!rv)
1750 Py_RETURN_FALSE;
1751 }
1752 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001753}
1754
1755PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1756
1757static PyObject *
1758set_issuperset(PySetObject *so, PyObject *other)
1759{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001760 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001761
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001762 if (!PyAnySet_Check(other)) {
1763 tmp = make_new_set(&PySet_Type, other);
1764 if (tmp == NULL)
1765 return NULL;
1766 result = set_issuperset(so, tmp);
1767 Py_DECREF(tmp);
1768 return result;
1769 }
1770 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001771}
1772
1773PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1774
Raymond Hettingera690a992003-11-16 16:17:49 +00001775static PyObject *
1776set_richcompare(PySetObject *v, PyObject *w, int op)
1777{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001778 PyObject *r1;
1779 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001780
Brian Curtindfc80e32011-08-10 20:28:54 -05001781 if(!PyAnySet_Check(w))
1782 Py_RETURN_NOTIMPLEMENTED;
1783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001784 switch (op) {
1785 case Py_EQ:
1786 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1787 Py_RETURN_FALSE;
1788 if (v->hash != -1 &&
1789 ((PySetObject *)w)->hash != -1 &&
1790 v->hash != ((PySetObject *)w)->hash)
1791 Py_RETURN_FALSE;
1792 return set_issubset(v, w);
1793 case Py_NE:
1794 r1 = set_richcompare(v, w, Py_EQ);
1795 if (r1 == NULL)
1796 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001797 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001798 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001799 if (r2 < 0)
1800 return NULL;
1801 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001802 case Py_LE:
1803 return set_issubset(v, w);
1804 case Py_GE:
1805 return set_issuperset(v, w);
1806 case Py_LT:
1807 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1808 Py_RETURN_FALSE;
1809 return set_issubset(v, w);
1810 case Py_GT:
1811 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1812 Py_RETURN_FALSE;
1813 return set_issuperset(v, w);
1814 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001815 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001816}
1817
Raymond Hettingera690a992003-11-16 16:17:49 +00001818static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001819set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001820{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001821 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001822 return NULL;
1823 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001824}
1825
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001826PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001827"Add an element to a set.\n\
1828\n\
1829This has no effect if the element is already present.");
1830
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001831static int
1832set_contains(PySetObject *so, PyObject *key)
1833{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 PyObject *tmpkey;
1835 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001837 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001838 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001839 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1840 return -1;
1841 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001842 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001843 if (tmpkey == NULL)
1844 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001845 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001846 Py_DECREF(tmpkey);
1847 }
1848 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001849}
1850
1851static PyObject *
1852set_direct_contains(PySetObject *so, PyObject *key)
1853{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001854 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001857 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001858 return NULL;
1859 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001860}
1861
1862PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1863
Raymond Hettingera690a992003-11-16 16:17:49 +00001864static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001865set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001866{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 PyObject *tmpkey;
1868 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001870 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001871 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1873 return NULL;
1874 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001875 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 if (tmpkey == NULL)
1877 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001879 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001880 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 return NULL;
1882 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001883
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001885 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 return NULL;
1887 }
1888 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001889}
1890
1891PyDoc_STRVAR(remove_doc,
1892"Remove an element from a set; it must be a member.\n\
1893\n\
1894If the element is not a member, raise a KeyError.");
1895
1896static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001897set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001898{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001899 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001901
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001903 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001904 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1905 return NULL;
1906 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001907 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 if (tmpkey == NULL)
1909 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001910 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001912 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001913 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 }
1915 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001916}
1917
1918PyDoc_STRVAR(discard_doc,
1919"Remove an element from a set if it is a member.\n\
1920\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001921If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001922
1923static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001924set_reduce(PySetObject *so)
1925{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001927 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001928
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001929 keys = PySequence_List((PyObject *)so);
1930 if (keys == NULL)
1931 goto done;
1932 args = PyTuple_Pack(1, keys);
1933 if (args == NULL)
1934 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001935 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 if (dict == NULL) {
1937 PyErr_Clear();
1938 dict = Py_None;
1939 Py_INCREF(dict);
1940 }
1941 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001942done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 Py_XDECREF(args);
1944 Py_XDECREF(keys);
1945 Py_XDECREF(dict);
1946 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001947}
1948
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001949static PyObject *
1950set_sizeof(PySetObject *so)
1951{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001954 res = sizeof(PySetObject);
1955 if (so->table != so->smalltable)
1956 res = res + (so->mask + 1) * sizeof(setentry);
1957 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001958}
1959
1960PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001961static int
1962set_init(PySetObject *self, PyObject *args, PyObject *kwds)
1963{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001964 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001966 if (!PyAnySet_Check(self))
1967 return -1;
1968 if (PySet_Check(self) && !_PyArg_NoKeywords("set()", kwds))
1969 return -1;
1970 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
1971 return -1;
1972 set_clear_internal(self);
1973 self->hash = -1;
1974 if (iterable == NULL)
1975 return 0;
1976 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001977}
1978
Raymond Hettingera690a992003-11-16 16:17:49 +00001979static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 set_len, /* sq_length */
1981 0, /* sq_concat */
1982 0, /* sq_repeat */
1983 0, /* sq_item */
1984 0, /* sq_slice */
1985 0, /* sq_ass_item */
1986 0, /* sq_ass_slice */
1987 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00001988};
1989
1990/* set object ********************************************************/
1991
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00001992#ifdef Py_DEBUG
1993static PyObject *test_c_api(PySetObject *so);
1994
1995PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
1996All is well if assertions don't fail.");
1997#endif
1998
Raymond Hettingera690a992003-11-16 16:17:49 +00001999static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002000 {"add", (PyCFunction)set_add, METH_O,
2001 add_doc},
2002 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2003 clear_doc},
2004 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2005 contains_doc},
2006 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2007 copy_doc},
2008 {"discard", (PyCFunction)set_discard, METH_O,
2009 discard_doc},
2010 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2011 difference_doc},
2012 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2013 difference_update_doc},
2014 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2015 intersection_doc},
2016 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2017 intersection_update_doc},
2018 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2019 isdisjoint_doc},
2020 {"issubset", (PyCFunction)set_issubset, METH_O,
2021 issubset_doc},
2022 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2023 issuperset_doc},
2024 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2025 pop_doc},
2026 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2027 reduce_doc},
2028 {"remove", (PyCFunction)set_remove, METH_O,
2029 remove_doc},
2030 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2031 sizeof_doc},
2032 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2033 symmetric_difference_doc},
2034 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2035 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002036#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002037 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2038 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002039#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002040 {"union", (PyCFunction)set_union, METH_VARARGS,
2041 union_doc},
2042 {"update", (PyCFunction)set_update, METH_VARARGS,
2043 update_doc},
2044 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002045};
2046
2047static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002048 0, /*nb_add*/
2049 (binaryfunc)set_sub, /*nb_subtract*/
2050 0, /*nb_multiply*/
2051 0, /*nb_remainder*/
2052 0, /*nb_divmod*/
2053 0, /*nb_power*/
2054 0, /*nb_negative*/
2055 0, /*nb_positive*/
2056 0, /*nb_absolute*/
2057 0, /*nb_bool*/
2058 0, /*nb_invert*/
2059 0, /*nb_lshift*/
2060 0, /*nb_rshift*/
2061 (binaryfunc)set_and, /*nb_and*/
2062 (binaryfunc)set_xor, /*nb_xor*/
2063 (binaryfunc)set_or, /*nb_or*/
2064 0, /*nb_int*/
2065 0, /*nb_reserved*/
2066 0, /*nb_float*/
2067 0, /*nb_inplace_add*/
2068 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2069 0, /*nb_inplace_multiply*/
2070 0, /*nb_inplace_remainder*/
2071 0, /*nb_inplace_power*/
2072 0, /*nb_inplace_lshift*/
2073 0, /*nb_inplace_rshift*/
2074 (binaryfunc)set_iand, /*nb_inplace_and*/
2075 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2076 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002077};
2078
2079PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002080"set() -> new empty set object\n\
2081set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002082\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002083Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002084
2085PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002086 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2087 "set", /* tp_name */
2088 sizeof(PySetObject), /* tp_basicsize */
2089 0, /* tp_itemsize */
2090 /* methods */
2091 (destructor)set_dealloc, /* tp_dealloc */
2092 0, /* tp_print */
2093 0, /* tp_getattr */
2094 0, /* tp_setattr */
2095 0, /* tp_reserved */
2096 (reprfunc)set_repr, /* tp_repr */
2097 &set_as_number, /* tp_as_number */
2098 &set_as_sequence, /* tp_as_sequence */
2099 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002100 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002101 0, /* tp_call */
2102 0, /* tp_str */
2103 PyObject_GenericGetAttr, /* tp_getattro */
2104 0, /* tp_setattro */
2105 0, /* tp_as_buffer */
2106 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2107 Py_TPFLAGS_BASETYPE, /* tp_flags */
2108 set_doc, /* tp_doc */
2109 (traverseproc)set_traverse, /* tp_traverse */
2110 (inquiry)set_clear_internal, /* tp_clear */
2111 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002112 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2113 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002114 0, /* tp_iternext */
2115 set_methods, /* tp_methods */
2116 0, /* tp_members */
2117 0, /* tp_getset */
2118 0, /* tp_base */
2119 0, /* tp_dict */
2120 0, /* tp_descr_get */
2121 0, /* tp_descr_set */
2122 0, /* tp_dictoffset */
2123 (initproc)set_init, /* tp_init */
2124 PyType_GenericAlloc, /* tp_alloc */
2125 set_new, /* tp_new */
2126 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002127};
2128
2129/* frozenset object ********************************************************/
2130
2131
2132static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002133 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2134 contains_doc},
2135 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2136 copy_doc},
2137 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2138 difference_doc},
2139 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2140 intersection_doc},
2141 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2142 isdisjoint_doc},
2143 {"issubset", (PyCFunction)set_issubset, METH_O,
2144 issubset_doc},
2145 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2146 issuperset_doc},
2147 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2148 reduce_doc},
2149 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2150 sizeof_doc},
2151 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2152 symmetric_difference_doc},
2153 {"union", (PyCFunction)set_union, METH_VARARGS,
2154 union_doc},
2155 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002156};
2157
2158static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 0, /*nb_add*/
2160 (binaryfunc)set_sub, /*nb_subtract*/
2161 0, /*nb_multiply*/
2162 0, /*nb_remainder*/
2163 0, /*nb_divmod*/
2164 0, /*nb_power*/
2165 0, /*nb_negative*/
2166 0, /*nb_positive*/
2167 0, /*nb_absolute*/
2168 0, /*nb_bool*/
2169 0, /*nb_invert*/
2170 0, /*nb_lshift*/
2171 0, /*nb_rshift*/
2172 (binaryfunc)set_and, /*nb_and*/
2173 (binaryfunc)set_xor, /*nb_xor*/
2174 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002175};
2176
2177PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002178"frozenset() -> empty frozenset object\n\
2179frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002180\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002181Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002182
2183PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2185 "frozenset", /* tp_name */
2186 sizeof(PySetObject), /* tp_basicsize */
2187 0, /* tp_itemsize */
2188 /* methods */
2189 (destructor)set_dealloc, /* tp_dealloc */
2190 0, /* tp_print */
2191 0, /* tp_getattr */
2192 0, /* tp_setattr */
2193 0, /* tp_reserved */
2194 (reprfunc)set_repr, /* tp_repr */
2195 &frozenset_as_number, /* tp_as_number */
2196 &set_as_sequence, /* tp_as_sequence */
2197 0, /* tp_as_mapping */
2198 frozenset_hash, /* tp_hash */
2199 0, /* tp_call */
2200 0, /* tp_str */
2201 PyObject_GenericGetAttr, /* tp_getattro */
2202 0, /* tp_setattro */
2203 0, /* tp_as_buffer */
2204 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2205 Py_TPFLAGS_BASETYPE, /* tp_flags */
2206 frozenset_doc, /* tp_doc */
2207 (traverseproc)set_traverse, /* tp_traverse */
2208 (inquiry)set_clear_internal, /* tp_clear */
2209 (richcmpfunc)set_richcompare, /* tp_richcompare */
2210 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2211 (getiterfunc)set_iter, /* tp_iter */
2212 0, /* tp_iternext */
2213 frozenset_methods, /* tp_methods */
2214 0, /* tp_members */
2215 0, /* tp_getset */
2216 0, /* tp_base */
2217 0, /* tp_dict */
2218 0, /* tp_descr_get */
2219 0, /* tp_descr_set */
2220 0, /* tp_dictoffset */
2221 0, /* tp_init */
2222 PyType_GenericAlloc, /* tp_alloc */
2223 frozenset_new, /* tp_new */
2224 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002225};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002226
2227
2228/***** C API functions *************************************************/
2229
2230PyObject *
2231PySet_New(PyObject *iterable)
2232{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002233 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002234}
2235
2236PyObject *
2237PyFrozenSet_New(PyObject *iterable)
2238{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002239 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002240}
2241
Neal Norwitz8c49c822006-03-04 18:41:19 +00002242Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002243PySet_Size(PyObject *anyset)
2244{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002245 if (!PyAnySet_Check(anyset)) {
2246 PyErr_BadInternalCall();
2247 return -1;
2248 }
2249 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002250}
2251
2252int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002253PySet_Clear(PyObject *set)
2254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002255 if (!PySet_Check(set)) {
2256 PyErr_BadInternalCall();
2257 return -1;
2258 }
2259 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002260}
2261
2262int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002263PySet_Contains(PyObject *anyset, PyObject *key)
2264{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002265 if (!PyAnySet_Check(anyset)) {
2266 PyErr_BadInternalCall();
2267 return -1;
2268 }
2269 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002270}
2271
2272int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002273PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002274{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002275 if (!PySet_Check(set)) {
2276 PyErr_BadInternalCall();
2277 return -1;
2278 }
2279 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002280}
2281
2282int
Christian Heimesfd66e512008-01-29 12:18:50 +00002283PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002284{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002285 if (!PySet_Check(anyset) &&
2286 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2287 PyErr_BadInternalCall();
2288 return -1;
2289 }
2290 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002291}
2292
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002293int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002294_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002295{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002296 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002298 if (!PyAnySet_Check(set)) {
2299 PyErr_BadInternalCall();
2300 return -1;
2301 }
2302 if (set_next((PySetObject *)set, pos, &entry) == 0)
2303 return 0;
2304 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002305 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002306 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002307}
2308
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002309PyObject *
2310PySet_Pop(PyObject *set)
2311{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002312 if (!PySet_Check(set)) {
2313 PyErr_BadInternalCall();
2314 return NULL;
2315 }
2316 return set_pop((PySetObject *)set);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002317}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002318
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002319int
2320_PySet_Update(PyObject *set, PyObject *iterable)
2321{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002322 if (!PySet_Check(set)) {
2323 PyErr_BadInternalCall();
2324 return -1;
2325 }
2326 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002327}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002328
Raymond Hettingere259f132013-12-15 11:56:14 -08002329/* Exported for the gdb plugin's benefit. */
2330PyObject *_PySet_Dummy = dummy;
2331
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002332#ifdef Py_DEBUG
2333
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002334/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002335 Returns True and original set is restored. */
2336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002337#define assertRaises(call_return_value, exception) \
2338 do { \
2339 assert(call_return_value); \
2340 assert(PyErr_ExceptionMatches(exception)); \
2341 PyErr_Clear(); \
2342 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002343
2344static PyObject *
2345test_c_api(PySetObject *so)
2346{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002347 Py_ssize_t count;
2348 char *s;
2349 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002350 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002351 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002352 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002353 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002355 /* Verify preconditions */
2356 assert(PyAnySet_Check(ob));
2357 assert(PyAnySet_CheckExact(ob));
2358 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002360 /* so.clear(); so |= set("abc"); */
2361 str = PyUnicode_FromString("abc");
2362 if (str == NULL)
2363 return NULL;
2364 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002365 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002366 Py_DECREF(str);
2367 return NULL;
2368 }
2369 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002371 /* Exercise type/size checks */
2372 assert(PySet_Size(ob) == 3);
2373 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002375 /* Raise TypeError for non-iterable constructor arguments */
2376 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2377 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002379 /* Raise TypeError for unhashable key */
2380 dup = PySet_New(ob);
2381 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2382 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2383 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002385 /* Exercise successful pop, contains, add, and discard */
2386 elem = PySet_Pop(ob);
2387 assert(PySet_Contains(ob, elem) == 0);
2388 assert(PySet_GET_SIZE(ob) == 2);
2389 assert(PySet_Add(ob, elem) == 0);
2390 assert(PySet_Contains(ob, elem) == 1);
2391 assert(PySet_GET_SIZE(ob) == 3);
2392 assert(PySet_Discard(ob, elem) == 1);
2393 assert(PySet_GET_SIZE(ob) == 2);
2394 assert(PySet_Discard(ob, elem) == 0);
2395 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002397 /* Exercise clear */
2398 dup2 = PySet_New(dup);
2399 assert(PySet_Clear(dup2) == 0);
2400 assert(PySet_Size(dup2) == 0);
2401 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002403 /* Raise SystemError on clear or update of frozen set */
2404 f = PyFrozenSet_New(dup);
2405 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2406 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2407 assert(PySet_Add(f, elem) == 0);
2408 Py_INCREF(f);
2409 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2410 Py_DECREF(f);
2411 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002413 /* Exercise direct iteration */
2414 i = 0, count = 0;
2415 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
2416 s = _PyUnicode_AsString(x);
2417 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2418 count++;
2419 }
2420 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002422 /* Exercise updates */
2423 dup2 = PySet_New(NULL);
2424 assert(_PySet_Update(dup2, dup) == 0);
2425 assert(PySet_Size(dup2) == 3);
2426 assert(_PySet_Update(dup2, dup) == 0);
2427 assert(PySet_Size(dup2) == 3);
2428 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002430 /* Raise SystemError when self argument is not a set or frozenset. */
2431 t = PyTuple_New(0);
2432 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2433 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2434 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002436 /* Raise SystemError when self argument is not a set. */
2437 f = PyFrozenSet_New(dup);
2438 assert(PySet_Size(f) == 3);
2439 assert(PyFrozenSet_CheckExact(f));
2440 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2441 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2442 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002443
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002444 /* Raise KeyError when popping from an empty set */
2445 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2446 Py_DECREF(ob);
2447 assert(PySet_GET_SIZE(ob) == 0);
2448 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002450 /* Restore the set from the copy using the PyNumber API */
2451 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2452 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002453
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002454 /* Verify constructors accept NULL arguments */
2455 f = PySet_New(NULL);
2456 assert(f != NULL);
2457 assert(PySet_GET_SIZE(f) == 0);
2458 Py_DECREF(f);
2459 f = PyFrozenSet_New(NULL);
2460 assert(f != NULL);
2461 assert(PyFrozenSet_CheckExact(f));
2462 assert(PySet_GET_SIZE(f) == 0);
2463 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002465 Py_DECREF(elem);
2466 Py_DECREF(dup);
2467 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002468}
2469
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002470#undef assertRaises
2471
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002472#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002473
2474/***** Dummy Struct *************************************************/
2475
2476static PyObject *
2477dummy_repr(PyObject *op)
2478{
2479 return PyUnicode_FromString("<dummy key>");
2480}
2481
2482static void
2483dummy_dealloc(PyObject* ignore)
2484{
2485 Py_FatalError("deallocating <dummy key>");
2486}
2487
2488static PyTypeObject _PySetDummy_Type = {
2489 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2490 "<dummy key> type",
2491 0,
2492 0,
2493 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2494 0, /*tp_print*/
2495 0, /*tp_getattr*/
2496 0, /*tp_setattr*/
2497 0, /*tp_reserved*/
2498 dummy_repr, /*tp_repr*/
2499 0, /*tp_as_number*/
2500 0, /*tp_as_sequence*/
2501 0, /*tp_as_mapping*/
2502 0, /*tp_hash */
2503 0, /*tp_call */
2504 0, /*tp_str */
2505 0, /*tp_getattro */
2506 0, /*tp_setattro */
2507 0, /*tp_as_buffer */
2508 Py_TPFLAGS_DEFAULT, /*tp_flags */
2509};
2510
2511static PyObject _dummy_struct = {
2512 _PyObject_EXTRA_INIT
2513 2, &_PySetDummy_Type
2514};
2515