blob: 4f04f49efaa34739dec6b5b882d0e1c960ab9d1e [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 Hettingerae7b00e2013-09-07 15:05:00 -07007 The basic lookup function used by all operations.
8 This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
9
10 The initial probe index is computed as hash mod the table size.
11 Subsequent probe indices are computed as explained in Objects/dictobject.c.
12
13 To improve cache locality, each probe inspects a series of consecutive
14 nearby entries before moving on to probes elsewhere in memory. This leaves
15 us with a hybrid of linear probing and open addressing. The linear probing
16 reduces the cost of hash collisions because consecutive memory accesses
17 tend to be much cheaper than scattered probes. After LINEAR_PROBES steps,
18 we then use open addressing with the upper bits from the hash value. This
19 helps break-up long chains of collisions.
20
21 All arithmetic on hash should ignore overflow.
22
Raymond Hettinger4d45c102015-01-25 16:27:40 -080023 Unlike the dictionary implementation, the lookkey function can return
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070024 NULL if the rich comparison returns an error.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000025*/
26
Raymond Hettingera690a992003-11-16 16:17:49 +000027#include "Python.h"
Raymond Hettingera9d99362005-08-05 00:01:15 +000028#include "structmember.h"
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000029
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000030/* Object used as dummy key to fill deleted entries */
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -050031static PyObject _dummy_struct;
32
33#define dummy (&_dummy_struct)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000034
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000035
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -070036/* ======================================================================== */
37/* ======= Begin logic for probing the hash table ========================= */
38
Raymond Hettinger710a67e2013-09-21 20:17:31 -070039/* Set this to zero to turn-off linear probing */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070040#ifndef LINEAR_PROBES
Raymond Hettinger742d8712013-09-08 00:25:57 -070041#define LINEAR_PROBES 9
Raymond Hettinger8408dc52013-09-15 14:57:15 -070042#endif
Raymond Hettinger742d8712013-09-08 00:25:57 -070043
44/* This must be >= 1 */
45#define PERTURB_SHIFT 5
46
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000047static setentry *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020048set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000049{
Raymond Hettinger70559b52015-07-23 07:42:23 -040050 setentry *table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020051 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070052 size_t perturb;
Raymond Hettingerafe89092013-08-28 20:59:31 -070053 size_t mask = so->mask;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -080054 size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070055 size_t j;
Raymond Hettinger4ef05282013-09-21 15:39:49 -070056 int cmp;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000057
Raymond Hettinger70559b52015-07-23 07:42:23 -040058 entry = &so->table[i];
Raymond Hettingerafe89092013-08-28 20:59:31 -070059 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000060 return entry;
Raymond Hettinger237b34b2013-08-17 02:31:53 -070061
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070062 perturb = hash;
63
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -070064 while (1) {
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080065 if (entry->hash == hash) {
Raymond Hettingerafe89092013-08-28 20:59:31 -070066 PyObject *startkey = entry->key;
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080067 /* startkey cannot be a dummy because the dummy hash field is -1 */
68 assert(startkey != dummy);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -080069 if (startkey == key)
70 return entry;
Raymond Hettinger93035c42015-01-25 16:12:49 -080071 if (PyUnicode_CheckExact(startkey)
72 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -070073 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger93035c42015-01-25 16:12:49 -080074 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -040075 table = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000076 Py_INCREF(startkey);
77 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
78 Py_DECREF(startkey);
Raymond Hettinger426d9952014-05-18 21:40:20 +010079 if (cmp < 0) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000080 return NULL;
Raymond Hettinger426d9952014-05-18 21:40:20 +010081 if (table != so->table || entry->key != startkey) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000082 return set_lookkey(so, key, hash);
Raymond Hettinger426d9952014-05-18 21:40:20 +010083 if (cmp > 0) /* likely */
Raymond Hettingerafe89092013-08-28 20:59:31 -070084 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -060085 mask = so->mask; /* help avoid a register spill */
Raymond Hettingerafe89092013-08-28 20:59:31 -070086 }
Raymond Hettingerafe89092013-08-28 20:59:31 -070087
Raymond Hettingerc658d852015-02-02 08:35:00 -080088 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -080089 for (j = 0 ; j < LINEAR_PROBES ; j++) {
Raymond Hettingerc658d852015-02-02 08:35:00 -080090 entry++;
Raymond Hettinger8651a502015-05-27 10:37:20 -070091 if (entry->hash == 0 && entry->key == NULL)
92 return entry;
Raymond Hettingerc658d852015-02-02 08:35:00 -080093 if (entry->hash == hash) {
94 PyObject *startkey = entry->key;
95 assert(startkey != dummy);
96 if (startkey == key)
97 return entry;
98 if (PyUnicode_CheckExact(startkey)
99 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700100 && _PyUnicode_EQ(startkey, key))
Raymond Hettingerc658d852015-02-02 08:35:00 -0800101 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400102 table = so->table;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800103 Py_INCREF(startkey);
104 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
105 Py_DECREF(startkey);
106 if (cmp < 0)
107 return NULL;
108 if (table != so->table || entry->key != startkey)
109 return set_lookkey(so, key, hash);
110 if (cmp > 0)
111 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -0600112 mask = so->mask;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800113 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700114 }
115 }
116
117 perturb >>= PERTURB_SHIFT;
118 i = (i * 5 + 1 + perturb) & mask;
119
Raymond Hettinger70559b52015-07-23 07:42:23 -0400120 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700121 if (entry->key == NULL)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700122 return entry;
123 }
124}
125
Raymond Hettinger15f08692015-07-03 17:21:17 -0700126static int set_table_resize(PySetObject *, Py_ssize_t);
127
Raymond Hettinger8651a502015-05-27 10:37:20 -0700128static int
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400129set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700130{
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400131 setentry *table;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700132 setentry *freeslot;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700133 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700134 size_t perturb;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400135 size_t mask;
136 size_t i; /* Unsigned for defined overflow behavior */
Raymond Hettinger8651a502015-05-27 10:37:20 -0700137 size_t j;
138 int cmp;
139
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400140 /* Pre-increment is necessary to prevent arbitrary code in the rich
141 comparison from deallocating the key just before the insertion. */
142 Py_INCREF(key);
143
144 restart:
145
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400146 mask = so->mask;
147 i = (size_t)hash & mask;
148
Raymond Hettinger70559b52015-07-23 07:42:23 -0400149 entry = &so->table[i];
Raymond Hettinger8651a502015-05-27 10:37:20 -0700150 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700151 goto found_unused;
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700152
153 freeslot = NULL;
154 perturb = hash;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700155
156 while (1) {
157 if (entry->hash == hash) {
158 PyObject *startkey = entry->key;
159 /* startkey cannot be a dummy because the dummy hash field is -1 */
160 assert(startkey != dummy);
161 if (startkey == key)
162 goto found_active;
163 if (PyUnicode_CheckExact(startkey)
164 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700165 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700166 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400167 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700168 Py_INCREF(startkey);
169 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
170 Py_DECREF(startkey);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700171 if (cmp > 0) /* likely */
172 goto found_active;
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700173 if (cmp < 0)
174 goto comparison_error;
175 /* Continuing the search from the current entry only makes
176 sense if the table and entry are unchanged; otherwise,
177 we have to restart from the beginning */
178 if (table != so->table || entry->key != startkey)
179 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700180 mask = so->mask; /* help avoid a register spill */
181 }
Raymond Hettinger70559b52015-07-23 07:42:23 -0400182 else if (entry->hash == -1 && freeslot == NULL)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700183 freeslot = entry;
184
185 if (i + LINEAR_PROBES <= mask) {
186 for (j = 0 ; j < LINEAR_PROBES ; j++) {
187 entry++;
188 if (entry->hash == 0 && entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700189 goto found_unused_or_dummy;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700190 if (entry->hash == hash) {
191 PyObject *startkey = entry->key;
192 assert(startkey != dummy);
193 if (startkey == key)
194 goto found_active;
195 if (PyUnicode_CheckExact(startkey)
196 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700197 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700198 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400199 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700200 Py_INCREF(startkey);
201 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
202 Py_DECREF(startkey);
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700203 if (cmp > 0)
204 goto found_active;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700205 if (cmp < 0)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400206 goto comparison_error;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700207 if (table != so->table || entry->key != startkey)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400208 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700209 mask = so->mask;
210 }
Raymond Hettinger91672612015-06-26 02:50:21 -0700211 else if (entry->hash == -1 && freeslot == NULL)
Raymond Hettingerc658d852015-02-02 08:35:00 -0800212 freeslot = entry;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700213 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700215
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700216 perturb >>= PERTURB_SHIFT;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -0800217 i = (i * 5 + 1 + perturb) & mask;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700218
Raymond Hettinger70559b52015-07-23 07:42:23 -0400219 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700220 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700221 goto found_unused_or_dummy;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700223
Raymond Hettinger15f08692015-07-03 17:21:17 -0700224 found_unused_or_dummy:
225 if (freeslot == NULL)
226 goto found_unused;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700227 so->used++;
228 freeslot->key = key;
229 freeslot->hash = hash;
230 return 0;
231
232 found_unused:
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700233 so->fill++;
234 so->used++;
235 entry->key = key;
236 entry->hash = hash;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800237 if ((size_t)so->fill*5 < mask*3)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700238 return 0;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400239 return set_table_resize(so, so->used);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700240
241 found_active:
Raymond Hettinger482c05c2015-07-20 01:23:32 -0400242 Py_DECREF(key);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700243 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000244
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400245 comparison_error:
Raymond Hettinger061091a2015-07-15 23:54:02 -0700246 Py_DECREF(key);
247 return -1;
248}
249
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000250/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000251Internal routine used by set_table_resize() to insert an item which is
252known to be absent from the set. This routine also assumes that
253the set contains no deleted entries. Besides the performance benefit,
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800254there is also safety benefit since using set_add_entry() risks making
255a callback in the middle of a set_table_resize(), see issue 1456209.
256The caller is responsible for updating the key's reference count and
257the setobject's fill and used fields.
Thomas Wouters89f507f2006-12-13 04:49:30 +0000258*/
259static void
Raymond Hettinger5088f602015-12-13 18:45:01 -0800260set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000261{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200262 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700263 size_t perturb = hash;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800264 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700265 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000266
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700267 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800268 entry = &table[i];
269 if (entry->key == NULL)
270 goto found_null;
271 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800272 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800273 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800274 if (entry->key == NULL)
275 goto found_null;
276 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700277 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700278 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800279 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700281 found_null:
Raymond Hettinger5088f602015-12-13 18:45:01 -0800282 entry->key = key;
Raymond Hettinger86d322f2015-12-13 19:27:17 -0800283 entry->hash = hash;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000284}
285
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700286/* ======== End logic for probing the hash table ========================== */
287/* ======================================================================== */
288
Thomas Wouters89f507f2006-12-13 04:49:30 +0000289/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000290Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000291keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000292actually be smaller than the old one.
293*/
294static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000296{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 Py_ssize_t newsize;
298 setentry *oldtable, *newtable, *entry;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800299 Py_ssize_t oldmask = so->mask;
300 size_t newmask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301 int is_oldtable_malloced;
302 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 assert(minused >= 0);
Raymond Hettinger48973002015-07-03 20:00:03 -0700305 minused = (minused > 50000) ? minused * 2 : minused * 4;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100308 /* XXX speed-up with intrinsics */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 for (newsize = PySet_MINSIZE;
310 newsize <= minused && newsize > 0;
311 newsize <<= 1)
312 ;
313 if (newsize <= 0) {
314 PyErr_NoMemory();
315 return -1;
316 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 /* Get space for a new table. */
319 oldtable = so->table;
320 assert(oldtable != NULL);
321 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 if (newsize == PySet_MINSIZE) {
324 /* A large table is shrinking, or we can't get any smaller. */
325 newtable = so->smalltable;
326 if (newtable == oldtable) {
327 if (so->fill == so->used) {
328 /* No dummies, so no point doing anything. */
329 return 0;
330 }
331 /* We're not going to resize it, but rebuild the
332 table anyway to purge old dummy entries.
333 Subtle: This is *necessary* if fill==size,
334 as set_lookkey needs at least one virgin slot to
335 terminate failing searches. If fill < size, it's
336 merely desirable, as dummies slow searches. */
337 assert(so->fill > so->used);
338 memcpy(small_copy, oldtable, sizeof(small_copy));
339 oldtable = small_copy;
340 }
341 }
342 else {
343 newtable = PyMem_NEW(setentry, newsize);
344 if (newtable == NULL) {
345 PyErr_NoMemory();
346 return -1;
347 }
348 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 /* Make the set empty, using the new table. */
351 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 memset(newtable, 0, sizeof(setentry) * newsize);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800353 so->mask = newsize - 1;
354 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000356 /* Copy the data over; this is refcount-neutral for active entries;
357 dummy entries aren't copied over, of course */
Raymond Hettinger5088f602015-12-13 18:45:01 -0800358 newmask = (size_t)so->mask;
Raymond Hettingere1af6962017-02-02 08:24:48 -0800359 if (so->fill == so->used) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800360 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800361 if (entry->key != NULL) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800362 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800363 }
364 }
365 } else {
Raymond Hettingere1af6962017-02-02 08:24:48 -0800366 so->fill = so->used;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800367 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800368 if (entry->key != NULL && entry->key != dummy) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800369 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800370 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000371 }
372 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 if (is_oldtable_malloced)
375 PyMem_DEL(oldtable);
376 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000377}
378
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000379static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700380set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000381{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700382 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000383
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700384 entry = set_lookkey(so, key, hash);
385 if (entry != NULL)
386 return entry->key != NULL;
387 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000388}
389
390#define DISCARD_NOTFOUND 0
391#define DISCARD_FOUND 1
392
393static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700394set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800395{
396 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000398
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700399 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 if (entry == NULL)
401 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700402 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 return DISCARD_NOTFOUND;
404 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800406 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 so->used--;
408 Py_DECREF(old_key);
409 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000410}
411
412static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700413set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000414{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200415 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000416
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700417 if (!PyUnicode_CheckExact(key) ||
418 (hash = ((PyASCIIObject *) key)->hash) == -1) {
419 hash = PyObject_Hash(key);
420 if (hash == -1)
421 return -1;
422 }
423 return set_add_entry(so, key, hash);
424}
425
426static int
427set_contains_key(PySetObject *so, PyObject *key)
428{
429 Py_hash_t hash;
430
431 if (!PyUnicode_CheckExact(key) ||
432 (hash = ((PyASCIIObject *) key)->hash) == -1) {
433 hash = PyObject_Hash(key);
434 if (hash == -1)
435 return -1;
436 }
437 return set_contains_entry(so, key, hash);
438}
439
440static int
441set_discard_key(PySetObject *so, PyObject *key)
442{
443 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000444
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000445 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200446 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 hash = PyObject_Hash(key);
448 if (hash == -1)
449 return -1;
450 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700451 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000452}
453
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700454static void
455set_empty_to_minsize(PySetObject *so)
456{
457 memset(so->smalltable, 0, sizeof(so->smalltable));
458 so->fill = 0;
459 so->used = 0;
460 so->mask = PySet_MINSIZE - 1;
461 so->table = so->smalltable;
462 so->hash = -1;
463}
464
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000465static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000466set_clear_internal(PySetObject *so)
467{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800468 setentry *entry;
469 setentry *table = so->table;
470 Py_ssize_t fill = so->fill;
471 Py_ssize_t used = so->used;
472 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000474
Raymond Hettinger583cd032013-09-07 22:06:35 -0700475 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 /* This is delicate. During the process of clearing the set,
479 * decrefs can cause the set to mutate. To avoid fatal confusion
480 * (voice of experience), we have to make the set empty before
481 * clearing the slots, and never refer to anything via so->ref while
482 * clearing.
483 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700485 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487 else if (fill > 0) {
488 /* It's a small table with something that needs to be cleared.
489 * Afraid the only safe way is to copy the set entries into
490 * another small table first.
491 */
492 memcpy(small_copy, table, sizeof(small_copy));
493 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700494 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 }
496 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 /* Now we can finally clear things. If C had refcounts, we could
499 * assert that the refcount on table is 1 now, i.e. that this function
500 * has unique access to it, so decref side-effects can't alter it.
501 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800502 for (entry = table; used > 0; entry++) {
503 if (entry->key && entry->key != dummy) {
504 used--;
505 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 if (table_is_malloced)
510 PyMem_DEL(table);
511 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000512}
513
514/*
515 * Iterate over a set table. Use like so:
516 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000517 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000518 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000519 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000520 * while (set_next(yourset, &pos, &entry)) {
521 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000522 * }
523 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000524 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000525 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000526 */
527static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000528set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000529{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000530 Py_ssize_t i;
531 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700532 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 assert (PyAnySet_Check(so));
535 i = *pos_ptr;
536 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700538 entry = &so->table[i];
539 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700541 entry++;
542 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 *pos_ptr = i+1;
544 if (i > mask)
545 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700546 assert(entry != NULL);
547 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000549}
550
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000551static void
552set_dealloc(PySetObject *so)
553{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200554 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800555 Py_ssize_t used = so->used;
556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 PyObject_GC_UnTrack(so);
558 Py_TRASHCAN_SAFE_BEGIN(so)
559 if (so->weakreflist != NULL)
560 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000561
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800562 for (entry = so->table; used > 0; entry++) {
563 if (entry->key && entry->key != dummy) {
564 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700565 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 }
567 }
568 if (so->table != so->smalltable)
569 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700570 Py_TYPE(so)->tp_free(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000571 Py_TRASHCAN_SAFE_END(so)
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000572}
573
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000574static PyObject *
575set_repr(PySetObject *so)
576{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200577 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000580 if (status != 0) {
581 if (status < 0)
582 return NULL;
583 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
584 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 /* shortcut for the empty set */
587 if (!so->used) {
588 Py_ReprLeave((PyObject*)so);
589 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
590 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000591
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000592 keys = PySequence_List((PyObject *)so);
593 if (keys == NULL)
594 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000595
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200596 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000597 listrepr = PyObject_Repr(keys);
598 Py_DECREF(keys);
599 if (listrepr == NULL)
600 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200601 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200603 if (tmp == NULL)
604 goto done;
605 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200606
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200607 if (Py_TYPE(so) != &PySet_Type)
608 result = PyUnicode_FromFormat("%s({%U})",
609 Py_TYPE(so)->tp_name,
610 listrepr);
611 else
612 result = PyUnicode_FromFormat("{%U}", listrepr);
613 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000614done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 Py_ReprLeave((PyObject*)so);
616 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000617}
618
Martin v. Löwis18e16552006-02-15 17:27:45 +0000619static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000620set_len(PyObject *so)
621{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000623}
624
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000625static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000626set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000627{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000629 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200630 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700631 setentry *so_entry;
632 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000633
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 assert (PyAnySet_Check(so));
635 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 other = (PySetObject*)otherset;
638 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700639 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 return 0;
641 /* Do one big resize at the start, rather than
642 * incrementally resizing as we insert new keys. Expect
643 * that there will be no (or few) overlapping keys.
644 */
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800645 if ((so->fill + other->used)*5 >= so->mask*3) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700646 if (set_table_resize(so, so->used + other->used) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000647 return -1;
648 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700649 so_entry = so->table;
650 other_entry = other->table;
651
652 /* If our table is empty, and both tables have the same size, and
653 there are no dummies to eliminate, then just copy the pointers. */
654 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
655 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
656 key = other_entry->key;
657 if (key != NULL) {
658 assert(so_entry->key == NULL);
659 Py_INCREF(key);
660 so_entry->key = key;
661 so_entry->hash = other_entry->hash;
662 }
663 }
664 so->fill = other->fill;
665 so->used = other->used;
666 return 0;
667 }
668
669 /* If our table is empty, we can use set_insert_clean() */
670 if (so->fill == 0) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800671 setentry *newtable = so->table;
672 size_t newmask = (size_t)so->mask;
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800673 so->fill = other->used;
674 so->used = other->used;
Raymond Hettingere4495872015-12-15 00:42:30 -0800675 for (i = other->mask + 1; i > 0 ; i--, other_entry++) {
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700676 key = other_entry->key;
677 if (key != NULL && key != dummy) {
678 Py_INCREF(key);
Raymond Hettinger5088f602015-12-13 18:45:01 -0800679 set_insert_clean(newtable, newmask, key, other_entry->hash);
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700680 }
681 }
682 return 0;
683 }
684
685 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700686 for (i = 0; i <= other->mask; i++) {
687 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700688 key = other_entry->key;
689 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700690 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000691 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000692 }
693 }
694 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000695}
696
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000697static PyObject *
698set_pop(PySetObject *so)
699{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800700 /* Make sure the search finger is in bounds */
701 Py_ssize_t i = so->finger & so->mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200702 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000703 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000704
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000705 assert (PyAnySet_Check(so));
706 if (so->used == 0) {
707 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
708 return NULL;
709 }
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000710
Raymond Hettinger1202a472015-01-18 13:12:42 -0800711 while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
712 i++;
Raymond Hettingered741d42015-01-18 21:25:15 -0800713 if (i > so->mask)
714 i = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000715 }
716 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800718 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 so->used--;
Raymond Hettinger1202a472015-01-18 13:12:42 -0800720 so->finger = i + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000722}
723
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000724PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
725Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000726
727static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000728set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000729{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 Py_ssize_t pos = 0;
731 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000732
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000733 while (set_next(so, &pos, &entry))
734 Py_VISIT(entry->key);
735 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000736}
737
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700738/* Work to increase the bit dispersion for closely spaced hash values.
739 This is important because some use cases have many combinations of a
740 small number of elements with nearby hashes so that many distinct
741 combinations collapse to only a handful of distinct hash values. */
742
743static Py_uhash_t
744_shuffle_bits(Py_uhash_t h)
745{
746 return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
747}
748
749/* Most of the constants in this hash algorithm are randomly chosen
750 large primes with "interesting bit patterns" and that passed tests
751 for good collision statistics on a variety of problematic datasets
752 including powersets and graph structures (such as David Eppstein's
753 graph recipes in Lib/test/test_set.py) */
754
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000755static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000756frozenset_hash(PyObject *self)
757{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758 PySetObject *so = (PySetObject *)self;
Raymond Hettinger41481952015-08-07 00:43:39 -0700759 Py_uhash_t hash = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000760 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000761
Raymond Hettingerb501a272015-08-06 22:15:22 -0700762 if (so->hash != -1)
763 return so->hash;
764
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700765 /* Xor-in shuffled bits from every entry's hash field because xor is
766 commutative and a frozenset hash should be independent of order.
767
768 For speed, include null entries and dummy entries and then
769 subtract out their effect afterwards so that the final hash
770 depends only on active entries. This allows the code to be
771 vectorized by the compiler and it saves the unpredictable
772 branches that would arise when trying to exclude null and dummy
773 entries on every iteration. */
774
775 for (entry = so->table; entry <= &so->table[so->mask]; entry++)
776 hash ^= _shuffle_bits(entry->hash);
777
Raymond Hettingera286a512015-08-01 11:07:11 -0700778 /* Remove the effect of an odd number of NULL entries */
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700779 if ((so->mask + 1 - so->fill) & 1)
780 hash ^= _shuffle_bits(0);
781
782 /* Remove the effect of an odd number of dummy entries */
783 if ((so->fill - so->used) & 1)
784 hash ^= _shuffle_bits(-1);
785
Raymond Hettinger41481952015-08-07 00:43:39 -0700786 /* Factor in the number of active entries */
787 hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;
788
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700789 /* Disperse patterns arising in nested frozensets */
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800790 hash = hash * 69069U + 907133923UL;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700791
Raymond Hettinger36c05002015-08-01 10:57:42 -0700792 /* -1 is reserved as an error code */
Victor Stinner12174a52014-08-15 23:17:38 +0200793 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800794 hash = 590923713UL;
Raymond Hettinger36c05002015-08-01 10:57:42 -0700795
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000796 so->hash = hash;
797 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000798}
799
Raymond Hettingera9d99362005-08-05 00:01:15 +0000800/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000801
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000802typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000803 PyObject_HEAD
804 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
805 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700806 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000807 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000808} setiterobject;
809
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000810static void
811setiter_dealloc(setiterobject *si)
812{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000813 Py_XDECREF(si->si_set);
814 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000815}
816
817static int
818setiter_traverse(setiterobject *si, visitproc visit, void *arg)
819{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000820 Py_VISIT(si->si_set);
821 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000822}
823
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000824static PyObject *
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000825setiter_len(setiterobject *si)
826{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000827 Py_ssize_t len = 0;
828 if (si->si_set != NULL && si->si_used == si->si_set->used)
829 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000830 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000831}
832
Armin Rigof5b3e362006-02-11 21:32:43 +0000833PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000834
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000835static PyObject *setiter_iternext(setiterobject *si);
836
837static PyObject *
838setiter_reduce(setiterobject *si)
839{
840 PyObject *list;
841 setiterobject tmp;
842
843 list = PyList_New(0);
844 if (!list)
845 return NULL;
846
Ezio Melotti0e1af282012-09-28 16:43:40 +0300847 /* copy the iterator state */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000848 tmp = *si;
849 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300850
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000851 /* iterate the temporary into a list */
852 for(;;) {
853 PyObject *element = setiter_iternext(&tmp);
854 if (element) {
855 if (PyList_Append(list, element)) {
856 Py_DECREF(element);
857 Py_DECREF(list);
858 Py_XDECREF(tmp.si_set);
859 return NULL;
860 }
861 Py_DECREF(element);
862 } else
863 break;
864 }
865 Py_XDECREF(tmp.si_set);
866 /* check for error */
867 if (tmp.si_set != NULL) {
868 /* we have an error */
869 Py_DECREF(list);
870 return NULL;
871 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200872 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000873}
874
875PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
876
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000877static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000878 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000879 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000880 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000881};
882
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000883static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000884{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700885 PyObject *key;
886 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200887 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000888 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000890 if (so == NULL)
891 return NULL;
892 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000894 if (si->si_used != so->used) {
895 PyErr_SetString(PyExc_RuntimeError,
896 "Set changed size during iteration");
897 si->si_used = -1; /* Make this state sticky */
898 return NULL;
899 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700900
901 i = si->si_pos;
902 assert(i>=0);
903 entry = so->table;
904 mask = so->mask;
905 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
906 i++;
907 si->si_pos = i+1;
908 if (i > mask)
909 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000910 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700911 key = entry[i].key;
912 Py_INCREF(key);
913 return key;
914
915fail:
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700916 si->si_set = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +0300917 Py_DECREF(so);
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700918 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000919}
920
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000921PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000922 PyVarObject_HEAD_INIT(&PyType_Type, 0)
923 "set_iterator", /* tp_name */
924 sizeof(setiterobject), /* tp_basicsize */
925 0, /* tp_itemsize */
926 /* methods */
927 (destructor)setiter_dealloc, /* tp_dealloc */
928 0, /* tp_print */
929 0, /* tp_getattr */
930 0, /* tp_setattr */
931 0, /* tp_reserved */
932 0, /* tp_repr */
933 0, /* tp_as_number */
934 0, /* tp_as_sequence */
935 0, /* tp_as_mapping */
936 0, /* tp_hash */
937 0, /* tp_call */
938 0, /* tp_str */
939 PyObject_GenericGetAttr, /* tp_getattro */
940 0, /* tp_setattro */
941 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700942 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000943 0, /* tp_doc */
944 (traverseproc)setiter_traverse, /* tp_traverse */
945 0, /* tp_clear */
946 0, /* tp_richcompare */
947 0, /* tp_weaklistoffset */
948 PyObject_SelfIter, /* tp_iter */
949 (iternextfunc)setiter_iternext, /* tp_iternext */
950 setiter_methods, /* tp_methods */
951 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000952};
953
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000954static PyObject *
955set_iter(PySetObject *so)
956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
958 if (si == NULL)
959 return NULL;
960 Py_INCREF(so);
961 si->si_set = so;
962 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700963 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000964 si->len = so->used;
965 _PyObject_GC_TRACK(si);
966 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000967}
968
Raymond Hettingerd7946662005-08-01 21:39:29 +0000969static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000970set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000971{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000972 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000973
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 if (PyAnySet_Check(other))
975 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000976
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 if (PyDict_CheckExact(other)) {
978 PyObject *value;
979 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000980 Py_hash_t hash;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200981 Py_ssize_t dictsize = PyDict_GET_SIZE(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 /* Do one big resize at the start, rather than
984 * incrementally resizing as we insert new keys. Expect
985 * that there will be no (or few) overlapping keys.
986 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700987 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 return -1;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800989 if ((so->fill + dictsize)*5 >= so->mask*3) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700990 if (set_table_resize(so, so->used + dictsize) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000991 return -1;
992 }
993 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700994 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000995 return -1;
996 }
997 return 0;
998 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000999
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001000 it = PyObject_GetIter(other);
1001 if (it == NULL)
1002 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +00001003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001005 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 Py_DECREF(it);
1007 Py_DECREF(key);
1008 return -1;
1009 }
1010 Py_DECREF(key);
1011 }
1012 Py_DECREF(it);
1013 if (PyErr_Occurred())
1014 return -1;
1015 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001016}
1017
1018static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001019set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001020{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001021 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001022
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1024 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001025 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001026 return NULL;
1027 }
1028 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001029}
1030
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001031PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001032"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001033
Raymond Hettinger426d9952014-05-18 21:40:20 +01001034/* XXX Todo:
1035 If aligned memory allocations become available, make the
1036 set object 64 byte aligned so that most of the fields
1037 can be retrieved or updated in a single cache line.
1038*/
1039
Raymond Hettingera38123e2003-11-24 22:18:49 +00001040static PyObject *
1041make_new_set(PyTypeObject *type, PyObject *iterable)
1042{
Raymond Hettinger8421d712016-04-29 01:37:05 -07001043 PySetObject *so;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001044
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001045 so = (PySetObject *)type->tp_alloc(type, 0);
1046 if (so == NULL)
1047 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001048
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001049 so->fill = 0;
1050 so->used = 0;
1051 so->mask = PySet_MINSIZE - 1;
1052 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001053 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001054 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001056
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001057 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001058 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 Py_DECREF(so);
1060 return NULL;
1061 }
1062 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001064 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001065}
1066
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001067static PyObject *
1068make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1069{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1071 if (PyType_IsSubtype(type, &PySet_Type))
1072 type = &PySet_Type;
1073 else
1074 type = &PyFrozenSet_Type;
1075 }
1076 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001077}
1078
Raymond Hettingerd7946662005-08-01 21:39:29 +00001079/* The empty frozenset is a singleton */
1080static PyObject *emptyfrozenset = NULL;
1081
Raymond Hettingera690a992003-11-16 16:17:49 +00001082static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001083frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001085 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001086
Raymond Hettingerf5021542016-02-04 02:46:16 -08001087 if (kwds != NULL && type == &PyFrozenSet_Type
1088 && !_PyArg_NoKeywords("frozenset()", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001089 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001090
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001091 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1092 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 if (type != &PyFrozenSet_Type)
1095 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001096
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001097 if (iterable != NULL) {
1098 /* frozenset(f) is idempotent */
1099 if (PyFrozenSet_CheckExact(iterable)) {
1100 Py_INCREF(iterable);
1101 return iterable;
1102 }
1103 result = make_new_set(type, iterable);
1104 if (result == NULL || PySet_GET_SIZE(result))
1105 return result;
1106 Py_DECREF(result);
1107 }
1108 /* The empty frozenset is a singleton */
1109 if (emptyfrozenset == NULL)
1110 emptyfrozenset = make_new_set(type, NULL);
1111 Py_XINCREF(emptyfrozenset);
1112 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001113}
1114
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001115static PyObject *
1116set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1117{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001119}
1120
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001121/* set_swap_bodies() switches the contents of any two sets by moving their
1122 internal data pointers and, if needed, copying the internal smalltables.
1123 Semantically equivalent to:
1124
1125 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1126
1127 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001128 Useful for operations that update in-place (by allowing an intermediate
1129 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001130*/
1131
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001132static void
1133set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001134{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 Py_ssize_t t;
1136 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001137 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001138 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001139
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 t = a->fill; a->fill = b->fill; b->fill = t;
1141 t = a->used; a->used = b->used; b->used = t;
1142 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001143
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001144 u = a->table;
1145 if (a->table == a->smalltable)
1146 u = b->smalltable;
1147 a->table = b->table;
1148 if (b->table == b->smalltable)
1149 a->table = a->smalltable;
1150 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 if (a->table == a->smalltable || b->table == b->smalltable) {
1153 memcpy(tab, a->smalltable, sizeof(tab));
1154 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1155 memcpy(b->smalltable, tab, sizeof(tab));
1156 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001158 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1159 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1160 h = a->hash; a->hash = b->hash; b->hash = h;
1161 } else {
1162 a->hash = -1;
1163 b->hash = -1;
1164 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001165}
1166
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001167static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001168set_copy(PySetObject *so)
1169{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001171}
1172
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001173static PyObject *
1174frozenset_copy(PySetObject *so)
1175{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001176 if (PyFrozenSet_CheckExact(so)) {
1177 Py_INCREF(so);
1178 return (PyObject *)so;
1179 }
1180 return set_copy(so);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001181}
1182
Raymond Hettingera690a992003-11-16 16:17:49 +00001183PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1184
1185static PyObject *
Raymond Hettingerc991db22005-08-11 07:58:45 +00001186set_clear(PySetObject *so)
1187{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001188 set_clear_internal(so);
1189 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001190}
1191
1192PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1193
1194static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001195set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001196{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 PySetObject *result;
1198 PyObject *other;
1199 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001201 result = (PySetObject *)set_copy(so);
1202 if (result == NULL)
1203 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001205 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1206 other = PyTuple_GET_ITEM(args, i);
1207 if ((PyObject *)so == other)
1208 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001209 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001210 Py_DECREF(result);
1211 return NULL;
1212 }
1213 }
1214 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001215}
1216
1217PyDoc_STRVAR(union_doc,
1218 "Return the union of sets as a new set.\n\
1219\n\
1220(i.e. all elements that are in either set.)");
1221
1222static PyObject *
1223set_or(PySetObject *so, PyObject *other)
1224{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001225 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001226
Brian Curtindfc80e32011-08-10 20:28:54 -05001227 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1228 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001230 result = (PySetObject *)set_copy(so);
1231 if (result == NULL)
1232 return NULL;
1233 if ((PyObject *)so == other)
1234 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001235 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 Py_DECREF(result);
1237 return NULL;
1238 }
1239 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001240}
1241
Raymond Hettingera690a992003-11-16 16:17:49 +00001242static PyObject *
1243set_ior(PySetObject *so, PyObject *other)
1244{
Brian Curtindfc80e32011-08-10 20:28:54 -05001245 if (!PyAnySet_Check(other))
1246 Py_RETURN_NOTIMPLEMENTED;
1247
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001248 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 return NULL;
1250 Py_INCREF(so);
1251 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001252}
1253
1254static PyObject *
1255set_intersection(PySetObject *so, PyObject *other)
1256{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 PySetObject *result;
1258 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001259 Py_hash_t hash;
1260 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 if ((PyObject *)so == other)
1263 return set_copy(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001265 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1266 if (result == NULL)
1267 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001269 if (PyAnySet_Check(other)) {
1270 Py_ssize_t pos = 0;
1271 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1274 tmp = (PyObject *)so;
1275 so = (PySetObject *)other;
1276 other = tmp;
1277 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001280 key = entry->key;
1281 hash = entry->hash;
1282 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001283 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 Py_DECREF(result);
1285 return NULL;
1286 }
1287 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001288 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 Py_DECREF(result);
1290 return NULL;
1291 }
1292 }
1293 }
1294 return (PyObject *)result;
1295 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 it = PyObject_GetIter(other);
1298 if (it == NULL) {
1299 Py_DECREF(result);
1300 return NULL;
1301 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001304 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001305 if (hash == -1)
1306 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001307 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001308 if (rv < 0)
1309 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001310 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001311 if (set_add_entry(result, key, hash))
1312 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 }
1314 Py_DECREF(key);
1315 }
1316 Py_DECREF(it);
1317 if (PyErr_Occurred()) {
1318 Py_DECREF(result);
1319 return NULL;
1320 }
1321 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001322 error:
1323 Py_DECREF(it);
1324 Py_DECREF(result);
1325 Py_DECREF(key);
1326 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001327}
1328
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001329static PyObject *
1330set_intersection_multi(PySetObject *so, PyObject *args)
1331{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001332 Py_ssize_t i;
1333 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 if (PyTuple_GET_SIZE(args) == 0)
1336 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 Py_INCREF(so);
1339 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1340 PyObject *other = PyTuple_GET_ITEM(args, i);
1341 PyObject *newresult = set_intersection((PySetObject *)result, other);
1342 if (newresult == NULL) {
1343 Py_DECREF(result);
1344 return NULL;
1345 }
1346 Py_DECREF(result);
1347 result = newresult;
1348 }
1349 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001350}
1351
Raymond Hettingera690a992003-11-16 16:17:49 +00001352PyDoc_STRVAR(intersection_doc,
1353"Return the intersection of two sets as a new set.\n\
1354\n\
1355(i.e. all elements that are in both sets.)");
1356
1357static PyObject *
1358set_intersection_update(PySetObject *so, PyObject *other)
1359{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001360 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001362 tmp = set_intersection(so, other);
1363 if (tmp == NULL)
1364 return NULL;
1365 set_swap_bodies(so, (PySetObject *)tmp);
1366 Py_DECREF(tmp);
1367 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001368}
1369
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001370static PyObject *
1371set_intersection_update_multi(PySetObject *so, PyObject *args)
1372{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 tmp = set_intersection_multi(so, args);
1376 if (tmp == NULL)
1377 return NULL;
1378 set_swap_bodies(so, (PySetObject *)tmp);
1379 Py_DECREF(tmp);
1380 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001381}
1382
Raymond Hettingera690a992003-11-16 16:17:49 +00001383PyDoc_STRVAR(intersection_update_doc,
1384"Update a set with the intersection of itself and another.");
1385
1386static PyObject *
1387set_and(PySetObject *so, PyObject *other)
1388{
Brian Curtindfc80e32011-08-10 20:28:54 -05001389 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1390 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001392}
1393
1394static PyObject *
1395set_iand(PySetObject *so, PyObject *other)
1396{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001397 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001398
Brian Curtindfc80e32011-08-10 20:28:54 -05001399 if (!PyAnySet_Check(other))
1400 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001401 result = set_intersection_update(so, other);
1402 if (result == NULL)
1403 return NULL;
1404 Py_DECREF(result);
1405 Py_INCREF(so);
1406 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001407}
1408
Guido van Rossum58da9312007-11-10 23:39:45 +00001409static PyObject *
1410set_isdisjoint(PySetObject *so, PyObject *other)
1411{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001412 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001413 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 if ((PyObject *)so == other) {
1416 if (PySet_GET_SIZE(so) == 0)
1417 Py_RETURN_TRUE;
1418 else
1419 Py_RETURN_FALSE;
1420 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001422 if (PyAnySet_CheckExact(other)) {
1423 Py_ssize_t pos = 0;
1424 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1427 tmp = (PyObject *)so;
1428 so = (PySetObject *)other;
1429 other = tmp;
1430 }
1431 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001432 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001433 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001434 return NULL;
1435 if (rv)
1436 Py_RETURN_FALSE;
1437 }
1438 Py_RETURN_TRUE;
1439 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 it = PyObject_GetIter(other);
1442 if (it == NULL)
1443 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001444
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001445 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001446 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 if (hash == -1) {
1449 Py_DECREF(key);
1450 Py_DECREF(it);
1451 return NULL;
1452 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001453 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001455 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001456 Py_DECREF(it);
1457 return NULL;
1458 }
1459 if (rv) {
1460 Py_DECREF(it);
1461 Py_RETURN_FALSE;
1462 }
1463 }
1464 Py_DECREF(it);
1465 if (PyErr_Occurred())
1466 return NULL;
1467 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001468}
1469
1470PyDoc_STRVAR(isdisjoint_doc,
1471"Return True if two sets have a null intersection.");
1472
Neal Norwitz6576bd82005-11-13 18:41:28 +00001473static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001474set_difference_update_internal(PySetObject *so, PyObject *other)
1475{
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001476 if (PySet_GET_SIZE(so) == 0) {
1477 return 0;
1478 }
1479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 if ((PyObject *)so == other)
1481 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 if (PyAnySet_Check(other)) {
1484 setentry *entry;
1485 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001488 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 return -1;
1490 } else {
1491 PyObject *key, *it;
1492 it = PyObject_GetIter(other);
1493 if (it == NULL)
1494 return -1;
1495
1496 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001497 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 Py_DECREF(it);
1499 Py_DECREF(key);
1500 return -1;
1501 }
1502 Py_DECREF(key);
1503 }
1504 Py_DECREF(it);
1505 if (PyErr_Occurred())
1506 return -1;
1507 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001508 /* If more than 1/4th are dummies, then resize them away. */
1509 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 return 0;
Raymond Hettinger48973002015-07-03 20:00:03 -07001511 return set_table_resize(so, so->used);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001512}
1513
Raymond Hettingera690a992003-11-16 16:17:49 +00001514static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001515set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001516{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1520 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001521 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001522 return NULL;
1523 }
1524 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001525}
1526
1527PyDoc_STRVAR(difference_update_doc,
1528"Remove all elements of another set from this set.");
1529
1530static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001531set_copy_and_difference(PySetObject *so, PyObject *other)
1532{
1533 PyObject *result;
1534
1535 result = set_copy(so);
1536 if (result == NULL)
1537 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001538 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001539 return result;
1540 Py_DECREF(result);
1541 return NULL;
1542}
1543
1544static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001545set_difference(PySetObject *so, PyObject *other)
1546{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001548 PyObject *key;
1549 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001550 setentry *entry;
1551 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001552 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001553
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001554 if (PySet_GET_SIZE(so) == 0) {
1555 return set_copy(so);
1556 }
1557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001559 return set_copy_and_difference(so, other);
1560 }
1561
1562 /* If len(so) much more than len(other), it's more efficient to simply copy
1563 * so and then iterate other looking for common elements. */
1564 if ((PySet_GET_SIZE(so) >> 2) > PyObject_Size(other)) {
1565 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001568 result = make_new_set_basetype(Py_TYPE(so), NULL);
1569 if (result == NULL)
1570 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001571
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 if (PyDict_CheckExact(other)) {
1573 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001574 key = entry->key;
1575 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001576 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001577 if (rv < 0) {
1578 Py_DECREF(result);
1579 return NULL;
1580 }
1581 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001582 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 Py_DECREF(result);
1584 return NULL;
1585 }
1586 }
1587 }
1588 return result;
1589 }
1590
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001591 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001592 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001593 key = entry->key;
1594 hash = entry->hash;
1595 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001596 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 Py_DECREF(result);
1598 return NULL;
1599 }
1600 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001601 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001602 Py_DECREF(result);
1603 return NULL;
1604 }
1605 }
1606 }
1607 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001608}
1609
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001610static PyObject *
1611set_difference_multi(PySetObject *so, PyObject *args)
1612{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 Py_ssize_t i;
1614 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001615
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616 if (PyTuple_GET_SIZE(args) == 0)
1617 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001618
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001619 other = PyTuple_GET_ITEM(args, 0);
1620 result = set_difference(so, other);
1621 if (result == NULL)
1622 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1625 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001626 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 Py_DECREF(result);
1628 return NULL;
1629 }
1630 }
1631 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001632}
1633
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001634PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001635"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001636\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001637(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001638static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001639set_sub(PySetObject *so, PyObject *other)
1640{
Brian Curtindfc80e32011-08-10 20:28:54 -05001641 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1642 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001643 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001644}
1645
1646static PyObject *
1647set_isub(PySetObject *so, PyObject *other)
1648{
Brian Curtindfc80e32011-08-10 20:28:54 -05001649 if (!PyAnySet_Check(other))
1650 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001651 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652 return NULL;
1653 Py_INCREF(so);
1654 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001655}
1656
1657static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001658set_symmetric_difference_update(PySetObject *so, PyObject *other)
1659{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 PySetObject *otherset;
1661 PyObject *key;
1662 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001663 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001664 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001665 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001666
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001667 if ((PyObject *)so == other)
1668 return set_clear(so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001669
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001670 if (PyDict_CheckExact(other)) {
1671 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001672 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001673 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001674 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001675 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001676 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001677 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001678 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001679 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001680 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001681 Py_DECREF(key);
1682 return NULL;
1683 }
1684 }
Georg Brandl2d444492010-09-03 10:52:55 +00001685 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001686 }
1687 Py_RETURN_NONE;
1688 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001689
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001690 if (PyAnySet_Check(other)) {
1691 Py_INCREF(other);
1692 otherset = (PySetObject *)other;
1693 } else {
1694 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1695 if (otherset == NULL)
1696 return NULL;
1697 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001698
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001699 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001700 key = entry->key;
1701 hash = entry->hash;
1702 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001703 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001704 Py_DECREF(otherset);
1705 return NULL;
1706 }
1707 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001708 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001709 Py_DECREF(otherset);
1710 return NULL;
1711 }
1712 }
1713 }
1714 Py_DECREF(otherset);
1715 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001716}
1717
1718PyDoc_STRVAR(symmetric_difference_update_doc,
1719"Update a set with the symmetric difference of itself and another.");
1720
1721static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001722set_symmetric_difference(PySetObject *so, PyObject *other)
1723{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001724 PyObject *rv;
1725 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001726
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001727 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1728 if (otherset == NULL)
1729 return NULL;
1730 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
1731 if (rv == NULL)
1732 return NULL;
1733 Py_DECREF(rv);
1734 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001735}
1736
1737PyDoc_STRVAR(symmetric_difference_doc,
1738"Return the symmetric difference of two sets as a new set.\n\
1739\n\
1740(i.e. all elements that are in exactly one of the sets.)");
1741
1742static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001743set_xor(PySetObject *so, PyObject *other)
1744{
Brian Curtindfc80e32011-08-10 20:28:54 -05001745 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1746 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001747 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001748}
1749
1750static PyObject *
1751set_ixor(PySetObject *so, PyObject *other)
1752{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001753 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001754
Brian Curtindfc80e32011-08-10 20:28:54 -05001755 if (!PyAnySet_Check(other))
1756 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001757 result = set_symmetric_difference_update(so, other);
1758 if (result == NULL)
1759 return NULL;
1760 Py_DECREF(result);
1761 Py_INCREF(so);
1762 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001763}
1764
1765static PyObject *
1766set_issubset(PySetObject *so, PyObject *other)
1767{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001768 setentry *entry;
1769 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001770 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001771
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001772 if (!PyAnySet_Check(other)) {
1773 PyObject *tmp, *result;
1774 tmp = make_new_set(&PySet_Type, other);
1775 if (tmp == NULL)
1776 return NULL;
1777 result = set_issubset(so, tmp);
1778 Py_DECREF(tmp);
1779 return result;
1780 }
1781 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1782 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001784 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001785 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001786 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001787 return NULL;
1788 if (!rv)
1789 Py_RETURN_FALSE;
1790 }
1791 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001792}
1793
1794PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1795
1796static PyObject *
1797set_issuperset(PySetObject *so, PyObject *other)
1798{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001799 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001800
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001801 if (!PyAnySet_Check(other)) {
1802 tmp = make_new_set(&PySet_Type, other);
1803 if (tmp == NULL)
1804 return NULL;
1805 result = set_issuperset(so, tmp);
1806 Py_DECREF(tmp);
1807 return result;
1808 }
1809 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001810}
1811
1812PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1813
Raymond Hettingera690a992003-11-16 16:17:49 +00001814static PyObject *
1815set_richcompare(PySetObject *v, PyObject *w, int op)
1816{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001817 PyObject *r1;
1818 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001819
Brian Curtindfc80e32011-08-10 20:28:54 -05001820 if(!PyAnySet_Check(w))
1821 Py_RETURN_NOTIMPLEMENTED;
1822
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001823 switch (op) {
1824 case Py_EQ:
1825 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1826 Py_RETURN_FALSE;
1827 if (v->hash != -1 &&
1828 ((PySetObject *)w)->hash != -1 &&
1829 v->hash != ((PySetObject *)w)->hash)
1830 Py_RETURN_FALSE;
1831 return set_issubset(v, w);
1832 case Py_NE:
1833 r1 = set_richcompare(v, w, Py_EQ);
1834 if (r1 == NULL)
1835 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001836 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001837 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001838 if (r2 < 0)
1839 return NULL;
1840 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001841 case Py_LE:
1842 return set_issubset(v, w);
1843 case Py_GE:
1844 return set_issuperset(v, w);
1845 case Py_LT:
1846 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1847 Py_RETURN_FALSE;
1848 return set_issubset(v, w);
1849 case Py_GT:
1850 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1851 Py_RETURN_FALSE;
1852 return set_issuperset(v, w);
1853 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001854 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001855}
1856
Raymond Hettingera690a992003-11-16 16:17:49 +00001857static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001858set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001859{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001860 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 return NULL;
1862 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001863}
1864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001866"Add an element to a set.\n\
1867\n\
1868This has no effect if the element is already present.");
1869
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001870static int
1871set_contains(PySetObject *so, PyObject *key)
1872{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873 PyObject *tmpkey;
1874 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001877 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1879 return -1;
1880 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001881 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001882 if (tmpkey == NULL)
1883 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001884 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 Py_DECREF(tmpkey);
1886 }
1887 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001888}
1889
1890static PyObject *
1891set_direct_contains(PySetObject *so, PyObject *key)
1892{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001896 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 return NULL;
1898 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001899}
1900
1901PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1902
Raymond Hettingera690a992003-11-16 16:17:49 +00001903static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001904set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001905{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 PyObject *tmpkey;
1907 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001908
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001910 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1912 return NULL;
1913 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001914 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 if (tmpkey == NULL)
1916 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001917 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001918 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001919 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001920 return NULL;
1921 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001922
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001924 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 return NULL;
1926 }
1927 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001928}
1929
1930PyDoc_STRVAR(remove_doc,
1931"Remove an element from a set; it must be a member.\n\
1932\n\
1933If the element is not a member, raise a KeyError.");
1934
1935static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001936set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001937{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001938 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001939 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001940
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001941 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001942 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1944 return NULL;
1945 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001946 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947 if (tmpkey == NULL)
1948 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001949 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001950 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001951 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001952 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001953 }
1954 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001955}
1956
1957PyDoc_STRVAR(discard_doc,
1958"Remove an element from a set if it is a member.\n\
1959\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001960If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001961
1962static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001963set_reduce(PySetObject *so)
1964{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001965 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001966 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001967
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968 keys = PySequence_List((PyObject *)so);
1969 if (keys == NULL)
1970 goto done;
1971 args = PyTuple_Pack(1, keys);
1972 if (args == NULL)
1973 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001974 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001975 if (dict == NULL) {
1976 PyErr_Clear();
1977 dict = Py_None;
1978 Py_INCREF(dict);
1979 }
1980 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001981done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001982 Py_XDECREF(args);
1983 Py_XDECREF(keys);
1984 Py_XDECREF(dict);
1985 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001986}
1987
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001988static PyObject *
1989set_sizeof(PySetObject *so)
1990{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001991 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001992
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02001993 res = _PyObject_SIZE(Py_TYPE(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001994 if (so->table != so->smalltable)
1995 res = res + (so->mask + 1) * sizeof(setentry);
1996 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001997}
1998
1999PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002000static int
2001set_init(PySetObject *self, PyObject *args, PyObject *kwds)
2002{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002004
Serhiy Storchakafa070292016-04-29 11:31:52 +03002005 if (kwds != NULL && !_PyArg_NoKeywords("set()", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 return -1;
2007 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
2008 return -1;
Raymond Hettingerb72e21b2016-03-25 02:29:59 -07002009 if (self->fill)
2010 set_clear_internal(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002011 self->hash = -1;
2012 if (iterable == NULL)
2013 return 0;
2014 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002015}
2016
Raymond Hettingera690a992003-11-16 16:17:49 +00002017static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002018 set_len, /* sq_length */
2019 0, /* sq_concat */
2020 0, /* sq_repeat */
2021 0, /* sq_item */
2022 0, /* sq_slice */
2023 0, /* sq_ass_item */
2024 0, /* sq_ass_slice */
2025 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002026};
2027
2028/* set object ********************************************************/
2029
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002030#ifdef Py_DEBUG
2031static PyObject *test_c_api(PySetObject *so);
2032
2033PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2034All is well if assertions don't fail.");
2035#endif
2036
Raymond Hettingera690a992003-11-16 16:17:49 +00002037static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002038 {"add", (PyCFunction)set_add, METH_O,
2039 add_doc},
2040 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2041 clear_doc},
2042 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2043 contains_doc},
2044 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2045 copy_doc},
2046 {"discard", (PyCFunction)set_discard, METH_O,
2047 discard_doc},
2048 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2049 difference_doc},
2050 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2051 difference_update_doc},
2052 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2053 intersection_doc},
2054 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2055 intersection_update_doc},
2056 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2057 isdisjoint_doc},
2058 {"issubset", (PyCFunction)set_issubset, METH_O,
2059 issubset_doc},
2060 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2061 issuperset_doc},
2062 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2063 pop_doc},
2064 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2065 reduce_doc},
2066 {"remove", (PyCFunction)set_remove, METH_O,
2067 remove_doc},
2068 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2069 sizeof_doc},
2070 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2071 symmetric_difference_doc},
2072 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2073 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002074#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002075 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2076 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002077#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002078 {"union", (PyCFunction)set_union, METH_VARARGS,
2079 union_doc},
2080 {"update", (PyCFunction)set_update, METH_VARARGS,
2081 update_doc},
2082 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002083};
2084
2085static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002086 0, /*nb_add*/
2087 (binaryfunc)set_sub, /*nb_subtract*/
2088 0, /*nb_multiply*/
2089 0, /*nb_remainder*/
2090 0, /*nb_divmod*/
2091 0, /*nb_power*/
2092 0, /*nb_negative*/
2093 0, /*nb_positive*/
2094 0, /*nb_absolute*/
2095 0, /*nb_bool*/
2096 0, /*nb_invert*/
2097 0, /*nb_lshift*/
2098 0, /*nb_rshift*/
2099 (binaryfunc)set_and, /*nb_and*/
2100 (binaryfunc)set_xor, /*nb_xor*/
2101 (binaryfunc)set_or, /*nb_or*/
2102 0, /*nb_int*/
2103 0, /*nb_reserved*/
2104 0, /*nb_float*/
2105 0, /*nb_inplace_add*/
2106 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2107 0, /*nb_inplace_multiply*/
2108 0, /*nb_inplace_remainder*/
2109 0, /*nb_inplace_power*/
2110 0, /*nb_inplace_lshift*/
2111 0, /*nb_inplace_rshift*/
2112 (binaryfunc)set_iand, /*nb_inplace_and*/
2113 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2114 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002115};
2116
2117PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002118"set() -> new empty set object\n\
2119set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002120\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002121Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002122
2123PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002124 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2125 "set", /* tp_name */
2126 sizeof(PySetObject), /* tp_basicsize */
2127 0, /* tp_itemsize */
2128 /* methods */
2129 (destructor)set_dealloc, /* tp_dealloc */
2130 0, /* tp_print */
2131 0, /* tp_getattr */
2132 0, /* tp_setattr */
2133 0, /* tp_reserved */
2134 (reprfunc)set_repr, /* tp_repr */
2135 &set_as_number, /* tp_as_number */
2136 &set_as_sequence, /* tp_as_sequence */
2137 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002138 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002139 0, /* tp_call */
2140 0, /* tp_str */
2141 PyObject_GenericGetAttr, /* tp_getattro */
2142 0, /* tp_setattro */
2143 0, /* tp_as_buffer */
2144 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2145 Py_TPFLAGS_BASETYPE, /* tp_flags */
2146 set_doc, /* tp_doc */
2147 (traverseproc)set_traverse, /* tp_traverse */
2148 (inquiry)set_clear_internal, /* tp_clear */
2149 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002150 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2151 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002152 0, /* tp_iternext */
2153 set_methods, /* tp_methods */
2154 0, /* tp_members */
2155 0, /* tp_getset */
2156 0, /* tp_base */
2157 0, /* tp_dict */
2158 0, /* tp_descr_get */
2159 0, /* tp_descr_set */
2160 0, /* tp_dictoffset */
2161 (initproc)set_init, /* tp_init */
2162 PyType_GenericAlloc, /* tp_alloc */
2163 set_new, /* tp_new */
2164 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002165};
2166
2167/* frozenset object ********************************************************/
2168
2169
2170static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2172 contains_doc},
2173 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2174 copy_doc},
2175 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2176 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002177 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178 intersection_doc},
2179 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2180 isdisjoint_doc},
2181 {"issubset", (PyCFunction)set_issubset, METH_O,
2182 issubset_doc},
2183 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2184 issuperset_doc},
2185 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2186 reduce_doc},
2187 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2188 sizeof_doc},
2189 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2190 symmetric_difference_doc},
2191 {"union", (PyCFunction)set_union, METH_VARARGS,
2192 union_doc},
2193 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002194};
2195
2196static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002197 0, /*nb_add*/
2198 (binaryfunc)set_sub, /*nb_subtract*/
2199 0, /*nb_multiply*/
2200 0, /*nb_remainder*/
2201 0, /*nb_divmod*/
2202 0, /*nb_power*/
2203 0, /*nb_negative*/
2204 0, /*nb_positive*/
2205 0, /*nb_absolute*/
2206 0, /*nb_bool*/
2207 0, /*nb_invert*/
2208 0, /*nb_lshift*/
2209 0, /*nb_rshift*/
2210 (binaryfunc)set_and, /*nb_and*/
2211 (binaryfunc)set_xor, /*nb_xor*/
2212 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002213};
2214
2215PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002216"frozenset() -> empty frozenset object\n\
2217frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002218\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002219Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002220
2221PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002222 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2223 "frozenset", /* tp_name */
2224 sizeof(PySetObject), /* tp_basicsize */
2225 0, /* tp_itemsize */
2226 /* methods */
2227 (destructor)set_dealloc, /* tp_dealloc */
2228 0, /* tp_print */
2229 0, /* tp_getattr */
2230 0, /* tp_setattr */
2231 0, /* tp_reserved */
2232 (reprfunc)set_repr, /* tp_repr */
2233 &frozenset_as_number, /* tp_as_number */
2234 &set_as_sequence, /* tp_as_sequence */
2235 0, /* tp_as_mapping */
2236 frozenset_hash, /* tp_hash */
2237 0, /* tp_call */
2238 0, /* tp_str */
2239 PyObject_GenericGetAttr, /* tp_getattro */
2240 0, /* tp_setattro */
2241 0, /* tp_as_buffer */
2242 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2243 Py_TPFLAGS_BASETYPE, /* tp_flags */
2244 frozenset_doc, /* tp_doc */
2245 (traverseproc)set_traverse, /* tp_traverse */
2246 (inquiry)set_clear_internal, /* tp_clear */
2247 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002248 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002249 (getiterfunc)set_iter, /* tp_iter */
2250 0, /* tp_iternext */
2251 frozenset_methods, /* tp_methods */
2252 0, /* tp_members */
2253 0, /* tp_getset */
2254 0, /* tp_base */
2255 0, /* tp_dict */
2256 0, /* tp_descr_get */
2257 0, /* tp_descr_set */
2258 0, /* tp_dictoffset */
2259 0, /* tp_init */
2260 PyType_GenericAlloc, /* tp_alloc */
2261 frozenset_new, /* tp_new */
2262 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002263};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002264
2265
2266/***** C API functions *************************************************/
2267
2268PyObject *
2269PySet_New(PyObject *iterable)
2270{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002271 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002272}
2273
2274PyObject *
2275PyFrozenSet_New(PyObject *iterable)
2276{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002277 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002278}
2279
Neal Norwitz8c49c822006-03-04 18:41:19 +00002280Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002281PySet_Size(PyObject *anyset)
2282{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002283 if (!PyAnySet_Check(anyset)) {
2284 PyErr_BadInternalCall();
2285 return -1;
2286 }
2287 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002288}
2289
2290int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002291PySet_Clear(PyObject *set)
2292{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002293 if (!PySet_Check(set)) {
2294 PyErr_BadInternalCall();
2295 return -1;
2296 }
2297 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002298}
2299
2300int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002301PySet_Contains(PyObject *anyset, PyObject *key)
2302{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002303 if (!PyAnySet_Check(anyset)) {
2304 PyErr_BadInternalCall();
2305 return -1;
2306 }
2307 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002308}
2309
2310int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002311PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002312{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002313 if (!PySet_Check(set)) {
2314 PyErr_BadInternalCall();
2315 return -1;
2316 }
2317 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002318}
2319
2320int
Christian Heimesfd66e512008-01-29 12:18:50 +00002321PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002322{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002323 if (!PySet_Check(anyset) &&
2324 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2325 PyErr_BadInternalCall();
2326 return -1;
2327 }
2328 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002329}
2330
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002331int
Raymond Hettinger3625af52016-03-27 01:15:07 -07002332PySet_ClearFreeList(void)
2333{
2334 return 0;
2335}
2336
2337void
2338PySet_Fini(void)
2339{
2340 Py_CLEAR(emptyfrozenset);
2341}
2342
2343int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002344_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002345{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002346 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002348 if (!PyAnySet_Check(set)) {
2349 PyErr_BadInternalCall();
2350 return -1;
2351 }
2352 if (set_next((PySetObject *)set, pos, &entry) == 0)
2353 return 0;
2354 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002355 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002356 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002357}
2358
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002359PyObject *
2360PySet_Pop(PyObject *set)
2361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002362 if (!PySet_Check(set)) {
2363 PyErr_BadInternalCall();
2364 return NULL;
2365 }
2366 return set_pop((PySetObject *)set);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002367}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002368
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002369int
2370_PySet_Update(PyObject *set, PyObject *iterable)
2371{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002372 if (!PySet_Check(set)) {
2373 PyErr_BadInternalCall();
2374 return -1;
2375 }
2376 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002377}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002378
Raymond Hettingere259f132013-12-15 11:56:14 -08002379/* Exported for the gdb plugin's benefit. */
2380PyObject *_PySet_Dummy = dummy;
2381
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002382#ifdef Py_DEBUG
2383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002384/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002385 Returns True and original set is restored. */
2386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002387#define assertRaises(call_return_value, exception) \
2388 do { \
2389 assert(call_return_value); \
2390 assert(PyErr_ExceptionMatches(exception)); \
2391 PyErr_Clear(); \
2392 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002393
2394static PyObject *
2395test_c_api(PySetObject *so)
2396{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002397 Py_ssize_t count;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +02002398 const char *s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002399 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002400 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002401 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002402 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002403 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405 /* Verify preconditions */
2406 assert(PyAnySet_Check(ob));
2407 assert(PyAnySet_CheckExact(ob));
2408 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002410 /* so.clear(); so |= set("abc"); */
2411 str = PyUnicode_FromString("abc");
2412 if (str == NULL)
2413 return NULL;
2414 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002415 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002416 Py_DECREF(str);
2417 return NULL;
2418 }
2419 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 /* Exercise type/size checks */
2422 assert(PySet_Size(ob) == 3);
2423 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002425 /* Raise TypeError for non-iterable constructor arguments */
2426 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2427 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002429 /* Raise TypeError for unhashable key */
2430 dup = PySet_New(ob);
2431 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2432 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2433 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002434
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002435 /* Exercise successful pop, contains, add, and discard */
2436 elem = PySet_Pop(ob);
2437 assert(PySet_Contains(ob, elem) == 0);
2438 assert(PySet_GET_SIZE(ob) == 2);
2439 assert(PySet_Add(ob, elem) == 0);
2440 assert(PySet_Contains(ob, elem) == 1);
2441 assert(PySet_GET_SIZE(ob) == 3);
2442 assert(PySet_Discard(ob, elem) == 1);
2443 assert(PySet_GET_SIZE(ob) == 2);
2444 assert(PySet_Discard(ob, elem) == 0);
2445 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002447 /* Exercise clear */
2448 dup2 = PySet_New(dup);
2449 assert(PySet_Clear(dup2) == 0);
2450 assert(PySet_Size(dup2) == 0);
2451 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002453 /* Raise SystemError on clear or update of frozen set */
2454 f = PyFrozenSet_New(dup);
2455 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2456 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2457 assert(PySet_Add(f, elem) == 0);
2458 Py_INCREF(f);
2459 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2460 Py_DECREF(f);
2461 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002462
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002463 /* Exercise direct iteration */
2464 i = 0, count = 0;
2465 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
Serhiy Storchaka06515832016-11-20 09:13:07 +02002466 s = PyUnicode_AsUTF8(x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002467 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2468 count++;
2469 }
2470 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002472 /* Exercise updates */
2473 dup2 = PySet_New(NULL);
2474 assert(_PySet_Update(dup2, dup) == 0);
2475 assert(PySet_Size(dup2) == 3);
2476 assert(_PySet_Update(dup2, dup) == 0);
2477 assert(PySet_Size(dup2) == 3);
2478 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002480 /* Raise SystemError when self argument is not a set or frozenset. */
2481 t = PyTuple_New(0);
2482 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2483 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2484 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002486 /* Raise SystemError when self argument is not a set. */
2487 f = PyFrozenSet_New(dup);
2488 assert(PySet_Size(f) == 3);
2489 assert(PyFrozenSet_CheckExact(f));
2490 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2491 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2492 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002494 /* Raise KeyError when popping from an empty set */
2495 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2496 Py_DECREF(ob);
2497 assert(PySet_GET_SIZE(ob) == 0);
2498 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002500 /* Restore the set from the copy using the PyNumber API */
2501 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2502 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002504 /* Verify constructors accept NULL arguments */
2505 f = PySet_New(NULL);
2506 assert(f != NULL);
2507 assert(PySet_GET_SIZE(f) == 0);
2508 Py_DECREF(f);
2509 f = PyFrozenSet_New(NULL);
2510 assert(f != NULL);
2511 assert(PyFrozenSet_CheckExact(f));
2512 assert(PySet_GET_SIZE(f) == 0);
2513 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002515 Py_DECREF(elem);
2516 Py_DECREF(dup);
2517 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002518}
2519
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002520#undef assertRaises
2521
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002522#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002523
2524/***** Dummy Struct *************************************************/
2525
2526static PyObject *
2527dummy_repr(PyObject *op)
2528{
2529 return PyUnicode_FromString("<dummy key>");
2530}
2531
2532static void
2533dummy_dealloc(PyObject* ignore)
2534{
2535 Py_FatalError("deallocating <dummy key>");
2536}
2537
2538static PyTypeObject _PySetDummy_Type = {
2539 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2540 "<dummy key> type",
2541 0,
2542 0,
2543 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2544 0, /*tp_print*/
2545 0, /*tp_getattr*/
2546 0, /*tp_setattr*/
2547 0, /*tp_reserved*/
2548 dummy_repr, /*tp_repr*/
2549 0, /*tp_as_number*/
2550 0, /*tp_as_sequence*/
2551 0, /*tp_as_mapping*/
2552 0, /*tp_hash */
2553 0, /*tp_call */
2554 0, /*tp_str */
2555 0, /*tp_getattro */
2556 0, /*tp_setattro */
2557 0, /*tp_as_buffer */
2558 Py_TPFLAGS_DEFAULT, /*tp_flags */
2559};
2560
2561static PyObject _dummy_struct = {
2562 _PyObject_EXTRA_INIT
2563 2, &_PySetDummy_Type
2564};
2565