blob: c1bc1e1234799f345cdbbc4640573ed4d9610513 [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 Hettinger15f08692015-07-03 17:21:17 -0700237 if ((size_t)so->fill*3 < mask*2)
238 return 0;
INADA Naokiefde51a2017-04-01 23:29:31 +0900239 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
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 Hettinger08e3dc02014-12-26 20:14:00 -0800299 Py_ssize_t oldfill = so->fill;
300 Py_ssize_t oldused = so->used;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800301 Py_ssize_t oldmask = so->mask;
302 size_t newmask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000303 int is_oldtable_malloced;
304 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 assert(minused >= 0);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100309 /* XXX speed-up with intrinsics */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 for (newsize = PySet_MINSIZE;
311 newsize <= minused && newsize > 0;
312 newsize <<= 1)
313 ;
314 if (newsize <= 0) {
315 PyErr_NoMemory();
316 return -1;
317 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000319 /* Get space for a new table. */
320 oldtable = so->table;
321 assert(oldtable != NULL);
322 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000324 if (newsize == PySet_MINSIZE) {
325 /* A large table is shrinking, or we can't get any smaller. */
326 newtable = so->smalltable;
327 if (newtable == oldtable) {
328 if (so->fill == so->used) {
329 /* No dummies, so no point doing anything. */
330 return 0;
331 }
332 /* We're not going to resize it, but rebuild the
333 table anyway to purge old dummy entries.
334 Subtle: This is *necessary* if fill==size,
335 as set_lookkey needs at least one virgin slot to
336 terminate failing searches. If fill < size, it's
337 merely desirable, as dummies slow searches. */
338 assert(so->fill > so->used);
339 memcpy(small_copy, oldtable, sizeof(small_copy));
340 oldtable = small_copy;
341 }
342 }
343 else {
344 newtable = PyMem_NEW(setentry, newsize);
345 if (newtable == NULL) {
346 PyErr_NoMemory();
347 return -1;
348 }
349 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 /* Make the set empty, using the new table. */
352 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 memset(newtable, 0, sizeof(setentry) * newsize);
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800354 so->fill = oldused;
355 so->used = oldused;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800356 so->mask = newsize - 1;
357 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 /* Copy the data over; this is refcount-neutral for active entries;
360 dummy entries aren't copied over, of course */
Raymond Hettinger5088f602015-12-13 18:45:01 -0800361 newmask = (size_t)so->mask;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800362 if (oldfill == oldused) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800363 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800364 if (entry->key != NULL) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800365 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800366 }
367 }
368 } else {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800369 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800370 if (entry->key != NULL && entry->key != dummy) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800371 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800372 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 }
374 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376 if (is_oldtable_malloced)
377 PyMem_DEL(oldtable);
378 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000379}
380
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000381static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700382set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000383{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700384 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000385
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700386 entry = set_lookkey(so, key, hash);
387 if (entry != NULL)
388 return entry->key != NULL;
389 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000390}
391
392#define DISCARD_NOTFOUND 0
393#define DISCARD_FOUND 1
394
395static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700396set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800397{
398 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000400
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700401 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 if (entry == NULL)
403 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700404 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 return DISCARD_NOTFOUND;
406 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800408 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 so->used--;
410 Py_DECREF(old_key);
411 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000412}
413
414static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700415set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000416{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200417 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000418
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700419 if (!PyUnicode_CheckExact(key) ||
420 (hash = ((PyASCIIObject *) key)->hash) == -1) {
421 hash = PyObject_Hash(key);
422 if (hash == -1)
423 return -1;
424 }
425 return set_add_entry(so, key, hash);
426}
427
428static int
429set_contains_key(PySetObject *so, PyObject *key)
430{
431 Py_hash_t hash;
432
433 if (!PyUnicode_CheckExact(key) ||
434 (hash = ((PyASCIIObject *) key)->hash) == -1) {
435 hash = PyObject_Hash(key);
436 if (hash == -1)
437 return -1;
438 }
439 return set_contains_entry(so, key, hash);
440}
441
442static int
443set_discard_key(PySetObject *so, PyObject *key)
444{
445 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200448 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 hash = PyObject_Hash(key);
450 if (hash == -1)
451 return -1;
452 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700453 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000454}
455
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700456static void
457set_empty_to_minsize(PySetObject *so)
458{
459 memset(so->smalltable, 0, sizeof(so->smalltable));
460 so->fill = 0;
461 so->used = 0;
462 so->mask = PySet_MINSIZE - 1;
463 so->table = so->smalltable;
464 so->hash = -1;
465}
466
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000467static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000468set_clear_internal(PySetObject *so)
469{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800470 setentry *entry;
471 setentry *table = so->table;
472 Py_ssize_t fill = so->fill;
473 Py_ssize_t used = so->used;
474 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000476
Raymond Hettinger583cd032013-09-07 22:06:35 -0700477 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 /* This is delicate. During the process of clearing the set,
481 * decrefs can cause the set to mutate. To avoid fatal confusion
482 * (voice of experience), we have to make the set empty before
483 * clearing the slots, and never refer to anything via so->ref while
484 * clearing.
485 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700487 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 else if (fill > 0) {
490 /* It's a small table with something that needs to be cleared.
491 * Afraid the only safe way is to copy the set entries into
492 * another small table first.
493 */
494 memcpy(small_copy, table, sizeof(small_copy));
495 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700496 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 }
498 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500 /* Now we can finally clear things. If C had refcounts, we could
501 * assert that the refcount on table is 1 now, i.e. that this function
502 * has unique access to it, so decref side-effects can't alter it.
503 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800504 for (entry = table; used > 0; entry++) {
505 if (entry->key && entry->key != dummy) {
506 used--;
507 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 if (table_is_malloced)
512 PyMem_DEL(table);
513 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000514}
515
516/*
517 * Iterate over a set table. Use like so:
518 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000519 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000520 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000521 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000522 * while (set_next(yourset, &pos, &entry)) {
523 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000524 * }
525 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000526 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000528 */
529static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000530set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000531{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 Py_ssize_t i;
533 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700534 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 assert (PyAnySet_Check(so));
537 i = *pos_ptr;
538 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700540 entry = &so->table[i];
541 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700543 entry++;
544 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 *pos_ptr = i+1;
546 if (i > mask)
547 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700548 assert(entry != NULL);
549 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000551}
552
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000553static void
554set_dealloc(PySetObject *so)
555{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200556 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800557 Py_ssize_t used = so->used;
558
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000559 PyObject_GC_UnTrack(so);
560 Py_TRASHCAN_SAFE_BEGIN(so)
561 if (so->weakreflist != NULL)
562 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000563
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800564 for (entry = so->table; used > 0; entry++) {
565 if (entry->key && entry->key != dummy) {
566 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700567 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000568 }
569 }
570 if (so->table != so->smalltable)
571 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700572 Py_TYPE(so)->tp_free(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 Py_TRASHCAN_SAFE_END(so)
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000574}
575
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000576static PyObject *
577set_repr(PySetObject *so)
578{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200579 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000580 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000581
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000582 if (status != 0) {
583 if (status < 0)
584 return NULL;
585 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
586 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 /* shortcut for the empty set */
589 if (!so->used) {
590 Py_ReprLeave((PyObject*)so);
591 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
592 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000594 keys = PySequence_List((PyObject *)so);
595 if (keys == NULL)
596 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000597
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200598 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000599 listrepr = PyObject_Repr(keys);
600 Py_DECREF(keys);
601 if (listrepr == NULL)
602 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200603 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200605 if (tmp == NULL)
606 goto done;
607 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200608
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200609 if (Py_TYPE(so) != &PySet_Type)
610 result = PyUnicode_FromFormat("%s({%U})",
611 Py_TYPE(so)->tp_name,
612 listrepr);
613 else
614 result = PyUnicode_FromFormat("{%U}", listrepr);
615 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000616done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 Py_ReprLeave((PyObject*)so);
618 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000619}
620
Martin v. Löwis18e16552006-02-15 17:27:45 +0000621static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000622set_len(PyObject *so)
623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000625}
626
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000627static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000628set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000629{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000631 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200632 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700633 setentry *so_entry;
634 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000636 assert (PyAnySet_Check(so));
637 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000639 other = (PySetObject*)otherset;
640 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700641 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000642 return 0;
643 /* Do one big resize at the start, rather than
644 * incrementally resizing as we insert new keys. Expect
645 * that there will be no (or few) overlapping keys.
646 */
Raymond Hettinger15f08692015-07-03 17:21:17 -0700647 if ((so->fill + other->used)*3 >= so->mask*2) {
INADA Naokiefde51a2017-04-01 23:29:31 +0900648 if (set_table_resize(so, (so->used + other->used)*2) != 0)
649 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000650 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700651 so_entry = so->table;
652 other_entry = other->table;
653
654 /* If our table is empty, and both tables have the same size, and
655 there are no dummies to eliminate, then just copy the pointers. */
656 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
657 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
658 key = other_entry->key;
659 if (key != NULL) {
660 assert(so_entry->key == NULL);
661 Py_INCREF(key);
662 so_entry->key = key;
663 so_entry->hash = other_entry->hash;
664 }
665 }
666 so->fill = other->fill;
667 so->used = other->used;
668 return 0;
669 }
670
671 /* If our table is empty, we can use set_insert_clean() */
672 if (so->fill == 0) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800673 setentry *newtable = so->table;
674 size_t newmask = (size_t)so->mask;
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800675 so->fill = other->used;
676 so->used = other->used;
Raymond Hettingere4495872015-12-15 00:42:30 -0800677 for (i = other->mask + 1; i > 0 ; i--, other_entry++) {
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700678 key = other_entry->key;
679 if (key != NULL && key != dummy) {
680 Py_INCREF(key);
Raymond Hettinger5088f602015-12-13 18:45:01 -0800681 set_insert_clean(newtable, newmask, key, other_entry->hash);
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700682 }
683 }
684 return 0;
685 }
686
687 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700688 for (i = 0; i <= other->mask; i++) {
689 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700690 key = other_entry->key;
691 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700692 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000693 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000694 }
695 }
696 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000697}
698
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000699static PyObject *
700set_pop(PySetObject *so)
701{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800702 /* Make sure the search finger is in bounds */
703 Py_ssize_t i = so->finger & so->mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200704 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000705 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000706
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 assert (PyAnySet_Check(so));
708 if (so->used == 0) {
709 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
710 return NULL;
711 }
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000712
Raymond Hettinger1202a472015-01-18 13:12:42 -0800713 while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
714 i++;
Raymond Hettingered741d42015-01-18 21:25:15 -0800715 if (i > so->mask)
716 i = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 }
718 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800720 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 so->used--;
Raymond Hettinger1202a472015-01-18 13:12:42 -0800722 so->finger = i + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000724}
725
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000726PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
727Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000728
729static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000730set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000731{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000732 Py_ssize_t pos = 0;
733 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 while (set_next(so, &pos, &entry))
736 Py_VISIT(entry->key);
737 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000738}
739
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700740/* Work to increase the bit dispersion for closely spaced hash values.
741 This is important because some use cases have many combinations of a
742 small number of elements with nearby hashes so that many distinct
743 combinations collapse to only a handful of distinct hash values. */
744
745static Py_uhash_t
746_shuffle_bits(Py_uhash_t h)
747{
748 return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
749}
750
751/* Most of the constants in this hash algorithm are randomly chosen
752 large primes with "interesting bit patterns" and that passed tests
753 for good collision statistics on a variety of problematic datasets
754 including powersets and graph structures (such as David Eppstein's
755 graph recipes in Lib/test/test_set.py) */
756
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000757static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000758frozenset_hash(PyObject *self)
759{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000760 PySetObject *so = (PySetObject *)self;
Raymond Hettinger41481952015-08-07 00:43:39 -0700761 Py_uhash_t hash = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000763
Raymond Hettingerb501a272015-08-06 22:15:22 -0700764 if (so->hash != -1)
765 return so->hash;
766
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700767 /* Xor-in shuffled bits from every entry's hash field because xor is
768 commutative and a frozenset hash should be independent of order.
769
770 For speed, include null entries and dummy entries and then
771 subtract out their effect afterwards so that the final hash
772 depends only on active entries. This allows the code to be
773 vectorized by the compiler and it saves the unpredictable
774 branches that would arise when trying to exclude null and dummy
775 entries on every iteration. */
776
777 for (entry = so->table; entry <= &so->table[so->mask]; entry++)
778 hash ^= _shuffle_bits(entry->hash);
779
Raymond Hettingera286a512015-08-01 11:07:11 -0700780 /* Remove the effect of an odd number of NULL entries */
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700781 if ((so->mask + 1 - so->fill) & 1)
782 hash ^= _shuffle_bits(0);
783
784 /* Remove the effect of an odd number of dummy entries */
785 if ((so->fill - so->used) & 1)
786 hash ^= _shuffle_bits(-1);
787
Raymond Hettinger41481952015-08-07 00:43:39 -0700788 /* Factor in the number of active entries */
789 hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;
790
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700791 /* Disperse patterns arising in nested frozensets */
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800792 hash = hash * 69069U + 907133923UL;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700793
Raymond Hettinger36c05002015-08-01 10:57:42 -0700794 /* -1 is reserved as an error code */
Victor Stinner12174a52014-08-15 23:17:38 +0200795 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800796 hash = 590923713UL;
Raymond Hettinger36c05002015-08-01 10:57:42 -0700797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 so->hash = hash;
799 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000800}
801
Raymond Hettingera9d99362005-08-05 00:01:15 +0000802/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000803
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000804typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000805 PyObject_HEAD
806 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
807 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700808 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000809 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000810} setiterobject;
811
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000812static void
813setiter_dealloc(setiterobject *si)
814{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000815 Py_XDECREF(si->si_set);
816 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000817}
818
819static int
820setiter_traverse(setiterobject *si, visitproc visit, void *arg)
821{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000822 Py_VISIT(si->si_set);
823 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000824}
825
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000826static PyObject *
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000827setiter_len(setiterobject *si)
828{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000829 Py_ssize_t len = 0;
830 if (si->si_set != NULL && si->si_used == si->si_set->used)
831 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000832 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000833}
834
Armin Rigof5b3e362006-02-11 21:32:43 +0000835PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000836
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000837static PyObject *setiter_iternext(setiterobject *si);
838
839static PyObject *
840setiter_reduce(setiterobject *si)
841{
842 PyObject *list;
843 setiterobject tmp;
844
845 list = PyList_New(0);
846 if (!list)
847 return NULL;
848
Ezio Melotti0e1af282012-09-28 16:43:40 +0300849 /* copy the iterator state */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000850 tmp = *si;
851 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300852
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000853 /* iterate the temporary into a list */
854 for(;;) {
855 PyObject *element = setiter_iternext(&tmp);
856 if (element) {
857 if (PyList_Append(list, element)) {
858 Py_DECREF(element);
859 Py_DECREF(list);
860 Py_XDECREF(tmp.si_set);
861 return NULL;
862 }
863 Py_DECREF(element);
864 } else
865 break;
866 }
867 Py_XDECREF(tmp.si_set);
868 /* check for error */
869 if (tmp.si_set != NULL) {
870 /* we have an error */
871 Py_DECREF(list);
872 return NULL;
873 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200874 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000875}
876
877PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
878
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000879static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000880 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000881 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000882 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000883};
884
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000885static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000886{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700887 PyObject *key;
888 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200889 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000890 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000891
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000892 if (so == NULL)
893 return NULL;
894 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000896 if (si->si_used != so->used) {
897 PyErr_SetString(PyExc_RuntimeError,
898 "Set changed size during iteration");
899 si->si_used = -1; /* Make this state sticky */
900 return NULL;
901 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700902
903 i = si->si_pos;
904 assert(i>=0);
905 entry = so->table;
906 mask = so->mask;
907 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
908 i++;
909 si->si_pos = i+1;
910 if (i > mask)
911 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000912 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700913 key = entry[i].key;
914 Py_INCREF(key);
915 return key;
916
917fail:
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700918 si->si_set = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +0300919 Py_DECREF(so);
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700920 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000921}
922
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000923PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000924 PyVarObject_HEAD_INIT(&PyType_Type, 0)
925 "set_iterator", /* tp_name */
926 sizeof(setiterobject), /* tp_basicsize */
927 0, /* tp_itemsize */
928 /* methods */
929 (destructor)setiter_dealloc, /* tp_dealloc */
930 0, /* tp_print */
931 0, /* tp_getattr */
932 0, /* tp_setattr */
933 0, /* tp_reserved */
934 0, /* tp_repr */
935 0, /* tp_as_number */
936 0, /* tp_as_sequence */
937 0, /* tp_as_mapping */
938 0, /* tp_hash */
939 0, /* tp_call */
940 0, /* tp_str */
941 PyObject_GenericGetAttr, /* tp_getattro */
942 0, /* tp_setattro */
943 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700944 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000945 0, /* tp_doc */
946 (traverseproc)setiter_traverse, /* tp_traverse */
947 0, /* tp_clear */
948 0, /* tp_richcompare */
949 0, /* tp_weaklistoffset */
950 PyObject_SelfIter, /* tp_iter */
951 (iternextfunc)setiter_iternext, /* tp_iternext */
952 setiter_methods, /* tp_methods */
953 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000954};
955
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000956static PyObject *
957set_iter(PySetObject *so)
958{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000959 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
960 if (si == NULL)
961 return NULL;
962 Py_INCREF(so);
963 si->si_set = so;
964 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700965 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 si->len = so->used;
967 _PyObject_GC_TRACK(si);
968 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000969}
970
Raymond Hettingerd7946662005-08-01 21:39:29 +0000971static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000972set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000973{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000975
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000976 if (PyAnySet_Check(other))
977 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000978
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000979 if (PyDict_CheckExact(other)) {
980 PyObject *value;
981 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000982 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 Py_ssize_t dictsize = PyDict_Size(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000984
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 /* Do one big resize at the start, rather than
986 * incrementally resizing as we insert new keys. Expect
987 * that there will be no (or few) overlapping keys.
988 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700989 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000990 return -1;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700991 if ((so->fill + dictsize)*3 >= so->mask*2) {
INADA Naokiefde51a2017-04-01 23:29:31 +0900992 if (set_table_resize(so, (so->used + dictsize)*2) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000993 return -1;
994 }
995 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700996 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000997 return -1;
998 }
999 return 0;
1000 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001002 it = PyObject_GetIter(other);
1003 if (it == NULL)
1004 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +00001005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001007 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 Py_DECREF(it);
1009 Py_DECREF(key);
1010 return -1;
1011 }
1012 Py_DECREF(key);
1013 }
1014 Py_DECREF(it);
1015 if (PyErr_Occurred())
1016 return -1;
1017 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001018}
1019
1020static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001021set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001022{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001024
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001025 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1026 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001027 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 return NULL;
1029 }
1030 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001031}
1032
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001033PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001034"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001035
Raymond Hettinger426d9952014-05-18 21:40:20 +01001036/* XXX Todo:
1037 If aligned memory allocations become available, make the
1038 set object 64 byte aligned so that most of the fields
1039 can be retrieved or updated in a single cache line.
1040*/
1041
Raymond Hettingera38123e2003-11-24 22:18:49 +00001042static PyObject *
1043make_new_set(PyTypeObject *type, PyObject *iterable)
1044{
Raymond Hettinger8421d712016-04-29 01:37:05 -07001045 PySetObject *so;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001046
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001047 so = (PySetObject *)type->tp_alloc(type, 0);
1048 if (so == NULL)
1049 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001050
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001051 so->fill = 0;
1052 so->used = 0;
1053 so->mask = PySet_MINSIZE - 1;
1054 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001055 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001056 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001057 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001058
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001060 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 Py_DECREF(so);
1062 return NULL;
1063 }
1064 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001067}
1068
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001069static PyObject *
1070make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1071{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1073 if (PyType_IsSubtype(type, &PySet_Type))
1074 type = &PySet_Type;
1075 else
1076 type = &PyFrozenSet_Type;
1077 }
1078 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001079}
1080
Raymond Hettingerd7946662005-08-01 21:39:29 +00001081/* The empty frozenset is a singleton */
1082static PyObject *emptyfrozenset = NULL;
1083
Raymond Hettingera690a992003-11-16 16:17:49 +00001084static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001085frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001086{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001088
Raymond Hettingerf5021542016-02-04 02:46:16 -08001089 if (kwds != NULL && type == &PyFrozenSet_Type
1090 && !_PyArg_NoKeywords("frozenset()", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001091 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001093 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1094 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 if (type != &PyFrozenSet_Type)
1097 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 if (iterable != NULL) {
1100 /* frozenset(f) is idempotent */
1101 if (PyFrozenSet_CheckExact(iterable)) {
1102 Py_INCREF(iterable);
1103 return iterable;
1104 }
1105 result = make_new_set(type, iterable);
1106 if (result == NULL || PySet_GET_SIZE(result))
1107 return result;
1108 Py_DECREF(result);
1109 }
1110 /* The empty frozenset is a singleton */
1111 if (emptyfrozenset == NULL)
1112 emptyfrozenset = make_new_set(type, NULL);
1113 Py_XINCREF(emptyfrozenset);
1114 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001115}
1116
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001117static PyObject *
1118set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1119{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001120 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001121}
1122
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001123/* set_swap_bodies() switches the contents of any two sets by moving their
1124 internal data pointers and, if needed, copying the internal smalltables.
1125 Semantically equivalent to:
1126
1127 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1128
1129 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001130 Useful for operations that update in-place (by allowing an intermediate
1131 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001132*/
1133
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001134static void
1135set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001136{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001137 Py_ssize_t t;
1138 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001139 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001140 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 t = a->fill; a->fill = b->fill; b->fill = t;
1143 t = a->used; a->used = b->used; b->used = t;
1144 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001145
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001146 u = a->table;
1147 if (a->table == a->smalltable)
1148 u = b->smalltable;
1149 a->table = b->table;
1150 if (b->table == b->smalltable)
1151 a->table = a->smalltable;
1152 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001154 if (a->table == a->smalltable || b->table == b->smalltable) {
1155 memcpy(tab, a->smalltable, sizeof(tab));
1156 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1157 memcpy(b->smalltable, tab, sizeof(tab));
1158 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001160 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1161 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1162 h = a->hash; a->hash = b->hash; b->hash = h;
1163 } else {
1164 a->hash = -1;
1165 b->hash = -1;
1166 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001167}
1168
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001169static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001170set_copy(PySetObject *so)
1171{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001173}
1174
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001175static PyObject *
1176frozenset_copy(PySetObject *so)
1177{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 if (PyFrozenSet_CheckExact(so)) {
1179 Py_INCREF(so);
1180 return (PyObject *)so;
1181 }
1182 return set_copy(so);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001183}
1184
Raymond Hettingera690a992003-11-16 16:17:49 +00001185PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1186
1187static PyObject *
Raymond Hettingerc991db22005-08-11 07:58:45 +00001188set_clear(PySetObject *so)
1189{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 set_clear_internal(so);
1191 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001192}
1193
1194PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1195
1196static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001197set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001198{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 PySetObject *result;
1200 PyObject *other;
1201 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001203 result = (PySetObject *)set_copy(so);
1204 if (result == NULL)
1205 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1208 other = PyTuple_GET_ITEM(args, i);
1209 if ((PyObject *)so == other)
1210 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001211 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 Py_DECREF(result);
1213 return NULL;
1214 }
1215 }
1216 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001217}
1218
1219PyDoc_STRVAR(union_doc,
1220 "Return the union of sets as a new set.\n\
1221\n\
1222(i.e. all elements that are in either set.)");
1223
1224static PyObject *
1225set_or(PySetObject *so, PyObject *other)
1226{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001227 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001228
Brian Curtindfc80e32011-08-10 20:28:54 -05001229 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1230 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 result = (PySetObject *)set_copy(so);
1233 if (result == NULL)
1234 return NULL;
1235 if ((PyObject *)so == other)
1236 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001237 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 Py_DECREF(result);
1239 return NULL;
1240 }
1241 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001242}
1243
Raymond Hettingera690a992003-11-16 16:17:49 +00001244static PyObject *
1245set_ior(PySetObject *so, PyObject *other)
1246{
Brian Curtindfc80e32011-08-10 20:28:54 -05001247 if (!PyAnySet_Check(other))
1248 Py_RETURN_NOTIMPLEMENTED;
1249
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001250 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 return NULL;
1252 Py_INCREF(so);
1253 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001254}
1255
1256static PyObject *
1257set_intersection(PySetObject *so, PyObject *other)
1258{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001259 PySetObject *result;
1260 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001261 Py_hash_t hash;
1262 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 if ((PyObject *)so == other)
1265 return set_copy(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1268 if (result == NULL)
1269 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 if (PyAnySet_Check(other)) {
1272 Py_ssize_t pos = 0;
1273 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1276 tmp = (PyObject *)so;
1277 so = (PySetObject *)other;
1278 other = tmp;
1279 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001282 key = entry->key;
1283 hash = entry->hash;
1284 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001285 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001286 Py_DECREF(result);
1287 return NULL;
1288 }
1289 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001290 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 Py_DECREF(result);
1292 return NULL;
1293 }
1294 }
1295 }
1296 return (PyObject *)result;
1297 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 it = PyObject_GetIter(other);
1300 if (it == NULL) {
1301 Py_DECREF(result);
1302 return NULL;
1303 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001306 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001307 if (hash == -1)
1308 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001309 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001310 if (rv < 0)
1311 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001313 if (set_add_entry(result, key, hash))
1314 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 }
1316 Py_DECREF(key);
1317 }
1318 Py_DECREF(it);
1319 if (PyErr_Occurred()) {
1320 Py_DECREF(result);
1321 return NULL;
1322 }
1323 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001324 error:
1325 Py_DECREF(it);
1326 Py_DECREF(result);
1327 Py_DECREF(key);
1328 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001329}
1330
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001331static PyObject *
1332set_intersection_multi(PySetObject *so, PyObject *args)
1333{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001334 Py_ssize_t i;
1335 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 if (PyTuple_GET_SIZE(args) == 0)
1338 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 Py_INCREF(so);
1341 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1342 PyObject *other = PyTuple_GET_ITEM(args, i);
1343 PyObject *newresult = set_intersection((PySetObject *)result, other);
1344 if (newresult == NULL) {
1345 Py_DECREF(result);
1346 return NULL;
1347 }
1348 Py_DECREF(result);
1349 result = newresult;
1350 }
1351 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001352}
1353
Raymond Hettingera690a992003-11-16 16:17:49 +00001354PyDoc_STRVAR(intersection_doc,
1355"Return the intersection of two sets as a new set.\n\
1356\n\
1357(i.e. all elements that are in both sets.)");
1358
1359static PyObject *
1360set_intersection_update(PySetObject *so, PyObject *other)
1361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001362 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001364 tmp = set_intersection(so, other);
1365 if (tmp == NULL)
1366 return NULL;
1367 set_swap_bodies(so, (PySetObject *)tmp);
1368 Py_DECREF(tmp);
1369 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001370}
1371
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001372static PyObject *
1373set_intersection_update_multi(PySetObject *so, PyObject *args)
1374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 tmp = set_intersection_multi(so, args);
1378 if (tmp == NULL)
1379 return NULL;
1380 set_swap_bodies(so, (PySetObject *)tmp);
1381 Py_DECREF(tmp);
1382 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001383}
1384
Raymond Hettingera690a992003-11-16 16:17:49 +00001385PyDoc_STRVAR(intersection_update_doc,
1386"Update a set with the intersection of itself and another.");
1387
1388static PyObject *
1389set_and(PySetObject *so, PyObject *other)
1390{
Brian Curtindfc80e32011-08-10 20:28:54 -05001391 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1392 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001394}
1395
1396static PyObject *
1397set_iand(PySetObject *so, PyObject *other)
1398{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001400
Brian Curtindfc80e32011-08-10 20:28:54 -05001401 if (!PyAnySet_Check(other))
1402 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001403 result = set_intersection_update(so, other);
1404 if (result == NULL)
1405 return NULL;
1406 Py_DECREF(result);
1407 Py_INCREF(so);
1408 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001409}
1410
Guido van Rossum58da9312007-11-10 23:39:45 +00001411static PyObject *
1412set_isdisjoint(PySetObject *so, PyObject *other)
1413{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001415 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 if ((PyObject *)so == other) {
1418 if (PySet_GET_SIZE(so) == 0)
1419 Py_RETURN_TRUE;
1420 else
1421 Py_RETURN_FALSE;
1422 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424 if (PyAnySet_CheckExact(other)) {
1425 Py_ssize_t pos = 0;
1426 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001428 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1429 tmp = (PyObject *)so;
1430 so = (PySetObject *)other;
1431 other = tmp;
1432 }
1433 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001434 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001435 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 return NULL;
1437 if (rv)
1438 Py_RETURN_FALSE;
1439 }
1440 Py_RETURN_TRUE;
1441 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001443 it = PyObject_GetIter(other);
1444 if (it == NULL)
1445 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001448 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 if (hash == -1) {
1451 Py_DECREF(key);
1452 Py_DECREF(it);
1453 return NULL;
1454 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001455 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001456 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001457 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001458 Py_DECREF(it);
1459 return NULL;
1460 }
1461 if (rv) {
1462 Py_DECREF(it);
1463 Py_RETURN_FALSE;
1464 }
1465 }
1466 Py_DECREF(it);
1467 if (PyErr_Occurred())
1468 return NULL;
1469 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001470}
1471
1472PyDoc_STRVAR(isdisjoint_doc,
1473"Return True if two sets have a null intersection.");
1474
Neal Norwitz6576bd82005-11-13 18:41:28 +00001475static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001476set_difference_update_internal(PySetObject *so, PyObject *other)
1477{
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001478 if (PySet_GET_SIZE(so) == 0) {
1479 return 0;
1480 }
1481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001482 if ((PyObject *)so == other)
1483 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 if (PyAnySet_Check(other)) {
1486 setentry *entry;
1487 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001490 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001491 return -1;
1492 } else {
1493 PyObject *key, *it;
1494 it = PyObject_GetIter(other);
1495 if (it == NULL)
1496 return -1;
1497
1498 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001499 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 Py_DECREF(it);
1501 Py_DECREF(key);
1502 return -1;
1503 }
1504 Py_DECREF(key);
1505 }
1506 Py_DECREF(it);
1507 if (PyErr_Occurred())
1508 return -1;
1509 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001510 /* If more than 1/4th are dummies, then resize them away. */
1511 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512 return 0;
INADA Naokiefde51a2017-04-01 23:29:31 +09001513 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001514}
1515
Raymond Hettingera690a992003-11-16 16:17:49 +00001516static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001517set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001518{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1522 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001523 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 return NULL;
1525 }
1526 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001527}
1528
1529PyDoc_STRVAR(difference_update_doc,
1530"Remove all elements of another set from this set.");
1531
1532static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001533set_copy_and_difference(PySetObject *so, PyObject *other)
1534{
1535 PyObject *result;
1536
1537 result = set_copy(so);
1538 if (result == NULL)
1539 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001540 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001541 return result;
1542 Py_DECREF(result);
1543 return NULL;
1544}
1545
1546static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001547set_difference(PySetObject *so, PyObject *other)
1548{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001550 PyObject *key;
1551 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001552 setentry *entry;
Serhiy Storchaka680fea42017-04-19 21:22:49 +03001553 Py_ssize_t pos = 0, other_size;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001554 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001555
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001556 if (PySet_GET_SIZE(so) == 0) {
1557 return set_copy(so);
1558 }
1559
Serhiy Storchaka680fea42017-04-19 21:22:49 +03001560 if (PyAnySet_Check(other)) {
1561 other_size = PySet_GET_SIZE(other);
1562 }
1563 else if (PyDict_CheckExact(other)) {
1564 other_size = PyDict_Size(other);
1565 }
1566 else {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001567 return set_copy_and_difference(so, other);
1568 }
1569
1570 /* If len(so) much more than len(other), it's more efficient to simply copy
1571 * so and then iterate other looking for common elements. */
Serhiy Storchaka680fea42017-04-19 21:22:49 +03001572 if ((PySet_GET_SIZE(so) >> 2) > other_size) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001573 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001574 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001575
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 result = make_new_set_basetype(Py_TYPE(so), NULL);
1577 if (result == NULL)
1578 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 if (PyDict_CheckExact(other)) {
1581 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001582 key = entry->key;
1583 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001584 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001585 if (rv < 0) {
1586 Py_DECREF(result);
1587 return NULL;
1588 }
1589 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001590 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 Py_DECREF(result);
1592 return NULL;
1593 }
1594 }
1595 }
1596 return result;
1597 }
1598
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001599 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001601 key = entry->key;
1602 hash = entry->hash;
1603 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001604 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001605 Py_DECREF(result);
1606 return NULL;
1607 }
1608 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001609 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001610 Py_DECREF(result);
1611 return NULL;
1612 }
1613 }
1614 }
1615 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001616}
1617
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001618static PyObject *
1619set_difference_multi(PySetObject *so, PyObject *args)
1620{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 Py_ssize_t i;
1622 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 if (PyTuple_GET_SIZE(args) == 0)
1625 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 other = PyTuple_GET_ITEM(args, 0);
1628 result = set_difference(so, other);
1629 if (result == NULL)
1630 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1633 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001634 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 Py_DECREF(result);
1636 return NULL;
1637 }
1638 }
1639 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001640}
1641
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001642PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001643"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001644\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001645(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001646static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001647set_sub(PySetObject *so, PyObject *other)
1648{
Brian Curtindfc80e32011-08-10 20:28:54 -05001649 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1650 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001652}
1653
1654static PyObject *
1655set_isub(PySetObject *so, PyObject *other)
1656{
Brian Curtindfc80e32011-08-10 20:28:54 -05001657 if (!PyAnySet_Check(other))
1658 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001659 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 return NULL;
1661 Py_INCREF(so);
1662 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001663}
1664
1665static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001666set_symmetric_difference_update(PySetObject *so, PyObject *other)
1667{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 PySetObject *otherset;
1669 PyObject *key;
1670 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001671 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001672 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001673 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001675 if ((PyObject *)so == other)
1676 return set_clear(so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001677
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001678 if (PyDict_CheckExact(other)) {
1679 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001680 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001681 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001682 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001683 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001684 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001685 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001686 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001687 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001688 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001689 Py_DECREF(key);
1690 return NULL;
1691 }
1692 }
Georg Brandl2d444492010-09-03 10:52:55 +00001693 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001694 }
1695 Py_RETURN_NONE;
1696 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001697
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001698 if (PyAnySet_Check(other)) {
1699 Py_INCREF(other);
1700 otherset = (PySetObject *)other;
1701 } else {
1702 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1703 if (otherset == NULL)
1704 return NULL;
1705 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001706
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001707 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001708 key = entry->key;
1709 hash = entry->hash;
1710 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001711 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001712 Py_DECREF(otherset);
1713 return NULL;
1714 }
1715 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001716 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001717 Py_DECREF(otherset);
1718 return NULL;
1719 }
1720 }
1721 }
1722 Py_DECREF(otherset);
1723 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001724}
1725
1726PyDoc_STRVAR(symmetric_difference_update_doc,
1727"Update a set with the symmetric difference of itself and another.");
1728
1729static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001730set_symmetric_difference(PySetObject *so, PyObject *other)
1731{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001732 PyObject *rv;
1733 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001735 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1736 if (otherset == NULL)
1737 return NULL;
1738 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
1739 if (rv == NULL)
1740 return NULL;
1741 Py_DECREF(rv);
1742 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001743}
1744
1745PyDoc_STRVAR(symmetric_difference_doc,
1746"Return the symmetric difference of two sets as a new set.\n\
1747\n\
1748(i.e. all elements that are in exactly one of the sets.)");
1749
1750static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001751set_xor(PySetObject *so, PyObject *other)
1752{
Brian Curtindfc80e32011-08-10 20:28:54 -05001753 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1754 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001755 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001756}
1757
1758static PyObject *
1759set_ixor(PySetObject *so, PyObject *other)
1760{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001762
Brian Curtindfc80e32011-08-10 20:28:54 -05001763 if (!PyAnySet_Check(other))
1764 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001765 result = set_symmetric_difference_update(so, other);
1766 if (result == NULL)
1767 return NULL;
1768 Py_DECREF(result);
1769 Py_INCREF(so);
1770 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001771}
1772
1773static PyObject *
1774set_issubset(PySetObject *so, PyObject *other)
1775{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776 setentry *entry;
1777 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001778 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001779
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780 if (!PyAnySet_Check(other)) {
1781 PyObject *tmp, *result;
1782 tmp = make_new_set(&PySet_Type, other);
1783 if (tmp == NULL)
1784 return NULL;
1785 result = set_issubset(so, tmp);
1786 Py_DECREF(tmp);
1787 return result;
1788 }
1789 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1790 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001791
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001792 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001793 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001794 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001795 return NULL;
1796 if (!rv)
1797 Py_RETURN_FALSE;
1798 }
1799 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001800}
1801
1802PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1803
1804static PyObject *
1805set_issuperset(PySetObject *so, PyObject *other)
1806{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001807 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001808
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001809 if (!PyAnySet_Check(other)) {
1810 tmp = make_new_set(&PySet_Type, other);
1811 if (tmp == NULL)
1812 return NULL;
1813 result = set_issuperset(so, tmp);
1814 Py_DECREF(tmp);
1815 return result;
1816 }
1817 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001818}
1819
1820PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1821
Raymond Hettingera690a992003-11-16 16:17:49 +00001822static PyObject *
1823set_richcompare(PySetObject *v, PyObject *w, int op)
1824{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001825 PyObject *r1;
1826 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001827
Brian Curtindfc80e32011-08-10 20:28:54 -05001828 if(!PyAnySet_Check(w))
1829 Py_RETURN_NOTIMPLEMENTED;
1830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001831 switch (op) {
1832 case Py_EQ:
1833 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1834 Py_RETURN_FALSE;
1835 if (v->hash != -1 &&
1836 ((PySetObject *)w)->hash != -1 &&
1837 v->hash != ((PySetObject *)w)->hash)
1838 Py_RETURN_FALSE;
1839 return set_issubset(v, w);
1840 case Py_NE:
1841 r1 = set_richcompare(v, w, Py_EQ);
1842 if (r1 == NULL)
1843 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001844 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001846 if (r2 < 0)
1847 return NULL;
1848 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001849 case Py_LE:
1850 return set_issubset(v, w);
1851 case Py_GE:
1852 return set_issuperset(v, w);
1853 case Py_LT:
1854 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1855 Py_RETURN_FALSE;
1856 return set_issubset(v, w);
1857 case Py_GT:
1858 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1859 Py_RETURN_FALSE;
1860 return set_issuperset(v, w);
1861 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001862 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001863}
1864
Raymond Hettingera690a992003-11-16 16:17:49 +00001865static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001866set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001867{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001868 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001869 return NULL;
1870 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001871}
1872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001874"Add an element to a set.\n\
1875\n\
1876This has no effect if the element is already present.");
1877
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001878static int
1879set_contains(PySetObject *so, PyObject *key)
1880{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 PyObject *tmpkey;
1882 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001883
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001885 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1887 return -1;
1888 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001889 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 if (tmpkey == NULL)
1891 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001892 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 Py_DECREF(tmpkey);
1894 }
1895 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001896}
1897
1898static PyObject *
1899set_direct_contains(PySetObject *so, PyObject *key)
1900{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001902
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001903 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001904 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 return NULL;
1906 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001907}
1908
1909PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1910
Raymond Hettingera690a992003-11-16 16:17:49 +00001911static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001912set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001913{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 PyObject *tmpkey;
1915 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001916
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001917 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001918 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1920 return NULL;
1921 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001922 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923 if (tmpkey == NULL)
1924 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001927 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001928 return NULL;
1929 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001932 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001933 return NULL;
1934 }
1935 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001936}
1937
1938PyDoc_STRVAR(remove_doc,
1939"Remove an element from a set; it must be a member.\n\
1940\n\
1941If the element is not a member, raise a KeyError.");
1942
1943static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001944set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001945{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001946 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001949 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001950 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1952 return NULL;
1953 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001954 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 if (tmpkey == NULL)
1956 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001957 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001958 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001959 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001960 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001961 }
1962 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001963}
1964
1965PyDoc_STRVAR(discard_doc,
1966"Remove an element from a set if it is a member.\n\
1967\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001969
1970static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001971set_reduce(PySetObject *so)
1972{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001974 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001975
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001976 keys = PySequence_List((PyObject *)so);
1977 if (keys == NULL)
1978 goto done;
1979 args = PyTuple_Pack(1, keys);
1980 if (args == NULL)
1981 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001982 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001983 if (dict == NULL) {
1984 PyErr_Clear();
1985 dict = Py_None;
1986 Py_INCREF(dict);
1987 }
1988 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001989done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001990 Py_XDECREF(args);
1991 Py_XDECREF(keys);
1992 Py_XDECREF(dict);
1993 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001994}
1995
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001996static PyObject *
1997set_sizeof(PySetObject *so)
1998{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001999 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002000
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02002001 res = _PyObject_SIZE(Py_TYPE(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002002 if (so->table != so->smalltable)
2003 res = res + (so->mask + 1) * sizeof(setentry);
2004 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002005}
2006
2007PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002008static int
2009set_init(PySetObject *self, PyObject *args, PyObject *kwds)
2010{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002011 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002012
Serhiy Storchakafa070292016-04-29 11:31:52 +03002013 if (kwds != NULL && !_PyArg_NoKeywords("set()", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002014 return -1;
2015 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
2016 return -1;
Raymond Hettingerb72e21b2016-03-25 02:29:59 -07002017 if (self->fill)
2018 set_clear_internal(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002019 self->hash = -1;
2020 if (iterable == NULL)
2021 return 0;
2022 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002023}
2024
Raymond Hettingera690a992003-11-16 16:17:49 +00002025static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002026 set_len, /* sq_length */
2027 0, /* sq_concat */
2028 0, /* sq_repeat */
2029 0, /* sq_item */
2030 0, /* sq_slice */
2031 0, /* sq_ass_item */
2032 0, /* sq_ass_slice */
2033 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002034};
2035
2036/* set object ********************************************************/
2037
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002038#ifdef Py_DEBUG
2039static PyObject *test_c_api(PySetObject *so);
2040
2041PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2042All is well if assertions don't fail.");
2043#endif
2044
Raymond Hettingera690a992003-11-16 16:17:49 +00002045static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002046 {"add", (PyCFunction)set_add, METH_O,
2047 add_doc},
2048 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2049 clear_doc},
2050 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2051 contains_doc},
2052 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2053 copy_doc},
2054 {"discard", (PyCFunction)set_discard, METH_O,
2055 discard_doc},
2056 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2057 difference_doc},
2058 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2059 difference_update_doc},
2060 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2061 intersection_doc},
2062 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2063 intersection_update_doc},
2064 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2065 isdisjoint_doc},
2066 {"issubset", (PyCFunction)set_issubset, METH_O,
2067 issubset_doc},
2068 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2069 issuperset_doc},
2070 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2071 pop_doc},
2072 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2073 reduce_doc},
2074 {"remove", (PyCFunction)set_remove, METH_O,
2075 remove_doc},
2076 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2077 sizeof_doc},
2078 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2079 symmetric_difference_doc},
2080 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2081 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002082#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002083 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2084 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002085#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002086 {"union", (PyCFunction)set_union, METH_VARARGS,
2087 union_doc},
2088 {"update", (PyCFunction)set_update, METH_VARARGS,
2089 update_doc},
2090 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002091};
2092
2093static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002094 0, /*nb_add*/
2095 (binaryfunc)set_sub, /*nb_subtract*/
2096 0, /*nb_multiply*/
2097 0, /*nb_remainder*/
2098 0, /*nb_divmod*/
2099 0, /*nb_power*/
2100 0, /*nb_negative*/
2101 0, /*nb_positive*/
2102 0, /*nb_absolute*/
2103 0, /*nb_bool*/
2104 0, /*nb_invert*/
2105 0, /*nb_lshift*/
2106 0, /*nb_rshift*/
2107 (binaryfunc)set_and, /*nb_and*/
2108 (binaryfunc)set_xor, /*nb_xor*/
2109 (binaryfunc)set_or, /*nb_or*/
2110 0, /*nb_int*/
2111 0, /*nb_reserved*/
2112 0, /*nb_float*/
2113 0, /*nb_inplace_add*/
2114 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2115 0, /*nb_inplace_multiply*/
2116 0, /*nb_inplace_remainder*/
2117 0, /*nb_inplace_power*/
2118 0, /*nb_inplace_lshift*/
2119 0, /*nb_inplace_rshift*/
2120 (binaryfunc)set_iand, /*nb_inplace_and*/
2121 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2122 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002123};
2124
2125PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002126"set() -> new empty set object\n\
2127set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002128\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002129Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002130
2131PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002132 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2133 "set", /* tp_name */
2134 sizeof(PySetObject), /* tp_basicsize */
2135 0, /* tp_itemsize */
2136 /* methods */
2137 (destructor)set_dealloc, /* tp_dealloc */
2138 0, /* tp_print */
2139 0, /* tp_getattr */
2140 0, /* tp_setattr */
2141 0, /* tp_reserved */
2142 (reprfunc)set_repr, /* tp_repr */
2143 &set_as_number, /* tp_as_number */
2144 &set_as_sequence, /* tp_as_sequence */
2145 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002146 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002147 0, /* tp_call */
2148 0, /* tp_str */
2149 PyObject_GenericGetAttr, /* tp_getattro */
2150 0, /* tp_setattro */
2151 0, /* tp_as_buffer */
2152 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2153 Py_TPFLAGS_BASETYPE, /* tp_flags */
2154 set_doc, /* tp_doc */
2155 (traverseproc)set_traverse, /* tp_traverse */
2156 (inquiry)set_clear_internal, /* tp_clear */
2157 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002158 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2159 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002160 0, /* tp_iternext */
2161 set_methods, /* tp_methods */
2162 0, /* tp_members */
2163 0, /* tp_getset */
2164 0, /* tp_base */
2165 0, /* tp_dict */
2166 0, /* tp_descr_get */
2167 0, /* tp_descr_set */
2168 0, /* tp_dictoffset */
2169 (initproc)set_init, /* tp_init */
2170 PyType_GenericAlloc, /* tp_alloc */
2171 set_new, /* tp_new */
2172 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002173};
2174
2175/* frozenset object ********************************************************/
2176
2177
2178static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002179 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2180 contains_doc},
2181 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2182 copy_doc},
2183 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2184 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002185 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002186 intersection_doc},
2187 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2188 isdisjoint_doc},
2189 {"issubset", (PyCFunction)set_issubset, METH_O,
2190 issubset_doc},
2191 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2192 issuperset_doc},
2193 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2194 reduce_doc},
2195 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2196 sizeof_doc},
2197 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2198 symmetric_difference_doc},
2199 {"union", (PyCFunction)set_union, METH_VARARGS,
2200 union_doc},
2201 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002202};
2203
2204static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002205 0, /*nb_add*/
2206 (binaryfunc)set_sub, /*nb_subtract*/
2207 0, /*nb_multiply*/
2208 0, /*nb_remainder*/
2209 0, /*nb_divmod*/
2210 0, /*nb_power*/
2211 0, /*nb_negative*/
2212 0, /*nb_positive*/
2213 0, /*nb_absolute*/
2214 0, /*nb_bool*/
2215 0, /*nb_invert*/
2216 0, /*nb_lshift*/
2217 0, /*nb_rshift*/
2218 (binaryfunc)set_and, /*nb_and*/
2219 (binaryfunc)set_xor, /*nb_xor*/
2220 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002221};
2222
2223PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002224"frozenset() -> empty frozenset object\n\
2225frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002226\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002227Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002228
2229PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002230 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2231 "frozenset", /* tp_name */
2232 sizeof(PySetObject), /* tp_basicsize */
2233 0, /* tp_itemsize */
2234 /* methods */
2235 (destructor)set_dealloc, /* tp_dealloc */
2236 0, /* tp_print */
2237 0, /* tp_getattr */
2238 0, /* tp_setattr */
2239 0, /* tp_reserved */
2240 (reprfunc)set_repr, /* tp_repr */
2241 &frozenset_as_number, /* tp_as_number */
2242 &set_as_sequence, /* tp_as_sequence */
2243 0, /* tp_as_mapping */
2244 frozenset_hash, /* tp_hash */
2245 0, /* tp_call */
2246 0, /* tp_str */
2247 PyObject_GenericGetAttr, /* tp_getattro */
2248 0, /* tp_setattro */
2249 0, /* tp_as_buffer */
2250 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2251 Py_TPFLAGS_BASETYPE, /* tp_flags */
2252 frozenset_doc, /* tp_doc */
2253 (traverseproc)set_traverse, /* tp_traverse */
2254 (inquiry)set_clear_internal, /* tp_clear */
2255 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002256 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002257 (getiterfunc)set_iter, /* tp_iter */
2258 0, /* tp_iternext */
2259 frozenset_methods, /* tp_methods */
2260 0, /* tp_members */
2261 0, /* tp_getset */
2262 0, /* tp_base */
2263 0, /* tp_dict */
2264 0, /* tp_descr_get */
2265 0, /* tp_descr_set */
2266 0, /* tp_dictoffset */
2267 0, /* tp_init */
2268 PyType_GenericAlloc, /* tp_alloc */
2269 frozenset_new, /* tp_new */
2270 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002271};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002272
2273
2274/***** C API functions *************************************************/
2275
2276PyObject *
2277PySet_New(PyObject *iterable)
2278{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002279 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002280}
2281
2282PyObject *
2283PyFrozenSet_New(PyObject *iterable)
2284{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002285 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002286}
2287
Neal Norwitz8c49c822006-03-04 18:41:19 +00002288Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002289PySet_Size(PyObject *anyset)
2290{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002291 if (!PyAnySet_Check(anyset)) {
2292 PyErr_BadInternalCall();
2293 return -1;
2294 }
2295 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002296}
2297
2298int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002299PySet_Clear(PyObject *set)
2300{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002301 if (!PySet_Check(set)) {
2302 PyErr_BadInternalCall();
2303 return -1;
2304 }
2305 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002306}
2307
2308int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002309PySet_Contains(PyObject *anyset, PyObject *key)
2310{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002311 if (!PyAnySet_Check(anyset)) {
2312 PyErr_BadInternalCall();
2313 return -1;
2314 }
2315 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002316}
2317
2318int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002319PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002320{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002321 if (!PySet_Check(set)) {
2322 PyErr_BadInternalCall();
2323 return -1;
2324 }
2325 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002326}
2327
2328int
Christian Heimesfd66e512008-01-29 12:18:50 +00002329PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002330{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002331 if (!PySet_Check(anyset) &&
2332 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2333 PyErr_BadInternalCall();
2334 return -1;
2335 }
2336 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002337}
2338
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002339int
Raymond Hettinger3625af52016-03-27 01:15:07 -07002340PySet_ClearFreeList(void)
2341{
2342 return 0;
2343}
2344
2345void
2346PySet_Fini(void)
2347{
2348 Py_CLEAR(emptyfrozenset);
2349}
2350
2351int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002352_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002353{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002354 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002356 if (!PyAnySet_Check(set)) {
2357 PyErr_BadInternalCall();
2358 return -1;
2359 }
2360 if (set_next((PySetObject *)set, pos, &entry) == 0)
2361 return 0;
2362 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002363 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002364 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002365}
2366
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002367PyObject *
2368PySet_Pop(PyObject *set)
2369{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002370 if (!PySet_Check(set)) {
2371 PyErr_BadInternalCall();
2372 return NULL;
2373 }
2374 return set_pop((PySetObject *)set);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002375}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002376
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002377int
2378_PySet_Update(PyObject *set, PyObject *iterable)
2379{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002380 if (!PySet_Check(set)) {
2381 PyErr_BadInternalCall();
2382 return -1;
2383 }
2384 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002385}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002386
Raymond Hettingere259f132013-12-15 11:56:14 -08002387/* Exported for the gdb plugin's benefit. */
2388PyObject *_PySet_Dummy = dummy;
2389
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002390#ifdef Py_DEBUG
2391
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002392/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002393 Returns True and original set is restored. */
2394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002395#define assertRaises(call_return_value, exception) \
2396 do { \
2397 assert(call_return_value); \
2398 assert(PyErr_ExceptionMatches(exception)); \
2399 PyErr_Clear(); \
2400 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002401
2402static PyObject *
2403test_c_api(PySetObject *so)
2404{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405 Py_ssize_t count;
2406 char *s;
2407 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002408 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002409 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002410 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002411 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002413 /* Verify preconditions */
2414 assert(PyAnySet_Check(ob));
2415 assert(PyAnySet_CheckExact(ob));
2416 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002418 /* so.clear(); so |= set("abc"); */
2419 str = PyUnicode_FromString("abc");
2420 if (str == NULL)
2421 return NULL;
2422 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002423 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002424 Py_DECREF(str);
2425 return NULL;
2426 }
2427 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002429 /* Exercise type/size checks */
2430 assert(PySet_Size(ob) == 3);
2431 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002433 /* Raise TypeError for non-iterable constructor arguments */
2434 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2435 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002437 /* Raise TypeError for unhashable key */
2438 dup = PySet_New(ob);
2439 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2440 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2441 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002443 /* Exercise successful pop, contains, add, and discard */
2444 elem = PySet_Pop(ob);
2445 assert(PySet_Contains(ob, elem) == 0);
2446 assert(PySet_GET_SIZE(ob) == 2);
2447 assert(PySet_Add(ob, elem) == 0);
2448 assert(PySet_Contains(ob, elem) == 1);
2449 assert(PySet_GET_SIZE(ob) == 3);
2450 assert(PySet_Discard(ob, elem) == 1);
2451 assert(PySet_GET_SIZE(ob) == 2);
2452 assert(PySet_Discard(ob, elem) == 0);
2453 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002455 /* Exercise clear */
2456 dup2 = PySet_New(dup);
2457 assert(PySet_Clear(dup2) == 0);
2458 assert(PySet_Size(dup2) == 0);
2459 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002461 /* Raise SystemError on clear or update of frozen set */
2462 f = PyFrozenSet_New(dup);
2463 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2464 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2465 assert(PySet_Add(f, elem) == 0);
2466 Py_INCREF(f);
2467 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2468 Py_DECREF(f);
2469 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002471 /* Exercise direct iteration */
2472 i = 0, count = 0;
2473 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
Serhiy Storchaka06515832016-11-20 09:13:07 +02002474 s = PyUnicode_AsUTF8(x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002475 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2476 count++;
2477 }
2478 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002480 /* Exercise updates */
2481 dup2 = PySet_New(NULL);
2482 assert(_PySet_Update(dup2, dup) == 0);
2483 assert(PySet_Size(dup2) == 3);
2484 assert(_PySet_Update(dup2, dup) == 0);
2485 assert(PySet_Size(dup2) == 3);
2486 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002488 /* Raise SystemError when self argument is not a set or frozenset. */
2489 t = PyTuple_New(0);
2490 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2491 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2492 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002494 /* Raise SystemError when self argument is not a set. */
2495 f = PyFrozenSet_New(dup);
2496 assert(PySet_Size(f) == 3);
2497 assert(PyFrozenSet_CheckExact(f));
2498 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2499 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2500 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002502 /* Raise KeyError when popping from an empty set */
2503 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2504 Py_DECREF(ob);
2505 assert(PySet_GET_SIZE(ob) == 0);
2506 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002508 /* Restore the set from the copy using the PyNumber API */
2509 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2510 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002512 /* Verify constructors accept NULL arguments */
2513 f = PySet_New(NULL);
2514 assert(f != NULL);
2515 assert(PySet_GET_SIZE(f) == 0);
2516 Py_DECREF(f);
2517 f = PyFrozenSet_New(NULL);
2518 assert(f != NULL);
2519 assert(PyFrozenSet_CheckExact(f));
2520 assert(PySet_GET_SIZE(f) == 0);
2521 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002523 Py_DECREF(elem);
2524 Py_DECREF(dup);
2525 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002526}
2527
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002528#undef assertRaises
2529
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002530#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002531
2532/***** Dummy Struct *************************************************/
2533
2534static PyObject *
2535dummy_repr(PyObject *op)
2536{
2537 return PyUnicode_FromString("<dummy key>");
2538}
2539
2540static void
2541dummy_dealloc(PyObject* ignore)
2542{
2543 Py_FatalError("deallocating <dummy key>");
2544}
2545
2546static PyTypeObject _PySetDummy_Type = {
2547 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2548 "<dummy key> type",
2549 0,
2550 0,
2551 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2552 0, /*tp_print*/
2553 0, /*tp_getattr*/
2554 0, /*tp_setattr*/
2555 0, /*tp_reserved*/
2556 dummy_repr, /*tp_repr*/
2557 0, /*tp_as_number*/
2558 0, /*tp_as_sequence*/
2559 0, /*tp_as_mapping*/
2560 0, /*tp_hash */
2561 0, /*tp_call */
2562 0, /*tp_str */
2563 0, /*tp_getattro */
2564 0, /*tp_setattro */
2565 0, /*tp_as_buffer */
2566 Py_TPFLAGS_DEFAULT, /*tp_flags */
2567};
2568
2569static PyObject _dummy_struct = {
2570 _PyObject_EXTRA_INIT
2571 2, &_PySetDummy_Type
2572};
2573