blob: 5c61bc71795fa1e457b2f10e37a7d830764b9216 [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;
INADA Naokie82cf862017-04-01 17:20:25 +0900239 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700240
241 found_active:
Raymond Hettinger482c05c2015-07-20 01:23:32 -0400242 Py_DECREF(key);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700243 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000244
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400245 comparison_error:
Raymond Hettinger061091a2015-07-15 23:54:02 -0700246 Py_DECREF(key);
247 return -1;
248}
249
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000250/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000251Internal routine used by set_table_resize() to insert an item which is
252known to be absent from the set. This routine also assumes that
253the set contains no deleted entries. Besides the performance benefit,
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800254there is also safety benefit since using set_add_entry() risks making
255a callback in the middle of a set_table_resize(), see issue 1456209.
256The caller is responsible for updating the key's reference count and
257the setobject's fill and used fields.
Thomas Wouters89f507f2006-12-13 04:49:30 +0000258*/
259static void
Raymond Hettinger5088f602015-12-13 18:45:01 -0800260set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000261{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200262 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700263 size_t perturb = hash;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800264 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700265 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000266
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700267 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800268 entry = &table[i];
269 if (entry->key == NULL)
270 goto found_null;
271 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800272 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800273 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800274 if (entry->key == NULL)
275 goto found_null;
276 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700277 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700278 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800279 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700281 found_null:
Raymond Hettinger5088f602015-12-13 18:45:01 -0800282 entry->key = key;
Raymond Hettinger86d322f2015-12-13 19:27:17 -0800283 entry->hash = hash;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000284}
285
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700286/* ======== End logic for probing the hash table ========================== */
287/* ======================================================================== */
288
Thomas Wouters89f507f2006-12-13 04:49:30 +0000289/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000290Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000291keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000292actually be smaller than the old one.
293*/
294static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000296{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 Py_ssize_t newsize;
298 setentry *oldtable, *newtable, *entry;
Raymond 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 Hettinger9f1a6792005-07-31 01:16:36 +0000305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100307 /* XXX speed-up with intrinsics */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 for (newsize = PySet_MINSIZE;
309 newsize <= minused && newsize > 0;
310 newsize <<= 1)
311 ;
312 if (newsize <= 0) {
313 PyErr_NoMemory();
314 return -1;
315 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 /* Get space for a new table. */
318 oldtable = so->table;
319 assert(oldtable != NULL);
320 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 if (newsize == PySet_MINSIZE) {
323 /* A large table is shrinking, or we can't get any smaller. */
324 newtable = so->smalltable;
325 if (newtable == oldtable) {
326 if (so->fill == so->used) {
327 /* No dummies, so no point doing anything. */
328 return 0;
329 }
330 /* We're not going to resize it, but rebuild the
331 table anyway to purge old dummy entries.
332 Subtle: This is *necessary* if fill==size,
333 as set_lookkey needs at least one virgin slot to
334 terminate failing searches. If fill < size, it's
335 merely desirable, as dummies slow searches. */
336 assert(so->fill > so->used);
337 memcpy(small_copy, oldtable, sizeof(small_copy));
338 oldtable = small_copy;
339 }
340 }
341 else {
342 newtable = PyMem_NEW(setentry, newsize);
343 if (newtable == NULL) {
344 PyErr_NoMemory();
345 return -1;
346 }
347 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000349 /* Make the set empty, using the new table. */
350 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 memset(newtable, 0, sizeof(setentry) * newsize);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800352 so->mask = newsize - 1;
353 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 /* Copy the data over; this is refcount-neutral for active entries;
356 dummy entries aren't copied over, of course */
Raymond Hettinger5088f602015-12-13 18:45:01 -0800357 newmask = (size_t)so->mask;
Raymond Hettingere1af6962017-02-02 08:24:48 -0800358 if (so->fill == so->used) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800359 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800360 if (entry->key != NULL) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800361 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800362 }
363 }
364 } else {
Raymond Hettingere1af6962017-02-02 08:24:48 -0800365 so->fill = so->used;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800366 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800367 if (entry->key != NULL && entry->key != dummy) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800368 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800369 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 }
371 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 if (is_oldtable_malloced)
374 PyMem_DEL(oldtable);
375 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000376}
377
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000378static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700379set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000380{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700381 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000382
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700383 entry = set_lookkey(so, key, hash);
384 if (entry != NULL)
385 return entry->key != NULL;
386 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000387}
388
389#define DISCARD_NOTFOUND 0
390#define DISCARD_FOUND 1
391
392static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700393set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800394{
395 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000397
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700398 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 if (entry == NULL)
400 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700401 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 return DISCARD_NOTFOUND;
403 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800405 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 so->used--;
407 Py_DECREF(old_key);
408 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000409}
410
411static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700412set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000413{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200414 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000415
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700416 if (!PyUnicode_CheckExact(key) ||
417 (hash = ((PyASCIIObject *) key)->hash) == -1) {
418 hash = PyObject_Hash(key);
419 if (hash == -1)
420 return -1;
421 }
422 return set_add_entry(so, key, hash);
423}
424
425static int
426set_contains_key(PySetObject *so, PyObject *key)
427{
428 Py_hash_t hash;
429
430 if (!PyUnicode_CheckExact(key) ||
431 (hash = ((PyASCIIObject *) key)->hash) == -1) {
432 hash = PyObject_Hash(key);
433 if (hash == -1)
434 return -1;
435 }
436 return set_contains_entry(so, key, hash);
437}
438
439static int
440set_discard_key(PySetObject *so, PyObject *key)
441{
442 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000443
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000444 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200445 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000446 hash = PyObject_Hash(key);
447 if (hash == -1)
448 return -1;
449 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700450 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000451}
452
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700453static void
454set_empty_to_minsize(PySetObject *so)
455{
456 memset(so->smalltable, 0, sizeof(so->smalltable));
457 so->fill = 0;
458 so->used = 0;
459 so->mask = PySet_MINSIZE - 1;
460 so->table = so->smalltable;
461 so->hash = -1;
462}
463
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000464static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000465set_clear_internal(PySetObject *so)
466{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800467 setentry *entry;
468 setentry *table = so->table;
469 Py_ssize_t fill = so->fill;
470 Py_ssize_t used = so->used;
471 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000473
Raymond Hettinger583cd032013-09-07 22:06:35 -0700474 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 /* This is delicate. During the process of clearing the set,
478 * decrefs can cause the set to mutate. To avoid fatal confusion
479 * (voice of experience), we have to make the set empty before
480 * clearing the slots, and never refer to anything via so->ref while
481 * clearing.
482 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700484 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 else if (fill > 0) {
487 /* It's a small table with something that needs to be cleared.
488 * Afraid the only safe way is to copy the set entries into
489 * another small table first.
490 */
491 memcpy(small_copy, table, sizeof(small_copy));
492 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700493 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 }
495 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 /* Now we can finally clear things. If C had refcounts, we could
498 * assert that the refcount on table is 1 now, i.e. that this function
499 * has unique access to it, so decref side-effects can't alter it.
500 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800501 for (entry = table; used > 0; entry++) {
502 if (entry->key && entry->key != dummy) {
503 used--;
504 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 if (table_is_malloced)
509 PyMem_DEL(table);
510 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000511}
512
513/*
514 * Iterate over a set table. Use like so:
515 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000516 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000517 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000518 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000519 * while (set_next(yourset, &pos, &entry)) {
520 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000521 * }
522 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000523 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000525 */
526static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000527set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000528{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000529 Py_ssize_t i;
530 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700531 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000532
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 assert (PyAnySet_Check(so));
534 i = *pos_ptr;
535 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700537 entry = &so->table[i];
538 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700540 entry++;
541 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 *pos_ptr = i+1;
543 if (i > mask)
544 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700545 assert(entry != NULL);
546 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000548}
549
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000550static void
551set_dealloc(PySetObject *so)
552{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200553 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800554 Py_ssize_t used = so->used;
555
INADA Naokia6296d32017-08-24 14:55:17 +0900556 /* bpo-31095: UnTrack is needed before calling any callbacks */
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) {
INADA Naokie82cf862017-04-01 17:20:25 +0900646 if (set_table_resize(so, (so->used + other->used)*2) != 0)
647 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 }
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{
INADA Naokia6296d32017-08-24 14:55:17 +0900813 /* bpo-31095: UnTrack is needed before calling any callbacks */
814 _PyObject_GC_UNTRACK(si);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000815 Py_XDECREF(si->si_set);
816 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000817}
818
819static int
820setiter_traverse(setiterobject *si, visitproc visit, void *arg)
821{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000822 Py_VISIT(si->si_set);
823 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000824}
825
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000826static PyObject *
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000827setiter_len(setiterobject *si)
828{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000829 Py_ssize_t len = 0;
830 if (si->si_set != NULL && si->si_used == si->si_set->used)
831 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000832 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000833}
834
Armin Rigof5b3e362006-02-11 21:32:43 +0000835PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000836
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000837static PyObject *setiter_iternext(setiterobject *si);
838
839static PyObject *
840setiter_reduce(setiterobject *si)
841{
842 PyObject *list;
843 setiterobject tmp;
844
845 list = PyList_New(0);
846 if (!list)
847 return NULL;
848
Ezio Melotti0e1af282012-09-28 16:43:40 +0300849 /* copy the iterator state */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000850 tmp = *si;
851 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300852
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000853 /* iterate the temporary into a list */
854 for(;;) {
855 PyObject *element = setiter_iternext(&tmp);
856 if (element) {
857 if (PyList_Append(list, element)) {
858 Py_DECREF(element);
859 Py_DECREF(list);
860 Py_XDECREF(tmp.si_set);
861 return NULL;
862 }
863 Py_DECREF(element);
864 } else
865 break;
866 }
867 Py_XDECREF(tmp.si_set);
868 /* check for error */
869 if (tmp.si_set != NULL) {
870 /* we have an error */
871 Py_DECREF(list);
872 return NULL;
873 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200874 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000875}
876
877PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
878
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000879static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000880 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000881 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000882 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000883};
884
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000885static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000886{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700887 PyObject *key;
888 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200889 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000890 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000891
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000892 if (so == NULL)
893 return NULL;
894 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000896 if (si->si_used != so->used) {
897 PyErr_SetString(PyExc_RuntimeError,
898 "Set changed size during iteration");
899 si->si_used = -1; /* Make this state sticky */
900 return NULL;
901 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700902
903 i = si->si_pos;
904 assert(i>=0);
905 entry = so->table;
906 mask = so->mask;
907 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
908 i++;
909 si->si_pos = i+1;
910 if (i > mask)
911 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000912 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700913 key = entry[i].key;
914 Py_INCREF(key);
915 return key;
916
917fail:
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700918 si->si_set = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +0300919 Py_DECREF(so);
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700920 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000921}
922
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000923PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000924 PyVarObject_HEAD_INIT(&PyType_Type, 0)
925 "set_iterator", /* tp_name */
926 sizeof(setiterobject), /* tp_basicsize */
927 0, /* tp_itemsize */
928 /* methods */
929 (destructor)setiter_dealloc, /* tp_dealloc */
930 0, /* tp_print */
931 0, /* tp_getattr */
932 0, /* tp_setattr */
933 0, /* tp_reserved */
934 0, /* tp_repr */
935 0, /* tp_as_number */
936 0, /* tp_as_sequence */
937 0, /* tp_as_mapping */
938 0, /* tp_hash */
939 0, /* tp_call */
940 0, /* tp_str */
941 PyObject_GenericGetAttr, /* tp_getattro */
942 0, /* tp_setattro */
943 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700944 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000945 0, /* tp_doc */
946 (traverseproc)setiter_traverse, /* tp_traverse */
947 0, /* tp_clear */
948 0, /* tp_richcompare */
949 0, /* tp_weaklistoffset */
950 PyObject_SelfIter, /* tp_iter */
951 (iternextfunc)setiter_iternext, /* tp_iternext */
952 setiter_methods, /* tp_methods */
953 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000954};
955
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000956static PyObject *
957set_iter(PySetObject *so)
958{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000959 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
960 if (si == NULL)
961 return NULL;
962 Py_INCREF(so);
963 si->si_set = so;
964 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700965 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 si->len = so->used;
967 _PyObject_GC_TRACK(si);
968 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000969}
970
Raymond Hettingerd7946662005-08-01 21:39:29 +0000971static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000972set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000973{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000975
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000976 if (PyAnySet_Check(other))
977 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000978
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000979 if (PyDict_CheckExact(other)) {
980 PyObject *value;
981 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000982 Py_hash_t hash;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200983 Py_ssize_t dictsize = PyDict_GET_SIZE(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000984
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 /* Do one big resize at the start, rather than
986 * incrementally resizing as we insert new keys. Expect
987 * that there will be no (or few) overlapping keys.
988 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700989 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000990 return -1;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800991 if ((so->fill + dictsize)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900992 if (set_table_resize(so, (so->used + dictsize)*2) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000993 return -1;
994 }
995 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700996 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000997 return -1;
998 }
999 return 0;
1000 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001002 it = PyObject_GetIter(other);
1003 if (it == NULL)
1004 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +00001005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001007 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 Py_DECREF(it);
1009 Py_DECREF(key);
1010 return -1;
1011 }
1012 Py_DECREF(key);
1013 }
1014 Py_DECREF(it);
1015 if (PyErr_Occurred())
1016 return -1;
1017 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001018}
1019
1020static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001021set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001022{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001024
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001025 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1026 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001027 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 return NULL;
1029 }
1030 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001031}
1032
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001033PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001034"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001035
Raymond Hettinger426d9952014-05-18 21:40:20 +01001036/* XXX Todo:
1037 If aligned memory allocations become available, make the
1038 set object 64 byte aligned so that most of the fields
1039 can be retrieved or updated in a single cache line.
1040*/
1041
Raymond Hettingera38123e2003-11-24 22:18:49 +00001042static PyObject *
1043make_new_set(PyTypeObject *type, PyObject *iterable)
1044{
Raymond Hettinger8421d712016-04-29 01:37:05 -07001045 PySetObject *so;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001046
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001047 so = (PySetObject *)type->tp_alloc(type, 0);
1048 if (so == NULL)
1049 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001050
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001051 so->fill = 0;
1052 so->used = 0;
1053 so->mask = PySet_MINSIZE - 1;
1054 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001055 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001056 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001057 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001058
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001060 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 Py_DECREF(so);
1062 return NULL;
1063 }
1064 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001067}
1068
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001069static PyObject *
1070make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1071{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1073 if (PyType_IsSubtype(type, &PySet_Type))
1074 type = &PySet_Type;
1075 else
1076 type = &PyFrozenSet_Type;
1077 }
1078 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001079}
1080
Raymond Hettingerd7946662005-08-01 21:39:29 +00001081/* The empty frozenset is a singleton */
1082static PyObject *emptyfrozenset = NULL;
1083
Raymond Hettingera690a992003-11-16 16:17:49 +00001084static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001085frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001086{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001088
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001089 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001090 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001091
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1093 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001094
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 if (type != &PyFrozenSet_Type)
1096 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001098 if (iterable != NULL) {
1099 /* frozenset(f) is idempotent */
1100 if (PyFrozenSet_CheckExact(iterable)) {
1101 Py_INCREF(iterable);
1102 return iterable;
1103 }
1104 result = make_new_set(type, iterable);
1105 if (result == NULL || PySet_GET_SIZE(result))
1106 return result;
1107 Py_DECREF(result);
1108 }
1109 /* The empty frozenset is a singleton */
1110 if (emptyfrozenset == NULL)
1111 emptyfrozenset = make_new_set(type, NULL);
1112 Py_XINCREF(emptyfrozenset);
1113 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001114}
1115
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001116static PyObject *
1117set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1118{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001119 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001120}
1121
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001122/* set_swap_bodies() switches the contents of any two sets by moving their
1123 internal data pointers and, if needed, copying the internal smalltables.
1124 Semantically equivalent to:
1125
1126 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1127
1128 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001129 Useful for operations that update in-place (by allowing an intermediate
1130 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001131*/
1132
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001133static void
1134set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001135{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 Py_ssize_t t;
1137 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001139 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001140
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001141 t = a->fill; a->fill = b->fill; b->fill = t;
1142 t = a->used; a->used = b->used; b->used = t;
1143 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 u = a->table;
1146 if (a->table == a->smalltable)
1147 u = b->smalltable;
1148 a->table = b->table;
1149 if (b->table == b->smalltable)
1150 a->table = a->smalltable;
1151 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001152
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 if (a->table == a->smalltable || b->table == b->smalltable) {
1154 memcpy(tab, a->smalltable, sizeof(tab));
1155 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1156 memcpy(b->smalltable, tab, sizeof(tab));
1157 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1160 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1161 h = a->hash; a->hash = b->hash; b->hash = h;
1162 } else {
1163 a->hash = -1;
1164 b->hash = -1;
1165 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001166}
1167
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001168static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001169set_copy(PySetObject *so)
1170{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001171 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001172}
1173
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001174static PyObject *
1175frozenset_copy(PySetObject *so)
1176{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001177 if (PyFrozenSet_CheckExact(so)) {
1178 Py_INCREF(so);
1179 return (PyObject *)so;
1180 }
1181 return set_copy(so);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001182}
1183
Raymond Hettingera690a992003-11-16 16:17:49 +00001184PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1185
1186static PyObject *
Raymond Hettingerc991db22005-08-11 07:58:45 +00001187set_clear(PySetObject *so)
1188{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 set_clear_internal(so);
1190 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001191}
1192
1193PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1194
1195static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001196set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001197{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001198 PySetObject *result;
1199 PyObject *other;
1200 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001201
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001202 result = (PySetObject *)set_copy(so);
1203 if (result == NULL)
1204 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001206 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1207 other = PyTuple_GET_ITEM(args, i);
1208 if ((PyObject *)so == other)
1209 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001210 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001211 Py_DECREF(result);
1212 return NULL;
1213 }
1214 }
1215 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001216}
1217
1218PyDoc_STRVAR(union_doc,
1219 "Return the union of sets as a new set.\n\
1220\n\
1221(i.e. all elements that are in either set.)");
1222
1223static PyObject *
1224set_or(PySetObject *so, PyObject *other)
1225{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001226 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001227
Brian Curtindfc80e32011-08-10 20:28:54 -05001228 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1229 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001231 result = (PySetObject *)set_copy(so);
1232 if (result == NULL)
1233 return NULL;
1234 if ((PyObject *)so == other)
1235 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001236 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 Py_DECREF(result);
1238 return NULL;
1239 }
1240 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001241}
1242
Raymond Hettingera690a992003-11-16 16:17:49 +00001243static PyObject *
1244set_ior(PySetObject *so, PyObject *other)
1245{
Brian Curtindfc80e32011-08-10 20:28:54 -05001246 if (!PyAnySet_Check(other))
1247 Py_RETURN_NOTIMPLEMENTED;
1248
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001249 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 return NULL;
1251 Py_INCREF(so);
1252 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001253}
1254
1255static PyObject *
1256set_intersection(PySetObject *so, PyObject *other)
1257{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 PySetObject *result;
1259 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001260 Py_hash_t hash;
1261 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 if ((PyObject *)so == other)
1264 return set_copy(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1267 if (result == NULL)
1268 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001270 if (PyAnySet_Check(other)) {
1271 Py_ssize_t pos = 0;
1272 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1275 tmp = (PyObject *)so;
1276 so = (PySetObject *)other;
1277 other = tmp;
1278 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001280 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001281 key = entry->key;
1282 hash = entry->hash;
1283 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001284 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001285 Py_DECREF(result);
1286 return NULL;
1287 }
1288 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001289 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001290 Py_DECREF(result);
1291 return NULL;
1292 }
1293 }
1294 }
1295 return (PyObject *)result;
1296 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 it = PyObject_GetIter(other);
1299 if (it == NULL) {
1300 Py_DECREF(result);
1301 return NULL;
1302 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001305 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001306 if (hash == -1)
1307 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001308 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001309 if (rv < 0)
1310 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001312 if (set_add_entry(result, key, hash))
1313 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 }
1315 Py_DECREF(key);
1316 }
1317 Py_DECREF(it);
1318 if (PyErr_Occurred()) {
1319 Py_DECREF(result);
1320 return NULL;
1321 }
1322 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001323 error:
1324 Py_DECREF(it);
1325 Py_DECREF(result);
1326 Py_DECREF(key);
1327 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001328}
1329
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001330static PyObject *
1331set_intersection_multi(PySetObject *so, PyObject *args)
1332{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 Py_ssize_t i;
1334 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 if (PyTuple_GET_SIZE(args) == 0)
1337 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001338
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001339 Py_INCREF(so);
1340 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1341 PyObject *other = PyTuple_GET_ITEM(args, i);
1342 PyObject *newresult = set_intersection((PySetObject *)result, other);
1343 if (newresult == NULL) {
1344 Py_DECREF(result);
1345 return NULL;
1346 }
1347 Py_DECREF(result);
1348 result = newresult;
1349 }
1350 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001351}
1352
Raymond Hettingera690a992003-11-16 16:17:49 +00001353PyDoc_STRVAR(intersection_doc,
1354"Return the intersection of two sets as a new set.\n\
1355\n\
1356(i.e. all elements that are in both sets.)");
1357
1358static PyObject *
1359set_intersection_update(PySetObject *so, PyObject *other)
1360{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001361 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001363 tmp = set_intersection(so, other);
1364 if (tmp == NULL)
1365 return NULL;
1366 set_swap_bodies(so, (PySetObject *)tmp);
1367 Py_DECREF(tmp);
1368 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001369}
1370
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001371static PyObject *
1372set_intersection_update_multi(PySetObject *so, PyObject *args)
1373{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 tmp = set_intersection_multi(so, args);
1377 if (tmp == NULL)
1378 return NULL;
1379 set_swap_bodies(so, (PySetObject *)tmp);
1380 Py_DECREF(tmp);
1381 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001382}
1383
Raymond Hettingera690a992003-11-16 16:17:49 +00001384PyDoc_STRVAR(intersection_update_doc,
1385"Update a set with the intersection of itself and another.");
1386
1387static PyObject *
1388set_and(PySetObject *so, PyObject *other)
1389{
Brian Curtindfc80e32011-08-10 20:28:54 -05001390 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1391 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001393}
1394
1395static PyObject *
1396set_iand(PySetObject *so, PyObject *other)
1397{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001398 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001399
Brian Curtindfc80e32011-08-10 20:28:54 -05001400 if (!PyAnySet_Check(other))
1401 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402 result = set_intersection_update(so, other);
1403 if (result == NULL)
1404 return NULL;
1405 Py_DECREF(result);
1406 Py_INCREF(so);
1407 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001408}
1409
Guido van Rossum58da9312007-11-10 23:39:45 +00001410static PyObject *
1411set_isdisjoint(PySetObject *so, PyObject *other)
1412{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001414 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416 if ((PyObject *)so == other) {
1417 if (PySet_GET_SIZE(so) == 0)
1418 Py_RETURN_TRUE;
1419 else
1420 Py_RETURN_FALSE;
1421 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001423 if (PyAnySet_CheckExact(other)) {
1424 Py_ssize_t pos = 0;
1425 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001427 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1428 tmp = (PyObject *)so;
1429 so = (PySetObject *)other;
1430 other = tmp;
1431 }
1432 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001433 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001434 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 return NULL;
1436 if (rv)
1437 Py_RETURN_FALSE;
1438 }
1439 Py_RETURN_TRUE;
1440 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001442 it = PyObject_GetIter(other);
1443 if (it == NULL)
1444 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001447 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001448
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001449 if (hash == -1) {
1450 Py_DECREF(key);
1451 Py_DECREF(it);
1452 return NULL;
1453 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001454 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001456 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 Py_DECREF(it);
1458 return NULL;
1459 }
1460 if (rv) {
1461 Py_DECREF(it);
1462 Py_RETURN_FALSE;
1463 }
1464 }
1465 Py_DECREF(it);
1466 if (PyErr_Occurred())
1467 return NULL;
1468 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001469}
1470
1471PyDoc_STRVAR(isdisjoint_doc,
1472"Return True if two sets have a null intersection.");
1473
Neal Norwitz6576bd82005-11-13 18:41:28 +00001474static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001475set_difference_update_internal(PySetObject *so, PyObject *other)
1476{
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001477 if (PySet_GET_SIZE(so) == 0) {
1478 return 0;
1479 }
1480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 if ((PyObject *)so == other)
1482 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 if (PyAnySet_Check(other)) {
1485 setentry *entry;
1486 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001489 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 return -1;
1491 } else {
1492 PyObject *key, *it;
1493 it = PyObject_GetIter(other);
1494 if (it == NULL)
1495 return -1;
1496
1497 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001498 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 Py_DECREF(it);
1500 Py_DECREF(key);
1501 return -1;
1502 }
1503 Py_DECREF(key);
1504 }
1505 Py_DECREF(it);
1506 if (PyErr_Occurred())
1507 return -1;
1508 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001509 /* If more than 1/4th are dummies, then resize them away. */
1510 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +09001512 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001513}
1514
Raymond Hettingera690a992003-11-16 16:17:49 +00001515static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001516set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001517{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1521 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001522 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001523 return NULL;
1524 }
1525 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001526}
1527
1528PyDoc_STRVAR(difference_update_doc,
1529"Remove all elements of another set from this set.");
1530
1531static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001532set_copy_and_difference(PySetObject *so, PyObject *other)
1533{
1534 PyObject *result;
1535
1536 result = set_copy(so);
1537 if (result == NULL)
1538 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001539 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001540 return result;
1541 Py_DECREF(result);
1542 return NULL;
1543}
1544
1545static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001546set_difference(PySetObject *so, PyObject *other)
1547{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001549 PyObject *key;
1550 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001551 setentry *entry;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001552 Py_ssize_t pos = 0, other_size;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001553 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001554
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001555 if (PySet_GET_SIZE(so) == 0) {
1556 return set_copy(so);
1557 }
1558
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001559 if (PyAnySet_Check(other)) {
1560 other_size = PySet_GET_SIZE(other);
1561 }
1562 else if (PyDict_CheckExact(other)) {
1563 other_size = PyDict_GET_SIZE(other);
1564 }
1565 else {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001566 return set_copy_and_difference(so, other);
1567 }
1568
1569 /* If len(so) much more than len(other), it's more efficient to simply copy
1570 * so and then iterate other looking for common elements. */
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001571 if ((PySet_GET_SIZE(so) >> 2) > other_size) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001572 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001573 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001574
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 result = make_new_set_basetype(Py_TYPE(so), NULL);
1576 if (result == NULL)
1577 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001578
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 if (PyDict_CheckExact(other)) {
1580 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001581 key = entry->key;
1582 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001583 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001584 if (rv < 0) {
1585 Py_DECREF(result);
1586 return NULL;
1587 }
1588 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001589 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001590 Py_DECREF(result);
1591 return NULL;
1592 }
1593 }
1594 }
1595 return result;
1596 }
1597
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001598 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001599 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001600 key = entry->key;
1601 hash = entry->hash;
1602 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001603 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 Py_DECREF(result);
1605 return NULL;
1606 }
1607 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001608 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001609 Py_DECREF(result);
1610 return NULL;
1611 }
1612 }
1613 }
1614 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001615}
1616
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001617static PyObject *
1618set_difference_multi(PySetObject *so, PyObject *args)
1619{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 Py_ssize_t i;
1621 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 if (PyTuple_GET_SIZE(args) == 0)
1624 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 other = PyTuple_GET_ITEM(args, 0);
1627 result = set_difference(so, other);
1628 if (result == NULL)
1629 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1632 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001633 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001634 Py_DECREF(result);
1635 return NULL;
1636 }
1637 }
1638 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001639}
1640
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001641PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001642"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001643\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001644(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001645static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001646set_sub(PySetObject *so, PyObject *other)
1647{
Brian Curtindfc80e32011-08-10 20:28:54 -05001648 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1649 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001650 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001651}
1652
1653static PyObject *
1654set_isub(PySetObject *so, PyObject *other)
1655{
Brian Curtindfc80e32011-08-10 20:28:54 -05001656 if (!PyAnySet_Check(other))
1657 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001658 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001659 return NULL;
1660 Py_INCREF(so);
1661 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001662}
1663
1664static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001665set_symmetric_difference_update(PySetObject *so, PyObject *other)
1666{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001667 PySetObject *otherset;
1668 PyObject *key;
1669 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001670 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001671 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001672 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001673
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001674 if ((PyObject *)so == other)
1675 return set_clear(so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001677 if (PyDict_CheckExact(other)) {
1678 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001679 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001680 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001681 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001682 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001683 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001684 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001685 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001686 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001687 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001688 Py_DECREF(key);
1689 return NULL;
1690 }
1691 }
Georg Brandl2d444492010-09-03 10:52:55 +00001692 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001693 }
1694 Py_RETURN_NONE;
1695 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001696
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001697 if (PyAnySet_Check(other)) {
1698 Py_INCREF(other);
1699 otherset = (PySetObject *)other;
1700 } else {
1701 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1702 if (otherset == NULL)
1703 return NULL;
1704 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001705
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001706 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001707 key = entry->key;
1708 hash = entry->hash;
1709 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001710 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001711 Py_DECREF(otherset);
1712 return NULL;
1713 }
1714 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001715 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001716 Py_DECREF(otherset);
1717 return NULL;
1718 }
1719 }
1720 }
1721 Py_DECREF(otherset);
1722 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001723}
1724
1725PyDoc_STRVAR(symmetric_difference_update_doc,
1726"Update a set with the symmetric difference of itself and another.");
1727
1728static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001729set_symmetric_difference(PySetObject *so, PyObject *other)
1730{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001731 PyObject *rv;
1732 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001733
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001734 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1735 if (otherset == NULL)
1736 return NULL;
1737 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
1738 if (rv == NULL)
1739 return NULL;
1740 Py_DECREF(rv);
1741 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001742}
1743
1744PyDoc_STRVAR(symmetric_difference_doc,
1745"Return the symmetric difference of two sets as a new set.\n\
1746\n\
1747(i.e. all elements that are in exactly one of the sets.)");
1748
1749static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001750set_xor(PySetObject *so, PyObject *other)
1751{
Brian Curtindfc80e32011-08-10 20:28:54 -05001752 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1753 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001754 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001755}
1756
1757static PyObject *
1758set_ixor(PySetObject *so, PyObject *other)
1759{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001760 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001761
Brian Curtindfc80e32011-08-10 20:28:54 -05001762 if (!PyAnySet_Check(other))
1763 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001764 result = set_symmetric_difference_update(so, other);
1765 if (result == NULL)
1766 return NULL;
1767 Py_DECREF(result);
1768 Py_INCREF(so);
1769 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001770}
1771
1772static PyObject *
1773set_issubset(PySetObject *so, PyObject *other)
1774{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 setentry *entry;
1776 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001777 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001778
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 if (!PyAnySet_Check(other)) {
1780 PyObject *tmp, *result;
1781 tmp = make_new_set(&PySet_Type, other);
1782 if (tmp == NULL)
1783 return NULL;
1784 result = set_issubset(so, tmp);
1785 Py_DECREF(tmp);
1786 return result;
1787 }
1788 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1789 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001790
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001791 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001792 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001793 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001794 return NULL;
1795 if (!rv)
1796 Py_RETURN_FALSE;
1797 }
1798 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001799}
1800
1801PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1802
1803static PyObject *
1804set_issuperset(PySetObject *so, PyObject *other)
1805{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001806 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001807
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001808 if (!PyAnySet_Check(other)) {
1809 tmp = make_new_set(&PySet_Type, other);
1810 if (tmp == NULL)
1811 return NULL;
1812 result = set_issuperset(so, tmp);
1813 Py_DECREF(tmp);
1814 return result;
1815 }
1816 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001817}
1818
1819PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1820
Raymond Hettingera690a992003-11-16 16:17:49 +00001821static PyObject *
1822set_richcompare(PySetObject *v, PyObject *w, int op)
1823{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001824 PyObject *r1;
1825 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001826
Brian Curtindfc80e32011-08-10 20:28:54 -05001827 if(!PyAnySet_Check(w))
1828 Py_RETURN_NOTIMPLEMENTED;
1829
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 switch (op) {
1831 case Py_EQ:
1832 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1833 Py_RETURN_FALSE;
1834 if (v->hash != -1 &&
1835 ((PySetObject *)w)->hash != -1 &&
1836 v->hash != ((PySetObject *)w)->hash)
1837 Py_RETURN_FALSE;
1838 return set_issubset(v, w);
1839 case Py_NE:
1840 r1 = set_richcompare(v, w, Py_EQ);
1841 if (r1 == NULL)
1842 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001843 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001844 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001845 if (r2 < 0)
1846 return NULL;
1847 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 case Py_LE:
1849 return set_issubset(v, w);
1850 case Py_GE:
1851 return set_issuperset(v, w);
1852 case Py_LT:
1853 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1854 Py_RETURN_FALSE;
1855 return set_issubset(v, w);
1856 case Py_GT:
1857 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1858 Py_RETURN_FALSE;
1859 return set_issuperset(v, w);
1860 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001861 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001862}
1863
Raymond Hettingera690a992003-11-16 16:17:49 +00001864static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001865set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001866{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001867 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 return NULL;
1869 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001870}
1871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001873"Add an element to a set.\n\
1874\n\
1875This has no effect if the element is already present.");
1876
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001877static int
1878set_contains(PySetObject *so, PyObject *key)
1879{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 PyObject *tmpkey;
1881 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001882
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001883 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001884 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1886 return -1;
1887 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001888 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001889 if (tmpkey == NULL)
1890 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001891 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 Py_DECREF(tmpkey);
1893 }
1894 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001895}
1896
1897static PyObject *
1898set_direct_contains(PySetObject *so, PyObject *key)
1899{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001901
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001903 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001904 return NULL;
1905 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001906}
1907
1908PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1909
Raymond Hettingera690a992003-11-16 16:17:49 +00001910static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001911set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001912{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001913 PyObject *tmpkey;
1914 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001916 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001917 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001918 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1919 return NULL;
1920 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001921 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 if (tmpkey == NULL)
1923 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001926 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927 return NULL;
1928 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001931 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001932 return NULL;
1933 }
1934 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001935}
1936
1937PyDoc_STRVAR(remove_doc,
1938"Remove an element from a set; it must be a member.\n\
1939\n\
1940If the element is not a member, raise a KeyError.");
1941
1942static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001943set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001944{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001945 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001948 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001949 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001950 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1951 return NULL;
1952 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001953 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001954 if (tmpkey == NULL)
1955 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001956 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001957 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001958 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001959 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001960 }
1961 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001962}
1963
1964PyDoc_STRVAR(discard_doc,
1965"Remove an element from a set if it is a member.\n\
1966\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001967If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001968
1969static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001970set_reduce(PySetObject *so)
1971{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001972 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001973 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001975 keys = PySequence_List((PyObject *)so);
1976 if (keys == NULL)
1977 goto done;
1978 args = PyTuple_Pack(1, keys);
1979 if (args == NULL)
1980 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001981 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001982 if (dict == NULL) {
1983 PyErr_Clear();
1984 dict = Py_None;
1985 Py_INCREF(dict);
1986 }
1987 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001988done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001989 Py_XDECREF(args);
1990 Py_XDECREF(keys);
1991 Py_XDECREF(dict);
1992 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001993}
1994
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001995static PyObject *
1996set_sizeof(PySetObject *so)
1997{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001998 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001999
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02002000 res = _PyObject_SIZE(Py_TYPE(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002001 if (so->table != so->smalltable)
2002 res = res + (so->mask + 1) * sizeof(setentry);
2003 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002004}
2005
2006PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002007static int
2008set_init(PySetObject *self, PyObject *args, PyObject *kwds)
2009{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002010 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002011
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03002012 if (!_PyArg_NoKeywords("set", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002013 return -1;
2014 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
2015 return -1;
Raymond Hettingerb72e21b2016-03-25 02:29:59 -07002016 if (self->fill)
2017 set_clear_internal(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002018 self->hash = -1;
2019 if (iterable == NULL)
2020 return 0;
2021 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002022}
2023
Raymond Hettingera690a992003-11-16 16:17:49 +00002024static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 set_len, /* sq_length */
2026 0, /* sq_concat */
2027 0, /* sq_repeat */
2028 0, /* sq_item */
2029 0, /* sq_slice */
2030 0, /* sq_ass_item */
2031 0, /* sq_ass_slice */
2032 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002033};
2034
2035/* set object ********************************************************/
2036
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002037#ifdef Py_DEBUG
2038static PyObject *test_c_api(PySetObject *so);
2039
2040PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2041All is well if assertions don't fail.");
2042#endif
2043
Raymond Hettingera690a992003-11-16 16:17:49 +00002044static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002045 {"add", (PyCFunction)set_add, METH_O,
2046 add_doc},
2047 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2048 clear_doc},
2049 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2050 contains_doc},
2051 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2052 copy_doc},
2053 {"discard", (PyCFunction)set_discard, METH_O,
2054 discard_doc},
2055 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2056 difference_doc},
2057 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2058 difference_update_doc},
2059 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2060 intersection_doc},
2061 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2062 intersection_update_doc},
2063 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2064 isdisjoint_doc},
2065 {"issubset", (PyCFunction)set_issubset, METH_O,
2066 issubset_doc},
2067 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2068 issuperset_doc},
2069 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2070 pop_doc},
2071 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2072 reduce_doc},
2073 {"remove", (PyCFunction)set_remove, METH_O,
2074 remove_doc},
2075 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2076 sizeof_doc},
2077 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2078 symmetric_difference_doc},
2079 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2080 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002081#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002082 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2083 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002084#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002085 {"union", (PyCFunction)set_union, METH_VARARGS,
2086 union_doc},
2087 {"update", (PyCFunction)set_update, METH_VARARGS,
2088 update_doc},
2089 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002090};
2091
2092static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002093 0, /*nb_add*/
2094 (binaryfunc)set_sub, /*nb_subtract*/
2095 0, /*nb_multiply*/
2096 0, /*nb_remainder*/
2097 0, /*nb_divmod*/
2098 0, /*nb_power*/
2099 0, /*nb_negative*/
2100 0, /*nb_positive*/
2101 0, /*nb_absolute*/
2102 0, /*nb_bool*/
2103 0, /*nb_invert*/
2104 0, /*nb_lshift*/
2105 0, /*nb_rshift*/
2106 (binaryfunc)set_and, /*nb_and*/
2107 (binaryfunc)set_xor, /*nb_xor*/
2108 (binaryfunc)set_or, /*nb_or*/
2109 0, /*nb_int*/
2110 0, /*nb_reserved*/
2111 0, /*nb_float*/
2112 0, /*nb_inplace_add*/
2113 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2114 0, /*nb_inplace_multiply*/
2115 0, /*nb_inplace_remainder*/
2116 0, /*nb_inplace_power*/
2117 0, /*nb_inplace_lshift*/
2118 0, /*nb_inplace_rshift*/
2119 (binaryfunc)set_iand, /*nb_inplace_and*/
2120 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2121 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002122};
2123
2124PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002125"set() -> new empty set object\n\
2126set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002127\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002128Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002129
2130PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002131 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2132 "set", /* tp_name */
2133 sizeof(PySetObject), /* tp_basicsize */
2134 0, /* tp_itemsize */
2135 /* methods */
2136 (destructor)set_dealloc, /* tp_dealloc */
2137 0, /* tp_print */
2138 0, /* tp_getattr */
2139 0, /* tp_setattr */
2140 0, /* tp_reserved */
2141 (reprfunc)set_repr, /* tp_repr */
2142 &set_as_number, /* tp_as_number */
2143 &set_as_sequence, /* tp_as_sequence */
2144 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002145 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002146 0, /* tp_call */
2147 0, /* tp_str */
2148 PyObject_GenericGetAttr, /* tp_getattro */
2149 0, /* tp_setattro */
2150 0, /* tp_as_buffer */
2151 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2152 Py_TPFLAGS_BASETYPE, /* tp_flags */
2153 set_doc, /* tp_doc */
2154 (traverseproc)set_traverse, /* tp_traverse */
2155 (inquiry)set_clear_internal, /* tp_clear */
2156 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002157 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2158 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 0, /* tp_iternext */
2160 set_methods, /* tp_methods */
2161 0, /* tp_members */
2162 0, /* tp_getset */
2163 0, /* tp_base */
2164 0, /* tp_dict */
2165 0, /* tp_descr_get */
2166 0, /* tp_descr_set */
2167 0, /* tp_dictoffset */
2168 (initproc)set_init, /* tp_init */
2169 PyType_GenericAlloc, /* tp_alloc */
2170 set_new, /* tp_new */
2171 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002172};
2173
2174/* frozenset object ********************************************************/
2175
2176
2177static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2179 contains_doc},
2180 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2181 copy_doc},
2182 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2183 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002184 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002185 intersection_doc},
2186 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2187 isdisjoint_doc},
2188 {"issubset", (PyCFunction)set_issubset, METH_O,
2189 issubset_doc},
2190 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2191 issuperset_doc},
2192 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2193 reduce_doc},
2194 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2195 sizeof_doc},
2196 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2197 symmetric_difference_doc},
2198 {"union", (PyCFunction)set_union, METH_VARARGS,
2199 union_doc},
2200 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002201};
2202
2203static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002204 0, /*nb_add*/
2205 (binaryfunc)set_sub, /*nb_subtract*/
2206 0, /*nb_multiply*/
2207 0, /*nb_remainder*/
2208 0, /*nb_divmod*/
2209 0, /*nb_power*/
2210 0, /*nb_negative*/
2211 0, /*nb_positive*/
2212 0, /*nb_absolute*/
2213 0, /*nb_bool*/
2214 0, /*nb_invert*/
2215 0, /*nb_lshift*/
2216 0, /*nb_rshift*/
2217 (binaryfunc)set_and, /*nb_and*/
2218 (binaryfunc)set_xor, /*nb_xor*/
2219 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002220};
2221
2222PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002223"frozenset() -> empty frozenset object\n\
2224frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002225\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002226Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002227
2228PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002229 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2230 "frozenset", /* tp_name */
2231 sizeof(PySetObject), /* tp_basicsize */
2232 0, /* tp_itemsize */
2233 /* methods */
2234 (destructor)set_dealloc, /* tp_dealloc */
2235 0, /* tp_print */
2236 0, /* tp_getattr */
2237 0, /* tp_setattr */
2238 0, /* tp_reserved */
2239 (reprfunc)set_repr, /* tp_repr */
2240 &frozenset_as_number, /* tp_as_number */
2241 &set_as_sequence, /* tp_as_sequence */
2242 0, /* tp_as_mapping */
2243 frozenset_hash, /* tp_hash */
2244 0, /* tp_call */
2245 0, /* tp_str */
2246 PyObject_GenericGetAttr, /* tp_getattro */
2247 0, /* tp_setattro */
2248 0, /* tp_as_buffer */
2249 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2250 Py_TPFLAGS_BASETYPE, /* tp_flags */
2251 frozenset_doc, /* tp_doc */
2252 (traverseproc)set_traverse, /* tp_traverse */
2253 (inquiry)set_clear_internal, /* tp_clear */
2254 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002255 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002256 (getiterfunc)set_iter, /* tp_iter */
2257 0, /* tp_iternext */
2258 frozenset_methods, /* tp_methods */
2259 0, /* tp_members */
2260 0, /* tp_getset */
2261 0, /* tp_base */
2262 0, /* tp_dict */
2263 0, /* tp_descr_get */
2264 0, /* tp_descr_set */
2265 0, /* tp_dictoffset */
2266 0, /* tp_init */
2267 PyType_GenericAlloc, /* tp_alloc */
2268 frozenset_new, /* tp_new */
2269 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002270};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002271
2272
2273/***** C API functions *************************************************/
2274
2275PyObject *
2276PySet_New(PyObject *iterable)
2277{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002278 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002279}
2280
2281PyObject *
2282PyFrozenSet_New(PyObject *iterable)
2283{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002284 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002285}
2286
Neal Norwitz8c49c822006-03-04 18:41:19 +00002287Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002288PySet_Size(PyObject *anyset)
2289{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002290 if (!PyAnySet_Check(anyset)) {
2291 PyErr_BadInternalCall();
2292 return -1;
2293 }
2294 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002295}
2296
2297int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002298PySet_Clear(PyObject *set)
2299{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002300 if (!PySet_Check(set)) {
2301 PyErr_BadInternalCall();
2302 return -1;
2303 }
2304 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002305}
2306
2307int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002308PySet_Contains(PyObject *anyset, PyObject *key)
2309{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002310 if (!PyAnySet_Check(anyset)) {
2311 PyErr_BadInternalCall();
2312 return -1;
2313 }
2314 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002315}
2316
2317int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002318PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002319{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002320 if (!PySet_Check(set)) {
2321 PyErr_BadInternalCall();
2322 return -1;
2323 }
2324 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002325}
2326
2327int
Christian Heimesfd66e512008-01-29 12:18:50 +00002328PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002329{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002330 if (!PySet_Check(anyset) &&
2331 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2332 PyErr_BadInternalCall();
2333 return -1;
2334 }
2335 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002336}
2337
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002338int
Raymond Hettinger3625af52016-03-27 01:15:07 -07002339PySet_ClearFreeList(void)
2340{
2341 return 0;
2342}
2343
2344void
2345PySet_Fini(void)
2346{
2347 Py_CLEAR(emptyfrozenset);
2348}
2349
2350int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002351_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002352{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002353 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002355 if (!PyAnySet_Check(set)) {
2356 PyErr_BadInternalCall();
2357 return -1;
2358 }
2359 if (set_next((PySetObject *)set, pos, &entry) == 0)
2360 return 0;
2361 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002362 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002363 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002364}
2365
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002366PyObject *
2367PySet_Pop(PyObject *set)
2368{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002369 if (!PySet_Check(set)) {
2370 PyErr_BadInternalCall();
2371 return NULL;
2372 }
2373 return set_pop((PySetObject *)set);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002374}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002375
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002376int
2377_PySet_Update(PyObject *set, PyObject *iterable)
2378{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002379 if (!PySet_Check(set)) {
2380 PyErr_BadInternalCall();
2381 return -1;
2382 }
2383 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002384}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002385
Raymond Hettingere259f132013-12-15 11:56:14 -08002386/* Exported for the gdb plugin's benefit. */
2387PyObject *_PySet_Dummy = dummy;
2388
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002389#ifdef Py_DEBUG
2390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002391/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002392 Returns True and original set is restored. */
2393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002394#define assertRaises(call_return_value, exception) \
2395 do { \
2396 assert(call_return_value); \
2397 assert(PyErr_ExceptionMatches(exception)); \
2398 PyErr_Clear(); \
2399 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002400
2401static PyObject *
2402test_c_api(PySetObject *so)
2403{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 Py_ssize_t count;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +02002405 const char *s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002406 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002407 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002409 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002410 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002412 /* Verify preconditions */
2413 assert(PyAnySet_Check(ob));
2414 assert(PyAnySet_CheckExact(ob));
2415 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002417 /* so.clear(); so |= set("abc"); */
2418 str = PyUnicode_FromString("abc");
2419 if (str == NULL)
2420 return NULL;
2421 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002422 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002423 Py_DECREF(str);
2424 return NULL;
2425 }
2426 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002428 /* Exercise type/size checks */
2429 assert(PySet_Size(ob) == 3);
2430 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002432 /* Raise TypeError for non-iterable constructor arguments */
2433 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2434 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002436 /* Raise TypeError for unhashable key */
2437 dup = PySet_New(ob);
2438 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2439 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2440 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002442 /* Exercise successful pop, contains, add, and discard */
2443 elem = PySet_Pop(ob);
2444 assert(PySet_Contains(ob, elem) == 0);
2445 assert(PySet_GET_SIZE(ob) == 2);
2446 assert(PySet_Add(ob, elem) == 0);
2447 assert(PySet_Contains(ob, elem) == 1);
2448 assert(PySet_GET_SIZE(ob) == 3);
2449 assert(PySet_Discard(ob, elem) == 1);
2450 assert(PySet_GET_SIZE(ob) == 2);
2451 assert(PySet_Discard(ob, elem) == 0);
2452 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002453
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002454 /* Exercise clear */
2455 dup2 = PySet_New(dup);
2456 assert(PySet_Clear(dup2) == 0);
2457 assert(PySet_Size(dup2) == 0);
2458 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002460 /* Raise SystemError on clear or update of frozen set */
2461 f = PyFrozenSet_New(dup);
2462 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2463 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2464 assert(PySet_Add(f, elem) == 0);
2465 Py_INCREF(f);
2466 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2467 Py_DECREF(f);
2468 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002470 /* Exercise direct iteration */
2471 i = 0, count = 0;
2472 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
Serhiy Storchaka06515832016-11-20 09:13:07 +02002473 s = PyUnicode_AsUTF8(x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002474 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2475 count++;
2476 }
2477 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002479 /* Exercise updates */
2480 dup2 = PySet_New(NULL);
2481 assert(_PySet_Update(dup2, dup) == 0);
2482 assert(PySet_Size(dup2) == 3);
2483 assert(_PySet_Update(dup2, dup) == 0);
2484 assert(PySet_Size(dup2) == 3);
2485 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002487 /* Raise SystemError when self argument is not a set or frozenset. */
2488 t = PyTuple_New(0);
2489 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2490 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2491 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002493 /* Raise SystemError when self argument is not a set. */
2494 f = PyFrozenSet_New(dup);
2495 assert(PySet_Size(f) == 3);
2496 assert(PyFrozenSet_CheckExact(f));
2497 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2498 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2499 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002501 /* Raise KeyError when popping from an empty set */
2502 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2503 Py_DECREF(ob);
2504 assert(PySet_GET_SIZE(ob) == 0);
2505 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002507 /* Restore the set from the copy using the PyNumber API */
2508 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2509 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002511 /* Verify constructors accept NULL arguments */
2512 f = PySet_New(NULL);
2513 assert(f != NULL);
2514 assert(PySet_GET_SIZE(f) == 0);
2515 Py_DECREF(f);
2516 f = PyFrozenSet_New(NULL);
2517 assert(f != NULL);
2518 assert(PyFrozenSet_CheckExact(f));
2519 assert(PySet_GET_SIZE(f) == 0);
2520 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002522 Py_DECREF(elem);
2523 Py_DECREF(dup);
2524 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002525}
2526
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002527#undef assertRaises
2528
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002529#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002530
2531/***** Dummy Struct *************************************************/
2532
2533static PyObject *
2534dummy_repr(PyObject *op)
2535{
2536 return PyUnicode_FromString("<dummy key>");
2537}
2538
2539static void
2540dummy_dealloc(PyObject* ignore)
2541{
2542 Py_FatalError("deallocating <dummy key>");
2543}
2544
2545static PyTypeObject _PySetDummy_Type = {
2546 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2547 "<dummy key> type",
2548 0,
2549 0,
2550 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2551 0, /*tp_print*/
2552 0, /*tp_getattr*/
2553 0, /*tp_setattr*/
2554 0, /*tp_reserved*/
2555 dummy_repr, /*tp_repr*/
2556 0, /*tp_as_number*/
2557 0, /*tp_as_sequence*/
2558 0, /*tp_as_mapping*/
2559 0, /*tp_hash */
2560 0, /*tp_call */
2561 0, /*tp_str */
2562 0, /*tp_getattro */
2563 0, /*tp_setattro */
2564 0, /*tp_as_buffer */
2565 Py_TPFLAGS_DEFAULT, /*tp_flags */
2566};
2567
2568static PyObject _dummy_struct = {
2569 _PyObject_EXTRA_INIT
2570 2, &_PySetDummy_Type
2571};
2572