blob: d0fb4f14f443b9fc3fb1ed72918ba6c9bbc6a1ed [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
130set_insert_key(PySetObject *so, PyObject *key, Py_hash_t hash)
131{
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 */
165 return set_insert_key(so, key, hash);
166 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)
193 return set_insert_key(so, key, hash);
194 if (cmp > 0)
195 goto found_active;
196 mask = so->mask;
197 }
Raymond Hettinger91672612015-06-26 02:50:21 -0700198 else if (entry->hash == -1 && freeslot == NULL)
Raymond Hettingerc658d852015-02-02 08:35:00 -0800199 freeslot = entry;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700200 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000201 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700202
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700203 perturb >>= PERTURB_SHIFT;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -0800204 i = (i * 5 + 1 + perturb) & mask;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700205
Raymond Hettinger59ecabd2015-01-31 02:45:12 -0800206 entry = &table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700207 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700208 goto found_unused_or_dummy;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700210
Raymond Hettinger15f08692015-07-03 17:21:17 -0700211 found_unused_or_dummy:
212 if (freeslot == NULL)
213 goto found_unused;
214 Py_INCREF(key);
215 so->used++;
216 freeslot->key = key;
217 freeslot->hash = hash;
218 return 0;
219
220 found_unused:
Raymond Hettinger2eff9e92015-06-27 22:03:35 -0700221 Py_INCREF(key);
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700222 so->fill++;
223 so->used++;
224 entry->key = key;
225 entry->hash = hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700226 if ((size_t)so->fill*3 < mask*2)
227 return 0;
Raymond Hettinger48973002015-07-03 20:00:03 -0700228 return set_table_resize(so, so->used);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700229
230 found_active:
Raymond Hettinger8651a502015-05-27 10:37:20 -0700231 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000232}
233
234/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000235Internal routine used by set_table_resize() to insert an item which is
236known to be absent from the set. This routine also assumes that
237the set contains no deleted entries. Besides the performance benefit,
238using set_insert_clean() in set_table_resize() is dangerous (SF bug #1456209).
239Note that no refcounts are changed by this routine; if needed, the caller
240is responsible for incref'ing `key`.
241*/
242static void
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200243set_insert_clean(PySetObject *so, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000244{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 setentry *table = so->table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200246 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700247 size_t perturb = hash;
248 size_t mask = (size_t)so->mask;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800249 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700250 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000251
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700252 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800253 entry = &table[i];
254 if (entry->key == NULL)
255 goto found_null;
256 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800257 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800258 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800259 if (entry->key == NULL)
260 goto found_null;
261 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700262 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700263 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800264 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000265 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700266 found_null:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 entry->key = key;
268 entry->hash = hash;
Raymond Hettinger4ef05282013-09-21 15:39:49 -0700269 so->fill++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 so->used++;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000271}
272
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700273/* ======== End logic for probing the hash table ========================== */
274/* ======================================================================== */
275
Thomas Wouters89f507f2006-12-13 04:49:30 +0000276/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000277Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000278keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000279actually be smaller than the old one.
280*/
281static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000282set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000283{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 Py_ssize_t newsize;
285 setentry *oldtable, *newtable, *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800286 Py_ssize_t oldfill = so->fill;
287 Py_ssize_t oldused = so->used;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 int is_oldtable_malloced;
289 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 assert(minused >= 0);
Raymond Hettinger48973002015-07-03 20:00:03 -0700292 minused = (minused > 50000) ? minused * 2 : minused * 4;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000294 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100295 /* XXX speed-up with intrinsics */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 for (newsize = PySet_MINSIZE;
297 newsize <= minused && newsize > 0;
298 newsize <<= 1)
299 ;
300 if (newsize <= 0) {
301 PyErr_NoMemory();
302 return -1;
303 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 /* Get space for a new table. */
306 oldtable = so->table;
307 assert(oldtable != NULL);
308 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 if (newsize == PySet_MINSIZE) {
311 /* A large table is shrinking, or we can't get any smaller. */
312 newtable = so->smalltable;
313 if (newtable == oldtable) {
314 if (so->fill == so->used) {
315 /* No dummies, so no point doing anything. */
316 return 0;
317 }
318 /* We're not going to resize it, but rebuild the
319 table anyway to purge old dummy entries.
320 Subtle: This is *necessary* if fill==size,
321 as set_lookkey needs at least one virgin slot to
322 terminate failing searches. If fill < size, it's
323 merely desirable, as dummies slow searches. */
324 assert(so->fill > so->used);
325 memcpy(small_copy, oldtable, sizeof(small_copy));
326 oldtable = small_copy;
327 }
328 }
329 else {
330 newtable = PyMem_NEW(setentry, newsize);
331 if (newtable == NULL) {
332 PyErr_NoMemory();
333 return -1;
334 }
335 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000337 /* Make the set empty, using the new table. */
338 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339 memset(newtable, 0, sizeof(setentry) * newsize);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000340 so->fill = 0;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800341 so->used = 0;
342 so->mask = newsize - 1;
343 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345 /* Copy the data over; this is refcount-neutral for active entries;
346 dummy entries aren't copied over, of course */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800347 if (oldfill == oldused) {
348 for (entry = oldtable; oldused > 0; entry++) {
349 if (entry->key != NULL) {
350 oldused--;
351 set_insert_clean(so, entry->key, entry->hash);
352 }
353 }
354 } else {
355 for (entry = oldtable; oldused > 0; entry++) {
356 if (entry->key != NULL && entry->key != dummy) {
357 oldused--;
358 set_insert_clean(so, entry->key, entry->hash);
359 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000360 }
361 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 if (is_oldtable_malloced)
364 PyMem_DEL(oldtable);
365 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000366}
367
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000368static int
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200369set_add_entry(PySetObject *so, setentry *entry)
Raymond Hettingerc991db22005-08-11 07:58:45 +0000370{
Raymond Hettinger15f08692015-07-03 17:21:17 -0700371 return set_insert_key(so, entry->key, entry->hash);
Raymond Hettingerc991db22005-08-11 07:58:45 +0000372}
373
374static int
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200375set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000376{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200377 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200380 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 hash = PyObject_Hash(key);
382 if (hash == -1)
383 return -1;
384 }
Raymond Hettinger15f08692015-07-03 17:21:17 -0700385 return set_insert_key(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000386}
387
388#define DISCARD_NOTFOUND 0
389#define DISCARD_FOUND 1
390
391static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000392set_discard_entry(PySetObject *so, setentry *oldentry)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800393{
394 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000395 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000396
Raymond Hettinger93035c42015-01-25 16:12:49 -0800397 entry = set_lookkey(so, oldentry->key, oldentry->hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000398 if (entry == NULL)
399 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700400 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000401 return DISCARD_NOTFOUND;
402 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800404 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 so->used--;
406 Py_DECREF(old_key);
407 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000408}
409
410static int
411set_discard_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000412{
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800413 setentry entry;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200414 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 assert (PyAnySet_Check(so));
Christian Heimes0ded5b52007-12-10 15:50:56 +0000417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000418 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200419 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 hash = PyObject_Hash(key);
421 if (hash == -1)
422 return -1;
423 }
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800424 entry.key = key;
425 entry.hash = hash;
426 return set_discard_entry(so, &entry);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000427}
428
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700429static void
430set_empty_to_minsize(PySetObject *so)
431{
432 memset(so->smalltable, 0, sizeof(so->smalltable));
433 so->fill = 0;
434 so->used = 0;
435 so->mask = PySet_MINSIZE - 1;
436 so->table = so->smalltable;
437 so->hash = -1;
438}
439
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000440static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000441set_clear_internal(PySetObject *so)
442{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800443 setentry *entry;
444 setentry *table = so->table;
445 Py_ssize_t fill = so->fill;
446 Py_ssize_t used = so->used;
447 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000448 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000449
Raymond Hettinger583cd032013-09-07 22:06:35 -0700450 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 /* This is delicate. During the process of clearing the set,
454 * decrefs can cause the set to mutate. To avoid fatal confusion
455 * (voice of experience), we have to make the set empty before
456 * clearing the slots, and never refer to anything via so->ref while
457 * clearing.
458 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700460 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 else if (fill > 0) {
463 /* It's a small table with something that needs to be cleared.
464 * Afraid the only safe way is to copy the set entries into
465 * another small table first.
466 */
467 memcpy(small_copy, table, sizeof(small_copy));
468 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700469 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 }
471 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000472
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473 /* Now we can finally clear things. If C had refcounts, we could
474 * assert that the refcount on table is 1 now, i.e. that this function
475 * has unique access to it, so decref side-effects can't alter it.
476 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800477 for (entry = table; used > 0; entry++) {
478 if (entry->key && entry->key != dummy) {
479 used--;
480 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000482 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 if (table_is_malloced)
485 PyMem_DEL(table);
486 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000487}
488
489/*
490 * Iterate over a set table. Use like so:
491 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000492 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000493 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000494 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000495 * while (set_next(yourset, &pos, &entry)) {
496 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000497 * }
498 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000499 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000501 */
502static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000503set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000504{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 Py_ssize_t i;
506 Py_ssize_t mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200507 setentry *table;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 assert (PyAnySet_Check(so));
510 i = *pos_ptr;
511 assert(i >= 0);
512 table = so->table;
513 mask = so->mask;
514 while (i <= mask && (table[i].key == NULL || table[i].key == dummy))
515 i++;
516 *pos_ptr = i+1;
517 if (i > mask)
518 return 0;
519 assert(table[i].key != NULL);
520 *entry_ptr = &table[i];
521 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000522}
523
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000524static void
525set_dealloc(PySetObject *so)
526{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200527 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800528 Py_ssize_t used = so->used;
529
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000530 PyObject_GC_UnTrack(so);
531 Py_TRASHCAN_SAFE_BEGIN(so)
532 if (so->weakreflist != NULL)
533 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000534
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800535 for (entry = so->table; used > 0; entry++) {
536 if (entry->key && entry->key != dummy) {
537 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700538 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 }
540 }
541 if (so->table != so->smalltable)
542 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700543 Py_TYPE(so)->tp_free(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000544 Py_TRASHCAN_SAFE_END(so)
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000545}
546
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000547static PyObject *
548set_repr(PySetObject *so)
549{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200550 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000552
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000553 if (status != 0) {
554 if (status < 0)
555 return NULL;
556 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
557 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000558
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000559 /* shortcut for the empty set */
560 if (!so->used) {
561 Py_ReprLeave((PyObject*)so);
562 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
563 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000565 keys = PySequence_List((PyObject *)so);
566 if (keys == NULL)
567 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000568
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200569 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 listrepr = PyObject_Repr(keys);
571 Py_DECREF(keys);
572 if (listrepr == NULL)
573 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200574 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000575 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200576 if (tmp == NULL)
577 goto done;
578 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200579
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200580 if (Py_TYPE(so) != &PySet_Type)
581 result = PyUnicode_FromFormat("%s({%U})",
582 Py_TYPE(so)->tp_name,
583 listrepr);
584 else
585 result = PyUnicode_FromFormat("{%U}", listrepr);
586 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000587done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 Py_ReprLeave((PyObject*)so);
589 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000590}
591
Martin v. Löwis18e16552006-02-15 17:27:45 +0000592static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000593set_len(PyObject *so)
594{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000596}
597
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000598static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000599set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000600{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000601 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000602 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200603 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700604 setentry *so_entry;
605 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 assert (PyAnySet_Check(so));
608 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000609
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 other = (PySetObject*)otherset;
611 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700612 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000613 return 0;
614 /* Do one big resize at the start, rather than
615 * incrementally resizing as we insert new keys. Expect
616 * that there will be no (or few) overlapping keys.
617 */
Raymond Hettinger15f08692015-07-03 17:21:17 -0700618 if ((so->fill + other->used)*3 >= so->mask*2) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700619 if (set_table_resize(so, so->used + other->used) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000620 return -1;
621 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700622 so_entry = so->table;
623 other_entry = other->table;
624
625 /* If our table is empty, and both tables have the same size, and
626 there are no dummies to eliminate, then just copy the pointers. */
627 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
628 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
629 key = other_entry->key;
630 if (key != NULL) {
631 assert(so_entry->key == NULL);
632 Py_INCREF(key);
633 so_entry->key = key;
634 so_entry->hash = other_entry->hash;
635 }
636 }
637 so->fill = other->fill;
638 so->used = other->used;
639 return 0;
640 }
641
642 /* If our table is empty, we can use set_insert_clean() */
643 if (so->fill == 0) {
644 for (i = 0; i <= other->mask; i++, other_entry++) {
645 key = other_entry->key;
646 if (key != NULL && key != dummy) {
647 Py_INCREF(key);
648 set_insert_clean(so, key, other_entry->hash);
649 }
650 }
651 return 0;
652 }
653
654 /* We can't assure there are no duplicates, so do normal insertions */
655 for (i = 0; i <= other->mask; i++, other_entry++) {
656 key = other_entry->key;
657 if (key != NULL && key != dummy) {
Raymond Hettinger2eff9e92015-06-27 22:03:35 -0700658 if (set_insert_key(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000659 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 }
661 }
662 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000663}
664
665static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000666set_contains_entry(PySetObject *so, setentry *entry)
667{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000668 PyObject *key;
669 setentry *lu_entry;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000670
Raymond Hettinger93035c42015-01-25 16:12:49 -0800671 lu_entry = set_lookkey(so, entry->key, entry->hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672 if (lu_entry == NULL)
673 return -1;
674 key = lu_entry->key;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700675 return key != NULL;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000676}
677
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800678static int
679set_contains_key(PySetObject *so, PyObject *key)
680{
Raymond Hettinger3c1f52e2015-07-03 18:31:09 -0700681 setentry *entry;
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800682 Py_hash_t hash;
683
684 if (!PyUnicode_CheckExact(key) ||
685 (hash = ((PyASCIIObject *) key)->hash) == -1) {
686 hash = PyObject_Hash(key);
687 if (hash == -1)
688 return -1;
689 }
Raymond Hettinger3c1f52e2015-07-03 18:31:09 -0700690 entry = set_lookkey(so, key, hash);
691 if (entry == NULL)
692 return -1;
693 return entry->key != NULL;
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800694}
695
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000696static PyObject *
697set_pop(PySetObject *so)
698{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800699 /* Make sure the search finger is in bounds */
700 Py_ssize_t i = so->finger & so->mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200701 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000702 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000703
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000704 assert (PyAnySet_Check(so));
705 if (so->used == 0) {
706 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
707 return NULL;
708 }
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000709
Raymond Hettinger1202a472015-01-18 13:12:42 -0800710 while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
711 i++;
Raymond Hettingered741d42015-01-18 21:25:15 -0800712 if (i > so->mask)
713 i = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000714 }
715 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800717 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 so->used--;
Raymond Hettinger1202a472015-01-18 13:12:42 -0800719 so->finger = i + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000721}
722
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000723PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
724Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000725
726static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000727set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000728{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000729 Py_ssize_t pos = 0;
730 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000731
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000732 while (set_next(so, &pos, &entry))
733 Py_VISIT(entry->key);
734 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000735}
736
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000737static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000738frozenset_hash(PyObject *self)
739{
Raymond Hettinger74fc8c42014-01-05 12:00:31 -0800740 /* Most of the constants in this hash algorithm are randomly choosen
741 large primes with "interesting bit patterns" and that passed
742 tests for good collision statistics on a variety of problematic
743 datasets such as:
744
745 ps = []
746 for r in range(21):
747 ps += itertools.combinations(range(20), r)
748 num_distinct_hashes = len({hash(frozenset(s)) for s in ps})
749
750 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000751 PySetObject *so = (PySetObject *)self;
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800752 Py_uhash_t h, hash = 1927868237UL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000753 setentry *entry;
754 Py_ssize_t pos = 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000755
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000756 if (so->hash != -1)
757 return so->hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000758
Mark Dickinson57e683e2011-09-24 18:18:40 +0100759 hash *= (Py_uhash_t)PySet_GET_SIZE(self) + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000760 while (set_next(so, &pos, &entry)) {
761 /* Work to increase the bit dispersion for closely spaced hash
Raymond Hettinger06a1c8d2015-01-30 18:02:15 -0800762 values. This is important because some use cases have many
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000763 combinations of a small number of elements with nearby
764 hashes so that many distinct combinations collapse to only
765 a handful of distinct hash values. */
Antoine Pitroufbb1c612010-10-23 17:37:54 +0000766 h = entry->hash;
Raymond Hettinger74fc8c42014-01-05 12:00:31 -0800767 hash ^= ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000768 }
Raymond Hettinger74fc8c42014-01-05 12:00:31 -0800769 /* Make the final result spread-out in a different pattern
Eric V. Smith6ba56652014-01-14 08:15:03 -0500770 than the algorithm for tuples or other python objects. */
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800771 hash = hash * 69069U + 907133923UL;
Victor Stinner12174a52014-08-15 23:17:38 +0200772 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800773 hash = 590923713UL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000774 so->hash = hash;
775 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000776}
777
Raymond Hettingera9d99362005-08-05 00:01:15 +0000778/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000779
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000780typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000781 PyObject_HEAD
782 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
783 Py_ssize_t si_used;
784 Py_ssize_t si_pos;
785 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000786} setiterobject;
787
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000788static void
789setiter_dealloc(setiterobject *si)
790{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000791 Py_XDECREF(si->si_set);
792 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000793}
794
795static int
796setiter_traverse(setiterobject *si, visitproc visit, void *arg)
797{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 Py_VISIT(si->si_set);
799 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000800}
801
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000802static PyObject *
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000803setiter_len(setiterobject *si)
804{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000805 Py_ssize_t len = 0;
806 if (si->si_set != NULL && si->si_used == si->si_set->used)
807 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000808 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000809}
810
Armin Rigof5b3e362006-02-11 21:32:43 +0000811PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000812
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000813static PyObject *setiter_iternext(setiterobject *si);
814
815static PyObject *
816setiter_reduce(setiterobject *si)
817{
818 PyObject *list;
819 setiterobject tmp;
820
821 list = PyList_New(0);
822 if (!list)
823 return NULL;
824
Ezio Melotti0e1af282012-09-28 16:43:40 +0300825 /* copy the iterator state */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000826 tmp = *si;
827 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300828
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000829 /* iterate the temporary into a list */
830 for(;;) {
831 PyObject *element = setiter_iternext(&tmp);
832 if (element) {
833 if (PyList_Append(list, element)) {
834 Py_DECREF(element);
835 Py_DECREF(list);
836 Py_XDECREF(tmp.si_set);
837 return NULL;
838 }
839 Py_DECREF(element);
840 } else
841 break;
842 }
843 Py_XDECREF(tmp.si_set);
844 /* check for error */
845 if (tmp.si_set != NULL) {
846 /* we have an error */
847 Py_DECREF(list);
848 return NULL;
849 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200850 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000851}
852
853PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
854
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000855static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000856 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000857 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000858 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000859};
860
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000861static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000862{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000863 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200864 Py_ssize_t i, mask;
865 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000866 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000868 if (so == NULL)
869 return NULL;
870 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000872 if (si->si_used != so->used) {
873 PyErr_SetString(PyExc_RuntimeError,
874 "Set changed size during iteration");
875 si->si_used = -1; /* Make this state sticky */
876 return NULL;
877 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000878
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000879 i = si->si_pos;
880 assert(i>=0);
881 entry = so->table;
882 mask = so->mask;
883 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
884 i++;
885 si->si_pos = i+1;
886 if (i > mask)
887 goto fail;
888 si->len--;
889 key = entry[i].key;
890 Py_INCREF(key);
891 return key;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000892
893fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000894 Py_DECREF(so);
895 si->si_set = NULL;
896 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000897}
898
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000899PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000900 PyVarObject_HEAD_INIT(&PyType_Type, 0)
901 "set_iterator", /* tp_name */
902 sizeof(setiterobject), /* tp_basicsize */
903 0, /* tp_itemsize */
904 /* methods */
905 (destructor)setiter_dealloc, /* tp_dealloc */
906 0, /* tp_print */
907 0, /* tp_getattr */
908 0, /* tp_setattr */
909 0, /* tp_reserved */
910 0, /* tp_repr */
911 0, /* tp_as_number */
912 0, /* tp_as_sequence */
913 0, /* tp_as_mapping */
914 0, /* tp_hash */
915 0, /* tp_call */
916 0, /* tp_str */
917 PyObject_GenericGetAttr, /* tp_getattro */
918 0, /* tp_setattro */
919 0, /* tp_as_buffer */
920 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
921 0, /* tp_doc */
922 (traverseproc)setiter_traverse, /* tp_traverse */
923 0, /* tp_clear */
924 0, /* tp_richcompare */
925 0, /* tp_weaklistoffset */
926 PyObject_SelfIter, /* tp_iter */
927 (iternextfunc)setiter_iternext, /* tp_iternext */
928 setiter_methods, /* tp_methods */
929 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000930};
931
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000932static PyObject *
933set_iter(PySetObject *so)
934{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000935 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
936 if (si == NULL)
937 return NULL;
938 Py_INCREF(so);
939 si->si_set = so;
940 si->si_used = so->used;
941 si->si_pos = 0;
942 si->len = so->used;
943 _PyObject_GC_TRACK(si);
944 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000945}
946
Raymond Hettingerd7946662005-08-01 21:39:29 +0000947static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000948set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000949{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000950 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000952 if (PyAnySet_Check(other))
953 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000954
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000955 if (PyDict_CheckExact(other)) {
956 PyObject *value;
957 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000958 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000959 Py_ssize_t dictsize = PyDict_Size(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 /* Do one big resize at the start, rather than
962 * incrementally resizing as we insert new keys. Expect
963 * that there will be no (or few) overlapping keys.
964 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700965 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 return -1;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700967 if ((so->fill + dictsize)*3 >= so->mask*2) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700968 if (set_table_resize(so, so->used + dictsize) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 return -1;
970 }
971 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger15f08692015-07-03 17:21:17 -0700972 if (set_insert_key(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 return -1;
974 }
975 return 0;
976 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 it = PyObject_GetIter(other);
979 if (it == NULL)
980 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +0000981
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700983 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 Py_DECREF(it);
985 Py_DECREF(key);
986 return -1;
987 }
988 Py_DECREF(key);
989 }
990 Py_DECREF(it);
991 if (PyErr_Occurred())
992 return -1;
993 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000994}
995
996static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000997set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +0000998{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001000
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001001 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1002 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001003 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 return NULL;
1005 }
1006 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001007}
1008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001009PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001010"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001011
Raymond Hettinger426d9952014-05-18 21:40:20 +01001012/* XXX Todo:
1013 If aligned memory allocations become available, make the
1014 set object 64 byte aligned so that most of the fields
1015 can be retrieved or updated in a single cache line.
1016*/
1017
Raymond Hettingera38123e2003-11-24 22:18:49 +00001018static PyObject *
1019make_new_set(PyTypeObject *type, PyObject *iterable)
1020{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001021 PySetObject *so = NULL;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001022
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 /* create PySetObject structure */
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001024 so = (PySetObject *)type->tp_alloc(type, 0);
1025 if (so == NULL)
1026 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001027
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001028 so->fill = 0;
1029 so->used = 0;
1030 so->mask = PySet_MINSIZE - 1;
1031 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001032 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001033 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001035
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001037 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001038 Py_DECREF(so);
1039 return NULL;
1040 }
1041 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001042
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001043 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001044}
1045
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001046static PyObject *
1047make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1048{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1050 if (PyType_IsSubtype(type, &PySet_Type))
1051 type = &PySet_Type;
1052 else
1053 type = &PyFrozenSet_Type;
1054 }
1055 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001056}
1057
Raymond Hettingerd7946662005-08-01 21:39:29 +00001058/* The empty frozenset is a singleton */
1059static PyObject *emptyfrozenset = NULL;
1060
Raymond Hettingera690a992003-11-16 16:17:49 +00001061static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001062frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001063{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001064 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset()", kwds))
1067 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1070 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001071
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 if (type != &PyFrozenSet_Type)
1073 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001074
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001075 if (iterable != NULL) {
1076 /* frozenset(f) is idempotent */
1077 if (PyFrozenSet_CheckExact(iterable)) {
1078 Py_INCREF(iterable);
1079 return iterable;
1080 }
1081 result = make_new_set(type, iterable);
1082 if (result == NULL || PySet_GET_SIZE(result))
1083 return result;
1084 Py_DECREF(result);
1085 }
1086 /* The empty frozenset is a singleton */
1087 if (emptyfrozenset == NULL)
1088 emptyfrozenset = make_new_set(type, NULL);
1089 Py_XINCREF(emptyfrozenset);
1090 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001091}
1092
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001093int
1094PySet_ClearFreeList(void)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001095{
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001096 return 0;
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001097}
1098
1099void
1100PySet_Fini(void)
1101{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 Py_CLEAR(emptyfrozenset);
Raymond Hettingera690a992003-11-16 16:17:49 +00001103}
1104
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001105static PyObject *
1106set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1107{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001108 if (type == &PySet_Type && !_PyArg_NoKeywords("set()", kwds))
1109 return NULL;
1110
1111 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001112}
1113
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001114/* set_swap_bodies() switches the contents of any two sets by moving their
1115 internal data pointers and, if needed, copying the internal smalltables.
1116 Semantically equivalent to:
1117
1118 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1119
1120 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001121 Useful for operations that update in-place (by allowing an intermediate
1122 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001123*/
1124
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001125static void
1126set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001127{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001128 Py_ssize_t t;
1129 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001130 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001131 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001133 t = a->fill; a->fill = b->fill; b->fill = t;
1134 t = a->used; a->used = b->used; b->used = t;
1135 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001137 u = a->table;
1138 if (a->table == a->smalltable)
1139 u = b->smalltable;
1140 a->table = b->table;
1141 if (b->table == b->smalltable)
1142 a->table = a->smalltable;
1143 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 if (a->table == a->smalltable || b->table == b->smalltable) {
1146 memcpy(tab, a->smalltable, sizeof(tab));
1147 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1148 memcpy(b->smalltable, tab, sizeof(tab));
1149 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1152 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1153 h = a->hash; a->hash = b->hash; b->hash = h;
1154 } else {
1155 a->hash = -1;
1156 b->hash = -1;
1157 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001158}
1159
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001160static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001161set_copy(PySetObject *so)
1162{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001163 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001164}
1165
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001166static PyObject *
1167frozenset_copy(PySetObject *so)
1168{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001169 if (PyFrozenSet_CheckExact(so)) {
1170 Py_INCREF(so);
1171 return (PyObject *)so;
1172 }
1173 return set_copy(so);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001174}
1175
Raymond Hettingera690a992003-11-16 16:17:49 +00001176PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1177
1178static PyObject *
Raymond Hettingerc991db22005-08-11 07:58:45 +00001179set_clear(PySetObject *so)
1180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001181 set_clear_internal(so);
1182 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001183}
1184
1185PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1186
1187static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001188set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001189{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 PySetObject *result;
1191 PyObject *other;
1192 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001194 result = (PySetObject *)set_copy(so);
1195 if (result == NULL)
1196 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001197
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001198 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1199 other = PyTuple_GET_ITEM(args, i);
1200 if ((PyObject *)so == other)
1201 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001202 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001203 Py_DECREF(result);
1204 return NULL;
1205 }
1206 }
1207 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001208}
1209
1210PyDoc_STRVAR(union_doc,
1211 "Return the union of sets as a new set.\n\
1212\n\
1213(i.e. all elements that are in either set.)");
1214
1215static PyObject *
1216set_or(PySetObject *so, PyObject *other)
1217{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001218 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001219
Brian Curtindfc80e32011-08-10 20:28:54 -05001220 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1221 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001223 result = (PySetObject *)set_copy(so);
1224 if (result == NULL)
1225 return NULL;
1226 if ((PyObject *)so == other)
1227 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001228 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001229 Py_DECREF(result);
1230 return NULL;
1231 }
1232 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001233}
1234
Raymond Hettingera690a992003-11-16 16:17:49 +00001235static PyObject *
1236set_ior(PySetObject *so, PyObject *other)
1237{
Brian Curtindfc80e32011-08-10 20:28:54 -05001238 if (!PyAnySet_Check(other))
1239 Py_RETURN_NOTIMPLEMENTED;
1240
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001241 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 return NULL;
1243 Py_INCREF(so);
1244 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001245}
1246
1247static PyObject *
1248set_intersection(PySetObject *so, PyObject *other)
1249{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 PySetObject *result;
1251 PyObject *key, *it, *tmp;
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)) {
1271 int rv = set_contains_entry(so, entry);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001272 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 Py_DECREF(result);
1274 return NULL;
1275 }
1276 if (rv) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001277 if (set_add_entry(result, entry)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001278 Py_DECREF(result);
1279 return NULL;
1280 }
1281 }
1282 }
1283 return (PyObject *)result;
1284 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001286 it = PyObject_GetIter(other);
1287 if (it == NULL) {
1288 Py_DECREF(result);
1289 return NULL;
1290 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 while ((key = PyIter_Next(it)) != NULL) {
1293 int rv;
1294 setentry entry;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001295 Py_hash_t hash = PyObject_Hash(key);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 if (hash == -1) {
1298 Py_DECREF(it);
1299 Py_DECREF(result);
1300 Py_DECREF(key);
1301 return NULL;
1302 }
1303 entry.hash = hash;
1304 entry.key = key;
1305 rv = set_contains_entry(so, &entry);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001306 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 Py_DECREF(it);
1308 Py_DECREF(result);
1309 Py_DECREF(key);
1310 return NULL;
1311 }
1312 if (rv) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001313 if (set_add_entry(result, &entry)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 Py_DECREF(it);
1315 Py_DECREF(result);
1316 Py_DECREF(key);
1317 return NULL;
1318 }
1319 }
1320 Py_DECREF(key);
1321 }
1322 Py_DECREF(it);
1323 if (PyErr_Occurred()) {
1324 Py_DECREF(result);
1325 return NULL;
1326 }
1327 return (PyObject *)result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001328}
1329
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001330static PyObject *
1331set_intersection_multi(PySetObject *so, PyObject *args)
1332{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 Py_ssize_t i;
1334 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 if (PyTuple_GET_SIZE(args) == 0)
1337 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001338
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001339 Py_INCREF(so);
1340 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1341 PyObject *other = PyTuple_GET_ITEM(args, i);
1342 PyObject *newresult = set_intersection((PySetObject *)result, other);
1343 if (newresult == NULL) {
1344 Py_DECREF(result);
1345 return NULL;
1346 }
1347 Py_DECREF(result);
1348 result = newresult;
1349 }
1350 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001351}
1352
Raymond Hettingera690a992003-11-16 16:17:49 +00001353PyDoc_STRVAR(intersection_doc,
1354"Return the intersection of two sets as a new set.\n\
1355\n\
1356(i.e. all elements that are in both sets.)");
1357
1358static PyObject *
1359set_intersection_update(PySetObject *so, PyObject *other)
1360{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001361 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001363 tmp = set_intersection(so, other);
1364 if (tmp == NULL)
1365 return NULL;
1366 set_swap_bodies(so, (PySetObject *)tmp);
1367 Py_DECREF(tmp);
1368 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001369}
1370
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001371static PyObject *
1372set_intersection_update_multi(PySetObject *so, PyObject *args)
1373{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 tmp = set_intersection_multi(so, args);
1377 if (tmp == NULL)
1378 return NULL;
1379 set_swap_bodies(so, (PySetObject *)tmp);
1380 Py_DECREF(tmp);
1381 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001382}
1383
Raymond Hettingera690a992003-11-16 16:17:49 +00001384PyDoc_STRVAR(intersection_update_doc,
1385"Update a set with the intersection of itself and another.");
1386
1387static PyObject *
1388set_and(PySetObject *so, PyObject *other)
1389{
Brian Curtindfc80e32011-08-10 20:28:54 -05001390 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1391 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001393}
1394
1395static PyObject *
1396set_iand(PySetObject *so, PyObject *other)
1397{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001398 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001399
Brian Curtindfc80e32011-08-10 20:28:54 -05001400 if (!PyAnySet_Check(other))
1401 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402 result = set_intersection_update(so, other);
1403 if (result == NULL)
1404 return NULL;
1405 Py_DECREF(result);
1406 Py_INCREF(so);
1407 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001408}
1409
Guido van Rossum58da9312007-11-10 23:39:45 +00001410static PyObject *
1411set_isdisjoint(PySetObject *so, PyObject *other)
1412{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 PyObject *key, *it, *tmp;
Guido van Rossum58da9312007-11-10 23:39:45 +00001414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 if ((PyObject *)so == other) {
1416 if (PySet_GET_SIZE(so) == 0)
1417 Py_RETURN_TRUE;
1418 else
1419 Py_RETURN_FALSE;
1420 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001422 if (PyAnySet_CheckExact(other)) {
1423 Py_ssize_t pos = 0;
1424 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1427 tmp = (PyObject *)so;
1428 so = (PySetObject *)other;
1429 other = tmp;
1430 }
1431 while (set_next((PySetObject *)other, &pos, &entry)) {
1432 int rv = set_contains_entry(so, entry);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001433 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001434 return NULL;
1435 if (rv)
1436 Py_RETURN_FALSE;
1437 }
1438 Py_RETURN_TRUE;
1439 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 it = PyObject_GetIter(other);
1442 if (it == NULL)
1443 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001444
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001445 while ((key = PyIter_Next(it)) != NULL) {
1446 int rv;
1447 setentry entry;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001448 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 if (hash == -1) {
1451 Py_DECREF(key);
1452 Py_DECREF(it);
1453 return NULL;
1454 }
1455 entry.hash = hash;
1456 entry.key = key;
1457 rv = set_contains_entry(so, &entry);
1458 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001459 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 Py_DECREF(it);
1461 return NULL;
1462 }
1463 if (rv) {
1464 Py_DECREF(it);
1465 Py_RETURN_FALSE;
1466 }
1467 }
1468 Py_DECREF(it);
1469 if (PyErr_Occurred())
1470 return NULL;
1471 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001472}
1473
1474PyDoc_STRVAR(isdisjoint_doc,
1475"Return True if two sets have a null intersection.");
1476
Neal Norwitz6576bd82005-11-13 18:41:28 +00001477static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001478set_difference_update_internal(PySetObject *so, PyObject *other)
1479{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 if ((PyObject *)so == other)
1481 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 if (PyAnySet_Check(other)) {
1484 setentry *entry;
1485 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettingerb3223262015-07-03 23:37:16 -07001488 if (set_discard_entry(so, entry) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 return -1;
1490 } else {
1491 PyObject *key, *it;
1492 it = PyObject_GetIter(other);
1493 if (it == NULL)
1494 return -1;
1495
1496 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001497 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 Py_DECREF(it);
1499 Py_DECREF(key);
1500 return -1;
1501 }
1502 Py_DECREF(key);
1503 }
1504 Py_DECREF(it);
1505 if (PyErr_Occurred())
1506 return -1;
1507 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001508 /* If more than 1/4th are dummies, then resize them away. */
1509 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 return 0;
Raymond Hettinger48973002015-07-03 20:00:03 -07001511 return set_table_resize(so, so->used);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001512}
1513
Raymond Hettingera690a992003-11-16 16:17:49 +00001514static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001515set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001516{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1520 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001521 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001522 return NULL;
1523 }
1524 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001525}
1526
1527PyDoc_STRVAR(difference_update_doc,
1528"Remove all elements of another set from this set.");
1529
1530static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001531set_copy_and_difference(PySetObject *so, PyObject *other)
1532{
1533 PyObject *result;
1534
1535 result = set_copy(so);
1536 if (result == NULL)
1537 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001538 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001539 return result;
1540 Py_DECREF(result);
1541 return NULL;
1542}
1543
1544static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001545set_difference(PySetObject *so, PyObject *other)
1546{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 PyObject *result;
1548 setentry *entry;
1549 Py_ssize_t pos = 0;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001550
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001551 if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001552 return set_copy_and_difference(so, other);
1553 }
1554
1555 /* If len(so) much more than len(other), it's more efficient to simply copy
1556 * so and then iterate other looking for common elements. */
1557 if ((PySet_GET_SIZE(so) >> 2) > PyObject_Size(other)) {
1558 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001559 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 result = make_new_set_basetype(Py_TYPE(so), NULL);
1562 if (result == NULL)
1563 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001565 if (PyDict_CheckExact(other)) {
1566 while (set_next(so, &pos, &entry)) {
Raymond Hettinger15f08692015-07-03 17:21:17 -07001567 PyObject *key = entry->key;
1568 Py_hash_t hash = entry->hash;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001569 int rv;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001570 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001571 if (rv < 0) {
1572 Py_DECREF(result);
1573 return NULL;
1574 }
1575 if (!rv) {
Raymond Hettinger15f08692015-07-03 17:21:17 -07001576 if (set_insert_key((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 Py_DECREF(result);
1578 return NULL;
1579 }
1580 }
1581 }
1582 return result;
1583 }
1584
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001585 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 while (set_next(so, &pos, &entry)) {
1587 int rv = set_contains_entry((PySetObject *)other, entry);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001588 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 Py_DECREF(result);
1590 return NULL;
1591 }
1592 if (!rv) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001593 if (set_add_entry((PySetObject *)result, entry)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 Py_DECREF(result);
1595 return NULL;
1596 }
1597 }
1598 }
1599 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001600}
1601
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001602static PyObject *
1603set_difference_multi(PySetObject *so, PyObject *args)
1604{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001605 Py_ssize_t i;
1606 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001607
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 if (PyTuple_GET_SIZE(args) == 0)
1609 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001610
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 other = PyTuple_GET_ITEM(args, 0);
1612 result = set_difference(so, other);
1613 if (result == NULL)
1614 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001615
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1617 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001618 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001619 Py_DECREF(result);
1620 return NULL;
1621 }
1622 }
1623 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001624}
1625
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001626PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001627"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001628\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001629(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001630static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001631set_sub(PySetObject *so, PyObject *other)
1632{
Brian Curtindfc80e32011-08-10 20:28:54 -05001633 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1634 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001636}
1637
1638static PyObject *
1639set_isub(PySetObject *so, PyObject *other)
1640{
Brian Curtindfc80e32011-08-10 20:28:54 -05001641 if (!PyAnySet_Check(other))
1642 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001643 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001644 return NULL;
1645 Py_INCREF(so);
1646 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001647}
1648
1649static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001650set_symmetric_difference_update(PySetObject *so, PyObject *other)
1651{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652 PySetObject *otherset;
1653 PyObject *key;
1654 Py_ssize_t pos = 0;
1655 setentry *entry;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001656
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001657 if ((PyObject *)so == other)
1658 return set_clear(so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 if (PyDict_CheckExact(other)) {
1661 PyObject *value;
1662 int rv;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001663 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001664 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
1665 setentry an_entry;
Thomas Wouters89f507f2006-12-13 04:49:30 +00001666
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001667 Py_INCREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 an_entry.hash = hash;
1669 an_entry.key = key;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001670
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001671 rv = set_discard_entry(so, &an_entry);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001672 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001673 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001674 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001675 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001676 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001677 if (set_add_entry(so, &an_entry)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001678 Py_DECREF(key);
1679 return NULL;
1680 }
1681 }
Georg Brandl2d444492010-09-03 10:52:55 +00001682 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001683 }
1684 Py_RETURN_NONE;
1685 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001687 if (PyAnySet_Check(other)) {
1688 Py_INCREF(other);
1689 otherset = (PySetObject *)other;
1690 } else {
1691 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1692 if (otherset == NULL)
1693 return NULL;
1694 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001695
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001696 while (set_next(otherset, &pos, &entry)) {
1697 int rv = set_discard_entry(so, entry);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001698 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001699 Py_DECREF(otherset);
1700 return NULL;
1701 }
1702 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001703 if (set_add_entry(so, entry)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001704 Py_DECREF(otherset);
1705 return NULL;
1706 }
1707 }
1708 }
1709 Py_DECREF(otherset);
1710 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001711}
1712
1713PyDoc_STRVAR(symmetric_difference_update_doc,
1714"Update a set with the symmetric difference of itself and another.");
1715
1716static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001717set_symmetric_difference(PySetObject *so, PyObject *other)
1718{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001719 PyObject *rv;
1720 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001721
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001722 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1723 if (otherset == NULL)
1724 return NULL;
1725 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
1726 if (rv == NULL)
1727 return NULL;
1728 Py_DECREF(rv);
1729 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001730}
1731
1732PyDoc_STRVAR(symmetric_difference_doc,
1733"Return the symmetric difference of two sets as a new set.\n\
1734\n\
1735(i.e. all elements that are in exactly one of the sets.)");
1736
1737static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001738set_xor(PySetObject *so, PyObject *other)
1739{
Brian Curtindfc80e32011-08-10 20:28:54 -05001740 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1741 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001742 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001743}
1744
1745static PyObject *
1746set_ixor(PySetObject *so, PyObject *other)
1747{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001748 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001749
Brian Curtindfc80e32011-08-10 20:28:54 -05001750 if (!PyAnySet_Check(other))
1751 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001752 result = set_symmetric_difference_update(so, other);
1753 if (result == NULL)
1754 return NULL;
1755 Py_DECREF(result);
1756 Py_INCREF(so);
1757 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001758}
1759
1760static PyObject *
1761set_issubset(PySetObject *so, PyObject *other)
1762{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 setentry *entry;
1764 Py_ssize_t pos = 0;
Raymond Hettingera690a992003-11-16 16:17:49 +00001765
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001766 if (!PyAnySet_Check(other)) {
1767 PyObject *tmp, *result;
1768 tmp = make_new_set(&PySet_Type, other);
1769 if (tmp == NULL)
1770 return NULL;
1771 result = set_issubset(so, tmp);
1772 Py_DECREF(tmp);
1773 return result;
1774 }
1775 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1776 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001777
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001778 while (set_next(so, &pos, &entry)) {
1779 int rv = set_contains_entry((PySetObject *)other, entry);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001780 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001781 return NULL;
1782 if (!rv)
1783 Py_RETURN_FALSE;
1784 }
1785 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001786}
1787
1788PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1789
1790static PyObject *
1791set_issuperset(PySetObject *so, PyObject *other)
1792{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001793 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001794
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001795 if (!PyAnySet_Check(other)) {
1796 tmp = make_new_set(&PySet_Type, other);
1797 if (tmp == NULL)
1798 return NULL;
1799 result = set_issuperset(so, tmp);
1800 Py_DECREF(tmp);
1801 return result;
1802 }
1803 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001804}
1805
1806PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1807
Raymond Hettingera690a992003-11-16 16:17:49 +00001808static PyObject *
1809set_richcompare(PySetObject *v, PyObject *w, int op)
1810{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001811 PyObject *r1;
1812 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001813
Brian Curtindfc80e32011-08-10 20:28:54 -05001814 if(!PyAnySet_Check(w))
1815 Py_RETURN_NOTIMPLEMENTED;
1816
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001817 switch (op) {
1818 case Py_EQ:
1819 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1820 Py_RETURN_FALSE;
1821 if (v->hash != -1 &&
1822 ((PySetObject *)w)->hash != -1 &&
1823 v->hash != ((PySetObject *)w)->hash)
1824 Py_RETURN_FALSE;
1825 return set_issubset(v, w);
1826 case Py_NE:
1827 r1 = set_richcompare(v, w, Py_EQ);
1828 if (r1 == NULL)
1829 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001830 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001831 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001832 if (r2 < 0)
1833 return NULL;
1834 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 case Py_LE:
1836 return set_issubset(v, w);
1837 case Py_GE:
1838 return set_issuperset(v, w);
1839 case Py_LT:
1840 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1841 Py_RETURN_FALSE;
1842 return set_issubset(v, w);
1843 case Py_GT:
1844 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1845 Py_RETURN_FALSE;
1846 return set_issuperset(v, w);
1847 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001848 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001849}
1850
Raymond Hettingera690a992003-11-16 16:17:49 +00001851static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001852set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001853{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001854 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855 return NULL;
1856 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001857}
1858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001860"Add an element to a set.\n\
1861\n\
1862This has no effect if the element is already present.");
1863
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001864static int
1865set_contains(PySetObject *so, PyObject *key)
1866{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 PyObject *tmpkey;
1868 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001870 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001871 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1873 return -1;
1874 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001875 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 if (tmpkey == NULL)
1877 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001878 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001879 Py_DECREF(tmpkey);
1880 }
1881 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001882}
1883
1884static PyObject *
1885set_direct_contains(PySetObject *so, PyObject *key)
1886{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001889 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001890 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 return NULL;
1892 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001893}
1894
1895PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1896
Raymond Hettingera690a992003-11-16 16:17:49 +00001897static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001898set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001899{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 PyObject *tmpkey;
1901 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001902
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001903 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001904 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1906 return NULL;
1907 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001908 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 if (tmpkey == NULL)
1910 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001912 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001913 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 return NULL;
1915 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001916
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001917 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001918 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 return NULL;
1920 }
1921 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001922}
1923
1924PyDoc_STRVAR(remove_doc,
1925"Remove an element from a set; it must be a member.\n\
1926\n\
1927If the element is not a member, raise a KeyError.");
1928
1929static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001930set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001931{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001932 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001933 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001934
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001935 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001936 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1938 return NULL;
1939 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001940 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001941 if (tmpkey == NULL)
1942 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001943 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001944 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001945 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001946 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947 }
1948 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001949}
1950
1951PyDoc_STRVAR(discard_doc,
1952"Remove an element from a set if it is a member.\n\
1953\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001954If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001955
1956static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001957set_reduce(PySetObject *so)
1958{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001959 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001960 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001961
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001962 keys = PySequence_List((PyObject *)so);
1963 if (keys == NULL)
1964 goto done;
1965 args = PyTuple_Pack(1, keys);
1966 if (args == NULL)
1967 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001968 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001969 if (dict == NULL) {
1970 PyErr_Clear();
1971 dict = Py_None;
1972 Py_INCREF(dict);
1973 }
1974 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001975done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001976 Py_XDECREF(args);
1977 Py_XDECREF(keys);
1978 Py_XDECREF(dict);
1979 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001980}
1981
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001982static PyObject *
1983set_sizeof(PySetObject *so)
1984{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001985 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001987 res = sizeof(PySetObject);
1988 if (so->table != so->smalltable)
1989 res = res + (so->mask + 1) * sizeof(setentry);
1990 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001991}
1992
1993PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001994static int
1995set_init(PySetObject *self, PyObject *args, PyObject *kwds)
1996{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001997 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001999 if (!PyAnySet_Check(self))
2000 return -1;
2001 if (PySet_Check(self) && !_PyArg_NoKeywords("set()", kwds))
2002 return -1;
2003 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
2004 return -1;
2005 set_clear_internal(self);
2006 self->hash = -1;
2007 if (iterable == NULL)
2008 return 0;
2009 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002010}
2011
Raymond Hettingera690a992003-11-16 16:17:49 +00002012static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002013 set_len, /* sq_length */
2014 0, /* sq_concat */
2015 0, /* sq_repeat */
2016 0, /* sq_item */
2017 0, /* sq_slice */
2018 0, /* sq_ass_item */
2019 0, /* sq_ass_slice */
2020 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002021};
2022
2023/* set object ********************************************************/
2024
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002025#ifdef Py_DEBUG
2026static PyObject *test_c_api(PySetObject *so);
2027
2028PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2029All is well if assertions don't fail.");
2030#endif
2031
Raymond Hettingera690a992003-11-16 16:17:49 +00002032static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002033 {"add", (PyCFunction)set_add, METH_O,
2034 add_doc},
2035 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2036 clear_doc},
2037 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2038 contains_doc},
2039 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2040 copy_doc},
2041 {"discard", (PyCFunction)set_discard, METH_O,
2042 discard_doc},
2043 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2044 difference_doc},
2045 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2046 difference_update_doc},
2047 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2048 intersection_doc},
2049 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2050 intersection_update_doc},
2051 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2052 isdisjoint_doc},
2053 {"issubset", (PyCFunction)set_issubset, METH_O,
2054 issubset_doc},
2055 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2056 issuperset_doc},
2057 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2058 pop_doc},
2059 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2060 reduce_doc},
2061 {"remove", (PyCFunction)set_remove, METH_O,
2062 remove_doc},
2063 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2064 sizeof_doc},
2065 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2066 symmetric_difference_doc},
2067 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2068 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002069#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002070 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2071 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002072#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002073 {"union", (PyCFunction)set_union, METH_VARARGS,
2074 union_doc},
2075 {"update", (PyCFunction)set_update, METH_VARARGS,
2076 update_doc},
2077 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002078};
2079
2080static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002081 0, /*nb_add*/
2082 (binaryfunc)set_sub, /*nb_subtract*/
2083 0, /*nb_multiply*/
2084 0, /*nb_remainder*/
2085 0, /*nb_divmod*/
2086 0, /*nb_power*/
2087 0, /*nb_negative*/
2088 0, /*nb_positive*/
2089 0, /*nb_absolute*/
2090 0, /*nb_bool*/
2091 0, /*nb_invert*/
2092 0, /*nb_lshift*/
2093 0, /*nb_rshift*/
2094 (binaryfunc)set_and, /*nb_and*/
2095 (binaryfunc)set_xor, /*nb_xor*/
2096 (binaryfunc)set_or, /*nb_or*/
2097 0, /*nb_int*/
2098 0, /*nb_reserved*/
2099 0, /*nb_float*/
2100 0, /*nb_inplace_add*/
2101 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2102 0, /*nb_inplace_multiply*/
2103 0, /*nb_inplace_remainder*/
2104 0, /*nb_inplace_power*/
2105 0, /*nb_inplace_lshift*/
2106 0, /*nb_inplace_rshift*/
2107 (binaryfunc)set_iand, /*nb_inplace_and*/
2108 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2109 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002110};
2111
2112PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002113"set() -> new empty set object\n\
2114set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002115\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002116Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002117
2118PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002119 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2120 "set", /* tp_name */
2121 sizeof(PySetObject), /* tp_basicsize */
2122 0, /* tp_itemsize */
2123 /* methods */
2124 (destructor)set_dealloc, /* tp_dealloc */
2125 0, /* tp_print */
2126 0, /* tp_getattr */
2127 0, /* tp_setattr */
2128 0, /* tp_reserved */
2129 (reprfunc)set_repr, /* tp_repr */
2130 &set_as_number, /* tp_as_number */
2131 &set_as_sequence, /* tp_as_sequence */
2132 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002133 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002134 0, /* tp_call */
2135 0, /* tp_str */
2136 PyObject_GenericGetAttr, /* tp_getattro */
2137 0, /* tp_setattro */
2138 0, /* tp_as_buffer */
2139 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2140 Py_TPFLAGS_BASETYPE, /* tp_flags */
2141 set_doc, /* tp_doc */
2142 (traverseproc)set_traverse, /* tp_traverse */
2143 (inquiry)set_clear_internal, /* tp_clear */
2144 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002145 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2146 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002147 0, /* tp_iternext */
2148 set_methods, /* tp_methods */
2149 0, /* tp_members */
2150 0, /* tp_getset */
2151 0, /* tp_base */
2152 0, /* tp_dict */
2153 0, /* tp_descr_get */
2154 0, /* tp_descr_set */
2155 0, /* tp_dictoffset */
2156 (initproc)set_init, /* tp_init */
2157 PyType_GenericAlloc, /* tp_alloc */
2158 set_new, /* tp_new */
2159 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002160};
2161
2162/* frozenset object ********************************************************/
2163
2164
2165static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002166 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2167 contains_doc},
2168 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2169 copy_doc},
2170 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2171 difference_doc},
2172 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2173 intersection_doc},
2174 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2175 isdisjoint_doc},
2176 {"issubset", (PyCFunction)set_issubset, METH_O,
2177 issubset_doc},
2178 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2179 issuperset_doc},
2180 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2181 reduce_doc},
2182 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2183 sizeof_doc},
2184 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2185 symmetric_difference_doc},
2186 {"union", (PyCFunction)set_union, METH_VARARGS,
2187 union_doc},
2188 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002189};
2190
2191static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002192 0, /*nb_add*/
2193 (binaryfunc)set_sub, /*nb_subtract*/
2194 0, /*nb_multiply*/
2195 0, /*nb_remainder*/
2196 0, /*nb_divmod*/
2197 0, /*nb_power*/
2198 0, /*nb_negative*/
2199 0, /*nb_positive*/
2200 0, /*nb_absolute*/
2201 0, /*nb_bool*/
2202 0, /*nb_invert*/
2203 0, /*nb_lshift*/
2204 0, /*nb_rshift*/
2205 (binaryfunc)set_and, /*nb_and*/
2206 (binaryfunc)set_xor, /*nb_xor*/
2207 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002208};
2209
2210PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002211"frozenset() -> empty frozenset object\n\
2212frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002213\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002214Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002215
2216PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002217 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2218 "frozenset", /* tp_name */
2219 sizeof(PySetObject), /* tp_basicsize */
2220 0, /* tp_itemsize */
2221 /* methods */
2222 (destructor)set_dealloc, /* tp_dealloc */
2223 0, /* tp_print */
2224 0, /* tp_getattr */
2225 0, /* tp_setattr */
2226 0, /* tp_reserved */
2227 (reprfunc)set_repr, /* tp_repr */
2228 &frozenset_as_number, /* tp_as_number */
2229 &set_as_sequence, /* tp_as_sequence */
2230 0, /* tp_as_mapping */
2231 frozenset_hash, /* tp_hash */
2232 0, /* tp_call */
2233 0, /* tp_str */
2234 PyObject_GenericGetAttr, /* tp_getattro */
2235 0, /* tp_setattro */
2236 0, /* tp_as_buffer */
2237 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2238 Py_TPFLAGS_BASETYPE, /* tp_flags */
2239 frozenset_doc, /* tp_doc */
2240 (traverseproc)set_traverse, /* tp_traverse */
2241 (inquiry)set_clear_internal, /* tp_clear */
2242 (richcmpfunc)set_richcompare, /* tp_richcompare */
2243 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2244 (getiterfunc)set_iter, /* tp_iter */
2245 0, /* tp_iternext */
2246 frozenset_methods, /* tp_methods */
2247 0, /* tp_members */
2248 0, /* tp_getset */
2249 0, /* tp_base */
2250 0, /* tp_dict */
2251 0, /* tp_descr_get */
2252 0, /* tp_descr_set */
2253 0, /* tp_dictoffset */
2254 0, /* tp_init */
2255 PyType_GenericAlloc, /* tp_alloc */
2256 frozenset_new, /* tp_new */
2257 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002258};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002259
2260
2261/***** C API functions *************************************************/
2262
2263PyObject *
2264PySet_New(PyObject *iterable)
2265{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002266 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002267}
2268
2269PyObject *
2270PyFrozenSet_New(PyObject *iterable)
2271{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002272 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002273}
2274
Neal Norwitz8c49c822006-03-04 18:41:19 +00002275Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002276PySet_Size(PyObject *anyset)
2277{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002278 if (!PyAnySet_Check(anyset)) {
2279 PyErr_BadInternalCall();
2280 return -1;
2281 }
2282 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002283}
2284
2285int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002286PySet_Clear(PyObject *set)
2287{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002288 if (!PySet_Check(set)) {
2289 PyErr_BadInternalCall();
2290 return -1;
2291 }
2292 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002293}
2294
2295int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002296PySet_Contains(PyObject *anyset, PyObject *key)
2297{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002298 if (!PyAnySet_Check(anyset)) {
2299 PyErr_BadInternalCall();
2300 return -1;
2301 }
2302 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002303}
2304
2305int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002306PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002307{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002308 if (!PySet_Check(set)) {
2309 PyErr_BadInternalCall();
2310 return -1;
2311 }
2312 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002313}
2314
2315int
Christian Heimesfd66e512008-01-29 12:18:50 +00002316PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002317{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002318 if (!PySet_Check(anyset) &&
2319 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2320 PyErr_BadInternalCall();
2321 return -1;
2322 }
2323 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002324}
2325
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002326int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002327_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002328{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002329 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002331 if (!PyAnySet_Check(set)) {
2332 PyErr_BadInternalCall();
2333 return -1;
2334 }
2335 if (set_next((PySetObject *)set, pos, &entry) == 0)
2336 return 0;
2337 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002338 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002339 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002340}
2341
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002342PyObject *
2343PySet_Pop(PyObject *set)
2344{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002345 if (!PySet_Check(set)) {
2346 PyErr_BadInternalCall();
2347 return NULL;
2348 }
2349 return set_pop((PySetObject *)set);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002350}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002351
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002352int
2353_PySet_Update(PyObject *set, PyObject *iterable)
2354{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002355 if (!PySet_Check(set)) {
2356 PyErr_BadInternalCall();
2357 return -1;
2358 }
2359 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002360}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002361
Raymond Hettingere259f132013-12-15 11:56:14 -08002362/* Exported for the gdb plugin's benefit. */
2363PyObject *_PySet_Dummy = dummy;
2364
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002365#ifdef Py_DEBUG
2366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002367/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002368 Returns True and original set is restored. */
2369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002370#define assertRaises(call_return_value, exception) \
2371 do { \
2372 assert(call_return_value); \
2373 assert(PyErr_ExceptionMatches(exception)); \
2374 PyErr_Clear(); \
2375 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002376
2377static PyObject *
2378test_c_api(PySetObject *so)
2379{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002380 Py_ssize_t count;
2381 char *s;
2382 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002383 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002384 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002385 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002386 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002388 /* Verify preconditions */
2389 assert(PyAnySet_Check(ob));
2390 assert(PyAnySet_CheckExact(ob));
2391 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002392
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002393 /* so.clear(); so |= set("abc"); */
2394 str = PyUnicode_FromString("abc");
2395 if (str == NULL)
2396 return NULL;
2397 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002398 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002399 Py_DECREF(str);
2400 return NULL;
2401 }
2402 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 /* Exercise type/size checks */
2405 assert(PySet_Size(ob) == 3);
2406 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 /* Raise TypeError for non-iterable constructor arguments */
2409 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2410 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002412 /* Raise TypeError for unhashable key */
2413 dup = PySet_New(ob);
2414 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2415 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2416 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002418 /* Exercise successful pop, contains, add, and discard */
2419 elem = PySet_Pop(ob);
2420 assert(PySet_Contains(ob, elem) == 0);
2421 assert(PySet_GET_SIZE(ob) == 2);
2422 assert(PySet_Add(ob, elem) == 0);
2423 assert(PySet_Contains(ob, elem) == 1);
2424 assert(PySet_GET_SIZE(ob) == 3);
2425 assert(PySet_Discard(ob, elem) == 1);
2426 assert(PySet_GET_SIZE(ob) == 2);
2427 assert(PySet_Discard(ob, elem) == 0);
2428 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002430 /* Exercise clear */
2431 dup2 = PySet_New(dup);
2432 assert(PySet_Clear(dup2) == 0);
2433 assert(PySet_Size(dup2) == 0);
2434 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002436 /* Raise SystemError on clear or update of frozen set */
2437 f = PyFrozenSet_New(dup);
2438 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2439 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2440 assert(PySet_Add(f, elem) == 0);
2441 Py_INCREF(f);
2442 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2443 Py_DECREF(f);
2444 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002446 /* Exercise direct iteration */
2447 i = 0, count = 0;
2448 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
2449 s = _PyUnicode_AsString(x);
2450 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2451 count++;
2452 }
2453 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002455 /* Exercise updates */
2456 dup2 = PySet_New(NULL);
2457 assert(_PySet_Update(dup2, dup) == 0);
2458 assert(PySet_Size(dup2) == 3);
2459 assert(_PySet_Update(dup2, dup) == 0);
2460 assert(PySet_Size(dup2) == 3);
2461 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002462
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002463 /* Raise SystemError when self argument is not a set or frozenset. */
2464 t = PyTuple_New(0);
2465 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2466 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2467 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002469 /* Raise SystemError when self argument is not a set. */
2470 f = PyFrozenSet_New(dup);
2471 assert(PySet_Size(f) == 3);
2472 assert(PyFrozenSet_CheckExact(f));
2473 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2474 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2475 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002477 /* Raise KeyError when popping from an empty set */
2478 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2479 Py_DECREF(ob);
2480 assert(PySet_GET_SIZE(ob) == 0);
2481 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002483 /* Restore the set from the copy using the PyNumber API */
2484 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2485 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002487 /* Verify constructors accept NULL arguments */
2488 f = PySet_New(NULL);
2489 assert(f != NULL);
2490 assert(PySet_GET_SIZE(f) == 0);
2491 Py_DECREF(f);
2492 f = PyFrozenSet_New(NULL);
2493 assert(f != NULL);
2494 assert(PyFrozenSet_CheckExact(f));
2495 assert(PySet_GET_SIZE(f) == 0);
2496 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002498 Py_DECREF(elem);
2499 Py_DECREF(dup);
2500 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002501}
2502
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002503#undef assertRaises
2504
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002505#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002506
2507/***** Dummy Struct *************************************************/
2508
2509static PyObject *
2510dummy_repr(PyObject *op)
2511{
2512 return PyUnicode_FromString("<dummy key>");
2513}
2514
2515static void
2516dummy_dealloc(PyObject* ignore)
2517{
2518 Py_FatalError("deallocating <dummy key>");
2519}
2520
2521static PyTypeObject _PySetDummy_Type = {
2522 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2523 "<dummy key> type",
2524 0,
2525 0,
2526 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2527 0, /*tp_print*/
2528 0, /*tp_getattr*/
2529 0, /*tp_setattr*/
2530 0, /*tp_reserved*/
2531 dummy_repr, /*tp_repr*/
2532 0, /*tp_as_number*/
2533 0, /*tp_as_sequence*/
2534 0, /*tp_as_mapping*/
2535 0, /*tp_hash */
2536 0, /*tp_call */
2537 0, /*tp_str */
2538 0, /*tp_getattro */
2539 0, /*tp_setattro */
2540 0, /*tp_as_buffer */
2541 Py_TPFLAGS_DEFAULT, /*tp_flags */
2542};
2543
2544static PyObject _dummy_struct = {
2545 _PyObject_EXTRA_INIT
2546 2, &_PySetDummy_Type
2547};
2548