blob: 24424ad8b982643d60569e80c312d7b67940e9f8 [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{
Raymond Hettinger70559b52015-07-23 07:42:23 -040053 setentry *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 Hettinger70559b52015-07-23 07:42:23 -040061 entry = &so->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;
Raymond Hettinger70559b52015-07-23 07:42:23 -040078 table = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000079 Py_INCREF(startkey);
80 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
81 Py_DECREF(startkey);
Raymond Hettinger426d9952014-05-18 21:40:20 +010082 if (cmp < 0) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083 return NULL;
Raymond Hettinger426d9952014-05-18 21:40:20 +010084 if (table != so->table || entry->key != startkey) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000085 return set_lookkey(so, key, hash);
Raymond Hettinger426d9952014-05-18 21:40:20 +010086 if (cmp > 0) /* likely */
Raymond Hettingerafe89092013-08-28 20:59:31 -070087 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -060088 mask = so->mask; /* help avoid a register spill */
Raymond Hettingerafe89092013-08-28 20:59:31 -070089 }
Raymond Hettingerafe89092013-08-28 20:59:31 -070090
Raymond Hettingerc658d852015-02-02 08:35:00 -080091 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -080092 for (j = 0 ; j < LINEAR_PROBES ; j++) {
Raymond Hettingerc658d852015-02-02 08:35:00 -080093 entry++;
Raymond Hettinger8651a502015-05-27 10:37:20 -070094 if (entry->hash == 0 && entry->key == NULL)
95 return entry;
Raymond Hettingerc658d852015-02-02 08:35:00 -080096 if (entry->hash == hash) {
97 PyObject *startkey = entry->key;
98 assert(startkey != dummy);
99 if (startkey == key)
100 return entry;
101 if (PyUnicode_CheckExact(startkey)
102 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700103 && _PyUnicode_EQ(startkey, key))
Raymond Hettingerc658d852015-02-02 08:35:00 -0800104 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400105 table = so->table;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800106 Py_INCREF(startkey);
107 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
108 Py_DECREF(startkey);
109 if (cmp < 0)
110 return NULL;
111 if (table != so->table || entry->key != startkey)
112 return set_lookkey(so, key, hash);
113 if (cmp > 0)
114 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -0600115 mask = so->mask;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800116 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700117 }
118 }
119
120 perturb >>= PERTURB_SHIFT;
121 i = (i * 5 + 1 + perturb) & mask;
122
Raymond Hettinger70559b52015-07-23 07:42:23 -0400123 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700124 if (entry->key == NULL)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700125 return entry;
126 }
127}
128
Raymond Hettinger15f08692015-07-03 17:21:17 -0700129static int set_table_resize(PySetObject *, Py_ssize_t);
130
Raymond Hettinger8651a502015-05-27 10:37:20 -0700131static int
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400132set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700133{
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400134 setentry *table;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700135 setentry *freeslot;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700136 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700137 size_t perturb;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400138 size_t mask;
139 size_t i; /* Unsigned for defined overflow behavior */
Raymond Hettinger8651a502015-05-27 10:37:20 -0700140 size_t j;
141 int cmp;
142
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400143 /* Pre-increment is necessary to prevent arbitrary code in the rich
144 comparison from deallocating the key just before the insertion. */
145 Py_INCREF(key);
146
147 restart:
148
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400149 mask = so->mask;
150 i = (size_t)hash & mask;
151
Raymond Hettinger70559b52015-07-23 07:42:23 -0400152 entry = &so->table[i];
Raymond Hettinger8651a502015-05-27 10:37:20 -0700153 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700154 goto found_unused;
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700155
156 freeslot = NULL;
157 perturb = hash;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700158
159 while (1) {
160 if (entry->hash == hash) {
161 PyObject *startkey = entry->key;
162 /* startkey cannot be a dummy because the dummy hash field is -1 */
163 assert(startkey != dummy);
164 if (startkey == key)
165 goto found_active;
166 if (PyUnicode_CheckExact(startkey)
167 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700168 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700169 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400170 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700171 Py_INCREF(startkey);
172 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
173 Py_DECREF(startkey);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700174 if (cmp > 0) /* likely */
175 goto found_active;
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700176 if (cmp < 0)
177 goto comparison_error;
178 /* Continuing the search from the current entry only makes
179 sense if the table and entry are unchanged; otherwise,
180 we have to restart from the beginning */
181 if (table != so->table || entry->key != startkey)
182 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700183 mask = so->mask; /* help avoid a register spill */
184 }
Raymond Hettinger70559b52015-07-23 07:42:23 -0400185 else if (entry->hash == -1 && freeslot == NULL)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700186 freeslot = entry;
187
188 if (i + LINEAR_PROBES <= mask) {
189 for (j = 0 ; j < LINEAR_PROBES ; j++) {
190 entry++;
191 if (entry->hash == 0 && entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700192 goto found_unused_or_dummy;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700193 if (entry->hash == hash) {
194 PyObject *startkey = entry->key;
195 assert(startkey != dummy);
196 if (startkey == key)
197 goto found_active;
198 if (PyUnicode_CheckExact(startkey)
199 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700200 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700201 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400202 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700203 Py_INCREF(startkey);
204 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
205 Py_DECREF(startkey);
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700206 if (cmp > 0)
207 goto found_active;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700208 if (cmp < 0)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400209 goto comparison_error;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700210 if (table != so->table || entry->key != startkey)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400211 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700212 mask = so->mask;
213 }
Raymond Hettinger91672612015-06-26 02:50:21 -0700214 else if (entry->hash == -1 && freeslot == NULL)
Raymond Hettingerc658d852015-02-02 08:35:00 -0800215 freeslot = entry;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700216 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000217 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700218
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700219 perturb >>= PERTURB_SHIFT;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -0800220 i = (i * 5 + 1 + perturb) & mask;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700221
Raymond Hettinger70559b52015-07-23 07:42:23 -0400222 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700223 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700224 goto found_unused_or_dummy;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000225 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700226
Raymond Hettinger15f08692015-07-03 17:21:17 -0700227 found_unused_or_dummy:
228 if (freeslot == NULL)
229 goto found_unused;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700230 so->used++;
231 freeslot->key = key;
232 freeslot->hash = hash;
233 return 0;
234
235 found_unused:
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700236 so->fill++;
237 so->used++;
238 entry->key = key;
239 entry->hash = hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700240 if ((size_t)so->fill*3 < mask*2)
241 return 0;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400242 return set_table_resize(so, so->used);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700243
244 found_active:
Raymond Hettinger482c05c2015-07-20 01:23:32 -0400245 Py_DECREF(key);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700246 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000247
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400248 comparison_error:
Raymond Hettinger061091a2015-07-15 23:54:02 -0700249 Py_DECREF(key);
250 return -1;
251}
252
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000253/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000254Internal routine used by set_table_resize() to insert an item which is
255known to be absent from the set. This routine also assumes that
256the set contains no deleted entries. Besides the performance benefit,
257using set_insert_clean() in set_table_resize() is dangerous (SF bug #1456209).
258Note that no refcounts are changed by this routine; if needed, the caller
259is responsible for incref'ing `key`.
260*/
261static void
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200262set_insert_clean(PySetObject *so, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000263{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 setentry *table = so->table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200265 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700266 size_t perturb = hash;
267 size_t mask = (size_t)so->mask;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800268 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700269 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000270
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700271 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800272 entry = &table[i];
273 if (entry->key == NULL)
274 goto found_null;
275 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800276 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800277 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800278 if (entry->key == NULL)
279 goto found_null;
280 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700281 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700282 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800283 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700285 found_null:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 entry->key = key;
287 entry->hash = hash;
Raymond Hettinger4ef05282013-09-21 15:39:49 -0700288 so->fill++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289 so->used++;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000290}
291
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700292/* ======== End logic for probing the hash table ========================== */
293/* ======================================================================== */
294
Thomas Wouters89f507f2006-12-13 04:49:30 +0000295/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000296Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000297keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000298actually be smaller than the old one.
299*/
300static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000301set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000302{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000303 Py_ssize_t newsize;
304 setentry *oldtable, *newtable, *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800305 Py_ssize_t oldfill = so->fill;
306 Py_ssize_t oldused = so->used;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 int is_oldtable_malloced;
308 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 assert(minused >= 0);
Raymond Hettinger48973002015-07-03 20:00:03 -0700311 minused = (minused > 50000) ? minused * 2 : minused * 4;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100314 /* XXX speed-up with intrinsics */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 for (newsize = PySet_MINSIZE;
316 newsize <= minused && newsize > 0;
317 newsize <<= 1)
318 ;
319 if (newsize <= 0) {
320 PyErr_NoMemory();
321 return -1;
322 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000324 /* Get space for a new table. */
325 oldtable = so->table;
326 assert(oldtable != NULL);
327 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 if (newsize == PySet_MINSIZE) {
330 /* A large table is shrinking, or we can't get any smaller. */
331 newtable = so->smalltable;
332 if (newtable == oldtable) {
333 if (so->fill == so->used) {
334 /* No dummies, so no point doing anything. */
335 return 0;
336 }
337 /* We're not going to resize it, but rebuild the
338 table anyway to purge old dummy entries.
339 Subtle: This is *necessary* if fill==size,
340 as set_lookkey needs at least one virgin slot to
341 terminate failing searches. If fill < size, it's
342 merely desirable, as dummies slow searches. */
343 assert(so->fill > so->used);
344 memcpy(small_copy, oldtable, sizeof(small_copy));
345 oldtable = small_copy;
346 }
347 }
348 else {
349 newtable = PyMem_NEW(setentry, newsize);
350 if (newtable == NULL) {
351 PyErr_NoMemory();
352 return -1;
353 }
354 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000356 /* Make the set empty, using the new table. */
357 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000358 memset(newtable, 0, sizeof(setentry) * newsize);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 so->fill = 0;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800360 so->used = 0;
361 so->mask = newsize - 1;
362 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 /* Copy the data over; this is refcount-neutral for active entries;
365 dummy entries aren't copied over, of course */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800366 if (oldfill == oldused) {
367 for (entry = oldtable; oldused > 0; entry++) {
368 if (entry->key != NULL) {
369 oldused--;
370 set_insert_clean(so, entry->key, entry->hash);
371 }
372 }
373 } else {
374 for (entry = oldtable; oldused > 0; entry++) {
375 if (entry->key != NULL && entry->key != dummy) {
376 oldused--;
377 set_insert_clean(so, entry->key, entry->hash);
378 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 }
380 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 if (is_oldtable_malloced)
383 PyMem_DEL(oldtable);
384 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000385}
386
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000387static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700388set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000389{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700390 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000391
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700392 entry = set_lookkey(so, key, hash);
393 if (entry != NULL)
394 return entry->key != NULL;
395 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000396}
397
398#define DISCARD_NOTFOUND 0
399#define DISCARD_FOUND 1
400
401static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700402set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800403{
404 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000406
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700407 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 if (entry == NULL)
409 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700410 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000411 return DISCARD_NOTFOUND;
412 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800414 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000415 so->used--;
416 Py_DECREF(old_key);
417 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000418}
419
420static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700421set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000422{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200423 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000424
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700425 if (!PyUnicode_CheckExact(key) ||
426 (hash = ((PyASCIIObject *) key)->hash) == -1) {
427 hash = PyObject_Hash(key);
428 if (hash == -1)
429 return -1;
430 }
431 return set_add_entry(so, key, hash);
432}
433
434static int
435set_contains_key(PySetObject *so, PyObject *key)
436{
437 Py_hash_t hash;
438
439 if (!PyUnicode_CheckExact(key) ||
440 (hash = ((PyASCIIObject *) key)->hash) == -1) {
441 hash = PyObject_Hash(key);
442 if (hash == -1)
443 return -1;
444 }
445 return set_contains_entry(so, key, hash);
446}
447
448static int
449set_discard_key(PySetObject *so, PyObject *key)
450{
451 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200454 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000455 hash = PyObject_Hash(key);
456 if (hash == -1)
457 return -1;
458 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700459 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000460}
461
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700462static void
463set_empty_to_minsize(PySetObject *so)
464{
465 memset(so->smalltable, 0, sizeof(so->smalltable));
466 so->fill = 0;
467 so->used = 0;
468 so->mask = PySet_MINSIZE - 1;
469 so->table = so->smalltable;
470 so->hash = -1;
471}
472
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000473static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000474set_clear_internal(PySetObject *so)
475{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800476 setentry *entry;
477 setentry *table = so->table;
478 Py_ssize_t fill = so->fill;
479 Py_ssize_t used = so->used;
480 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000482
Raymond Hettinger583cd032013-09-07 22:06:35 -0700483 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 /* This is delicate. During the process of clearing the set,
487 * decrefs can cause the set to mutate. To avoid fatal confusion
488 * (voice of experience), we have to make the set empty before
489 * clearing the slots, and never refer to anything via so->ref while
490 * clearing.
491 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700493 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 else if (fill > 0) {
496 /* It's a small table with something that needs to be cleared.
497 * Afraid the only safe way is to copy the set entries into
498 * another small table first.
499 */
500 memcpy(small_copy, table, sizeof(small_copy));
501 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700502 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000503 }
504 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 /* Now we can finally clear things. If C had refcounts, we could
507 * assert that the refcount on table is 1 now, i.e. that this function
508 * has unique access to it, so decref side-effects can't alter it.
509 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800510 for (entry = table; used > 0; entry++) {
511 if (entry->key && entry->key != dummy) {
512 used--;
513 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000517 if (table_is_malloced)
518 PyMem_DEL(table);
519 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000520}
521
522/*
523 * Iterate over a set table. Use like so:
524 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000525 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000526 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000527 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000528 * while (set_next(yourset, &pos, &entry)) {
529 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000530 * }
531 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000532 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000534 */
535static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000536set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000537{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 Py_ssize_t i;
539 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700540 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 assert (PyAnySet_Check(so));
543 i = *pos_ptr;
544 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700546 entry = &so->table[i];
547 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700549 entry++;
550 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 *pos_ptr = i+1;
552 if (i > mask)
553 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700554 assert(entry != NULL);
555 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000556 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000557}
558
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000559static void
560set_dealloc(PySetObject *so)
561{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200562 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800563 Py_ssize_t used = so->used;
564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000565 PyObject_GC_UnTrack(so);
566 Py_TRASHCAN_SAFE_BEGIN(so)
567 if (so->weakreflist != NULL)
568 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000569
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800570 for (entry = so->table; used > 0; entry++) {
571 if (entry->key && entry->key != dummy) {
572 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700573 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000574 }
575 }
576 if (so->table != so->smalltable)
577 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700578 Py_TYPE(so)->tp_free(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000579 Py_TRASHCAN_SAFE_END(so)
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000580}
581
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000582static PyObject *
583set_repr(PySetObject *so)
584{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200585 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 if (status != 0) {
589 if (status < 0)
590 return NULL;
591 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
592 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000594 /* shortcut for the empty set */
595 if (!so->used) {
596 Py_ReprLeave((PyObject*)so);
597 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
598 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 keys = PySequence_List((PyObject *)so);
601 if (keys == NULL)
602 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000603
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200604 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 listrepr = PyObject_Repr(keys);
606 Py_DECREF(keys);
607 if (listrepr == NULL)
608 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200609 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200611 if (tmp == NULL)
612 goto done;
613 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200614
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200615 if (Py_TYPE(so) != &PySet_Type)
616 result = PyUnicode_FromFormat("%s({%U})",
617 Py_TYPE(so)->tp_name,
618 listrepr);
619 else
620 result = PyUnicode_FromFormat("{%U}", listrepr);
621 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000622done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 Py_ReprLeave((PyObject*)so);
624 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000625}
626
Martin v. Löwis18e16552006-02-15 17:27:45 +0000627static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000628set_len(PyObject *so)
629{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000631}
632
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000633static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000634set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000635{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000636 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000637 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200638 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700639 setentry *so_entry;
640 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000641
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000642 assert (PyAnySet_Check(so));
643 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000644
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000645 other = (PySetObject*)otherset;
646 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700647 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 return 0;
649 /* Do one big resize at the start, rather than
650 * incrementally resizing as we insert new keys. Expect
651 * that there will be no (or few) overlapping keys.
652 */
Raymond Hettinger15f08692015-07-03 17:21:17 -0700653 if ((so->fill + other->used)*3 >= so->mask*2) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700654 if (set_table_resize(so, so->used + other->used) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000655 return -1;
656 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700657 so_entry = so->table;
658 other_entry = other->table;
659
660 /* If our table is empty, and both tables have the same size, and
661 there are no dummies to eliminate, then just copy the pointers. */
662 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
663 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
664 key = other_entry->key;
665 if (key != NULL) {
666 assert(so_entry->key == NULL);
667 Py_INCREF(key);
668 so_entry->key = key;
669 so_entry->hash = other_entry->hash;
670 }
671 }
672 so->fill = other->fill;
673 so->used = other->used;
674 return 0;
675 }
676
677 /* If our table is empty, we can use set_insert_clean() */
678 if (so->fill == 0) {
679 for (i = 0; i <= other->mask; i++, other_entry++) {
680 key = other_entry->key;
681 if (key != NULL && key != dummy) {
682 Py_INCREF(key);
683 set_insert_clean(so, key, other_entry->hash);
684 }
685 }
686 return 0;
687 }
688
689 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700690 for (i = 0; i <= other->mask; i++) {
691 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700692 key = other_entry->key;
693 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700694 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000696 }
697 }
698 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000699}
700
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000701static PyObject *
702set_pop(PySetObject *so)
703{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800704 /* Make sure the search finger is in bounds */
705 Py_ssize_t i = so->finger & so->mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200706 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000708
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000709 assert (PyAnySet_Check(so));
710 if (so->used == 0) {
711 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
712 return NULL;
713 }
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000714
Raymond Hettinger1202a472015-01-18 13:12:42 -0800715 while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
716 i++;
Raymond Hettingered741d42015-01-18 21:25:15 -0800717 if (i > so->mask)
718 i = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 }
720 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800722 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 so->used--;
Raymond Hettinger1202a472015-01-18 13:12:42 -0800724 so->finger = i + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000726}
727
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000728PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
729Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000730
731static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000732set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000733{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 Py_ssize_t pos = 0;
735 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000736
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000737 while (set_next(so, &pos, &entry))
738 Py_VISIT(entry->key);
739 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000740}
741
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700742/* Work to increase the bit dispersion for closely spaced hash values.
743 This is important because some use cases have many combinations of a
744 small number of elements with nearby hashes so that many distinct
745 combinations collapse to only a handful of distinct hash values. */
746
747static Py_uhash_t
748_shuffle_bits(Py_uhash_t h)
749{
750 return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
751}
752
753/* Most of the constants in this hash algorithm are randomly chosen
754 large primes with "interesting bit patterns" and that passed tests
755 for good collision statistics on a variety of problematic datasets
756 including powersets and graph structures (such as David Eppstein's
757 graph recipes in Lib/test/test_set.py) */
758
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000759static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000760frozenset_hash(PyObject *self)
761{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 PySetObject *so = (PySetObject *)self;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700763 Py_uhash_t hash = 1927868237UL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000764 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000765
Raymond Hettinger36c05002015-08-01 10:57:42 -0700766 /* Initial dispersion based on the number of active entries */
Mark Dickinson57e683e2011-09-24 18:18:40 +0100767 hash *= (Py_uhash_t)PySet_GET_SIZE(self) + 1;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700768
769 /* Xor-in shuffled bits from every entry's hash field because xor is
770 commutative and a frozenset hash should be independent of order.
771
772 For speed, include null entries and dummy entries and then
773 subtract out their effect afterwards so that the final hash
774 depends only on active entries. This allows the code to be
775 vectorized by the compiler and it saves the unpredictable
776 branches that would arise when trying to exclude null and dummy
777 entries on every iteration. */
778
779 for (entry = so->table; entry <= &so->table[so->mask]; entry++)
780 hash ^= _shuffle_bits(entry->hash);
781
Raymond Hettingera286a512015-08-01 11:07:11 -0700782 /* Remove the effect of an odd number of NULL entries */
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700783 if ((so->mask + 1 - so->fill) & 1)
784 hash ^= _shuffle_bits(0);
785
786 /* Remove the effect of an odd number of dummy entries */
787 if ((so->fill - so->used) & 1)
788 hash ^= _shuffle_bits(-1);
789
790 /* Disperse patterns arising in nested frozensets */
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800791 hash = hash * 69069U + 907133923UL;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700792
Raymond Hettinger36c05002015-08-01 10:57:42 -0700793 /* -1 is reserved as an error code */
Victor Stinner12174a52014-08-15 23:17:38 +0200794 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800795 hash = 590923713UL;
Raymond Hettinger36c05002015-08-01 10:57:42 -0700796
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000797 so->hash = hash;
798 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000799}
800
Raymond Hettingera9d99362005-08-05 00:01:15 +0000801/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000802
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000803typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000804 PyObject_HEAD
805 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
806 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700807 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000808 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000809} setiterobject;
810
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000811static void
812setiter_dealloc(setiterobject *si)
813{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000814 Py_XDECREF(si->si_set);
815 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000816}
817
818static int
819setiter_traverse(setiterobject *si, visitproc visit, void *arg)
820{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000821 Py_VISIT(si->si_set);
822 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000823}
824
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000825static PyObject *
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000826setiter_len(setiterobject *si)
827{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000828 Py_ssize_t len = 0;
829 if (si->si_set != NULL && si->si_used == si->si_set->used)
830 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000831 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000832}
833
Armin Rigof5b3e362006-02-11 21:32:43 +0000834PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000835
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000836static PyObject *setiter_iternext(setiterobject *si);
837
838static PyObject *
839setiter_reduce(setiterobject *si)
840{
841 PyObject *list;
842 setiterobject tmp;
843
844 list = PyList_New(0);
845 if (!list)
846 return NULL;
847
Ezio Melotti0e1af282012-09-28 16:43:40 +0300848 /* copy the iterator state */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000849 tmp = *si;
850 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300851
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000852 /* iterate the temporary into a list */
853 for(;;) {
854 PyObject *element = setiter_iternext(&tmp);
855 if (element) {
856 if (PyList_Append(list, element)) {
857 Py_DECREF(element);
858 Py_DECREF(list);
859 Py_XDECREF(tmp.si_set);
860 return NULL;
861 }
862 Py_DECREF(element);
863 } else
864 break;
865 }
866 Py_XDECREF(tmp.si_set);
867 /* check for error */
868 if (tmp.si_set != NULL) {
869 /* we have an error */
870 Py_DECREF(list);
871 return NULL;
872 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200873 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000874}
875
876PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
877
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000878static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000879 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000880 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000881 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000882};
883
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000884static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000885{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700886 PyObject *key;
887 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200888 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000891 if (so == NULL)
892 return NULL;
893 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000895 if (si->si_used != so->used) {
896 PyErr_SetString(PyExc_RuntimeError,
897 "Set changed size during iteration");
898 si->si_used = -1; /* Make this state sticky */
899 return NULL;
900 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700901
902 i = si->si_pos;
903 assert(i>=0);
904 entry = so->table;
905 mask = so->mask;
906 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
907 i++;
908 si->si_pos = i+1;
909 if (i > mask)
910 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700912 key = entry[i].key;
913 Py_INCREF(key);
914 return key;
915
916fail:
917 Py_DECREF(so);
918 si->si_set = NULL;
919 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000920}
921
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000922PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000923 PyVarObject_HEAD_INIT(&PyType_Type, 0)
924 "set_iterator", /* tp_name */
925 sizeof(setiterobject), /* tp_basicsize */
926 0, /* tp_itemsize */
927 /* methods */
928 (destructor)setiter_dealloc, /* tp_dealloc */
929 0, /* tp_print */
930 0, /* tp_getattr */
931 0, /* tp_setattr */
932 0, /* tp_reserved */
933 0, /* tp_repr */
934 0, /* tp_as_number */
935 0, /* tp_as_sequence */
936 0, /* tp_as_mapping */
937 0, /* tp_hash */
938 0, /* tp_call */
939 0, /* tp_str */
940 PyObject_GenericGetAttr, /* tp_getattro */
941 0, /* tp_setattro */
942 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700943 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000944 0, /* tp_doc */
945 (traverseproc)setiter_traverse, /* tp_traverse */
946 0, /* tp_clear */
947 0, /* tp_richcompare */
948 0, /* tp_weaklistoffset */
949 PyObject_SelfIter, /* tp_iter */
950 (iternextfunc)setiter_iternext, /* tp_iternext */
951 setiter_methods, /* tp_methods */
952 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000953};
954
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000955static PyObject *
956set_iter(PySetObject *so)
957{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000958 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
959 if (si == NULL)
960 return NULL;
961 Py_INCREF(so);
962 si->si_set = so;
963 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700964 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000965 si->len = so->used;
966 _PyObject_GC_TRACK(si);
967 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000968}
969
Raymond Hettingerd7946662005-08-01 21:39:29 +0000970static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000971set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000972{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000975 if (PyAnySet_Check(other))
976 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 if (PyDict_CheckExact(other)) {
979 PyObject *value;
980 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000981 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 Py_ssize_t dictsize = PyDict_Size(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 /* Do one big resize at the start, rather than
985 * incrementally resizing as we insert new keys. Expect
986 * that there will be no (or few) overlapping keys.
987 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700988 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 return -1;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700990 if ((so->fill + dictsize)*3 >= so->mask*2) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700991 if (set_table_resize(so, so->used + dictsize) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000992 return -1;
993 }
994 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700995 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000996 return -1;
997 }
998 return 0;
999 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001000
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001001 it = PyObject_GetIter(other);
1002 if (it == NULL)
1003 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +00001004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001006 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 Py_DECREF(it);
1008 Py_DECREF(key);
1009 return -1;
1010 }
1011 Py_DECREF(key);
1012 }
1013 Py_DECREF(it);
1014 if (PyErr_Occurred())
1015 return -1;
1016 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001017}
1018
1019static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001020set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001021{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001022 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001024 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1025 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001026 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 return NULL;
1028 }
1029 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001030}
1031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001033"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001034
Raymond Hettinger426d9952014-05-18 21:40:20 +01001035/* XXX Todo:
1036 If aligned memory allocations become available, make the
1037 set object 64 byte aligned so that most of the fields
1038 can be retrieved or updated in a single cache line.
1039*/
1040
Raymond Hettingera38123e2003-11-24 22:18:49 +00001041static PyObject *
1042make_new_set(PyTypeObject *type, PyObject *iterable)
1043{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001044 PySetObject *so = NULL;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001045
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046 /* create PySetObject structure */
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001047 so = (PySetObject *)type->tp_alloc(type, 0);
1048 if (so == NULL)
1049 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001050
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001051 so->fill = 0;
1052 so->used = 0;
1053 so->mask = PySet_MINSIZE - 1;
1054 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001055 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001056 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001057 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001058
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001060 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 Py_DECREF(so);
1062 return NULL;
1063 }
1064 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001067}
1068
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001069static PyObject *
1070make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1071{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1073 if (PyType_IsSubtype(type, &PySet_Type))
1074 type = &PySet_Type;
1075 else
1076 type = &PyFrozenSet_Type;
1077 }
1078 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001079}
1080
Raymond Hettingerd7946662005-08-01 21:39:29 +00001081/* The empty frozenset is a singleton */
1082static PyObject *emptyfrozenset = NULL;
1083
Raymond Hettingera690a992003-11-16 16:17:49 +00001084static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001085frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001086{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001088
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001089 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset()", kwds))
1090 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001091
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1093 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001094
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 if (type != &PyFrozenSet_Type)
1096 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001098 if (iterable != NULL) {
1099 /* frozenset(f) is idempotent */
1100 if (PyFrozenSet_CheckExact(iterable)) {
1101 Py_INCREF(iterable);
1102 return iterable;
1103 }
1104 result = make_new_set(type, iterable);
1105 if (result == NULL || PySet_GET_SIZE(result))
1106 return result;
1107 Py_DECREF(result);
1108 }
1109 /* The empty frozenset is a singleton */
1110 if (emptyfrozenset == NULL)
1111 emptyfrozenset = make_new_set(type, NULL);
1112 Py_XINCREF(emptyfrozenset);
1113 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001114}
1115
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001116int
1117PySet_ClearFreeList(void)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001118{
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001119 return 0;
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001120}
1121
1122void
1123PySet_Fini(void)
1124{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001125 Py_CLEAR(emptyfrozenset);
Raymond Hettingera690a992003-11-16 16:17:49 +00001126}
1127
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001128static PyObject *
1129set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1130{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001131 if (type == &PySet_Type && !_PyArg_NoKeywords("set()", kwds))
1132 return NULL;
1133
1134 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001135}
1136
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001137/* set_swap_bodies() switches the contents of any two sets by moving their
1138 internal data pointers and, if needed, copying the internal smalltables.
1139 Semantically equivalent to:
1140
1141 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1142
1143 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001144 Useful for operations that update in-place (by allowing an intermediate
1145 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001146*/
1147
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001148static void
1149set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001150{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 Py_ssize_t t;
1152 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001154 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001155
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 t = a->fill; a->fill = b->fill; b->fill = t;
1157 t = a->used; a->used = b->used; b->used = t;
1158 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001160 u = a->table;
1161 if (a->table == a->smalltable)
1162 u = b->smalltable;
1163 a->table = b->table;
1164 if (b->table == b->smalltable)
1165 a->table = a->smalltable;
1166 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 if (a->table == a->smalltable || b->table == b->smalltable) {
1169 memcpy(tab, a->smalltable, sizeof(tab));
1170 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1171 memcpy(b->smalltable, tab, sizeof(tab));
1172 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001174 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1175 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1176 h = a->hash; a->hash = b->hash; b->hash = h;
1177 } else {
1178 a->hash = -1;
1179 b->hash = -1;
1180 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001181}
1182
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001183static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001184set_copy(PySetObject *so)
1185{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001187}
1188
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001189static PyObject *
1190frozenset_copy(PySetObject *so)
1191{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001192 if (PyFrozenSet_CheckExact(so)) {
1193 Py_INCREF(so);
1194 return (PyObject *)so;
1195 }
1196 return set_copy(so);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001197}
1198
Raymond Hettingera690a992003-11-16 16:17:49 +00001199PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1200
1201static PyObject *
Raymond Hettingerc991db22005-08-11 07:58:45 +00001202set_clear(PySetObject *so)
1203{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001204 set_clear_internal(so);
1205 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001206}
1207
1208PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1209
1210static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001211set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001212{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001213 PySetObject *result;
1214 PyObject *other;
1215 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 result = (PySetObject *)set_copy(so);
1218 if (result == NULL)
1219 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001221 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1222 other = PyTuple_GET_ITEM(args, i);
1223 if ((PyObject *)so == other)
1224 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001225 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001226 Py_DECREF(result);
1227 return NULL;
1228 }
1229 }
1230 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001231}
1232
1233PyDoc_STRVAR(union_doc,
1234 "Return the union of sets as a new set.\n\
1235\n\
1236(i.e. all elements that are in either set.)");
1237
1238static PyObject *
1239set_or(PySetObject *so, PyObject *other)
1240{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001242
Brian Curtindfc80e32011-08-10 20:28:54 -05001243 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1244 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 result = (PySetObject *)set_copy(so);
1247 if (result == NULL)
1248 return NULL;
1249 if ((PyObject *)so == other)
1250 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001251 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 Py_DECREF(result);
1253 return NULL;
1254 }
1255 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001256}
1257
Raymond Hettingera690a992003-11-16 16:17:49 +00001258static PyObject *
1259set_ior(PySetObject *so, PyObject *other)
1260{
Brian Curtindfc80e32011-08-10 20:28:54 -05001261 if (!PyAnySet_Check(other))
1262 Py_RETURN_NOTIMPLEMENTED;
1263
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001264 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001265 return NULL;
1266 Py_INCREF(so);
1267 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001268}
1269
1270static PyObject *
1271set_intersection(PySetObject *so, PyObject *other)
1272{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 PySetObject *result;
1274 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001275 Py_hash_t hash;
1276 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001278 if ((PyObject *)so == other)
1279 return set_copy(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1282 if (result == NULL)
1283 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001285 if (PyAnySet_Check(other)) {
1286 Py_ssize_t pos = 0;
1287 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1290 tmp = (PyObject *)so;
1291 so = (PySetObject *)other;
1292 other = tmp;
1293 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001296 key = entry->key;
1297 hash = entry->hash;
1298 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001299 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 Py_DECREF(result);
1301 return NULL;
1302 }
1303 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001304 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 Py_DECREF(result);
1306 return NULL;
1307 }
1308 }
1309 }
1310 return (PyObject *)result;
1311 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 it = PyObject_GetIter(other);
1314 if (it == NULL) {
1315 Py_DECREF(result);
1316 return NULL;
1317 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001320 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001321 if (hash == -1)
1322 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001323 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001324 if (rv < 0)
1325 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001327 if (set_add_entry(result, key, hash))
1328 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 }
1330 Py_DECREF(key);
1331 }
1332 Py_DECREF(it);
1333 if (PyErr_Occurred()) {
1334 Py_DECREF(result);
1335 return NULL;
1336 }
1337 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001338 error:
1339 Py_DECREF(it);
1340 Py_DECREF(result);
1341 Py_DECREF(key);
1342 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001343}
1344
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001345static PyObject *
1346set_intersection_multi(PySetObject *so, PyObject *args)
1347{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 Py_ssize_t i;
1349 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 if (PyTuple_GET_SIZE(args) == 0)
1352 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 Py_INCREF(so);
1355 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1356 PyObject *other = PyTuple_GET_ITEM(args, i);
1357 PyObject *newresult = set_intersection((PySetObject *)result, other);
1358 if (newresult == NULL) {
1359 Py_DECREF(result);
1360 return NULL;
1361 }
1362 Py_DECREF(result);
1363 result = newresult;
1364 }
1365 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001366}
1367
Raymond Hettingera690a992003-11-16 16:17:49 +00001368PyDoc_STRVAR(intersection_doc,
1369"Return the intersection of two sets as a new set.\n\
1370\n\
1371(i.e. all elements that are in both sets.)");
1372
1373static PyObject *
1374set_intersection_update(PySetObject *so, PyObject *other)
1375{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001378 tmp = set_intersection(so, other);
1379 if (tmp == NULL)
1380 return NULL;
1381 set_swap_bodies(so, (PySetObject *)tmp);
1382 Py_DECREF(tmp);
1383 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001384}
1385
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001386static PyObject *
1387set_intersection_update_multi(PySetObject *so, PyObject *args)
1388{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 tmp = set_intersection_multi(so, args);
1392 if (tmp == NULL)
1393 return NULL;
1394 set_swap_bodies(so, (PySetObject *)tmp);
1395 Py_DECREF(tmp);
1396 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001397}
1398
Raymond Hettingera690a992003-11-16 16:17:49 +00001399PyDoc_STRVAR(intersection_update_doc,
1400"Update a set with the intersection of itself and another.");
1401
1402static PyObject *
1403set_and(PySetObject *so, PyObject *other)
1404{
Brian Curtindfc80e32011-08-10 20:28:54 -05001405 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1406 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001407 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001408}
1409
1410static PyObject *
1411set_iand(PySetObject *so, PyObject *other)
1412{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001414
Brian Curtindfc80e32011-08-10 20:28:54 -05001415 if (!PyAnySet_Check(other))
1416 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 result = set_intersection_update(so, other);
1418 if (result == NULL)
1419 return NULL;
1420 Py_DECREF(result);
1421 Py_INCREF(so);
1422 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001423}
1424
Guido van Rossum58da9312007-11-10 23:39:45 +00001425static PyObject *
1426set_isdisjoint(PySetObject *so, PyObject *other)
1427{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001428 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001429 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 if ((PyObject *)so == other) {
1432 if (PySet_GET_SIZE(so) == 0)
1433 Py_RETURN_TRUE;
1434 else
1435 Py_RETURN_FALSE;
1436 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 if (PyAnySet_CheckExact(other)) {
1439 Py_ssize_t pos = 0;
1440 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001442 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1443 tmp = (PyObject *)so;
1444 so = (PySetObject *)other;
1445 other = tmp;
1446 }
1447 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001448 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001449 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 return NULL;
1451 if (rv)
1452 Py_RETURN_FALSE;
1453 }
1454 Py_RETURN_TRUE;
1455 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 it = PyObject_GetIter(other);
1458 if (it == NULL)
1459 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001462 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 if (hash == -1) {
1465 Py_DECREF(key);
1466 Py_DECREF(it);
1467 return NULL;
1468 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001469 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001471 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 Py_DECREF(it);
1473 return NULL;
1474 }
1475 if (rv) {
1476 Py_DECREF(it);
1477 Py_RETURN_FALSE;
1478 }
1479 }
1480 Py_DECREF(it);
1481 if (PyErr_Occurred())
1482 return NULL;
1483 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001484}
1485
1486PyDoc_STRVAR(isdisjoint_doc,
1487"Return True if two sets have a null intersection.");
1488
Neal Norwitz6576bd82005-11-13 18:41:28 +00001489static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001490set_difference_update_internal(PySetObject *so, PyObject *other)
1491{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 if ((PyObject *)so == other)
1493 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001495 if (PyAnySet_Check(other)) {
1496 setentry *entry;
1497 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001500 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 return -1;
1502 } else {
1503 PyObject *key, *it;
1504 it = PyObject_GetIter(other);
1505 if (it == NULL)
1506 return -1;
1507
1508 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001509 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 Py_DECREF(it);
1511 Py_DECREF(key);
1512 return -1;
1513 }
1514 Py_DECREF(key);
1515 }
1516 Py_DECREF(it);
1517 if (PyErr_Occurred())
1518 return -1;
1519 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001520 /* If more than 1/4th are dummies, then resize them away. */
1521 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001522 return 0;
Raymond Hettinger48973002015-07-03 20:00:03 -07001523 return set_table_resize(so, so->used);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001524}
1525
Raymond Hettingera690a992003-11-16 16:17:49 +00001526static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001527set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001528{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1532 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001533 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001534 return NULL;
1535 }
1536 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001537}
1538
1539PyDoc_STRVAR(difference_update_doc,
1540"Remove all elements of another set from this set.");
1541
1542static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001543set_copy_and_difference(PySetObject *so, PyObject *other)
1544{
1545 PyObject *result;
1546
1547 result = set_copy(so);
1548 if (result == NULL)
1549 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001550 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001551 return result;
1552 Py_DECREF(result);
1553 return NULL;
1554}
1555
1556static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001557set_difference(PySetObject *so, PyObject *other)
1558{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001559 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001560 PyObject *key;
1561 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001562 setentry *entry;
1563 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001564 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001567 return set_copy_and_difference(so, other);
1568 }
1569
1570 /* If len(so) much more than len(other), it's more efficient to simply copy
1571 * so and then iterate other looking for common elements. */
1572 if ((PySet_GET_SIZE(so) >> 2) > PyObject_Size(other)) {
1573 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001574 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001575
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 result = make_new_set_basetype(Py_TYPE(so), NULL);
1577 if (result == NULL)
1578 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 if (PyDict_CheckExact(other)) {
1581 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001582 key = entry->key;
1583 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001584 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001585 if (rv < 0) {
1586 Py_DECREF(result);
1587 return NULL;
1588 }
1589 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001590 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 Py_DECREF(result);
1592 return NULL;
1593 }
1594 }
1595 }
1596 return result;
1597 }
1598
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001599 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001601 key = entry->key;
1602 hash = entry->hash;
1603 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001604 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001605 Py_DECREF(result);
1606 return NULL;
1607 }
1608 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001609 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001610 Py_DECREF(result);
1611 return NULL;
1612 }
1613 }
1614 }
1615 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001616}
1617
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001618static PyObject *
1619set_difference_multi(PySetObject *so, PyObject *args)
1620{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 Py_ssize_t i;
1622 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 if (PyTuple_GET_SIZE(args) == 0)
1625 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 other = PyTuple_GET_ITEM(args, 0);
1628 result = set_difference(so, other);
1629 if (result == NULL)
1630 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1633 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001634 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 Py_DECREF(result);
1636 return NULL;
1637 }
1638 }
1639 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001640}
1641
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001642PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001643"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001644\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001645(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001646static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001647set_sub(PySetObject *so, PyObject *other)
1648{
Brian Curtindfc80e32011-08-10 20:28:54 -05001649 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1650 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001652}
1653
1654static PyObject *
1655set_isub(PySetObject *so, PyObject *other)
1656{
Brian Curtindfc80e32011-08-10 20:28:54 -05001657 if (!PyAnySet_Check(other))
1658 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001659 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 return NULL;
1661 Py_INCREF(so);
1662 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001663}
1664
1665static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001666set_symmetric_difference_update(PySetObject *so, PyObject *other)
1667{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 PySetObject *otherset;
1669 PyObject *key;
1670 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001671 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001672 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001673 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001675 if ((PyObject *)so == other)
1676 return set_clear(so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001677
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001678 if (PyDict_CheckExact(other)) {
1679 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001680 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001681 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001682 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001683 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001684 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001685 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001686 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001687 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001688 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001689 Py_DECREF(key);
1690 return NULL;
1691 }
1692 }
Georg Brandl2d444492010-09-03 10:52:55 +00001693 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001694 }
1695 Py_RETURN_NONE;
1696 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001697
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001698 if (PyAnySet_Check(other)) {
1699 Py_INCREF(other);
1700 otherset = (PySetObject *)other;
1701 } else {
1702 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1703 if (otherset == NULL)
1704 return NULL;
1705 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001706
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001707 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001708 key = entry->key;
1709 hash = entry->hash;
1710 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001711 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001712 Py_DECREF(otherset);
1713 return NULL;
1714 }
1715 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001716 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001717 Py_DECREF(otherset);
1718 return NULL;
1719 }
1720 }
1721 }
1722 Py_DECREF(otherset);
1723 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001724}
1725
1726PyDoc_STRVAR(symmetric_difference_update_doc,
1727"Update a set with the symmetric difference of itself and another.");
1728
1729static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001730set_symmetric_difference(PySetObject *so, PyObject *other)
1731{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001732 PyObject *rv;
1733 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001735 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1736 if (otherset == NULL)
1737 return NULL;
1738 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
1739 if (rv == NULL)
1740 return NULL;
1741 Py_DECREF(rv);
1742 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001743}
1744
1745PyDoc_STRVAR(symmetric_difference_doc,
1746"Return the symmetric difference of two sets as a new set.\n\
1747\n\
1748(i.e. all elements that are in exactly one of the sets.)");
1749
1750static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001751set_xor(PySetObject *so, PyObject *other)
1752{
Brian Curtindfc80e32011-08-10 20:28:54 -05001753 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1754 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001755 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001756}
1757
1758static PyObject *
1759set_ixor(PySetObject *so, PyObject *other)
1760{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001762
Brian Curtindfc80e32011-08-10 20:28:54 -05001763 if (!PyAnySet_Check(other))
1764 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001765 result = set_symmetric_difference_update(so, other);
1766 if (result == NULL)
1767 return NULL;
1768 Py_DECREF(result);
1769 Py_INCREF(so);
1770 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001771}
1772
1773static PyObject *
1774set_issubset(PySetObject *so, PyObject *other)
1775{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776 setentry *entry;
1777 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001778 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001779
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780 if (!PyAnySet_Check(other)) {
1781 PyObject *tmp, *result;
1782 tmp = make_new_set(&PySet_Type, other);
1783 if (tmp == NULL)
1784 return NULL;
1785 result = set_issubset(so, tmp);
1786 Py_DECREF(tmp);
1787 return result;
1788 }
1789 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1790 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001791
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001792 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001793 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001794 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001795 return NULL;
1796 if (!rv)
1797 Py_RETURN_FALSE;
1798 }
1799 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001800}
1801
1802PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1803
1804static PyObject *
1805set_issuperset(PySetObject *so, PyObject *other)
1806{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001807 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001808
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001809 if (!PyAnySet_Check(other)) {
1810 tmp = make_new_set(&PySet_Type, other);
1811 if (tmp == NULL)
1812 return NULL;
1813 result = set_issuperset(so, tmp);
1814 Py_DECREF(tmp);
1815 return result;
1816 }
1817 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001818}
1819
1820PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1821
Raymond Hettingera690a992003-11-16 16:17:49 +00001822static PyObject *
1823set_richcompare(PySetObject *v, PyObject *w, int op)
1824{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001825 PyObject *r1;
1826 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001827
Brian Curtindfc80e32011-08-10 20:28:54 -05001828 if(!PyAnySet_Check(w))
1829 Py_RETURN_NOTIMPLEMENTED;
1830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001831 switch (op) {
1832 case Py_EQ:
1833 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1834 Py_RETURN_FALSE;
1835 if (v->hash != -1 &&
1836 ((PySetObject *)w)->hash != -1 &&
1837 v->hash != ((PySetObject *)w)->hash)
1838 Py_RETURN_FALSE;
1839 return set_issubset(v, w);
1840 case Py_NE:
1841 r1 = set_richcompare(v, w, Py_EQ);
1842 if (r1 == NULL)
1843 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001844 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001846 if (r2 < 0)
1847 return NULL;
1848 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001849 case Py_LE:
1850 return set_issubset(v, w);
1851 case Py_GE:
1852 return set_issuperset(v, w);
1853 case Py_LT:
1854 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1855 Py_RETURN_FALSE;
1856 return set_issubset(v, w);
1857 case Py_GT:
1858 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1859 Py_RETURN_FALSE;
1860 return set_issuperset(v, w);
1861 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001862 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001863}
1864
Raymond Hettingera690a992003-11-16 16:17:49 +00001865static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001866set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001867{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001868 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001869 return NULL;
1870 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001871}
1872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001874"Add an element to a set.\n\
1875\n\
1876This has no effect if the element is already present.");
1877
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001878static int
1879set_contains(PySetObject *so, PyObject *key)
1880{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 PyObject *tmpkey;
1882 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001883
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001885 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1887 return -1;
1888 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001889 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 if (tmpkey == NULL)
1891 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001892 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 Py_DECREF(tmpkey);
1894 }
1895 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001896}
1897
1898static PyObject *
1899set_direct_contains(PySetObject *so, PyObject *key)
1900{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001902
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001903 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001904 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 return NULL;
1906 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001907}
1908
1909PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1910
Raymond Hettingera690a992003-11-16 16:17:49 +00001911static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001912set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001913{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 PyObject *tmpkey;
1915 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001916
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001917 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001918 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1920 return NULL;
1921 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001922 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923 if (tmpkey == NULL)
1924 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001927 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001928 return NULL;
1929 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001932 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001933 return NULL;
1934 }
1935 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001936}
1937
1938PyDoc_STRVAR(remove_doc,
1939"Remove an element from a set; it must be a member.\n\
1940\n\
1941If the element is not a member, raise a KeyError.");
1942
1943static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001944set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001945{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001946 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001949 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001950 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1952 return NULL;
1953 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001954 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 if (tmpkey == NULL)
1956 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001957 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001958 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001959 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001960 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001961 }
1962 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001963}
1964
1965PyDoc_STRVAR(discard_doc,
1966"Remove an element from a set if it is a member.\n\
1967\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001969
1970static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001971set_reduce(PySetObject *so)
1972{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001974 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001975
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001976 keys = PySequence_List((PyObject *)so);
1977 if (keys == NULL)
1978 goto done;
1979 args = PyTuple_Pack(1, keys);
1980 if (args == NULL)
1981 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001982 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001983 if (dict == NULL) {
1984 PyErr_Clear();
1985 dict = Py_None;
1986 Py_INCREF(dict);
1987 }
1988 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001989done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001990 Py_XDECREF(args);
1991 Py_XDECREF(keys);
1992 Py_XDECREF(dict);
1993 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001994}
1995
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001996static PyObject *
1997set_sizeof(PySetObject *so)
1998{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001999 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002000
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002001 res = sizeof(PySetObject);
2002 if (so->table != so->smalltable)
2003 res = res + (so->mask + 1) * sizeof(setentry);
2004 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002005}
2006
2007PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002008static int
2009set_init(PySetObject *self, PyObject *args, PyObject *kwds)
2010{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002011 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002012
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002013 if (!PyAnySet_Check(self))
2014 return -1;
2015 if (PySet_Check(self) && !_PyArg_NoKeywords("set()", kwds))
2016 return -1;
2017 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
2018 return -1;
2019 set_clear_internal(self);
2020 self->hash = -1;
2021 if (iterable == NULL)
2022 return 0;
2023 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002024}
2025
Raymond Hettingera690a992003-11-16 16:17:49 +00002026static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002027 set_len, /* sq_length */
2028 0, /* sq_concat */
2029 0, /* sq_repeat */
2030 0, /* sq_item */
2031 0, /* sq_slice */
2032 0, /* sq_ass_item */
2033 0, /* sq_ass_slice */
2034 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002035};
2036
2037/* set object ********************************************************/
2038
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002039#ifdef Py_DEBUG
2040static PyObject *test_c_api(PySetObject *so);
2041
2042PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2043All is well if assertions don't fail.");
2044#endif
2045
Raymond Hettingera690a992003-11-16 16:17:49 +00002046static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002047 {"add", (PyCFunction)set_add, METH_O,
2048 add_doc},
2049 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2050 clear_doc},
2051 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2052 contains_doc},
2053 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2054 copy_doc},
2055 {"discard", (PyCFunction)set_discard, METH_O,
2056 discard_doc},
2057 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2058 difference_doc},
2059 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2060 difference_update_doc},
2061 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2062 intersection_doc},
2063 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2064 intersection_update_doc},
2065 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2066 isdisjoint_doc},
2067 {"issubset", (PyCFunction)set_issubset, METH_O,
2068 issubset_doc},
2069 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2070 issuperset_doc},
2071 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2072 pop_doc},
2073 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2074 reduce_doc},
2075 {"remove", (PyCFunction)set_remove, METH_O,
2076 remove_doc},
2077 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2078 sizeof_doc},
2079 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2080 symmetric_difference_doc},
2081 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2082 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002083#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002084 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2085 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002086#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002087 {"union", (PyCFunction)set_union, METH_VARARGS,
2088 union_doc},
2089 {"update", (PyCFunction)set_update, METH_VARARGS,
2090 update_doc},
2091 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002092};
2093
2094static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002095 0, /*nb_add*/
2096 (binaryfunc)set_sub, /*nb_subtract*/
2097 0, /*nb_multiply*/
2098 0, /*nb_remainder*/
2099 0, /*nb_divmod*/
2100 0, /*nb_power*/
2101 0, /*nb_negative*/
2102 0, /*nb_positive*/
2103 0, /*nb_absolute*/
2104 0, /*nb_bool*/
2105 0, /*nb_invert*/
2106 0, /*nb_lshift*/
2107 0, /*nb_rshift*/
2108 (binaryfunc)set_and, /*nb_and*/
2109 (binaryfunc)set_xor, /*nb_xor*/
2110 (binaryfunc)set_or, /*nb_or*/
2111 0, /*nb_int*/
2112 0, /*nb_reserved*/
2113 0, /*nb_float*/
2114 0, /*nb_inplace_add*/
2115 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2116 0, /*nb_inplace_multiply*/
2117 0, /*nb_inplace_remainder*/
2118 0, /*nb_inplace_power*/
2119 0, /*nb_inplace_lshift*/
2120 0, /*nb_inplace_rshift*/
2121 (binaryfunc)set_iand, /*nb_inplace_and*/
2122 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2123 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002124};
2125
2126PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002127"set() -> new empty set object\n\
2128set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002129\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002130Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002131
2132PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002133 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2134 "set", /* tp_name */
2135 sizeof(PySetObject), /* tp_basicsize */
2136 0, /* tp_itemsize */
2137 /* methods */
2138 (destructor)set_dealloc, /* tp_dealloc */
2139 0, /* tp_print */
2140 0, /* tp_getattr */
2141 0, /* tp_setattr */
2142 0, /* tp_reserved */
2143 (reprfunc)set_repr, /* tp_repr */
2144 &set_as_number, /* tp_as_number */
2145 &set_as_sequence, /* tp_as_sequence */
2146 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002147 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002148 0, /* tp_call */
2149 0, /* tp_str */
2150 PyObject_GenericGetAttr, /* tp_getattro */
2151 0, /* tp_setattro */
2152 0, /* tp_as_buffer */
2153 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2154 Py_TPFLAGS_BASETYPE, /* tp_flags */
2155 set_doc, /* tp_doc */
2156 (traverseproc)set_traverse, /* tp_traverse */
2157 (inquiry)set_clear_internal, /* tp_clear */
2158 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002159 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2160 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 0, /* tp_iternext */
2162 set_methods, /* tp_methods */
2163 0, /* tp_members */
2164 0, /* tp_getset */
2165 0, /* tp_base */
2166 0, /* tp_dict */
2167 0, /* tp_descr_get */
2168 0, /* tp_descr_set */
2169 0, /* tp_dictoffset */
2170 (initproc)set_init, /* tp_init */
2171 PyType_GenericAlloc, /* tp_alloc */
2172 set_new, /* tp_new */
2173 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002174};
2175
2176/* frozenset object ********************************************************/
2177
2178
2179static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002180 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2181 contains_doc},
2182 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2183 copy_doc},
2184 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2185 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002186 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002187 intersection_doc},
2188 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2189 isdisjoint_doc},
2190 {"issubset", (PyCFunction)set_issubset, METH_O,
2191 issubset_doc},
2192 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2193 issuperset_doc},
2194 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2195 reduce_doc},
2196 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2197 sizeof_doc},
2198 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2199 symmetric_difference_doc},
2200 {"union", (PyCFunction)set_union, METH_VARARGS,
2201 union_doc},
2202 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002203};
2204
2205static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002206 0, /*nb_add*/
2207 (binaryfunc)set_sub, /*nb_subtract*/
2208 0, /*nb_multiply*/
2209 0, /*nb_remainder*/
2210 0, /*nb_divmod*/
2211 0, /*nb_power*/
2212 0, /*nb_negative*/
2213 0, /*nb_positive*/
2214 0, /*nb_absolute*/
2215 0, /*nb_bool*/
2216 0, /*nb_invert*/
2217 0, /*nb_lshift*/
2218 0, /*nb_rshift*/
2219 (binaryfunc)set_and, /*nb_and*/
2220 (binaryfunc)set_xor, /*nb_xor*/
2221 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002222};
2223
2224PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002225"frozenset() -> empty frozenset object\n\
2226frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002227\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002228Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002229
2230PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002231 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2232 "frozenset", /* tp_name */
2233 sizeof(PySetObject), /* tp_basicsize */
2234 0, /* tp_itemsize */
2235 /* methods */
2236 (destructor)set_dealloc, /* tp_dealloc */
2237 0, /* tp_print */
2238 0, /* tp_getattr */
2239 0, /* tp_setattr */
2240 0, /* tp_reserved */
2241 (reprfunc)set_repr, /* tp_repr */
2242 &frozenset_as_number, /* tp_as_number */
2243 &set_as_sequence, /* tp_as_sequence */
2244 0, /* tp_as_mapping */
2245 frozenset_hash, /* tp_hash */
2246 0, /* tp_call */
2247 0, /* tp_str */
2248 PyObject_GenericGetAttr, /* tp_getattro */
2249 0, /* tp_setattro */
2250 0, /* tp_as_buffer */
2251 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2252 Py_TPFLAGS_BASETYPE, /* tp_flags */
2253 frozenset_doc, /* tp_doc */
2254 (traverseproc)set_traverse, /* tp_traverse */
2255 (inquiry)set_clear_internal, /* tp_clear */
2256 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002257 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002258 (getiterfunc)set_iter, /* tp_iter */
2259 0, /* tp_iternext */
2260 frozenset_methods, /* tp_methods */
2261 0, /* tp_members */
2262 0, /* tp_getset */
2263 0, /* tp_base */
2264 0, /* tp_dict */
2265 0, /* tp_descr_get */
2266 0, /* tp_descr_set */
2267 0, /* tp_dictoffset */
2268 0, /* tp_init */
2269 PyType_GenericAlloc, /* tp_alloc */
2270 frozenset_new, /* tp_new */
2271 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002272};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002273
2274
2275/***** C API functions *************************************************/
2276
2277PyObject *
2278PySet_New(PyObject *iterable)
2279{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002280 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002281}
2282
2283PyObject *
2284PyFrozenSet_New(PyObject *iterable)
2285{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002286 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002287}
2288
Neal Norwitz8c49c822006-03-04 18:41:19 +00002289Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002290PySet_Size(PyObject *anyset)
2291{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002292 if (!PyAnySet_Check(anyset)) {
2293 PyErr_BadInternalCall();
2294 return -1;
2295 }
2296 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002297}
2298
2299int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002300PySet_Clear(PyObject *set)
2301{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002302 if (!PySet_Check(set)) {
2303 PyErr_BadInternalCall();
2304 return -1;
2305 }
2306 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002307}
2308
2309int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002310PySet_Contains(PyObject *anyset, PyObject *key)
2311{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002312 if (!PyAnySet_Check(anyset)) {
2313 PyErr_BadInternalCall();
2314 return -1;
2315 }
2316 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002317}
2318
2319int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002320PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002321{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002322 if (!PySet_Check(set)) {
2323 PyErr_BadInternalCall();
2324 return -1;
2325 }
2326 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002327}
2328
2329int
Christian Heimesfd66e512008-01-29 12:18:50 +00002330PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002331{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002332 if (!PySet_Check(anyset) &&
2333 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2334 PyErr_BadInternalCall();
2335 return -1;
2336 }
2337 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002338}
2339
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002340int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002341_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002342{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002343 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002345 if (!PyAnySet_Check(set)) {
2346 PyErr_BadInternalCall();
2347 return -1;
2348 }
2349 if (set_next((PySetObject *)set, pos, &entry) == 0)
2350 return 0;
2351 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002352 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002353 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002354}
2355
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002356PyObject *
2357PySet_Pop(PyObject *set)
2358{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002359 if (!PySet_Check(set)) {
2360 PyErr_BadInternalCall();
2361 return NULL;
2362 }
2363 return set_pop((PySetObject *)set);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002364}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002365
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002366int
2367_PySet_Update(PyObject *set, PyObject *iterable)
2368{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002369 if (!PySet_Check(set)) {
2370 PyErr_BadInternalCall();
2371 return -1;
2372 }
2373 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002374}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002375
Raymond Hettingere259f132013-12-15 11:56:14 -08002376/* Exported for the gdb plugin's benefit. */
2377PyObject *_PySet_Dummy = dummy;
2378
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002379#ifdef Py_DEBUG
2380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002381/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002382 Returns True and original set is restored. */
2383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002384#define assertRaises(call_return_value, exception) \
2385 do { \
2386 assert(call_return_value); \
2387 assert(PyErr_ExceptionMatches(exception)); \
2388 PyErr_Clear(); \
2389 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002390
2391static PyObject *
2392test_c_api(PySetObject *so)
2393{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002394 Py_ssize_t count;
2395 char *s;
2396 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002397 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002398 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002399 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002400 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002402 /* Verify preconditions */
2403 assert(PyAnySet_Check(ob));
2404 assert(PyAnySet_CheckExact(ob));
2405 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002406
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002407 /* so.clear(); so |= set("abc"); */
2408 str = PyUnicode_FromString("abc");
2409 if (str == NULL)
2410 return NULL;
2411 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002412 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002413 Py_DECREF(str);
2414 return NULL;
2415 }
2416 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002418 /* Exercise type/size checks */
2419 assert(PySet_Size(ob) == 3);
2420 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002422 /* Raise TypeError for non-iterable constructor arguments */
2423 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2424 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002426 /* Raise TypeError for unhashable key */
2427 dup = PySet_New(ob);
2428 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2429 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2430 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002432 /* Exercise successful pop, contains, add, and discard */
2433 elem = PySet_Pop(ob);
2434 assert(PySet_Contains(ob, elem) == 0);
2435 assert(PySet_GET_SIZE(ob) == 2);
2436 assert(PySet_Add(ob, elem) == 0);
2437 assert(PySet_Contains(ob, elem) == 1);
2438 assert(PySet_GET_SIZE(ob) == 3);
2439 assert(PySet_Discard(ob, elem) == 1);
2440 assert(PySet_GET_SIZE(ob) == 2);
2441 assert(PySet_Discard(ob, elem) == 0);
2442 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002443
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002444 /* Exercise clear */
2445 dup2 = PySet_New(dup);
2446 assert(PySet_Clear(dup2) == 0);
2447 assert(PySet_Size(dup2) == 0);
2448 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002450 /* Raise SystemError on clear or update of frozen set */
2451 f = PyFrozenSet_New(dup);
2452 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2453 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2454 assert(PySet_Add(f, elem) == 0);
2455 Py_INCREF(f);
2456 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2457 Py_DECREF(f);
2458 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002460 /* Exercise direct iteration */
2461 i = 0, count = 0;
2462 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
2463 s = _PyUnicode_AsString(x);
2464 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2465 count++;
2466 }
2467 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002469 /* Exercise updates */
2470 dup2 = PySet_New(NULL);
2471 assert(_PySet_Update(dup2, dup) == 0);
2472 assert(PySet_Size(dup2) == 3);
2473 assert(_PySet_Update(dup2, dup) == 0);
2474 assert(PySet_Size(dup2) == 3);
2475 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002477 /* Raise SystemError when self argument is not a set or frozenset. */
2478 t = PyTuple_New(0);
2479 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2480 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2481 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002483 /* Raise SystemError when self argument is not a set. */
2484 f = PyFrozenSet_New(dup);
2485 assert(PySet_Size(f) == 3);
2486 assert(PyFrozenSet_CheckExact(f));
2487 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2488 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2489 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002491 /* Raise KeyError when popping from an empty set */
2492 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2493 Py_DECREF(ob);
2494 assert(PySet_GET_SIZE(ob) == 0);
2495 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002497 /* Restore the set from the copy using the PyNumber API */
2498 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2499 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002501 /* Verify constructors accept NULL arguments */
2502 f = PySet_New(NULL);
2503 assert(f != NULL);
2504 assert(PySet_GET_SIZE(f) == 0);
2505 Py_DECREF(f);
2506 f = PyFrozenSet_New(NULL);
2507 assert(f != NULL);
2508 assert(PyFrozenSet_CheckExact(f));
2509 assert(PySet_GET_SIZE(f) == 0);
2510 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002512 Py_DECREF(elem);
2513 Py_DECREF(dup);
2514 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002515}
2516
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002517#undef assertRaises
2518
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002519#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002520
2521/***** Dummy Struct *************************************************/
2522
2523static PyObject *
2524dummy_repr(PyObject *op)
2525{
2526 return PyUnicode_FromString("<dummy key>");
2527}
2528
2529static void
2530dummy_dealloc(PyObject* ignore)
2531{
2532 Py_FatalError("deallocating <dummy key>");
2533}
2534
2535static PyTypeObject _PySetDummy_Type = {
2536 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2537 "<dummy key> type",
2538 0,
2539 0,
2540 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2541 0, /*tp_print*/
2542 0, /*tp_getattr*/
2543 0, /*tp_setattr*/
2544 0, /*tp_reserved*/
2545 dummy_repr, /*tp_repr*/
2546 0, /*tp_as_number*/
2547 0, /*tp_as_sequence*/
2548 0, /*tp_as_mapping*/
2549 0, /*tp_hash */
2550 0, /*tp_call */
2551 0, /*tp_str */
2552 0, /*tp_getattro */
2553 0, /*tp_setattro */
2554 0, /*tp_as_buffer */
2555 Py_TPFLAGS_DEFAULT, /*tp_flags */
2556};
2557
2558static PyObject _dummy_struct = {
2559 _PyObject_EXTRA_INIT
2560 2, &_PySetDummy_Type
2561};
2562