blob: 2ccf183e3c79117c8c25bc5bc1265c5cb4eb675b [file] [log] [blame]
Raymond Hettingerc991db22005-08-11 07:58:45 +00001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002/* set object implementation
Raymond Hettingerae7b00e2013-09-07 15:05:00 -07003
Raymond Hettingera9d99362005-08-05 00:01:15 +00004 Written and maintained by Raymond D. Hettinger <python@rcn.com>
5 Derived from Lib/sets.py and Objects/dictobject.c.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00006
Raymond Hettingerae7b00e2013-09-07 15:05:00 -07007 The basic lookup function used by all operations.
8 This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
9
10 The initial probe index is computed as hash mod the table size.
11 Subsequent probe indices are computed as explained in Objects/dictobject.c.
12
13 To improve cache locality, each probe inspects a series of consecutive
14 nearby entries before moving on to probes elsewhere in memory. This leaves
15 us with a hybrid of linear probing and open addressing. The linear probing
16 reduces the cost of hash collisions because consecutive memory accesses
17 tend to be much cheaper than scattered probes. After LINEAR_PROBES steps,
18 we then use open addressing with the upper bits from the hash value. This
19 helps break-up long chains of collisions.
20
21 All arithmetic on hash should ignore overflow.
22
Raymond Hettinger4d45c102015-01-25 16:27:40 -080023 Unlike the dictionary implementation, the lookkey function can return
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070024 NULL if the rich comparison returns an error.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000025*/
26
Raymond Hettingera690a992003-11-16 16:17:49 +000027#include "Python.h"
Raymond Hettingera9d99362005-08-05 00:01:15 +000028#include "structmember.h"
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000029
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000030/* Object used as dummy key to fill deleted entries */
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -050031static PyObject _dummy_struct;
32
33#define dummy (&_dummy_struct)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000034
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000035
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -070036/* ======================================================================== */
37/* ======= Begin logic for probing the hash table ========================= */
38
Raymond Hettinger710a67e2013-09-21 20:17:31 -070039/* Set this to zero to turn-off linear probing */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070040#ifndef LINEAR_PROBES
Raymond Hettinger742d8712013-09-08 00:25:57 -070041#define LINEAR_PROBES 9
Raymond Hettinger8408dc52013-09-15 14:57:15 -070042#endif
Raymond Hettinger742d8712013-09-08 00:25:57 -070043
44/* This must be >= 1 */
45#define PERTURB_SHIFT 5
46
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000047static setentry *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020048set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000049{
Raymond Hettinger70559b52015-07-23 07:42:23 -040050 setentry *table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020051 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070052 size_t perturb;
Raymond Hettingerafe89092013-08-28 20:59:31 -070053 size_t mask = so->mask;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -080054 size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070055 size_t j;
Raymond Hettinger4ef05282013-09-21 15:39:49 -070056 int cmp;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000057
Raymond Hettinger70559b52015-07-23 07:42:23 -040058 entry = &so->table[i];
Raymond Hettingerafe89092013-08-28 20:59:31 -070059 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000060 return entry;
Raymond Hettinger237b34b2013-08-17 02:31:53 -070061
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070062 perturb = hash;
63
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -070064 while (1) {
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080065 if (entry->hash == hash) {
Raymond Hettingerafe89092013-08-28 20:59:31 -070066 PyObject *startkey = entry->key;
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080067 /* startkey cannot be a dummy because the dummy hash field is -1 */
68 assert(startkey != dummy);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -080069 if (startkey == key)
70 return entry;
Raymond Hettinger93035c42015-01-25 16:12:49 -080071 if (PyUnicode_CheckExact(startkey)
72 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -070073 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger93035c42015-01-25 16:12:49 -080074 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -040075 table = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000076 Py_INCREF(startkey);
77 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
78 Py_DECREF(startkey);
Raymond Hettinger426d9952014-05-18 21:40:20 +010079 if (cmp < 0) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000080 return NULL;
Raymond Hettinger426d9952014-05-18 21:40:20 +010081 if (table != so->table || entry->key != startkey) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000082 return set_lookkey(so, key, hash);
Raymond Hettinger426d9952014-05-18 21:40:20 +010083 if (cmp > 0) /* likely */
Raymond Hettingerafe89092013-08-28 20:59:31 -070084 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -060085 mask = so->mask; /* help avoid a register spill */
Raymond Hettingerafe89092013-08-28 20:59:31 -070086 }
Raymond Hettingerafe89092013-08-28 20:59:31 -070087
Raymond Hettingerc658d852015-02-02 08:35:00 -080088 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -080089 for (j = 0 ; j < LINEAR_PROBES ; j++) {
Raymond Hettingerc658d852015-02-02 08:35:00 -080090 entry++;
Raymond Hettinger8651a502015-05-27 10:37:20 -070091 if (entry->hash == 0 && entry->key == NULL)
92 return entry;
Raymond Hettingerc658d852015-02-02 08:35:00 -080093 if (entry->hash == hash) {
94 PyObject *startkey = entry->key;
95 assert(startkey != dummy);
96 if (startkey == key)
97 return entry;
98 if (PyUnicode_CheckExact(startkey)
99 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700100 && _PyUnicode_EQ(startkey, key))
Raymond Hettingerc658d852015-02-02 08:35:00 -0800101 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400102 table = so->table;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800103 Py_INCREF(startkey);
104 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
105 Py_DECREF(startkey);
106 if (cmp < 0)
107 return NULL;
108 if (table != so->table || entry->key != startkey)
109 return set_lookkey(so, key, hash);
110 if (cmp > 0)
111 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -0600112 mask = so->mask;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800113 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700114 }
115 }
116
117 perturb >>= PERTURB_SHIFT;
118 i = (i * 5 + 1 + perturb) & mask;
119
Raymond Hettinger70559b52015-07-23 07:42:23 -0400120 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700121 if (entry->key == NULL)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700122 return entry;
123 }
124}
125
Raymond Hettinger15f08692015-07-03 17:21:17 -0700126static int set_table_resize(PySetObject *, Py_ssize_t);
127
Raymond Hettinger8651a502015-05-27 10:37:20 -0700128static int
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400129set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700130{
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400131 setentry *table;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700132 setentry *freeslot;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700133 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700134 size_t perturb;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400135 size_t mask;
136 size_t i; /* Unsigned for defined overflow behavior */
Raymond Hettinger8651a502015-05-27 10:37:20 -0700137 size_t j;
138 int cmp;
139
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400140 /* Pre-increment is necessary to prevent arbitrary code in the rich
141 comparison from deallocating the key just before the insertion. */
142 Py_INCREF(key);
143
144 restart:
145
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400146 mask = so->mask;
147 i = (size_t)hash & mask;
148
Raymond Hettinger70559b52015-07-23 07:42:23 -0400149 entry = &so->table[i];
Raymond Hettinger8651a502015-05-27 10:37:20 -0700150 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700151 goto found_unused;
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700152
153 freeslot = NULL;
154 perturb = hash;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700155
156 while (1) {
157 if (entry->hash == hash) {
158 PyObject *startkey = entry->key;
159 /* startkey cannot be a dummy because the dummy hash field is -1 */
160 assert(startkey != dummy);
161 if (startkey == key)
162 goto found_active;
163 if (PyUnicode_CheckExact(startkey)
164 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700165 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700166 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400167 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700168 Py_INCREF(startkey);
169 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
170 Py_DECREF(startkey);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700171 if (cmp > 0) /* likely */
172 goto found_active;
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700173 if (cmp < 0)
174 goto comparison_error;
175 /* Continuing the search from the current entry only makes
176 sense if the table and entry are unchanged; otherwise,
177 we have to restart from the beginning */
178 if (table != so->table || entry->key != startkey)
179 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700180 mask = so->mask; /* help avoid a register spill */
181 }
Raymond Hettinger70559b52015-07-23 07:42:23 -0400182 else if (entry->hash == -1 && freeslot == NULL)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700183 freeslot = entry;
184
185 if (i + LINEAR_PROBES <= mask) {
186 for (j = 0 ; j < LINEAR_PROBES ; j++) {
187 entry++;
188 if (entry->hash == 0 && entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700189 goto found_unused_or_dummy;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700190 if (entry->hash == hash) {
191 PyObject *startkey = entry->key;
192 assert(startkey != dummy);
193 if (startkey == key)
194 goto found_active;
195 if (PyUnicode_CheckExact(startkey)
196 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700197 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700198 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400199 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700200 Py_INCREF(startkey);
201 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
202 Py_DECREF(startkey);
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700203 if (cmp > 0)
204 goto found_active;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700205 if (cmp < 0)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400206 goto comparison_error;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700207 if (table != so->table || entry->key != startkey)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400208 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700209 mask = so->mask;
210 }
Raymond Hettinger91672612015-06-26 02:50:21 -0700211 else if (entry->hash == -1 && freeslot == NULL)
Raymond Hettingerc658d852015-02-02 08:35:00 -0800212 freeslot = entry;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700213 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700215
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700216 perturb >>= PERTURB_SHIFT;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -0800217 i = (i * 5 + 1 + perturb) & mask;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700218
Raymond Hettinger70559b52015-07-23 07:42:23 -0400219 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700220 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700221 goto found_unused_or_dummy;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700223
Raymond Hettinger15f08692015-07-03 17:21:17 -0700224 found_unused_or_dummy:
225 if (freeslot == NULL)
226 goto found_unused;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700227 so->used++;
228 freeslot->key = key;
229 freeslot->hash = hash;
230 return 0;
231
232 found_unused:
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700233 so->fill++;
234 so->used++;
235 entry->key = key;
236 entry->hash = hash;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800237 if ((size_t)so->fill*5 < mask*3)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700238 return 0;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400239 return set_table_resize(so, so->used);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700240
241 found_active:
Raymond Hettinger482c05c2015-07-20 01:23:32 -0400242 Py_DECREF(key);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700243 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000244
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400245 comparison_error:
Raymond Hettinger061091a2015-07-15 23:54:02 -0700246 Py_DECREF(key);
247 return -1;
248}
249
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000250/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000251Internal routine used by set_table_resize() to insert an item which is
252known to be absent from the set. This routine also assumes that
253the set contains no deleted entries. Besides the performance benefit,
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800254there is also safety benefit since using set_add_entry() risks making
255a callback in the middle of a set_table_resize(), see issue 1456209.
256The caller is responsible for updating the key's reference count and
257the setobject's fill and used fields.
Thomas Wouters89f507f2006-12-13 04:49:30 +0000258*/
259static void
Raymond Hettinger5088f602015-12-13 18:45:01 -0800260set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000261{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200262 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700263 size_t perturb = hash;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800264 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700265 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000266
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700267 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800268 entry = &table[i];
269 if (entry->key == NULL)
270 goto found_null;
271 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800272 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800273 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800274 if (entry->key == NULL)
275 goto found_null;
276 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700277 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700278 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800279 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700281 found_null:
Raymond Hettinger5088f602015-12-13 18:45:01 -0800282 entry->key = key;
Raymond Hettinger86d322f2015-12-13 19:27:17 -0800283 entry->hash = hash;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000284}
285
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700286/* ======== End logic for probing the hash table ========================== */
287/* ======================================================================== */
288
Thomas Wouters89f507f2006-12-13 04:49:30 +0000289/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000290Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000291keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000292actually be smaller than the old one.
293*/
294static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000296{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 Py_ssize_t newsize;
298 setentry *oldtable, *newtable, *entry;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800299 Py_ssize_t oldmask = so->mask;
300 size_t newmask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301 int is_oldtable_malloced;
302 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 assert(minused >= 0);
Raymond Hettinger48973002015-07-03 20:00:03 -0700305 minused = (minused > 50000) ? minused * 2 : minused * 4;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100308 /* XXX speed-up with intrinsics */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 for (newsize = PySet_MINSIZE;
310 newsize <= minused && newsize > 0;
311 newsize <<= 1)
312 ;
313 if (newsize <= 0) {
314 PyErr_NoMemory();
315 return -1;
316 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 /* Get space for a new table. */
319 oldtable = so->table;
320 assert(oldtable != NULL);
321 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 if (newsize == PySet_MINSIZE) {
324 /* A large table is shrinking, or we can't get any smaller. */
325 newtable = so->smalltable;
326 if (newtable == oldtable) {
327 if (so->fill == so->used) {
328 /* No dummies, so no point doing anything. */
329 return 0;
330 }
331 /* We're not going to resize it, but rebuild the
332 table anyway to purge old dummy entries.
333 Subtle: This is *necessary* if fill==size,
334 as set_lookkey needs at least one virgin slot to
335 terminate failing searches. If fill < size, it's
336 merely desirable, as dummies slow searches. */
337 assert(so->fill > so->used);
338 memcpy(small_copy, oldtable, sizeof(small_copy));
339 oldtable = small_copy;
340 }
341 }
342 else {
343 newtable = PyMem_NEW(setentry, newsize);
344 if (newtable == NULL) {
345 PyErr_NoMemory();
346 return -1;
347 }
348 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 /* Make the set empty, using the new table. */
351 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 memset(newtable, 0, sizeof(setentry) * newsize);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800353 so->mask = newsize - 1;
354 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000356 /* Copy the data over; this is refcount-neutral for active entries;
357 dummy entries aren't copied over, of course */
Raymond Hettinger5088f602015-12-13 18:45:01 -0800358 newmask = (size_t)so->mask;
Raymond Hettingere1af6962017-02-02 08:24:48 -0800359 if (so->fill == so->used) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800360 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800361 if (entry->key != NULL) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800362 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800363 }
364 }
365 } else {
Raymond Hettingere1af6962017-02-02 08:24:48 -0800366 so->fill = so->used;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800367 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800368 if (entry->key != NULL && entry->key != dummy) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800369 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800370 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000371 }
372 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 if (is_oldtable_malloced)
375 PyMem_DEL(oldtable);
376 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000377}
378
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000379static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700380set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000381{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700382 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000383
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700384 entry = set_lookkey(so, key, hash);
385 if (entry != NULL)
386 return entry->key != NULL;
387 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000388}
389
390#define DISCARD_NOTFOUND 0
391#define DISCARD_FOUND 1
392
393static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700394set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800395{
396 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000398
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700399 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 if (entry == NULL)
401 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700402 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 return DISCARD_NOTFOUND;
404 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800406 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 so->used--;
408 Py_DECREF(old_key);
409 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000410}
411
412static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700413set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000414{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200415 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000416
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700417 if (!PyUnicode_CheckExact(key) ||
418 (hash = ((PyASCIIObject *) key)->hash) == -1) {
419 hash = PyObject_Hash(key);
420 if (hash == -1)
421 return -1;
422 }
423 return set_add_entry(so, key, hash);
424}
425
426static int
427set_contains_key(PySetObject *so, PyObject *key)
428{
429 Py_hash_t hash;
430
431 if (!PyUnicode_CheckExact(key) ||
432 (hash = ((PyASCIIObject *) key)->hash) == -1) {
433 hash = PyObject_Hash(key);
434 if (hash == -1)
435 return -1;
436 }
437 return set_contains_entry(so, key, hash);
438}
439
440static int
441set_discard_key(PySetObject *so, PyObject *key)
442{
443 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000444
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000445 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200446 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 hash = PyObject_Hash(key);
448 if (hash == -1)
449 return -1;
450 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700451 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000452}
453
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700454static void
455set_empty_to_minsize(PySetObject *so)
456{
457 memset(so->smalltable, 0, sizeof(so->smalltable));
458 so->fill = 0;
459 so->used = 0;
460 so->mask = PySet_MINSIZE - 1;
461 so->table = so->smalltable;
462 so->hash = -1;
463}
464
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000465static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000466set_clear_internal(PySetObject *so)
467{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800468 setentry *entry;
469 setentry *table = so->table;
470 Py_ssize_t fill = so->fill;
471 Py_ssize_t used = so->used;
472 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000474
Raymond Hettinger583cd032013-09-07 22:06:35 -0700475 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 /* This is delicate. During the process of clearing the set,
479 * decrefs can cause the set to mutate. To avoid fatal confusion
480 * (voice of experience), we have to make the set empty before
481 * clearing the slots, and never refer to anything via so->ref while
482 * clearing.
483 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700485 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487 else if (fill > 0) {
488 /* It's a small table with something that needs to be cleared.
489 * Afraid the only safe way is to copy the set entries into
490 * another small table first.
491 */
492 memcpy(small_copy, table, sizeof(small_copy));
493 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700494 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 }
496 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 /* Now we can finally clear things. If C had refcounts, we could
499 * assert that the refcount on table is 1 now, i.e. that this function
500 * has unique access to it, so decref side-effects can't alter it.
501 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800502 for (entry = table; used > 0; entry++) {
503 if (entry->key && entry->key != dummy) {
504 used--;
505 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 if (table_is_malloced)
510 PyMem_DEL(table);
511 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000512}
513
514/*
515 * Iterate over a set table. Use like so:
516 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000517 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000518 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000519 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000520 * while (set_next(yourset, &pos, &entry)) {
521 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000522 * }
523 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000524 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000525 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000526 */
527static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000528set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000529{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000530 Py_ssize_t i;
531 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700532 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 assert (PyAnySet_Check(so));
535 i = *pos_ptr;
536 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700538 entry = &so->table[i];
539 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700541 entry++;
542 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 *pos_ptr = i+1;
544 if (i > mask)
545 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700546 assert(entry != NULL);
547 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000549}
550
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000551static void
552set_dealloc(PySetObject *so)
553{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200554 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800555 Py_ssize_t used = so->used;
556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 PyObject_GC_UnTrack(so);
558 Py_TRASHCAN_SAFE_BEGIN(so)
559 if (so->weakreflist != NULL)
560 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000561
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800562 for (entry = so->table; used > 0; entry++) {
563 if (entry->key && entry->key != dummy) {
564 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700565 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 }
567 }
568 if (so->table != so->smalltable)
569 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700570 Py_TYPE(so)->tp_free(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000571 Py_TRASHCAN_SAFE_END(so)
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000572}
573
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000574static PyObject *
575set_repr(PySetObject *so)
576{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200577 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000580 if (status != 0) {
581 if (status < 0)
582 return NULL;
583 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
584 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 /* shortcut for the empty set */
587 if (!so->used) {
588 Py_ReprLeave((PyObject*)so);
589 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
590 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000591
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000592 keys = PySequence_List((PyObject *)so);
593 if (keys == NULL)
594 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000595
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200596 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000597 listrepr = PyObject_Repr(keys);
598 Py_DECREF(keys);
599 if (listrepr == NULL)
600 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200601 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200603 if (tmp == NULL)
604 goto done;
605 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200606
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200607 if (Py_TYPE(so) != &PySet_Type)
608 result = PyUnicode_FromFormat("%s({%U})",
609 Py_TYPE(so)->tp_name,
610 listrepr);
611 else
612 result = PyUnicode_FromFormat("{%U}", listrepr);
613 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000614done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 Py_ReprLeave((PyObject*)so);
616 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000617}
618
Martin v. Löwis18e16552006-02-15 17:27:45 +0000619static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000620set_len(PyObject *so)
621{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000623}
624
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000625static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000626set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000627{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000629 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200630 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700631 setentry *so_entry;
632 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000633
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 assert (PyAnySet_Check(so));
635 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 other = (PySetObject*)otherset;
638 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700639 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 return 0;
641 /* Do one big resize at the start, rather than
642 * incrementally resizing as we insert new keys. Expect
643 * that there will be no (or few) overlapping keys.
644 */
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800645 if ((so->fill + other->used)*5 >= so->mask*3) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700646 if (set_table_resize(so, so->used + other->used) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000647 return -1;
648 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700649 so_entry = so->table;
650 other_entry = other->table;
651
652 /* If our table is empty, and both tables have the same size, and
653 there are no dummies to eliminate, then just copy the pointers. */
654 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
655 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
656 key = other_entry->key;
657 if (key != NULL) {
658 assert(so_entry->key == NULL);
659 Py_INCREF(key);
660 so_entry->key = key;
661 so_entry->hash = other_entry->hash;
662 }
663 }
664 so->fill = other->fill;
665 so->used = other->used;
666 return 0;
667 }
668
669 /* If our table is empty, we can use set_insert_clean() */
670 if (so->fill == 0) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800671 setentry *newtable = so->table;
672 size_t newmask = (size_t)so->mask;
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800673 so->fill = other->used;
674 so->used = other->used;
Raymond Hettingere4495872015-12-15 00:42:30 -0800675 for (i = other->mask + 1; i > 0 ; i--, other_entry++) {
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700676 key = other_entry->key;
677 if (key != NULL && key != dummy) {
678 Py_INCREF(key);
Raymond Hettinger5088f602015-12-13 18:45:01 -0800679 set_insert_clean(newtable, newmask, key, other_entry->hash);
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700680 }
681 }
682 return 0;
683 }
684
685 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700686 for (i = 0; i <= other->mask; i++) {
687 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700688 key = other_entry->key;
689 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700690 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000691 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000692 }
693 }
694 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000695}
696
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000697static PyObject *
698set_pop(PySetObject *so)
699{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800700 /* Make sure the search finger is in bounds */
701 Py_ssize_t i = so->finger & so->mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200702 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000703 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000704
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000705 assert (PyAnySet_Check(so));
706 if (so->used == 0) {
707 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
708 return NULL;
709 }
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000710
Raymond Hettinger1202a472015-01-18 13:12:42 -0800711 while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
712 i++;
Raymond Hettingered741d42015-01-18 21:25:15 -0800713 if (i > so->mask)
714 i = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000715 }
716 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800718 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 so->used--;
Raymond Hettinger1202a472015-01-18 13:12:42 -0800720 so->finger = i + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000722}
723
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000724PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
725Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000726
727static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000728set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000729{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 Py_ssize_t pos = 0;
731 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000732
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000733 while (set_next(so, &pos, &entry))
734 Py_VISIT(entry->key);
735 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000736}
737
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700738/* Work to increase the bit dispersion for closely spaced hash values.
739 This is important because some use cases have many combinations of a
740 small number of elements with nearby hashes so that many distinct
741 combinations collapse to only a handful of distinct hash values. */
742
743static Py_uhash_t
744_shuffle_bits(Py_uhash_t h)
745{
746 return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
747}
748
749/* Most of the constants in this hash algorithm are randomly chosen
750 large primes with "interesting bit patterns" and that passed tests
751 for good collision statistics on a variety of problematic datasets
752 including powersets and graph structures (such as David Eppstein's
753 graph recipes in Lib/test/test_set.py) */
754
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000755static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000756frozenset_hash(PyObject *self)
757{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758 PySetObject *so = (PySetObject *)self;
Raymond Hettinger41481952015-08-07 00:43:39 -0700759 Py_uhash_t hash = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000760 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000761
Raymond Hettingerb501a272015-08-06 22:15:22 -0700762 if (so->hash != -1)
763 return so->hash;
764
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700765 /* Xor-in shuffled bits from every entry's hash field because xor is
766 commutative and a frozenset hash should be independent of order.
767
768 For speed, include null entries and dummy entries and then
769 subtract out their effect afterwards so that the final hash
770 depends only on active entries. This allows the code to be
771 vectorized by the compiler and it saves the unpredictable
772 branches that would arise when trying to exclude null and dummy
773 entries on every iteration. */
774
775 for (entry = so->table; entry <= &so->table[so->mask]; entry++)
776 hash ^= _shuffle_bits(entry->hash);
777
Raymond Hettingera286a512015-08-01 11:07:11 -0700778 /* Remove the effect of an odd number of NULL entries */
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700779 if ((so->mask + 1 - so->fill) & 1)
780 hash ^= _shuffle_bits(0);
781
782 /* Remove the effect of an odd number of dummy entries */
783 if ((so->fill - so->used) & 1)
784 hash ^= _shuffle_bits(-1);
785
Raymond Hettinger41481952015-08-07 00:43:39 -0700786 /* Factor in the number of active entries */
787 hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;
788
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700789 /* Disperse patterns arising in nested frozensets */
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800790 hash = hash * 69069U + 907133923UL;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700791
Raymond Hettinger36c05002015-08-01 10:57:42 -0700792 /* -1 is reserved as an error code */
Victor Stinner12174a52014-08-15 23:17:38 +0200793 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800794 hash = 590923713UL;
Raymond Hettinger36c05002015-08-01 10:57:42 -0700795
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000796 so->hash = hash;
797 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000798}
799
Raymond Hettingera9d99362005-08-05 00:01:15 +0000800/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000801
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000802typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000803 PyObject_HEAD
804 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
805 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700806 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000807 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000808} setiterobject;
809
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000810static void
811setiter_dealloc(setiterobject *si)
812{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000813 Py_XDECREF(si->si_set);
814 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000815}
816
817static int
818setiter_traverse(setiterobject *si, visitproc visit, void *arg)
819{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000820 Py_VISIT(si->si_set);
821 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000822}
823
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000824static PyObject *
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000825setiter_len(setiterobject *si)
826{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000827 Py_ssize_t len = 0;
828 if (si->si_set != NULL && si->si_used == si->si_set->used)
829 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000830 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000831}
832
Armin Rigof5b3e362006-02-11 21:32:43 +0000833PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000834
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000835static PyObject *setiter_iternext(setiterobject *si);
836
837static PyObject *
838setiter_reduce(setiterobject *si)
839{
840 PyObject *list;
841 setiterobject tmp;
842
843 list = PyList_New(0);
844 if (!list)
845 return NULL;
846
Ezio Melotti0e1af282012-09-28 16:43:40 +0300847 /* copy the iterator state */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000848 tmp = *si;
849 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300850
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000851 /* iterate the temporary into a list */
852 for(;;) {
853 PyObject *element = setiter_iternext(&tmp);
854 if (element) {
855 if (PyList_Append(list, element)) {
856 Py_DECREF(element);
857 Py_DECREF(list);
858 Py_XDECREF(tmp.si_set);
859 return NULL;
860 }
861 Py_DECREF(element);
862 } else
863 break;
864 }
865 Py_XDECREF(tmp.si_set);
866 /* check for error */
867 if (tmp.si_set != NULL) {
868 /* we have an error */
869 Py_DECREF(list);
870 return NULL;
871 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200872 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000873}
874
875PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
876
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000877static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000878 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000879 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000880 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000881};
882
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000883static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000884{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700885 PyObject *key;
886 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200887 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000888 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000890 if (so == NULL)
891 return NULL;
892 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000894 if (si->si_used != so->used) {
895 PyErr_SetString(PyExc_RuntimeError,
896 "Set changed size during iteration");
897 si->si_used = -1; /* Make this state sticky */
898 return NULL;
899 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700900
901 i = si->si_pos;
902 assert(i>=0);
903 entry = so->table;
904 mask = so->mask;
905 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
906 i++;
907 si->si_pos = i+1;
908 if (i > mask)
909 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000910 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700911 key = entry[i].key;
912 Py_INCREF(key);
913 return key;
914
915fail:
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700916 si->si_set = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +0300917 Py_DECREF(so);
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700918 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000919}
920
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000921PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000922 PyVarObject_HEAD_INIT(&PyType_Type, 0)
923 "set_iterator", /* tp_name */
924 sizeof(setiterobject), /* tp_basicsize */
925 0, /* tp_itemsize */
926 /* methods */
927 (destructor)setiter_dealloc, /* tp_dealloc */
928 0, /* tp_print */
929 0, /* tp_getattr */
930 0, /* tp_setattr */
931 0, /* tp_reserved */
932 0, /* tp_repr */
933 0, /* tp_as_number */
934 0, /* tp_as_sequence */
935 0, /* tp_as_mapping */
936 0, /* tp_hash */
937 0, /* tp_call */
938 0, /* tp_str */
939 PyObject_GenericGetAttr, /* tp_getattro */
940 0, /* tp_setattro */
941 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700942 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000943 0, /* tp_doc */
944 (traverseproc)setiter_traverse, /* tp_traverse */
945 0, /* tp_clear */
946 0, /* tp_richcompare */
947 0, /* tp_weaklistoffset */
948 PyObject_SelfIter, /* tp_iter */
949 (iternextfunc)setiter_iternext, /* tp_iternext */
950 setiter_methods, /* tp_methods */
951 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000952};
953
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000954static PyObject *
955set_iter(PySetObject *so)
956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
958 if (si == NULL)
959 return NULL;
960 Py_INCREF(so);
961 si->si_set = so;
962 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700963 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000964 si->len = so->used;
965 _PyObject_GC_TRACK(si);
966 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000967}
968
Raymond Hettingerd7946662005-08-01 21:39:29 +0000969static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000970set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000971{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000972 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000973
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 if (PyAnySet_Check(other))
975 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000976
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 if (PyDict_CheckExact(other)) {
978 PyObject *value;
979 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000980 Py_hash_t hash;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200981 Py_ssize_t dictsize = PyDict_GET_SIZE(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 /* Do one big resize at the start, rather than
984 * incrementally resizing as we insert new keys. Expect
985 * that there will be no (or few) overlapping keys.
986 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700987 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 return -1;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800989 if ((so->fill + dictsize)*5 >= so->mask*3) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700990 if (set_table_resize(so, so->used + dictsize) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000991 return -1;
992 }
993 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700994 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000995 return -1;
996 }
997 return 0;
998 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000999
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001000 it = PyObject_GetIter(other);
1001 if (it == NULL)
1002 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +00001003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001005 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 Py_DECREF(it);
1007 Py_DECREF(key);
1008 return -1;
1009 }
1010 Py_DECREF(key);
1011 }
1012 Py_DECREF(it);
1013 if (PyErr_Occurred())
1014 return -1;
1015 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001016}
1017
1018static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001019set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001020{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001021 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001022
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1024 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001025 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001026 return NULL;
1027 }
1028 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001029}
1030
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001031PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001032"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001033
Raymond Hettinger426d9952014-05-18 21:40:20 +01001034/* XXX Todo:
1035 If aligned memory allocations become available, make the
1036 set object 64 byte aligned so that most of the fields
1037 can be retrieved or updated in a single cache line.
1038*/
1039
Raymond Hettingera38123e2003-11-24 22:18:49 +00001040static PyObject *
1041make_new_set(PyTypeObject *type, PyObject *iterable)
1042{
Raymond Hettinger8421d712016-04-29 01:37:05 -07001043 PySetObject *so;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001044
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001045 so = (PySetObject *)type->tp_alloc(type, 0);
1046 if (so == NULL)
1047 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001048
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001049 so->fill = 0;
1050 so->used = 0;
1051 so->mask = PySet_MINSIZE - 1;
1052 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001053 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001054 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001056
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001057 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001058 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 Py_DECREF(so);
1060 return NULL;
1061 }
1062 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001064 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001065}
1066
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001067static PyObject *
1068make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1069{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1071 if (PyType_IsSubtype(type, &PySet_Type))
1072 type = &PySet_Type;
1073 else
1074 type = &PyFrozenSet_Type;
1075 }
1076 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001077}
1078
Raymond Hettingerd7946662005-08-01 21:39:29 +00001079/* The empty frozenset is a singleton */
1080static PyObject *emptyfrozenset = NULL;
1081
Raymond Hettingera690a992003-11-16 16:17:49 +00001082static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001083frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001085 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001086
Serhiy Storchaka68a001d2017-02-06 10:41:46 +02001087 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset()", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001088 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001089
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001090 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1091 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001093 if (type != &PyFrozenSet_Type)
1094 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 if (iterable != NULL) {
1097 /* frozenset(f) is idempotent */
1098 if (PyFrozenSet_CheckExact(iterable)) {
1099 Py_INCREF(iterable);
1100 return iterable;
1101 }
1102 result = make_new_set(type, iterable);
1103 if (result == NULL || PySet_GET_SIZE(result))
1104 return result;
1105 Py_DECREF(result);
1106 }
1107 /* The empty frozenset is a singleton */
1108 if (emptyfrozenset == NULL)
1109 emptyfrozenset = make_new_set(type, NULL);
1110 Py_XINCREF(emptyfrozenset);
1111 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001112}
1113
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001114static PyObject *
1115set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1116{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001117 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001118}
1119
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001120/* set_swap_bodies() switches the contents of any two sets by moving their
1121 internal data pointers and, if needed, copying the internal smalltables.
1122 Semantically equivalent to:
1123
1124 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1125
1126 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001127 Useful for operations that update in-place (by allowing an intermediate
1128 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001129*/
1130
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001131static void
1132set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001133{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001134 Py_ssize_t t;
1135 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001137 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001139 t = a->fill; a->fill = b->fill; b->fill = t;
1140 t = a->used; a->used = b->used; b->used = t;
1141 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001143 u = a->table;
1144 if (a->table == a->smalltable)
1145 u = b->smalltable;
1146 a->table = b->table;
1147 if (b->table == b->smalltable)
1148 a->table = a->smalltable;
1149 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 if (a->table == a->smalltable || b->table == b->smalltable) {
1152 memcpy(tab, a->smalltable, sizeof(tab));
1153 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1154 memcpy(b->smalltable, tab, sizeof(tab));
1155 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001157 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1158 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1159 h = a->hash; a->hash = b->hash; b->hash = h;
1160 } else {
1161 a->hash = -1;
1162 b->hash = -1;
1163 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001164}
1165
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001166static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001167set_copy(PySetObject *so)
1168{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001169 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001170}
1171
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001172static PyObject *
1173frozenset_copy(PySetObject *so)
1174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 if (PyFrozenSet_CheckExact(so)) {
1176 Py_INCREF(so);
1177 return (PyObject *)so;
1178 }
1179 return set_copy(so);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001180}
1181
Raymond Hettingera690a992003-11-16 16:17:49 +00001182PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1183
1184static PyObject *
Raymond Hettingerc991db22005-08-11 07:58:45 +00001185set_clear(PySetObject *so)
1186{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 set_clear_internal(so);
1188 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001189}
1190
1191PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1192
1193static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001194set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001195{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001196 PySetObject *result;
1197 PyObject *other;
1198 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 result = (PySetObject *)set_copy(so);
1201 if (result == NULL)
1202 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001204 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1205 other = PyTuple_GET_ITEM(args, i);
1206 if ((PyObject *)so == other)
1207 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001208 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 Py_DECREF(result);
1210 return NULL;
1211 }
1212 }
1213 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001214}
1215
1216PyDoc_STRVAR(union_doc,
1217 "Return the union of sets as a new set.\n\
1218\n\
1219(i.e. all elements that are in either set.)");
1220
1221static PyObject *
1222set_or(PySetObject *so, PyObject *other)
1223{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001224 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001225
Brian Curtindfc80e32011-08-10 20:28:54 -05001226 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1227 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001229 result = (PySetObject *)set_copy(so);
1230 if (result == NULL)
1231 return NULL;
1232 if ((PyObject *)so == other)
1233 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001234 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 Py_DECREF(result);
1236 return NULL;
1237 }
1238 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001239}
1240
Raymond Hettingera690a992003-11-16 16:17:49 +00001241static PyObject *
1242set_ior(PySetObject *so, PyObject *other)
1243{
Brian Curtindfc80e32011-08-10 20:28:54 -05001244 if (!PyAnySet_Check(other))
1245 Py_RETURN_NOTIMPLEMENTED;
1246
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001247 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 return NULL;
1249 Py_INCREF(so);
1250 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001251}
1252
1253static PyObject *
1254set_intersection(PySetObject *so, PyObject *other)
1255{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 PySetObject *result;
1257 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001258 Py_hash_t hash;
1259 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 if ((PyObject *)so == other)
1262 return set_copy(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1265 if (result == NULL)
1266 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 if (PyAnySet_Check(other)) {
1269 Py_ssize_t pos = 0;
1270 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001272 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1273 tmp = (PyObject *)so;
1274 so = (PySetObject *)other;
1275 other = tmp;
1276 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001278 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001279 key = entry->key;
1280 hash = entry->hash;
1281 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001282 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 Py_DECREF(result);
1284 return NULL;
1285 }
1286 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001287 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 Py_DECREF(result);
1289 return NULL;
1290 }
1291 }
1292 }
1293 return (PyObject *)result;
1294 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 it = PyObject_GetIter(other);
1297 if (it == NULL) {
1298 Py_DECREF(result);
1299 return NULL;
1300 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001303 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001304 if (hash == -1)
1305 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001306 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001307 if (rv < 0)
1308 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001309 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001310 if (set_add_entry(result, key, hash))
1311 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 }
1313 Py_DECREF(key);
1314 }
1315 Py_DECREF(it);
1316 if (PyErr_Occurred()) {
1317 Py_DECREF(result);
1318 return NULL;
1319 }
1320 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001321 error:
1322 Py_DECREF(it);
1323 Py_DECREF(result);
1324 Py_DECREF(key);
1325 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001326}
1327
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001328static PyObject *
1329set_intersection_multi(PySetObject *so, PyObject *args)
1330{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001331 Py_ssize_t i;
1332 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001333
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001334 if (PyTuple_GET_SIZE(args) == 0)
1335 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 Py_INCREF(so);
1338 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1339 PyObject *other = PyTuple_GET_ITEM(args, i);
1340 PyObject *newresult = set_intersection((PySetObject *)result, other);
1341 if (newresult == NULL) {
1342 Py_DECREF(result);
1343 return NULL;
1344 }
1345 Py_DECREF(result);
1346 result = newresult;
1347 }
1348 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001349}
1350
Raymond Hettingera690a992003-11-16 16:17:49 +00001351PyDoc_STRVAR(intersection_doc,
1352"Return the intersection of two sets as a new set.\n\
1353\n\
1354(i.e. all elements that are in both sets.)");
1355
1356static PyObject *
1357set_intersection_update(PySetObject *so, PyObject *other)
1358{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001359 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001361 tmp = set_intersection(so, other);
1362 if (tmp == NULL)
1363 return NULL;
1364 set_swap_bodies(so, (PySetObject *)tmp);
1365 Py_DECREF(tmp);
1366 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001367}
1368
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001369static PyObject *
1370set_intersection_update_multi(PySetObject *so, PyObject *args)
1371{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 tmp = set_intersection_multi(so, args);
1375 if (tmp == NULL)
1376 return NULL;
1377 set_swap_bodies(so, (PySetObject *)tmp);
1378 Py_DECREF(tmp);
1379 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001380}
1381
Raymond Hettingera690a992003-11-16 16:17:49 +00001382PyDoc_STRVAR(intersection_update_doc,
1383"Update a set with the intersection of itself and another.");
1384
1385static PyObject *
1386set_and(PySetObject *so, PyObject *other)
1387{
Brian Curtindfc80e32011-08-10 20:28:54 -05001388 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1389 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001391}
1392
1393static PyObject *
1394set_iand(PySetObject *so, PyObject *other)
1395{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001397
Brian Curtindfc80e32011-08-10 20:28:54 -05001398 if (!PyAnySet_Check(other))
1399 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001400 result = set_intersection_update(so, other);
1401 if (result == NULL)
1402 return NULL;
1403 Py_DECREF(result);
1404 Py_INCREF(so);
1405 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001406}
1407
Guido van Rossum58da9312007-11-10 23:39:45 +00001408static PyObject *
1409set_isdisjoint(PySetObject *so, PyObject *other)
1410{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001412 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414 if ((PyObject *)so == other) {
1415 if (PySet_GET_SIZE(so) == 0)
1416 Py_RETURN_TRUE;
1417 else
1418 Py_RETURN_FALSE;
1419 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 if (PyAnySet_CheckExact(other)) {
1422 Py_ssize_t pos = 0;
1423 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1426 tmp = (PyObject *)so;
1427 so = (PySetObject *)other;
1428 other = tmp;
1429 }
1430 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001431 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001432 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 return NULL;
1434 if (rv)
1435 Py_RETURN_FALSE;
1436 }
1437 Py_RETURN_TRUE;
1438 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 it = PyObject_GetIter(other);
1441 if (it == NULL)
1442 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001443
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001444 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001445 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 if (hash == -1) {
1448 Py_DECREF(key);
1449 Py_DECREF(it);
1450 return NULL;
1451 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001452 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001453 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001454 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 Py_DECREF(it);
1456 return NULL;
1457 }
1458 if (rv) {
1459 Py_DECREF(it);
1460 Py_RETURN_FALSE;
1461 }
1462 }
1463 Py_DECREF(it);
1464 if (PyErr_Occurred())
1465 return NULL;
1466 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001467}
1468
1469PyDoc_STRVAR(isdisjoint_doc,
1470"Return True if two sets have a null intersection.");
1471
Neal Norwitz6576bd82005-11-13 18:41:28 +00001472static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001473set_difference_update_internal(PySetObject *so, PyObject *other)
1474{
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001475 if (PySet_GET_SIZE(so) == 0) {
1476 return 0;
1477 }
1478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001479 if ((PyObject *)so == other)
1480 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001482 if (PyAnySet_Check(other)) {
1483 setentry *entry;
1484 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001486 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001487 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 return -1;
1489 } else {
1490 PyObject *key, *it;
1491 it = PyObject_GetIter(other);
1492 if (it == NULL)
1493 return -1;
1494
1495 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001496 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001497 Py_DECREF(it);
1498 Py_DECREF(key);
1499 return -1;
1500 }
1501 Py_DECREF(key);
1502 }
1503 Py_DECREF(it);
1504 if (PyErr_Occurred())
1505 return -1;
1506 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001507 /* If more than 1/4th are dummies, then resize them away. */
1508 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 return 0;
Raymond Hettinger48973002015-07-03 20:00:03 -07001510 return set_table_resize(so, so->used);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001511}
1512
Raymond Hettingera690a992003-11-16 16:17:49 +00001513static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001514set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001515{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001517
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1519 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001520 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 return NULL;
1522 }
1523 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001524}
1525
1526PyDoc_STRVAR(difference_update_doc,
1527"Remove all elements of another set from this set.");
1528
1529static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001530set_copy_and_difference(PySetObject *so, PyObject *other)
1531{
1532 PyObject *result;
1533
1534 result = set_copy(so);
1535 if (result == NULL)
1536 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001537 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001538 return result;
1539 Py_DECREF(result);
1540 return NULL;
1541}
1542
1543static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001544set_difference(PySetObject *so, PyObject *other)
1545{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001547 PyObject *key;
1548 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 setentry *entry;
1550 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001551 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001552
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001553 if (PySet_GET_SIZE(so) == 0) {
1554 return set_copy(so);
1555 }
1556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001557 if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001558 return set_copy_and_difference(so, other);
1559 }
1560
1561 /* If len(so) much more than len(other), it's more efficient to simply copy
1562 * so and then iterate other looking for common elements. */
1563 if ((PySet_GET_SIZE(so) >> 2) > PyObject_Size(other)) {
1564 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001565 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001566
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001567 result = make_new_set_basetype(Py_TYPE(so), NULL);
1568 if (result == NULL)
1569 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001571 if (PyDict_CheckExact(other)) {
1572 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001573 key = entry->key;
1574 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001575 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001576 if (rv < 0) {
1577 Py_DECREF(result);
1578 return NULL;
1579 }
1580 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001581 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 Py_DECREF(result);
1583 return NULL;
1584 }
1585 }
1586 }
1587 return result;
1588 }
1589
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001590 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001592 key = entry->key;
1593 hash = entry->hash;
1594 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001595 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001596 Py_DECREF(result);
1597 return NULL;
1598 }
1599 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001600 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 Py_DECREF(result);
1602 return NULL;
1603 }
1604 }
1605 }
1606 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001607}
1608
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001609static PyObject *
1610set_difference_multi(PySetObject *so, PyObject *args)
1611{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001612 Py_ssize_t i;
1613 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001614
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 if (PyTuple_GET_SIZE(args) == 0)
1616 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001617
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001618 other = PyTuple_GET_ITEM(args, 0);
1619 result = set_difference(so, other);
1620 if (result == NULL)
1621 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1624 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001625 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 Py_DECREF(result);
1627 return NULL;
1628 }
1629 }
1630 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001631}
1632
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001633PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001634"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001635\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001636(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001637static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001638set_sub(PySetObject *so, PyObject *other)
1639{
Brian Curtindfc80e32011-08-10 20:28:54 -05001640 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1641 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001643}
1644
1645static PyObject *
1646set_isub(PySetObject *so, PyObject *other)
1647{
Brian Curtindfc80e32011-08-10 20:28:54 -05001648 if (!PyAnySet_Check(other))
1649 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001650 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 return NULL;
1652 Py_INCREF(so);
1653 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001654}
1655
1656static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001657set_symmetric_difference_update(PySetObject *so, PyObject *other)
1658{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001659 PySetObject *otherset;
1660 PyObject *key;
1661 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001662 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001663 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001664 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001666 if ((PyObject *)so == other)
1667 return set_clear(so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001668
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001669 if (PyDict_CheckExact(other)) {
1670 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001671 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001672 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001673 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001674 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001675 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001676 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001677 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001678 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001679 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001680 Py_DECREF(key);
1681 return NULL;
1682 }
1683 }
Georg Brandl2d444492010-09-03 10:52:55 +00001684 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001685 }
1686 Py_RETURN_NONE;
1687 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001688
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001689 if (PyAnySet_Check(other)) {
1690 Py_INCREF(other);
1691 otherset = (PySetObject *)other;
1692 } else {
1693 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1694 if (otherset == NULL)
1695 return NULL;
1696 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001697
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001698 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001699 key = entry->key;
1700 hash = entry->hash;
1701 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001702 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001703 Py_DECREF(otherset);
1704 return NULL;
1705 }
1706 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001707 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001708 Py_DECREF(otherset);
1709 return NULL;
1710 }
1711 }
1712 }
1713 Py_DECREF(otherset);
1714 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001715}
1716
1717PyDoc_STRVAR(symmetric_difference_update_doc,
1718"Update a set with the symmetric difference of itself and another.");
1719
1720static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001721set_symmetric_difference(PySetObject *so, PyObject *other)
1722{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001723 PyObject *rv;
1724 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001725
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001726 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1727 if (otherset == NULL)
1728 return NULL;
1729 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
1730 if (rv == NULL)
1731 return NULL;
1732 Py_DECREF(rv);
1733 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001734}
1735
1736PyDoc_STRVAR(symmetric_difference_doc,
1737"Return the symmetric difference of two sets as a new set.\n\
1738\n\
1739(i.e. all elements that are in exactly one of the sets.)");
1740
1741static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001742set_xor(PySetObject *so, PyObject *other)
1743{
Brian Curtindfc80e32011-08-10 20:28:54 -05001744 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1745 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001746 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001747}
1748
1749static PyObject *
1750set_ixor(PySetObject *so, PyObject *other)
1751{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001752 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001753
Brian Curtindfc80e32011-08-10 20:28:54 -05001754 if (!PyAnySet_Check(other))
1755 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001756 result = set_symmetric_difference_update(so, other);
1757 if (result == NULL)
1758 return NULL;
1759 Py_DECREF(result);
1760 Py_INCREF(so);
1761 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001762}
1763
1764static PyObject *
1765set_issubset(PySetObject *so, PyObject *other)
1766{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001767 setentry *entry;
1768 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001769 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001770
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001771 if (!PyAnySet_Check(other)) {
1772 PyObject *tmp, *result;
1773 tmp = make_new_set(&PySet_Type, other);
1774 if (tmp == NULL)
1775 return NULL;
1776 result = set_issubset(so, tmp);
1777 Py_DECREF(tmp);
1778 return result;
1779 }
1780 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1781 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001782
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001783 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001784 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001785 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 return NULL;
1787 if (!rv)
1788 Py_RETURN_FALSE;
1789 }
1790 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001791}
1792
1793PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1794
1795static PyObject *
1796set_issuperset(PySetObject *so, PyObject *other)
1797{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001798 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001800 if (!PyAnySet_Check(other)) {
1801 tmp = make_new_set(&PySet_Type, other);
1802 if (tmp == NULL)
1803 return NULL;
1804 result = set_issuperset(so, tmp);
1805 Py_DECREF(tmp);
1806 return result;
1807 }
1808 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001809}
1810
1811PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1812
Raymond Hettingera690a992003-11-16 16:17:49 +00001813static PyObject *
1814set_richcompare(PySetObject *v, PyObject *w, int op)
1815{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001816 PyObject *r1;
1817 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001818
Brian Curtindfc80e32011-08-10 20:28:54 -05001819 if(!PyAnySet_Check(w))
1820 Py_RETURN_NOTIMPLEMENTED;
1821
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001822 switch (op) {
1823 case Py_EQ:
1824 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1825 Py_RETURN_FALSE;
1826 if (v->hash != -1 &&
1827 ((PySetObject *)w)->hash != -1 &&
1828 v->hash != ((PySetObject *)w)->hash)
1829 Py_RETURN_FALSE;
1830 return set_issubset(v, w);
1831 case Py_NE:
1832 r1 = set_richcompare(v, w, Py_EQ);
1833 if (r1 == NULL)
1834 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001835 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001837 if (r2 < 0)
1838 return NULL;
1839 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001840 case Py_LE:
1841 return set_issubset(v, w);
1842 case Py_GE:
1843 return set_issuperset(v, w);
1844 case Py_LT:
1845 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1846 Py_RETURN_FALSE;
1847 return set_issubset(v, w);
1848 case Py_GT:
1849 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1850 Py_RETURN_FALSE;
1851 return set_issuperset(v, w);
1852 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001853 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001854}
1855
Raymond Hettingera690a992003-11-16 16:17:49 +00001856static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001857set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001858{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001859 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001860 return NULL;
1861 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001862}
1863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001865"Add an element to a set.\n\
1866\n\
1867This has no effect if the element is already present.");
1868
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001869static int
1870set_contains(PySetObject *so, PyObject *key)
1871{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 PyObject *tmpkey;
1873 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001876 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1878 return -1;
1879 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001880 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 if (tmpkey == NULL)
1882 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001883 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 Py_DECREF(tmpkey);
1885 }
1886 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001887}
1888
1889static PyObject *
1890set_direct_contains(PySetObject *so, PyObject *key)
1891{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001895 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 return NULL;
1897 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001898}
1899
1900PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1901
Raymond Hettingera690a992003-11-16 16:17:49 +00001902static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001903set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001904{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 PyObject *tmpkey;
1906 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001907
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001909 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1911 return NULL;
1912 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001913 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 if (tmpkey == NULL)
1915 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001916 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001917 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001918 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 return NULL;
1920 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001923 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 return NULL;
1925 }
1926 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001927}
1928
1929PyDoc_STRVAR(remove_doc,
1930"Remove an element from a set; it must be a member.\n\
1931\n\
1932If the element is not a member, raise a KeyError.");
1933
1934static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001935set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001936{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001937 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001940 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001941 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001942 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1943 return NULL;
1944 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001945 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 if (tmpkey == NULL)
1947 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001948 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001949 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001950 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001951 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 }
1953 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001954}
1955
1956PyDoc_STRVAR(discard_doc,
1957"Remove an element from a set if it is a member.\n\
1958\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001959If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001960
1961static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001962set_reduce(PySetObject *so)
1963{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001964 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001965 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001967 keys = PySequence_List((PyObject *)so);
1968 if (keys == NULL)
1969 goto done;
1970 args = PyTuple_Pack(1, keys);
1971 if (args == NULL)
1972 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001973 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001974 if (dict == NULL) {
1975 PyErr_Clear();
1976 dict = Py_None;
1977 Py_INCREF(dict);
1978 }
1979 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001980done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001981 Py_XDECREF(args);
1982 Py_XDECREF(keys);
1983 Py_XDECREF(dict);
1984 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001985}
1986
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001987static PyObject *
1988set_sizeof(PySetObject *so)
1989{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001990 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001991
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02001992 res = _PyObject_SIZE(Py_TYPE(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001993 if (so->table != so->smalltable)
1994 res = res + (so->mask + 1) * sizeof(setentry);
1995 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001996}
1997
1998PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001999static int
2000set_init(PySetObject *self, PyObject *args, PyObject *kwds)
2001{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002002 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002003
Serhiy Storchaka68a001d2017-02-06 10:41:46 +02002004 if (!_PyArg_NoKeywords("set()", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002005 return -1;
2006 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
2007 return -1;
Raymond Hettingerb72e21b2016-03-25 02:29:59 -07002008 if (self->fill)
2009 set_clear_internal(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002010 self->hash = -1;
2011 if (iterable == NULL)
2012 return 0;
2013 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002014}
2015
Raymond Hettingera690a992003-11-16 16:17:49 +00002016static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002017 set_len, /* sq_length */
2018 0, /* sq_concat */
2019 0, /* sq_repeat */
2020 0, /* sq_item */
2021 0, /* sq_slice */
2022 0, /* sq_ass_item */
2023 0, /* sq_ass_slice */
2024 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002025};
2026
2027/* set object ********************************************************/
2028
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002029#ifdef Py_DEBUG
2030static PyObject *test_c_api(PySetObject *so);
2031
2032PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2033All is well if assertions don't fail.");
2034#endif
2035
Raymond Hettingera690a992003-11-16 16:17:49 +00002036static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002037 {"add", (PyCFunction)set_add, METH_O,
2038 add_doc},
2039 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2040 clear_doc},
2041 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2042 contains_doc},
2043 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2044 copy_doc},
2045 {"discard", (PyCFunction)set_discard, METH_O,
2046 discard_doc},
2047 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2048 difference_doc},
2049 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2050 difference_update_doc},
2051 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2052 intersection_doc},
2053 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2054 intersection_update_doc},
2055 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2056 isdisjoint_doc},
2057 {"issubset", (PyCFunction)set_issubset, METH_O,
2058 issubset_doc},
2059 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2060 issuperset_doc},
2061 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2062 pop_doc},
2063 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2064 reduce_doc},
2065 {"remove", (PyCFunction)set_remove, METH_O,
2066 remove_doc},
2067 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2068 sizeof_doc},
2069 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2070 symmetric_difference_doc},
2071 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2072 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002073#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002074 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2075 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002076#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002077 {"union", (PyCFunction)set_union, METH_VARARGS,
2078 union_doc},
2079 {"update", (PyCFunction)set_update, METH_VARARGS,
2080 update_doc},
2081 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002082};
2083
2084static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002085 0, /*nb_add*/
2086 (binaryfunc)set_sub, /*nb_subtract*/
2087 0, /*nb_multiply*/
2088 0, /*nb_remainder*/
2089 0, /*nb_divmod*/
2090 0, /*nb_power*/
2091 0, /*nb_negative*/
2092 0, /*nb_positive*/
2093 0, /*nb_absolute*/
2094 0, /*nb_bool*/
2095 0, /*nb_invert*/
2096 0, /*nb_lshift*/
2097 0, /*nb_rshift*/
2098 (binaryfunc)set_and, /*nb_and*/
2099 (binaryfunc)set_xor, /*nb_xor*/
2100 (binaryfunc)set_or, /*nb_or*/
2101 0, /*nb_int*/
2102 0, /*nb_reserved*/
2103 0, /*nb_float*/
2104 0, /*nb_inplace_add*/
2105 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2106 0, /*nb_inplace_multiply*/
2107 0, /*nb_inplace_remainder*/
2108 0, /*nb_inplace_power*/
2109 0, /*nb_inplace_lshift*/
2110 0, /*nb_inplace_rshift*/
2111 (binaryfunc)set_iand, /*nb_inplace_and*/
2112 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2113 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002114};
2115
2116PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002117"set() -> new empty set object\n\
2118set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002119\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002120Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002121
2122PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2124 "set", /* tp_name */
2125 sizeof(PySetObject), /* tp_basicsize */
2126 0, /* tp_itemsize */
2127 /* methods */
2128 (destructor)set_dealloc, /* tp_dealloc */
2129 0, /* tp_print */
2130 0, /* tp_getattr */
2131 0, /* tp_setattr */
2132 0, /* tp_reserved */
2133 (reprfunc)set_repr, /* tp_repr */
2134 &set_as_number, /* tp_as_number */
2135 &set_as_sequence, /* tp_as_sequence */
2136 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002137 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002138 0, /* tp_call */
2139 0, /* tp_str */
2140 PyObject_GenericGetAttr, /* tp_getattro */
2141 0, /* tp_setattro */
2142 0, /* tp_as_buffer */
2143 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2144 Py_TPFLAGS_BASETYPE, /* tp_flags */
2145 set_doc, /* tp_doc */
2146 (traverseproc)set_traverse, /* tp_traverse */
2147 (inquiry)set_clear_internal, /* tp_clear */
2148 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002149 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2150 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 0, /* tp_iternext */
2152 set_methods, /* tp_methods */
2153 0, /* tp_members */
2154 0, /* tp_getset */
2155 0, /* tp_base */
2156 0, /* tp_dict */
2157 0, /* tp_descr_get */
2158 0, /* tp_descr_set */
2159 0, /* tp_dictoffset */
2160 (initproc)set_init, /* tp_init */
2161 PyType_GenericAlloc, /* tp_alloc */
2162 set_new, /* tp_new */
2163 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002164};
2165
2166/* frozenset object ********************************************************/
2167
2168
2169static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002170 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2171 contains_doc},
2172 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2173 copy_doc},
2174 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2175 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002176 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177 intersection_doc},
2178 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2179 isdisjoint_doc},
2180 {"issubset", (PyCFunction)set_issubset, METH_O,
2181 issubset_doc},
2182 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2183 issuperset_doc},
2184 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2185 reduce_doc},
2186 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2187 sizeof_doc},
2188 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2189 symmetric_difference_doc},
2190 {"union", (PyCFunction)set_union, METH_VARARGS,
2191 union_doc},
2192 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002193};
2194
2195static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 0, /*nb_add*/
2197 (binaryfunc)set_sub, /*nb_subtract*/
2198 0, /*nb_multiply*/
2199 0, /*nb_remainder*/
2200 0, /*nb_divmod*/
2201 0, /*nb_power*/
2202 0, /*nb_negative*/
2203 0, /*nb_positive*/
2204 0, /*nb_absolute*/
2205 0, /*nb_bool*/
2206 0, /*nb_invert*/
2207 0, /*nb_lshift*/
2208 0, /*nb_rshift*/
2209 (binaryfunc)set_and, /*nb_and*/
2210 (binaryfunc)set_xor, /*nb_xor*/
2211 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002212};
2213
2214PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002215"frozenset() -> empty frozenset object\n\
2216frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002217\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002218Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002219
2220PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002221 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2222 "frozenset", /* tp_name */
2223 sizeof(PySetObject), /* tp_basicsize */
2224 0, /* tp_itemsize */
2225 /* methods */
2226 (destructor)set_dealloc, /* tp_dealloc */
2227 0, /* tp_print */
2228 0, /* tp_getattr */
2229 0, /* tp_setattr */
2230 0, /* tp_reserved */
2231 (reprfunc)set_repr, /* tp_repr */
2232 &frozenset_as_number, /* tp_as_number */
2233 &set_as_sequence, /* tp_as_sequence */
2234 0, /* tp_as_mapping */
2235 frozenset_hash, /* tp_hash */
2236 0, /* tp_call */
2237 0, /* tp_str */
2238 PyObject_GenericGetAttr, /* tp_getattro */
2239 0, /* tp_setattro */
2240 0, /* tp_as_buffer */
2241 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2242 Py_TPFLAGS_BASETYPE, /* tp_flags */
2243 frozenset_doc, /* tp_doc */
2244 (traverseproc)set_traverse, /* tp_traverse */
2245 (inquiry)set_clear_internal, /* tp_clear */
2246 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002247 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002248 (getiterfunc)set_iter, /* tp_iter */
2249 0, /* tp_iternext */
2250 frozenset_methods, /* tp_methods */
2251 0, /* tp_members */
2252 0, /* tp_getset */
2253 0, /* tp_base */
2254 0, /* tp_dict */
2255 0, /* tp_descr_get */
2256 0, /* tp_descr_set */
2257 0, /* tp_dictoffset */
2258 0, /* tp_init */
2259 PyType_GenericAlloc, /* tp_alloc */
2260 frozenset_new, /* tp_new */
2261 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002262};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002263
2264
2265/***** C API functions *************************************************/
2266
2267PyObject *
2268PySet_New(PyObject *iterable)
2269{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002270 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002271}
2272
2273PyObject *
2274PyFrozenSet_New(PyObject *iterable)
2275{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002276 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002277}
2278
Neal Norwitz8c49c822006-03-04 18:41:19 +00002279Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002280PySet_Size(PyObject *anyset)
2281{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002282 if (!PyAnySet_Check(anyset)) {
2283 PyErr_BadInternalCall();
2284 return -1;
2285 }
2286 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002287}
2288
2289int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002290PySet_Clear(PyObject *set)
2291{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002292 if (!PySet_Check(set)) {
2293 PyErr_BadInternalCall();
2294 return -1;
2295 }
2296 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002297}
2298
2299int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002300PySet_Contains(PyObject *anyset, PyObject *key)
2301{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002302 if (!PyAnySet_Check(anyset)) {
2303 PyErr_BadInternalCall();
2304 return -1;
2305 }
2306 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002307}
2308
2309int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002310PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002311{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002312 if (!PySet_Check(set)) {
2313 PyErr_BadInternalCall();
2314 return -1;
2315 }
2316 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002317}
2318
2319int
Christian Heimesfd66e512008-01-29 12:18:50 +00002320PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002321{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002322 if (!PySet_Check(anyset) &&
2323 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2324 PyErr_BadInternalCall();
2325 return -1;
2326 }
2327 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002328}
2329
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002330int
Raymond Hettinger3625af52016-03-27 01:15:07 -07002331PySet_ClearFreeList(void)
2332{
2333 return 0;
2334}
2335
2336void
2337PySet_Fini(void)
2338{
2339 Py_CLEAR(emptyfrozenset);
2340}
2341
2342int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002343_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002344{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002345 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002347 if (!PyAnySet_Check(set)) {
2348 PyErr_BadInternalCall();
2349 return -1;
2350 }
2351 if (set_next((PySetObject *)set, pos, &entry) == 0)
2352 return 0;
2353 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002354 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002355 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002356}
2357
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002358PyObject *
2359PySet_Pop(PyObject *set)
2360{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002361 if (!PySet_Check(set)) {
2362 PyErr_BadInternalCall();
2363 return NULL;
2364 }
2365 return set_pop((PySetObject *)set);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002366}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002367
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002368int
2369_PySet_Update(PyObject *set, PyObject *iterable)
2370{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002371 if (!PySet_Check(set)) {
2372 PyErr_BadInternalCall();
2373 return -1;
2374 }
2375 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002376}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002377
Raymond Hettingere259f132013-12-15 11:56:14 -08002378/* Exported for the gdb plugin's benefit. */
2379PyObject *_PySet_Dummy = dummy;
2380
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002381#ifdef Py_DEBUG
2382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002383/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002384 Returns True and original set is restored. */
2385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002386#define assertRaises(call_return_value, exception) \
2387 do { \
2388 assert(call_return_value); \
2389 assert(PyErr_ExceptionMatches(exception)); \
2390 PyErr_Clear(); \
2391 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002392
2393static PyObject *
2394test_c_api(PySetObject *so)
2395{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002396 Py_ssize_t count;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +02002397 const char *s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002398 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002399 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002400 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002401 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002402 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 /* Verify preconditions */
2405 assert(PyAnySet_Check(ob));
2406 assert(PyAnySet_CheckExact(ob));
2407 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002409 /* so.clear(); so |= set("abc"); */
2410 str = PyUnicode_FromString("abc");
2411 if (str == NULL)
2412 return NULL;
2413 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002414 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002415 Py_DECREF(str);
2416 return NULL;
2417 }
2418 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002420 /* Exercise type/size checks */
2421 assert(PySet_Size(ob) == 3);
2422 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002424 /* Raise TypeError for non-iterable constructor arguments */
2425 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2426 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002428 /* Raise TypeError for unhashable key */
2429 dup = PySet_New(ob);
2430 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2431 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2432 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002433
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002434 /* Exercise successful pop, contains, add, and discard */
2435 elem = PySet_Pop(ob);
2436 assert(PySet_Contains(ob, elem) == 0);
2437 assert(PySet_GET_SIZE(ob) == 2);
2438 assert(PySet_Add(ob, elem) == 0);
2439 assert(PySet_Contains(ob, elem) == 1);
2440 assert(PySet_GET_SIZE(ob) == 3);
2441 assert(PySet_Discard(ob, elem) == 1);
2442 assert(PySet_GET_SIZE(ob) == 2);
2443 assert(PySet_Discard(ob, elem) == 0);
2444 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002446 /* Exercise clear */
2447 dup2 = PySet_New(dup);
2448 assert(PySet_Clear(dup2) == 0);
2449 assert(PySet_Size(dup2) == 0);
2450 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002452 /* Raise SystemError on clear or update of frozen set */
2453 f = PyFrozenSet_New(dup);
2454 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2455 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2456 assert(PySet_Add(f, elem) == 0);
2457 Py_INCREF(f);
2458 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2459 Py_DECREF(f);
2460 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002462 /* Exercise direct iteration */
2463 i = 0, count = 0;
2464 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
Serhiy Storchaka06515832016-11-20 09:13:07 +02002465 s = PyUnicode_AsUTF8(x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002466 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2467 count++;
2468 }
2469 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002471 /* Exercise updates */
2472 dup2 = PySet_New(NULL);
2473 assert(_PySet_Update(dup2, dup) == 0);
2474 assert(PySet_Size(dup2) == 3);
2475 assert(_PySet_Update(dup2, dup) == 0);
2476 assert(PySet_Size(dup2) == 3);
2477 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002479 /* Raise SystemError when self argument is not a set or frozenset. */
2480 t = PyTuple_New(0);
2481 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2482 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2483 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002485 /* Raise SystemError when self argument is not a set. */
2486 f = PyFrozenSet_New(dup);
2487 assert(PySet_Size(f) == 3);
2488 assert(PyFrozenSet_CheckExact(f));
2489 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2490 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2491 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002493 /* Raise KeyError when popping from an empty set */
2494 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2495 Py_DECREF(ob);
2496 assert(PySet_GET_SIZE(ob) == 0);
2497 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002499 /* Restore the set from the copy using the PyNumber API */
2500 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2501 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002503 /* Verify constructors accept NULL arguments */
2504 f = PySet_New(NULL);
2505 assert(f != NULL);
2506 assert(PySet_GET_SIZE(f) == 0);
2507 Py_DECREF(f);
2508 f = PyFrozenSet_New(NULL);
2509 assert(f != NULL);
2510 assert(PyFrozenSet_CheckExact(f));
2511 assert(PySet_GET_SIZE(f) == 0);
2512 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002514 Py_DECREF(elem);
2515 Py_DECREF(dup);
2516 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002517}
2518
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002519#undef assertRaises
2520
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002521#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002522
2523/***** Dummy Struct *************************************************/
2524
2525static PyObject *
2526dummy_repr(PyObject *op)
2527{
2528 return PyUnicode_FromString("<dummy key>");
2529}
2530
2531static void
2532dummy_dealloc(PyObject* ignore)
2533{
2534 Py_FatalError("deallocating <dummy key>");
2535}
2536
2537static PyTypeObject _PySetDummy_Type = {
2538 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2539 "<dummy key> type",
2540 0,
2541 0,
2542 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2543 0, /*tp_print*/
2544 0, /*tp_getattr*/
2545 0, /*tp_setattr*/
2546 0, /*tp_reserved*/
2547 dummy_repr, /*tp_repr*/
2548 0, /*tp_as_number*/
2549 0, /*tp_as_sequence*/
2550 0, /*tp_as_mapping*/
2551 0, /*tp_hash */
2552 0, /*tp_call */
2553 0, /*tp_str */
2554 0, /*tp_getattro */
2555 0, /*tp_setattro */
2556 0, /*tp_as_buffer */
2557 Py_TPFLAGS_DEFAULT, /*tp_flags */
2558};
2559
2560static PyObject _dummy_struct = {
2561 _PyObject_EXTRA_INIT
2562 2, &_PySetDummy_Type
2563};
2564