blob: 83bff8176c80beada8861799ecf65380494250b3 [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 Hettinger061091a2015-07-15 23:54:02 -0700130_set_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 Hettinger061091a2015-07-15 23:54:02 -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 Hettinger061091a2015-07-15 23:54:02 -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;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700214 so->used++;
215 freeslot->key = key;
216 freeslot->hash = hash;
217 return 0;
218
219 found_unused:
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700220 so->fill++;
221 so->used++;
222 entry->key = key;
223 entry->hash = hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700224 if ((size_t)so->fill*3 < mask*2)
225 return 0;
Raymond Hettinger482c05c2015-07-20 01:23:32 -0400226 if (!set_table_resize(so, so->used))
227 return 0;
228 Py_INCREF(key);
229 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700230
231 found_active:
Raymond Hettinger482c05c2015-07-20 01:23:32 -0400232 Py_DECREF(key);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700233 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000234}
235
Raymond Hettinger061091a2015-07-15 23:54:02 -0700236static int
237set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
238{
239 Py_INCREF(key);
240 if (!_set_add_entry(so, key, hash))
241 return 0;
242 Py_DECREF(key);
243 return -1;
244}
245
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000246/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000247Internal routine used by set_table_resize() to insert an item which is
248known to be absent from the set. This routine also assumes that
249the set contains no deleted entries. Besides the performance benefit,
250using set_insert_clean() in set_table_resize() is dangerous (SF bug #1456209).
251Note that no refcounts are changed by this routine; if needed, the caller
252is responsible for incref'ing `key`.
253*/
254static void
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200255set_insert_clean(PySetObject *so, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000256{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 setentry *table = so->table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200258 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700259 size_t perturb = hash;
260 size_t mask = (size_t)so->mask;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800261 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700262 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000263
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700264 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800265 entry = &table[i];
266 if (entry->key == NULL)
267 goto found_null;
268 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800269 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800270 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800271 if (entry->key == NULL)
272 goto found_null;
273 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700274 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700275 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800276 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000277 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700278 found_null:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000279 entry->key = key;
280 entry->hash = hash;
Raymond Hettinger4ef05282013-09-21 15:39:49 -0700281 so->fill++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 so->used++;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000283}
284
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700285/* ======== End logic for probing the hash table ========================== */
286/* ======================================================================== */
287
Thomas Wouters89f507f2006-12-13 04:49:30 +0000288/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000289Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000290keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000291actually be smaller than the old one.
292*/
293static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000294set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000295{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 Py_ssize_t newsize;
297 setentry *oldtable, *newtable, *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800298 Py_ssize_t oldfill = so->fill;
299 Py_ssize_t oldused = so->used;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 int is_oldtable_malloced;
301 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000303 assert(minused >= 0);
Raymond Hettinger48973002015-07-03 20:00:03 -0700304 minused = (minused > 50000) ? minused * 2 : minused * 4;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100307 /* XXX speed-up with intrinsics */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 for (newsize = PySet_MINSIZE;
309 newsize <= minused && newsize > 0;
310 newsize <<= 1)
311 ;
312 if (newsize <= 0) {
313 PyErr_NoMemory();
314 return -1;
315 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 /* Get space for a new table. */
318 oldtable = so->table;
319 assert(oldtable != NULL);
320 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 if (newsize == PySet_MINSIZE) {
323 /* A large table is shrinking, or we can't get any smaller. */
324 newtable = so->smalltable;
325 if (newtable == oldtable) {
326 if (so->fill == so->used) {
327 /* No dummies, so no point doing anything. */
328 return 0;
329 }
330 /* We're not going to resize it, but rebuild the
331 table anyway to purge old dummy entries.
332 Subtle: This is *necessary* if fill==size,
333 as set_lookkey needs at least one virgin slot to
334 terminate failing searches. If fill < size, it's
335 merely desirable, as dummies slow searches. */
336 assert(so->fill > so->used);
337 memcpy(small_copy, oldtable, sizeof(small_copy));
338 oldtable = small_copy;
339 }
340 }
341 else {
342 newtable = PyMem_NEW(setentry, newsize);
343 if (newtable == NULL) {
344 PyErr_NoMemory();
345 return -1;
346 }
347 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000349 /* Make the set empty, using the new table. */
350 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 memset(newtable, 0, sizeof(setentry) * newsize);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 so->fill = 0;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800353 so->used = 0;
354 so->mask = newsize - 1;
355 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 /* Copy the data over; this is refcount-neutral for active entries;
358 dummy entries aren't copied over, of course */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800359 if (oldfill == oldused) {
360 for (entry = oldtable; oldused > 0; entry++) {
361 if (entry->key != NULL) {
362 oldused--;
363 set_insert_clean(so, entry->key, entry->hash);
364 }
365 }
366 } else {
367 for (entry = oldtable; oldused > 0; entry++) {
368 if (entry->key != NULL && entry->key != dummy) {
369 oldused--;
370 set_insert_clean(so, entry->key, entry->hash);
371 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372 }
373 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000375 if (is_oldtable_malloced)
376 PyMem_DEL(oldtable);
377 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000378}
379
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000380static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700381set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000382{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700383 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000384
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700385 entry = set_lookkey(so, key, hash);
386 if (entry != NULL)
387 return entry->key != NULL;
388 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000389}
390
391#define DISCARD_NOTFOUND 0
392#define DISCARD_FOUND 1
393
394static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700395set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800396{
397 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000398 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000399
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700400 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000401 if (entry == NULL)
402 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700403 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 return DISCARD_NOTFOUND;
405 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800407 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 so->used--;
409 Py_DECREF(old_key);
410 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000411}
412
413static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700414set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000415{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200416 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000417
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700418 if (!PyUnicode_CheckExact(key) ||
419 (hash = ((PyASCIIObject *) key)->hash) == -1) {
420 hash = PyObject_Hash(key);
421 if (hash == -1)
422 return -1;
423 }
424 return set_add_entry(so, key, hash);
425}
426
427static int
428set_contains_key(PySetObject *so, PyObject *key)
429{
430 Py_hash_t hash;
431
432 if (!PyUnicode_CheckExact(key) ||
433 (hash = ((PyASCIIObject *) key)->hash) == -1) {
434 hash = PyObject_Hash(key);
435 if (hash == -1)
436 return -1;
437 }
438 return set_contains_entry(so, key, hash);
439}
440
441static int
442set_discard_key(PySetObject *so, PyObject *key)
443{
444 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000446 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200447 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000448 hash = PyObject_Hash(key);
449 if (hash == -1)
450 return -1;
451 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700452 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000453}
454
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700455static void
456set_empty_to_minsize(PySetObject *so)
457{
458 memset(so->smalltable, 0, sizeof(so->smalltable));
459 so->fill = 0;
460 so->used = 0;
461 so->mask = PySet_MINSIZE - 1;
462 so->table = so->smalltable;
463 so->hash = -1;
464}
465
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000466static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000467set_clear_internal(PySetObject *so)
468{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800469 setentry *entry;
470 setentry *table = so->table;
471 Py_ssize_t fill = so->fill;
472 Py_ssize_t used = so->used;
473 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000475
Raymond Hettinger583cd032013-09-07 22:06:35 -0700476 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 /* This is delicate. During the process of clearing the set,
480 * decrefs can cause the set to mutate. To avoid fatal confusion
481 * (voice of experience), we have to make the set empty before
482 * clearing the slots, and never refer to anything via so->ref while
483 * clearing.
484 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700486 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488 else if (fill > 0) {
489 /* It's a small table with something that needs to be cleared.
490 * Afraid the only safe way is to copy the set entries into
491 * another small table first.
492 */
493 memcpy(small_copy, table, sizeof(small_copy));
494 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700495 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 }
497 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 /* Now we can finally clear things. If C had refcounts, we could
500 * assert that the refcount on table is 1 now, i.e. that this function
501 * has unique access to it, so decref side-effects can't alter it.
502 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800503 for (entry = table; used > 0; entry++) {
504 if (entry->key && entry->key != dummy) {
505 used--;
506 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 if (table_is_malloced)
511 PyMem_DEL(table);
512 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000513}
514
515/*
516 * Iterate over a set table. Use like so:
517 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000518 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000519 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000520 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000521 * while (set_next(yourset, &pos, &entry)) {
522 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000523 * }
524 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000525 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000527 */
528static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000529set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000530{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000531 Py_ssize_t i;
532 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700533 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 assert (PyAnySet_Check(so));
536 i = *pos_ptr;
537 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700539 entry = &so->table[i];
540 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700542 entry++;
543 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000544 *pos_ptr = i+1;
545 if (i > mask)
546 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700547 assert(entry != NULL);
548 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000549 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000550}
551
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000552static void
553set_dealloc(PySetObject *so)
554{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200555 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800556 Py_ssize_t used = so->used;
557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000558 PyObject_GC_UnTrack(so);
559 Py_TRASHCAN_SAFE_BEGIN(so)
560 if (so->weakreflist != NULL)
561 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000562
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800563 for (entry = so->table; used > 0; entry++) {
564 if (entry->key && entry->key != dummy) {
565 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700566 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000567 }
568 }
569 if (so->table != so->smalltable)
570 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700571 Py_TYPE(so)->tp_free(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000572 Py_TRASHCAN_SAFE_END(so)
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000573}
574
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000575static PyObject *
576set_repr(PySetObject *so)
577{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200578 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000579 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 if (status != 0) {
582 if (status < 0)
583 return NULL;
584 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
585 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000586
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000587 /* shortcut for the empty set */
588 if (!so->used) {
589 Py_ReprLeave((PyObject*)so);
590 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
591 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000592
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 keys = PySequence_List((PyObject *)so);
594 if (keys == NULL)
595 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000596
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200597 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000598 listrepr = PyObject_Repr(keys);
599 Py_DECREF(keys);
600 if (listrepr == NULL)
601 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200602 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000603 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200604 if (tmp == NULL)
605 goto done;
606 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200607
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200608 if (Py_TYPE(so) != &PySet_Type)
609 result = PyUnicode_FromFormat("%s({%U})",
610 Py_TYPE(so)->tp_name,
611 listrepr);
612 else
613 result = PyUnicode_FromFormat("{%U}", listrepr);
614 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000615done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000616 Py_ReprLeave((PyObject*)so);
617 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000618}
619
Martin v. Löwis18e16552006-02-15 17:27:45 +0000620static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000621set_len(PyObject *so)
622{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000624}
625
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000626static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000627set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000628{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000630 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200631 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700632 setentry *so_entry;
633 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 assert (PyAnySet_Check(so));
636 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000637
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 other = (PySetObject*)otherset;
639 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700640 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 return 0;
642 /* Do one big resize at the start, rather than
643 * incrementally resizing as we insert new keys. Expect
644 * that there will be no (or few) overlapping keys.
645 */
Raymond Hettinger15f08692015-07-03 17:21:17 -0700646 if ((so->fill + other->used)*3 >= so->mask*2) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700647 if (set_table_resize(so, so->used + other->used) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 return -1;
649 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700650 so_entry = so->table;
651 other_entry = other->table;
652
653 /* If our table is empty, and both tables have the same size, and
654 there are no dummies to eliminate, then just copy the pointers. */
655 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
656 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
657 key = other_entry->key;
658 if (key != NULL) {
659 assert(so_entry->key == NULL);
660 Py_INCREF(key);
661 so_entry->key = key;
662 so_entry->hash = other_entry->hash;
663 }
664 }
665 so->fill = other->fill;
666 so->used = other->used;
667 return 0;
668 }
669
670 /* If our table is empty, we can use set_insert_clean() */
671 if (so->fill == 0) {
672 for (i = 0; i <= other->mask; i++, other_entry++) {
673 key = other_entry->key;
674 if (key != NULL && key != dummy) {
675 Py_INCREF(key);
676 set_insert_clean(so, key, other_entry->hash);
677 }
678 }
679 return 0;
680 }
681
682 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700683 for (i = 0; i <= other->mask; i++) {
684 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700685 key = other_entry->key;
686 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700687 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000688 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000689 }
690 }
691 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000692}
693
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000694static PyObject *
695set_pop(PySetObject *so)
696{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800697 /* Make sure the search finger is in bounds */
698 Py_ssize_t i = so->finger & so->mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200699 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000700 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000701
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000702 assert (PyAnySet_Check(so));
703 if (so->used == 0) {
704 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
705 return NULL;
706 }
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000707
Raymond Hettinger1202a472015-01-18 13:12:42 -0800708 while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
709 i++;
Raymond Hettingered741d42015-01-18 21:25:15 -0800710 if (i > so->mask)
711 i = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000712 }
713 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000714 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800715 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 so->used--;
Raymond Hettinger1202a472015-01-18 13:12:42 -0800717 so->finger = i + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000719}
720
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000721PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
722Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000723
724static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000725set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000726{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000727 Py_ssize_t pos = 0;
728 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 while (set_next(so, &pos, &entry))
731 Py_VISIT(entry->key);
732 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000733}
734
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000735static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000736frozenset_hash(PyObject *self)
737{
Raymond Hettinger74fc8c42014-01-05 12:00:31 -0800738 /* Most of the constants in this hash algorithm are randomly choosen
739 large primes with "interesting bit patterns" and that passed
740 tests for good collision statistics on a variety of problematic
741 datasets such as:
742
743 ps = []
744 for r in range(21):
745 ps += itertools.combinations(range(20), r)
746 num_distinct_hashes = len({hash(frozenset(s)) for s in ps})
747
748 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000749 PySetObject *so = (PySetObject *)self;
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800750 Py_uhash_t h, hash = 1927868237UL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000751 setentry *entry;
752 Py_ssize_t pos = 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000753
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000754 if (so->hash != -1)
755 return so->hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000756
Mark Dickinson57e683e2011-09-24 18:18:40 +0100757 hash *= (Py_uhash_t)PySet_GET_SIZE(self) + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758 while (set_next(so, &pos, &entry)) {
759 /* Work to increase the bit dispersion for closely spaced hash
Raymond Hettinger06a1c8d2015-01-30 18:02:15 -0800760 values. This is important because some use cases have many
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000761 combinations of a small number of elements with nearby
762 hashes so that many distinct combinations collapse to only
763 a handful of distinct hash values. */
Antoine Pitroufbb1c612010-10-23 17:37:54 +0000764 h = entry->hash;
Raymond Hettinger74fc8c42014-01-05 12:00:31 -0800765 hash ^= ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000766 }
Raymond Hettinger74fc8c42014-01-05 12:00:31 -0800767 /* Make the final result spread-out in a different pattern
Eric V. Smith6ba56652014-01-14 08:15:03 -0500768 than the algorithm for tuples or other python objects. */
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800769 hash = hash * 69069U + 907133923UL;
Victor Stinner12174a52014-08-15 23:17:38 +0200770 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800771 hash = 590923713UL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000772 so->hash = hash;
773 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000774}
775
Raymond Hettingera9d99362005-08-05 00:01:15 +0000776/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000777
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000778typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000779 PyObject_HEAD
780 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
781 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700782 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000783 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000784} setiterobject;
785
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000786static void
787setiter_dealloc(setiterobject *si)
788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000789 Py_XDECREF(si->si_set);
790 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000791}
792
793static int
794setiter_traverse(setiterobject *si, visitproc visit, void *arg)
795{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000796 Py_VISIT(si->si_set);
797 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000798}
799
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000800static PyObject *
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000801setiter_len(setiterobject *si)
802{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000803 Py_ssize_t len = 0;
804 if (si->si_set != NULL && si->si_used == si->si_set->used)
805 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000806 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000807}
808
Armin Rigof5b3e362006-02-11 21:32:43 +0000809PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000810
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000811static PyObject *setiter_iternext(setiterobject *si);
812
813static PyObject *
814setiter_reduce(setiterobject *si)
815{
816 PyObject *list;
817 setiterobject tmp;
818
819 list = PyList_New(0);
820 if (!list)
821 return NULL;
822
Ezio Melotti0e1af282012-09-28 16:43:40 +0300823 /* copy the iterator state */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000824 tmp = *si;
825 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300826
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000827 /* iterate the temporary into a list */
828 for(;;) {
829 PyObject *element = setiter_iternext(&tmp);
830 if (element) {
831 if (PyList_Append(list, element)) {
832 Py_DECREF(element);
833 Py_DECREF(list);
834 Py_XDECREF(tmp.si_set);
835 return NULL;
836 }
837 Py_DECREF(element);
838 } else
839 break;
840 }
841 Py_XDECREF(tmp.si_set);
842 /* check for error */
843 if (tmp.si_set != NULL) {
844 /* we have an error */
845 Py_DECREF(list);
846 return NULL;
847 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200848 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000849}
850
851PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
852
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000853static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000854 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000855 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000856 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000857};
858
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000859static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000860{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700861 PyObject *key;
862 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200863 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000864 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000866 if (so == NULL)
867 return NULL;
868 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000870 if (si->si_used != so->used) {
871 PyErr_SetString(PyExc_RuntimeError,
872 "Set changed size during iteration");
873 si->si_used = -1; /* Make this state sticky */
874 return NULL;
875 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700876
877 i = si->si_pos;
878 assert(i>=0);
879 entry = so->table;
880 mask = so->mask;
881 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
882 i++;
883 si->si_pos = i+1;
884 if (i > mask)
885 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700887 key = entry[i].key;
888 Py_INCREF(key);
889 return key;
890
891fail:
892 Py_DECREF(so);
893 si->si_set = NULL;
894 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000895}
896
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000897PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000898 PyVarObject_HEAD_INIT(&PyType_Type, 0)
899 "set_iterator", /* tp_name */
900 sizeof(setiterobject), /* tp_basicsize */
901 0, /* tp_itemsize */
902 /* methods */
903 (destructor)setiter_dealloc, /* tp_dealloc */
904 0, /* tp_print */
905 0, /* tp_getattr */
906 0, /* tp_setattr */
907 0, /* tp_reserved */
908 0, /* tp_repr */
909 0, /* tp_as_number */
910 0, /* tp_as_sequence */
911 0, /* tp_as_mapping */
912 0, /* tp_hash */
913 0, /* tp_call */
914 0, /* tp_str */
915 PyObject_GenericGetAttr, /* tp_getattro */
916 0, /* tp_setattro */
917 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700918 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000919 0, /* tp_doc */
920 (traverseproc)setiter_traverse, /* tp_traverse */
921 0, /* tp_clear */
922 0, /* tp_richcompare */
923 0, /* tp_weaklistoffset */
924 PyObject_SelfIter, /* tp_iter */
925 (iternextfunc)setiter_iternext, /* tp_iternext */
926 setiter_methods, /* tp_methods */
927 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000928};
929
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000930static PyObject *
931set_iter(PySetObject *so)
932{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000933 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
934 if (si == NULL)
935 return NULL;
936 Py_INCREF(so);
937 si->si_set = so;
938 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700939 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000940 si->len = so->used;
941 _PyObject_GC_TRACK(si);
942 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000943}
944
Raymond Hettingerd7946662005-08-01 21:39:29 +0000945static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000946set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000947{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000948 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000950 if (PyAnySet_Check(other))
951 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000952
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000953 if (PyDict_CheckExact(other)) {
954 PyObject *value;
955 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000956 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 Py_ssize_t dictsize = PyDict_Size(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000959 /* Do one big resize at the start, rather than
960 * incrementally resizing as we insert new keys. Expect
961 * that there will be no (or few) overlapping keys.
962 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700963 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000964 return -1;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700965 if ((so->fill + dictsize)*3 >= so->mask*2) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700966 if (set_table_resize(so, so->used + dictsize) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 return -1;
968 }
969 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700970 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 return -1;
972 }
973 return 0;
974 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000975
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000976 it = PyObject_GetIter(other);
977 if (it == NULL)
978 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +0000979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000980 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700981 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 Py_DECREF(it);
983 Py_DECREF(key);
984 return -1;
985 }
986 Py_DECREF(key);
987 }
988 Py_DECREF(it);
989 if (PyErr_Occurred())
990 return -1;
991 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000992}
993
994static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000995set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +0000996{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000997 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1000 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001001 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001002 return NULL;
1003 }
1004 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001005}
1006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001008"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001009
Raymond Hettinger426d9952014-05-18 21:40:20 +01001010/* XXX Todo:
1011 If aligned memory allocations become available, make the
1012 set object 64 byte aligned so that most of the fields
1013 can be retrieved or updated in a single cache line.
1014*/
1015
Raymond Hettingera38123e2003-11-24 22:18:49 +00001016static PyObject *
1017make_new_set(PyTypeObject *type, PyObject *iterable)
1018{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001019 PySetObject *so = NULL;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001020
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001021 /* create PySetObject structure */
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001022 so = (PySetObject *)type->tp_alloc(type, 0);
1023 if (so == NULL)
1024 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001025
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001026 so->fill = 0;
1027 so->used = 0;
1028 so->mask = PySet_MINSIZE - 1;
1029 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001030 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001031 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001033
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001035 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 Py_DECREF(so);
1037 return NULL;
1038 }
1039 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001042}
1043
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001044static PyObject *
1045make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1046{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001047 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1048 if (PyType_IsSubtype(type, &PySet_Type))
1049 type = &PySet_Type;
1050 else
1051 type = &PyFrozenSet_Type;
1052 }
1053 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001054}
1055
Raymond Hettingerd7946662005-08-01 21:39:29 +00001056/* The empty frozenset is a singleton */
1057static PyObject *emptyfrozenset = NULL;
1058
Raymond Hettingera690a992003-11-16 16:17:49 +00001059static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001060frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001061{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001064 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset()", kwds))
1065 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001066
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001067 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1068 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 if (type != &PyFrozenSet_Type)
1071 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 if (iterable != NULL) {
1074 /* frozenset(f) is idempotent */
1075 if (PyFrozenSet_CheckExact(iterable)) {
1076 Py_INCREF(iterable);
1077 return iterable;
1078 }
1079 result = make_new_set(type, iterable);
1080 if (result == NULL || PySet_GET_SIZE(result))
1081 return result;
1082 Py_DECREF(result);
1083 }
1084 /* The empty frozenset is a singleton */
1085 if (emptyfrozenset == NULL)
1086 emptyfrozenset = make_new_set(type, NULL);
1087 Py_XINCREF(emptyfrozenset);
1088 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001089}
1090
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001091int
1092PySet_ClearFreeList(void)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001093{
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001094 return 0;
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001095}
1096
1097void
1098PySet_Fini(void)
1099{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 Py_CLEAR(emptyfrozenset);
Raymond Hettingera690a992003-11-16 16:17:49 +00001101}
1102
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001103static PyObject *
1104set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1105{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001106 if (type == &PySet_Type && !_PyArg_NoKeywords("set()", kwds))
1107 return NULL;
1108
1109 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001110}
1111
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001112/* set_swap_bodies() switches the contents of any two sets by moving their
1113 internal data pointers and, if needed, copying the internal smalltables.
1114 Semantically equivalent to:
1115
1116 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1117
1118 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001119 Useful for operations that update in-place (by allowing an intermediate
1120 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001121*/
1122
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001123static void
1124set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001125{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001126 Py_ssize_t t;
1127 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001128 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001129 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001130
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001131 t = a->fill; a->fill = b->fill; b->fill = t;
1132 t = a->used; a->used = b->used; b->used = t;
1133 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 u = a->table;
1136 if (a->table == a->smalltable)
1137 u = b->smalltable;
1138 a->table = b->table;
1139 if (b->table == b->smalltable)
1140 a->table = a->smalltable;
1141 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001143 if (a->table == a->smalltable || b->table == b->smalltable) {
1144 memcpy(tab, a->smalltable, sizeof(tab));
1145 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1146 memcpy(b->smalltable, tab, sizeof(tab));
1147 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1150 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1151 h = a->hash; a->hash = b->hash; b->hash = h;
1152 } else {
1153 a->hash = -1;
1154 b->hash = -1;
1155 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001156}
1157
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001158static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001159set_copy(PySetObject *so)
1160{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001162}
1163
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001164static PyObject *
1165frozenset_copy(PySetObject *so)
1166{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001167 if (PyFrozenSet_CheckExact(so)) {
1168 Py_INCREF(so);
1169 return (PyObject *)so;
1170 }
1171 return set_copy(so);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001172}
1173
Raymond Hettingera690a992003-11-16 16:17:49 +00001174PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1175
1176static PyObject *
Raymond Hettingerc991db22005-08-11 07:58:45 +00001177set_clear(PySetObject *so)
1178{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001179 set_clear_internal(so);
1180 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001181}
1182
1183PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1184
1185static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001186set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001187{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001188 PySetObject *result;
1189 PyObject *other;
1190 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001191
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001192 result = (PySetObject *)set_copy(so);
1193 if (result == NULL)
1194 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001196 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1197 other = PyTuple_GET_ITEM(args, i);
1198 if ((PyObject *)so == other)
1199 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001200 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001201 Py_DECREF(result);
1202 return NULL;
1203 }
1204 }
1205 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001206}
1207
1208PyDoc_STRVAR(union_doc,
1209 "Return the union of sets as a new set.\n\
1210\n\
1211(i.e. all elements that are in either set.)");
1212
1213static PyObject *
1214set_or(PySetObject *so, PyObject *other)
1215{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001217
Brian Curtindfc80e32011-08-10 20:28:54 -05001218 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1219 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001221 result = (PySetObject *)set_copy(so);
1222 if (result == NULL)
1223 return NULL;
1224 if ((PyObject *)so == other)
1225 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001226 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001227 Py_DECREF(result);
1228 return NULL;
1229 }
1230 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001231}
1232
Raymond Hettingera690a992003-11-16 16:17:49 +00001233static PyObject *
1234set_ior(PySetObject *so, PyObject *other)
1235{
Brian Curtindfc80e32011-08-10 20:28:54 -05001236 if (!PyAnySet_Check(other))
1237 Py_RETURN_NOTIMPLEMENTED;
1238
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001239 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 return NULL;
1241 Py_INCREF(so);
1242 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001243}
1244
1245static PyObject *
1246set_intersection(PySetObject *so, PyObject *other)
1247{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 PySetObject *result;
1249 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001250 Py_hash_t hash;
1251 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 if ((PyObject *)so == other)
1254 return set_copy(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1257 if (result == NULL)
1258 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 if (PyAnySet_Check(other)) {
1261 Py_ssize_t pos = 0;
1262 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1265 tmp = (PyObject *)so;
1266 so = (PySetObject *)other;
1267 other = tmp;
1268 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001270 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001271 key = entry->key;
1272 hash = entry->hash;
1273 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001274 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 Py_DECREF(result);
1276 return NULL;
1277 }
1278 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001279 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001280 Py_DECREF(result);
1281 return NULL;
1282 }
1283 }
1284 }
1285 return (PyObject *)result;
1286 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 it = PyObject_GetIter(other);
1289 if (it == NULL) {
1290 Py_DECREF(result);
1291 return NULL;
1292 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001295 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001296 if (hash == -1)
1297 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001298 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001299 if (rv < 0)
1300 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001302 if (set_add_entry(result, key, hash))
1303 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 }
1305 Py_DECREF(key);
1306 }
1307 Py_DECREF(it);
1308 if (PyErr_Occurred()) {
1309 Py_DECREF(result);
1310 return NULL;
1311 }
1312 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001313 error:
1314 Py_DECREF(it);
1315 Py_DECREF(result);
1316 Py_DECREF(key);
1317 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001318}
1319
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001320static PyObject *
1321set_intersection_multi(PySetObject *so, PyObject *args)
1322{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 Py_ssize_t i;
1324 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 if (PyTuple_GET_SIZE(args) == 0)
1327 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 Py_INCREF(so);
1330 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1331 PyObject *other = PyTuple_GET_ITEM(args, i);
1332 PyObject *newresult = set_intersection((PySetObject *)result, other);
1333 if (newresult == NULL) {
1334 Py_DECREF(result);
1335 return NULL;
1336 }
1337 Py_DECREF(result);
1338 result = newresult;
1339 }
1340 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001341}
1342
Raymond Hettingera690a992003-11-16 16:17:49 +00001343PyDoc_STRVAR(intersection_doc,
1344"Return the intersection of two sets as a new set.\n\
1345\n\
1346(i.e. all elements that are in both sets.)");
1347
1348static PyObject *
1349set_intersection_update(PySetObject *so, PyObject *other)
1350{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 tmp = set_intersection(so, other);
1354 if (tmp == NULL)
1355 return NULL;
1356 set_swap_bodies(so, (PySetObject *)tmp);
1357 Py_DECREF(tmp);
1358 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001359}
1360
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001361static PyObject *
1362set_intersection_update_multi(PySetObject *so, PyObject *args)
1363{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001364 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 tmp = set_intersection_multi(so, args);
1367 if (tmp == NULL)
1368 return NULL;
1369 set_swap_bodies(so, (PySetObject *)tmp);
1370 Py_DECREF(tmp);
1371 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001372}
1373
Raymond Hettingera690a992003-11-16 16:17:49 +00001374PyDoc_STRVAR(intersection_update_doc,
1375"Update a set with the intersection of itself and another.");
1376
1377static PyObject *
1378set_and(PySetObject *so, PyObject *other)
1379{
Brian Curtindfc80e32011-08-10 20:28:54 -05001380 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1381 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001383}
1384
1385static PyObject *
1386set_iand(PySetObject *so, PyObject *other)
1387{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001389
Brian Curtindfc80e32011-08-10 20:28:54 -05001390 if (!PyAnySet_Check(other))
1391 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 result = set_intersection_update(so, other);
1393 if (result == NULL)
1394 return NULL;
1395 Py_DECREF(result);
1396 Py_INCREF(so);
1397 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001398}
1399
Guido van Rossum58da9312007-11-10 23:39:45 +00001400static PyObject *
1401set_isdisjoint(PySetObject *so, PyObject *other)
1402{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001403 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001404 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001406 if ((PyObject *)so == other) {
1407 if (PySet_GET_SIZE(so) == 0)
1408 Py_RETURN_TRUE;
1409 else
1410 Py_RETURN_FALSE;
1411 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 if (PyAnySet_CheckExact(other)) {
1414 Py_ssize_t pos = 0;
1415 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1418 tmp = (PyObject *)so;
1419 so = (PySetObject *)other;
1420 other = tmp;
1421 }
1422 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001423 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001424 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 return NULL;
1426 if (rv)
1427 Py_RETURN_FALSE;
1428 }
1429 Py_RETURN_TRUE;
1430 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 it = PyObject_GetIter(other);
1433 if (it == NULL)
1434 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001437 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 if (hash == -1) {
1440 Py_DECREF(key);
1441 Py_DECREF(it);
1442 return NULL;
1443 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001444 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001445 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001446 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 Py_DECREF(it);
1448 return NULL;
1449 }
1450 if (rv) {
1451 Py_DECREF(it);
1452 Py_RETURN_FALSE;
1453 }
1454 }
1455 Py_DECREF(it);
1456 if (PyErr_Occurred())
1457 return NULL;
1458 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001459}
1460
1461PyDoc_STRVAR(isdisjoint_doc,
1462"Return True if two sets have a null intersection.");
1463
Neal Norwitz6576bd82005-11-13 18:41:28 +00001464static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001465set_difference_update_internal(PySetObject *so, PyObject *other)
1466{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001467 if ((PyObject *)so == other)
1468 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 if (PyAnySet_Check(other)) {
1471 setentry *entry;
1472 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001475 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 return -1;
1477 } else {
1478 PyObject *key, *it;
1479 it = PyObject_GetIter(other);
1480 if (it == NULL)
1481 return -1;
1482
1483 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001484 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 Py_DECREF(it);
1486 Py_DECREF(key);
1487 return -1;
1488 }
1489 Py_DECREF(key);
1490 }
1491 Py_DECREF(it);
1492 if (PyErr_Occurred())
1493 return -1;
1494 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001495 /* If more than 1/4th are dummies, then resize them away. */
1496 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001497 return 0;
Raymond Hettinger48973002015-07-03 20:00:03 -07001498 return set_table_resize(so, so->used);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001499}
1500
Raymond Hettingera690a992003-11-16 16:17:49 +00001501static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001502set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001503{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1507 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001508 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 return NULL;
1510 }
1511 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001512}
1513
1514PyDoc_STRVAR(difference_update_doc,
1515"Remove all elements of another set from this set.");
1516
1517static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001518set_copy_and_difference(PySetObject *so, PyObject *other)
1519{
1520 PyObject *result;
1521
1522 result = set_copy(so);
1523 if (result == NULL)
1524 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001525 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001526 return result;
1527 Py_DECREF(result);
1528 return NULL;
1529}
1530
1531static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001532set_difference(PySetObject *so, PyObject *other)
1533{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001534 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001535 PyObject *key;
1536 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 setentry *entry;
1538 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001539 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001540
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541 if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001542 return set_copy_and_difference(so, other);
1543 }
1544
1545 /* If len(so) much more than len(other), it's more efficient to simply copy
1546 * so and then iterate other looking for common elements. */
1547 if ((PySet_GET_SIZE(so) >> 2) > PyObject_Size(other)) {
1548 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001550
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001551 result = make_new_set_basetype(Py_TYPE(so), NULL);
1552 if (result == NULL)
1553 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001555 if (PyDict_CheckExact(other)) {
1556 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001557 key = entry->key;
1558 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001559 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001560 if (rv < 0) {
1561 Py_DECREF(result);
1562 return NULL;
1563 }
1564 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001565 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 Py_DECREF(result);
1567 return NULL;
1568 }
1569 }
1570 }
1571 return result;
1572 }
1573
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001574 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001576 key = entry->key;
1577 hash = entry->hash;
1578 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001579 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 Py_DECREF(result);
1581 return NULL;
1582 }
1583 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001584 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 Py_DECREF(result);
1586 return NULL;
1587 }
1588 }
1589 }
1590 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001591}
1592
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001593static PyObject *
1594set_difference_multi(PySetObject *so, PyObject *args)
1595{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001596 Py_ssize_t i;
1597 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001598
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001599 if (PyTuple_GET_SIZE(args) == 0)
1600 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001602 other = PyTuple_GET_ITEM(args, 0);
1603 result = set_difference(so, other);
1604 if (result == NULL)
1605 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001607 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1608 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001609 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001610 Py_DECREF(result);
1611 return NULL;
1612 }
1613 }
1614 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001615}
1616
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001617PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001618"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001619\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001620(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001621static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001622set_sub(PySetObject *so, PyObject *other)
1623{
Brian Curtindfc80e32011-08-10 20:28:54 -05001624 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1625 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001627}
1628
1629static PyObject *
1630set_isub(PySetObject *so, PyObject *other)
1631{
Brian Curtindfc80e32011-08-10 20:28:54 -05001632 if (!PyAnySet_Check(other))
1633 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001634 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 return NULL;
1636 Py_INCREF(so);
1637 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001638}
1639
1640static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001641set_symmetric_difference_update(PySetObject *so, PyObject *other)
1642{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001643 PySetObject *otherset;
1644 PyObject *key;
1645 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001646 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001648 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001649
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001650 if ((PyObject *)so == other)
1651 return set_clear(so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001652
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001653 if (PyDict_CheckExact(other)) {
1654 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001655 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001656 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001657 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001658 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001659 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001661 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001662 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001663 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001664 Py_DECREF(key);
1665 return NULL;
1666 }
1667 }
Georg Brandl2d444492010-09-03 10:52:55 +00001668 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001669 }
1670 Py_RETURN_NONE;
1671 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001672
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001673 if (PyAnySet_Check(other)) {
1674 Py_INCREF(other);
1675 otherset = (PySetObject *)other;
1676 } else {
1677 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1678 if (otherset == NULL)
1679 return NULL;
1680 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001681
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001682 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001683 key = entry->key;
1684 hash = entry->hash;
1685 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001686 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001687 Py_DECREF(otherset);
1688 return NULL;
1689 }
1690 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001691 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001692 Py_DECREF(otherset);
1693 return NULL;
1694 }
1695 }
1696 }
1697 Py_DECREF(otherset);
1698 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001699}
1700
1701PyDoc_STRVAR(symmetric_difference_update_doc,
1702"Update a set with the symmetric difference of itself and another.");
1703
1704static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001705set_symmetric_difference(PySetObject *so, PyObject *other)
1706{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001707 PyObject *rv;
1708 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001709
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001710 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1711 if (otherset == NULL)
1712 return NULL;
1713 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
1714 if (rv == NULL)
1715 return NULL;
1716 Py_DECREF(rv);
1717 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001718}
1719
1720PyDoc_STRVAR(symmetric_difference_doc,
1721"Return the symmetric difference of two sets as a new set.\n\
1722\n\
1723(i.e. all elements that are in exactly one of the sets.)");
1724
1725static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001726set_xor(PySetObject *so, PyObject *other)
1727{
Brian Curtindfc80e32011-08-10 20:28:54 -05001728 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1729 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001730 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001731}
1732
1733static PyObject *
1734set_ixor(PySetObject *so, PyObject *other)
1735{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001736 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001737
Brian Curtindfc80e32011-08-10 20:28:54 -05001738 if (!PyAnySet_Check(other))
1739 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 result = set_symmetric_difference_update(so, other);
1741 if (result == NULL)
1742 return NULL;
1743 Py_DECREF(result);
1744 Py_INCREF(so);
1745 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001746}
1747
1748static PyObject *
1749set_issubset(PySetObject *so, PyObject *other)
1750{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001751 setentry *entry;
1752 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001753 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001754
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001755 if (!PyAnySet_Check(other)) {
1756 PyObject *tmp, *result;
1757 tmp = make_new_set(&PySet_Type, other);
1758 if (tmp == NULL)
1759 return NULL;
1760 result = set_issubset(so, tmp);
1761 Py_DECREF(tmp);
1762 return result;
1763 }
1764 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1765 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001766
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001767 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001768 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001769 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001770 return NULL;
1771 if (!rv)
1772 Py_RETURN_FALSE;
1773 }
1774 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001775}
1776
1777PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1778
1779static PyObject *
1780set_issuperset(PySetObject *so, PyObject *other)
1781{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001782 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001784 if (!PyAnySet_Check(other)) {
1785 tmp = make_new_set(&PySet_Type, other);
1786 if (tmp == NULL)
1787 return NULL;
1788 result = set_issuperset(so, tmp);
1789 Py_DECREF(tmp);
1790 return result;
1791 }
1792 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001793}
1794
1795PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1796
Raymond Hettingera690a992003-11-16 16:17:49 +00001797static PyObject *
1798set_richcompare(PySetObject *v, PyObject *w, int op)
1799{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001800 PyObject *r1;
1801 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001802
Brian Curtindfc80e32011-08-10 20:28:54 -05001803 if(!PyAnySet_Check(w))
1804 Py_RETURN_NOTIMPLEMENTED;
1805
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001806 switch (op) {
1807 case Py_EQ:
1808 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1809 Py_RETURN_FALSE;
1810 if (v->hash != -1 &&
1811 ((PySetObject *)w)->hash != -1 &&
1812 v->hash != ((PySetObject *)w)->hash)
1813 Py_RETURN_FALSE;
1814 return set_issubset(v, w);
1815 case Py_NE:
1816 r1 = set_richcompare(v, w, Py_EQ);
1817 if (r1 == NULL)
1818 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001819 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001820 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001821 if (r2 < 0)
1822 return NULL;
1823 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001824 case Py_LE:
1825 return set_issubset(v, w);
1826 case Py_GE:
1827 return set_issuperset(v, w);
1828 case Py_LT:
1829 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1830 Py_RETURN_FALSE;
1831 return set_issubset(v, w);
1832 case Py_GT:
1833 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1834 Py_RETURN_FALSE;
1835 return set_issuperset(v, w);
1836 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001837 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001838}
1839
Raymond Hettingera690a992003-11-16 16:17:49 +00001840static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001841set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001842{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001843 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001844 return NULL;
1845 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001846}
1847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001849"Add an element to a set.\n\
1850\n\
1851This has no effect if the element is already present.");
1852
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001853static int
1854set_contains(PySetObject *so, PyObject *key)
1855{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856 PyObject *tmpkey;
1857 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001860 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1862 return -1;
1863 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001864 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 if (tmpkey == NULL)
1866 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001867 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 Py_DECREF(tmpkey);
1869 }
1870 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001871}
1872
1873static PyObject *
1874set_direct_contains(PySetObject *so, PyObject *key)
1875{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001879 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 return NULL;
1881 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001882}
1883
1884PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1885
Raymond Hettingera690a992003-11-16 16:17:49 +00001886static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001887set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001888{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001889 PyObject *tmpkey;
1890 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001891
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001893 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1895 return NULL;
1896 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001897 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001898 if (tmpkey == NULL)
1899 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001902 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001903 return NULL;
1904 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001905
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001907 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 return NULL;
1909 }
1910 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001911}
1912
1913PyDoc_STRVAR(remove_doc,
1914"Remove an element from a set; it must be a member.\n\
1915\n\
1916If the element is not a member, raise a KeyError.");
1917
1918static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001919set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001920{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001921 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001923
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001925 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1927 return NULL;
1928 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001929 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 if (tmpkey == NULL)
1931 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001932 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001933 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001934 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001935 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 }
1937 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001938}
1939
1940PyDoc_STRVAR(discard_doc,
1941"Remove an element from a set if it is a member.\n\
1942\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001944
1945static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001946set_reduce(PySetObject *so)
1947{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001948 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001949 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 keys = PySequence_List((PyObject *)so);
1952 if (keys == NULL)
1953 goto done;
1954 args = PyTuple_Pack(1, keys);
1955 if (args == NULL)
1956 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001957 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001958 if (dict == NULL) {
1959 PyErr_Clear();
1960 dict = Py_None;
1961 Py_INCREF(dict);
1962 }
1963 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001964done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001965 Py_XDECREF(args);
1966 Py_XDECREF(keys);
1967 Py_XDECREF(dict);
1968 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001969}
1970
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001971static PyObject *
1972set_sizeof(PySetObject *so)
1973{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001974 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001975
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001976 res = sizeof(PySetObject);
1977 if (so->table != so->smalltable)
1978 res = res + (so->mask + 1) * sizeof(setentry);
1979 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001980}
1981
1982PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001983static int
1984set_init(PySetObject *self, PyObject *args, PyObject *kwds)
1985{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001986 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001988 if (!PyAnySet_Check(self))
1989 return -1;
1990 if (PySet_Check(self) && !_PyArg_NoKeywords("set()", kwds))
1991 return -1;
1992 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
1993 return -1;
1994 set_clear_internal(self);
1995 self->hash = -1;
1996 if (iterable == NULL)
1997 return 0;
1998 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001999}
2000
Raymond Hettingera690a992003-11-16 16:17:49 +00002001static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002002 set_len, /* sq_length */
2003 0, /* sq_concat */
2004 0, /* sq_repeat */
2005 0, /* sq_item */
2006 0, /* sq_slice */
2007 0, /* sq_ass_item */
2008 0, /* sq_ass_slice */
2009 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002010};
2011
2012/* set object ********************************************************/
2013
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002014#ifdef Py_DEBUG
2015static PyObject *test_c_api(PySetObject *so);
2016
2017PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2018All is well if assertions don't fail.");
2019#endif
2020
Raymond Hettingera690a992003-11-16 16:17:49 +00002021static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002022 {"add", (PyCFunction)set_add, METH_O,
2023 add_doc},
2024 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2025 clear_doc},
2026 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2027 contains_doc},
2028 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2029 copy_doc},
2030 {"discard", (PyCFunction)set_discard, METH_O,
2031 discard_doc},
2032 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2033 difference_doc},
2034 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2035 difference_update_doc},
2036 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2037 intersection_doc},
2038 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2039 intersection_update_doc},
2040 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2041 isdisjoint_doc},
2042 {"issubset", (PyCFunction)set_issubset, METH_O,
2043 issubset_doc},
2044 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2045 issuperset_doc},
2046 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2047 pop_doc},
2048 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2049 reduce_doc},
2050 {"remove", (PyCFunction)set_remove, METH_O,
2051 remove_doc},
2052 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2053 sizeof_doc},
2054 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2055 symmetric_difference_doc},
2056 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2057 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002058#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002059 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2060 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002061#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002062 {"union", (PyCFunction)set_union, METH_VARARGS,
2063 union_doc},
2064 {"update", (PyCFunction)set_update, METH_VARARGS,
2065 update_doc},
2066 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002067};
2068
2069static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002070 0, /*nb_add*/
2071 (binaryfunc)set_sub, /*nb_subtract*/
2072 0, /*nb_multiply*/
2073 0, /*nb_remainder*/
2074 0, /*nb_divmod*/
2075 0, /*nb_power*/
2076 0, /*nb_negative*/
2077 0, /*nb_positive*/
2078 0, /*nb_absolute*/
2079 0, /*nb_bool*/
2080 0, /*nb_invert*/
2081 0, /*nb_lshift*/
2082 0, /*nb_rshift*/
2083 (binaryfunc)set_and, /*nb_and*/
2084 (binaryfunc)set_xor, /*nb_xor*/
2085 (binaryfunc)set_or, /*nb_or*/
2086 0, /*nb_int*/
2087 0, /*nb_reserved*/
2088 0, /*nb_float*/
2089 0, /*nb_inplace_add*/
2090 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2091 0, /*nb_inplace_multiply*/
2092 0, /*nb_inplace_remainder*/
2093 0, /*nb_inplace_power*/
2094 0, /*nb_inplace_lshift*/
2095 0, /*nb_inplace_rshift*/
2096 (binaryfunc)set_iand, /*nb_inplace_and*/
2097 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2098 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002099};
2100
2101PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002102"set() -> new empty set object\n\
2103set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002104\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002105Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002106
2107PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002108 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2109 "set", /* tp_name */
2110 sizeof(PySetObject), /* tp_basicsize */
2111 0, /* tp_itemsize */
2112 /* methods */
2113 (destructor)set_dealloc, /* tp_dealloc */
2114 0, /* tp_print */
2115 0, /* tp_getattr */
2116 0, /* tp_setattr */
2117 0, /* tp_reserved */
2118 (reprfunc)set_repr, /* tp_repr */
2119 &set_as_number, /* tp_as_number */
2120 &set_as_sequence, /* tp_as_sequence */
2121 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002122 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 0, /* tp_call */
2124 0, /* tp_str */
2125 PyObject_GenericGetAttr, /* tp_getattro */
2126 0, /* tp_setattro */
2127 0, /* tp_as_buffer */
2128 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2129 Py_TPFLAGS_BASETYPE, /* tp_flags */
2130 set_doc, /* tp_doc */
2131 (traverseproc)set_traverse, /* tp_traverse */
2132 (inquiry)set_clear_internal, /* tp_clear */
2133 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002134 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2135 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002136 0, /* tp_iternext */
2137 set_methods, /* tp_methods */
2138 0, /* tp_members */
2139 0, /* tp_getset */
2140 0, /* tp_base */
2141 0, /* tp_dict */
2142 0, /* tp_descr_get */
2143 0, /* tp_descr_set */
2144 0, /* tp_dictoffset */
2145 (initproc)set_init, /* tp_init */
2146 PyType_GenericAlloc, /* tp_alloc */
2147 set_new, /* tp_new */
2148 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002149};
2150
2151/* frozenset object ********************************************************/
2152
2153
2154static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002155 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2156 contains_doc},
2157 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2158 copy_doc},
2159 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2160 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002161 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002162 intersection_doc},
2163 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2164 isdisjoint_doc},
2165 {"issubset", (PyCFunction)set_issubset, METH_O,
2166 issubset_doc},
2167 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2168 issuperset_doc},
2169 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2170 reduce_doc},
2171 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2172 sizeof_doc},
2173 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2174 symmetric_difference_doc},
2175 {"union", (PyCFunction)set_union, METH_VARARGS,
2176 union_doc},
2177 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002178};
2179
2180static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002181 0, /*nb_add*/
2182 (binaryfunc)set_sub, /*nb_subtract*/
2183 0, /*nb_multiply*/
2184 0, /*nb_remainder*/
2185 0, /*nb_divmod*/
2186 0, /*nb_power*/
2187 0, /*nb_negative*/
2188 0, /*nb_positive*/
2189 0, /*nb_absolute*/
2190 0, /*nb_bool*/
2191 0, /*nb_invert*/
2192 0, /*nb_lshift*/
2193 0, /*nb_rshift*/
2194 (binaryfunc)set_and, /*nb_and*/
2195 (binaryfunc)set_xor, /*nb_xor*/
2196 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002197};
2198
2199PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002200"frozenset() -> empty frozenset object\n\
2201frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002202\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002203Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002204
2205PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002206 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2207 "frozenset", /* tp_name */
2208 sizeof(PySetObject), /* tp_basicsize */
2209 0, /* tp_itemsize */
2210 /* methods */
2211 (destructor)set_dealloc, /* tp_dealloc */
2212 0, /* tp_print */
2213 0, /* tp_getattr */
2214 0, /* tp_setattr */
2215 0, /* tp_reserved */
2216 (reprfunc)set_repr, /* tp_repr */
2217 &frozenset_as_number, /* tp_as_number */
2218 &set_as_sequence, /* tp_as_sequence */
2219 0, /* tp_as_mapping */
2220 frozenset_hash, /* tp_hash */
2221 0, /* tp_call */
2222 0, /* tp_str */
2223 PyObject_GenericGetAttr, /* tp_getattro */
2224 0, /* tp_setattro */
2225 0, /* tp_as_buffer */
2226 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2227 Py_TPFLAGS_BASETYPE, /* tp_flags */
2228 frozenset_doc, /* tp_doc */
2229 (traverseproc)set_traverse, /* tp_traverse */
2230 (inquiry)set_clear_internal, /* tp_clear */
2231 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002232 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002233 (getiterfunc)set_iter, /* tp_iter */
2234 0, /* tp_iternext */
2235 frozenset_methods, /* tp_methods */
2236 0, /* tp_members */
2237 0, /* tp_getset */
2238 0, /* tp_base */
2239 0, /* tp_dict */
2240 0, /* tp_descr_get */
2241 0, /* tp_descr_set */
2242 0, /* tp_dictoffset */
2243 0, /* tp_init */
2244 PyType_GenericAlloc, /* tp_alloc */
2245 frozenset_new, /* tp_new */
2246 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002247};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002248
2249
2250/***** C API functions *************************************************/
2251
2252PyObject *
2253PySet_New(PyObject *iterable)
2254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002255 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002256}
2257
2258PyObject *
2259PyFrozenSet_New(PyObject *iterable)
2260{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002261 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002262}
2263
Neal Norwitz8c49c822006-03-04 18:41:19 +00002264Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002265PySet_Size(PyObject *anyset)
2266{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002267 if (!PyAnySet_Check(anyset)) {
2268 PyErr_BadInternalCall();
2269 return -1;
2270 }
2271 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002272}
2273
2274int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002275PySet_Clear(PyObject *set)
2276{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002277 if (!PySet_Check(set)) {
2278 PyErr_BadInternalCall();
2279 return -1;
2280 }
2281 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002282}
2283
2284int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002285PySet_Contains(PyObject *anyset, PyObject *key)
2286{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002287 if (!PyAnySet_Check(anyset)) {
2288 PyErr_BadInternalCall();
2289 return -1;
2290 }
2291 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002292}
2293
2294int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002295PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002296{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002297 if (!PySet_Check(set)) {
2298 PyErr_BadInternalCall();
2299 return -1;
2300 }
2301 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002302}
2303
2304int
Christian Heimesfd66e512008-01-29 12:18:50 +00002305PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002306{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002307 if (!PySet_Check(anyset) &&
2308 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2309 PyErr_BadInternalCall();
2310 return -1;
2311 }
2312 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002313}
2314
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002315int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002316_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002317{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002318 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002320 if (!PyAnySet_Check(set)) {
2321 PyErr_BadInternalCall();
2322 return -1;
2323 }
2324 if (set_next((PySetObject *)set, pos, &entry) == 0)
2325 return 0;
2326 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002327 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002328 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002329}
2330
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002331PyObject *
2332PySet_Pop(PyObject *set)
2333{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002334 if (!PySet_Check(set)) {
2335 PyErr_BadInternalCall();
2336 return NULL;
2337 }
2338 return set_pop((PySetObject *)set);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002339}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002340
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002341int
2342_PySet_Update(PyObject *set, PyObject *iterable)
2343{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002344 if (!PySet_Check(set)) {
2345 PyErr_BadInternalCall();
2346 return -1;
2347 }
2348 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002349}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002350
Raymond Hettingere259f132013-12-15 11:56:14 -08002351/* Exported for the gdb plugin's benefit. */
2352PyObject *_PySet_Dummy = dummy;
2353
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002354#ifdef Py_DEBUG
2355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002356/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002357 Returns True and original set is restored. */
2358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002359#define assertRaises(call_return_value, exception) \
2360 do { \
2361 assert(call_return_value); \
2362 assert(PyErr_ExceptionMatches(exception)); \
2363 PyErr_Clear(); \
2364 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002365
2366static PyObject *
2367test_c_api(PySetObject *so)
2368{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002369 Py_ssize_t count;
2370 char *s;
2371 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002372 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002373 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002374 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002375 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002377 /* Verify preconditions */
2378 assert(PyAnySet_Check(ob));
2379 assert(PyAnySet_CheckExact(ob));
2380 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002382 /* so.clear(); so |= set("abc"); */
2383 str = PyUnicode_FromString("abc");
2384 if (str == NULL)
2385 return NULL;
2386 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002387 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002388 Py_DECREF(str);
2389 return NULL;
2390 }
2391 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002392
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002393 /* Exercise type/size checks */
2394 assert(PySet_Size(ob) == 3);
2395 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002397 /* Raise TypeError for non-iterable constructor arguments */
2398 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2399 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002400
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002401 /* Raise TypeError for unhashable key */
2402 dup = PySet_New(ob);
2403 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2404 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2405 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002406
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002407 /* Exercise successful pop, contains, add, and discard */
2408 elem = PySet_Pop(ob);
2409 assert(PySet_Contains(ob, elem) == 0);
2410 assert(PySet_GET_SIZE(ob) == 2);
2411 assert(PySet_Add(ob, elem) == 0);
2412 assert(PySet_Contains(ob, elem) == 1);
2413 assert(PySet_GET_SIZE(ob) == 3);
2414 assert(PySet_Discard(ob, elem) == 1);
2415 assert(PySet_GET_SIZE(ob) == 2);
2416 assert(PySet_Discard(ob, elem) == 0);
2417 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002418
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002419 /* Exercise clear */
2420 dup2 = PySet_New(dup);
2421 assert(PySet_Clear(dup2) == 0);
2422 assert(PySet_Size(dup2) == 0);
2423 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002425 /* Raise SystemError on clear or update of frozen set */
2426 f = PyFrozenSet_New(dup);
2427 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2428 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2429 assert(PySet_Add(f, elem) == 0);
2430 Py_INCREF(f);
2431 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2432 Py_DECREF(f);
2433 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002434
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002435 /* Exercise direct iteration */
2436 i = 0, count = 0;
2437 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
2438 s = _PyUnicode_AsString(x);
2439 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2440 count++;
2441 }
2442 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002443
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002444 /* Exercise updates */
2445 dup2 = PySet_New(NULL);
2446 assert(_PySet_Update(dup2, dup) == 0);
2447 assert(PySet_Size(dup2) == 3);
2448 assert(_PySet_Update(dup2, dup) == 0);
2449 assert(PySet_Size(dup2) == 3);
2450 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002452 /* Raise SystemError when self argument is not a set or frozenset. */
2453 t = PyTuple_New(0);
2454 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2455 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2456 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002458 /* Raise SystemError when self argument is not a set. */
2459 f = PyFrozenSet_New(dup);
2460 assert(PySet_Size(f) == 3);
2461 assert(PyFrozenSet_CheckExact(f));
2462 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2463 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2464 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002466 /* Raise KeyError when popping from an empty set */
2467 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2468 Py_DECREF(ob);
2469 assert(PySet_GET_SIZE(ob) == 0);
2470 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002472 /* Restore the set from the copy using the PyNumber API */
2473 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2474 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002476 /* Verify constructors accept NULL arguments */
2477 f = PySet_New(NULL);
2478 assert(f != NULL);
2479 assert(PySet_GET_SIZE(f) == 0);
2480 Py_DECREF(f);
2481 f = PyFrozenSet_New(NULL);
2482 assert(f != NULL);
2483 assert(PyFrozenSet_CheckExact(f));
2484 assert(PySet_GET_SIZE(f) == 0);
2485 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002487 Py_DECREF(elem);
2488 Py_DECREF(dup);
2489 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002490}
2491
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002492#undef assertRaises
2493
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002494#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002495
2496/***** Dummy Struct *************************************************/
2497
2498static PyObject *
2499dummy_repr(PyObject *op)
2500{
2501 return PyUnicode_FromString("<dummy key>");
2502}
2503
2504static void
2505dummy_dealloc(PyObject* ignore)
2506{
2507 Py_FatalError("deallocating <dummy key>");
2508}
2509
2510static PyTypeObject _PySetDummy_Type = {
2511 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2512 "<dummy key> type",
2513 0,
2514 0,
2515 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2516 0, /*tp_print*/
2517 0, /*tp_getattr*/
2518 0, /*tp_setattr*/
2519 0, /*tp_reserved*/
2520 dummy_repr, /*tp_repr*/
2521 0, /*tp_as_number*/
2522 0, /*tp_as_sequence*/
2523 0, /*tp_as_mapping*/
2524 0, /*tp_hash */
2525 0, /*tp_call */
2526 0, /*tp_str */
2527 0, /*tp_getattro */
2528 0, /*tp_setattro */
2529 0, /*tp_as_buffer */
2530 Py_TPFLAGS_DEFAULT, /*tp_flags */
2531};
2532
2533static PyObject _dummy_struct = {
2534 _PyObject_EXTRA_INIT
2535 2, &_PySetDummy_Type
2536};
2537