blob: a9dba31c4238594049c98f4229f2f3b55ba14585 [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
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000556 PyObject_GC_UnTrack(so);
557 Py_TRASHCAN_SAFE_BEGIN(so)
558 if (so->weakreflist != NULL)
559 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000560
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800561 for (entry = so->table; used > 0; entry++) {
562 if (entry->key && entry->key != dummy) {
563 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700564 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000565 }
566 }
567 if (so->table != so->smalltable)
568 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700569 Py_TYPE(so)->tp_free(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 Py_TRASHCAN_SAFE_END(so)
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000571}
572
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000573static PyObject *
574set_repr(PySetObject *so)
575{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200576 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000577 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000578
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000579 if (status != 0) {
580 if (status < 0)
581 return NULL;
582 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
583 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000584
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000585 /* shortcut for the empty set */
586 if (!so->used) {
587 Py_ReprLeave((PyObject*)so);
588 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
589 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000591 keys = PySequence_List((PyObject *)so);
592 if (keys == NULL)
593 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000594
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200595 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000596 listrepr = PyObject_Repr(keys);
597 Py_DECREF(keys);
598 if (listrepr == NULL)
599 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200600 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000601 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200602 if (tmp == NULL)
603 goto done;
604 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200605
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200606 if (Py_TYPE(so) != &PySet_Type)
607 result = PyUnicode_FromFormat("%s({%U})",
608 Py_TYPE(so)->tp_name,
609 listrepr);
610 else
611 result = PyUnicode_FromFormat("{%U}", listrepr);
612 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000613done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614 Py_ReprLeave((PyObject*)so);
615 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000616}
617
Martin v. Löwis18e16552006-02-15 17:27:45 +0000618static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000619set_len(PyObject *so)
620{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000621 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000622}
623
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000624static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000625set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000626{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000627 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000628 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200629 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700630 setentry *so_entry;
631 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 assert (PyAnySet_Check(so));
634 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000636 other = (PySetObject*)otherset;
637 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700638 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000639 return 0;
640 /* Do one big resize at the start, rather than
641 * incrementally resizing as we insert new keys. Expect
642 * that there will be no (or few) overlapping keys.
643 */
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800644 if ((so->fill + other->used)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900645 if (set_table_resize(so, (so->used + other->used)*2) != 0)
646 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000647 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700648 so_entry = so->table;
649 other_entry = other->table;
650
651 /* If our table is empty, and both tables have the same size, and
652 there are no dummies to eliminate, then just copy the pointers. */
653 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
654 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
655 key = other_entry->key;
656 if (key != NULL) {
657 assert(so_entry->key == NULL);
658 Py_INCREF(key);
659 so_entry->key = key;
660 so_entry->hash = other_entry->hash;
661 }
662 }
663 so->fill = other->fill;
664 so->used = other->used;
665 return 0;
666 }
667
668 /* If our table is empty, we can use set_insert_clean() */
669 if (so->fill == 0) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800670 setentry *newtable = so->table;
671 size_t newmask = (size_t)so->mask;
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800672 so->fill = other->used;
673 so->used = other->used;
Raymond Hettingere4495872015-12-15 00:42:30 -0800674 for (i = other->mask + 1; i > 0 ; i--, other_entry++) {
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700675 key = other_entry->key;
676 if (key != NULL && key != dummy) {
677 Py_INCREF(key);
Raymond Hettinger5088f602015-12-13 18:45:01 -0800678 set_insert_clean(newtable, newmask, key, other_entry->hash);
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700679 }
680 }
681 return 0;
682 }
683
684 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700685 for (i = 0; i <= other->mask; i++) {
686 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700687 key = other_entry->key;
688 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700689 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000690 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000691 }
692 }
693 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000694}
695
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000696static PyObject *
697set_pop(PySetObject *so)
698{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800699 /* Make sure the search finger is in bounds */
700 Py_ssize_t i = so->finger & so->mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200701 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000702 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000703
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000704 assert (PyAnySet_Check(so));
705 if (so->used == 0) {
706 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
707 return NULL;
708 }
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000709
Raymond Hettinger1202a472015-01-18 13:12:42 -0800710 while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
711 i++;
Raymond Hettingered741d42015-01-18 21:25:15 -0800712 if (i > so->mask)
713 i = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000714 }
715 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800717 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 so->used--;
Raymond Hettinger1202a472015-01-18 13:12:42 -0800719 so->finger = i + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000721}
722
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000723PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
724Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000725
726static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000727set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000728{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000729 Py_ssize_t pos = 0;
730 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000731
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000732 while (set_next(so, &pos, &entry))
733 Py_VISIT(entry->key);
734 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000735}
736
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700737/* Work to increase the bit dispersion for closely spaced hash values.
738 This is important because some use cases have many combinations of a
739 small number of elements with nearby hashes so that many distinct
740 combinations collapse to only a handful of distinct hash values. */
741
742static Py_uhash_t
743_shuffle_bits(Py_uhash_t h)
744{
745 return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
746}
747
748/* Most of the constants in this hash algorithm are randomly chosen
749 large primes with "interesting bit patterns" and that passed tests
750 for good collision statistics on a variety of problematic datasets
751 including powersets and graph structures (such as David Eppstein's
752 graph recipes in Lib/test/test_set.py) */
753
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000754static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000755frozenset_hash(PyObject *self)
756{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000757 PySetObject *so = (PySetObject *)self;
Raymond Hettinger41481952015-08-07 00:43:39 -0700758 Py_uhash_t hash = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000760
Raymond Hettingerb501a272015-08-06 22:15:22 -0700761 if (so->hash != -1)
762 return so->hash;
763
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700764 /* Xor-in shuffled bits from every entry's hash field because xor is
765 commutative and a frozenset hash should be independent of order.
766
767 For speed, include null entries and dummy entries and then
768 subtract out their effect afterwards so that the final hash
769 depends only on active entries. This allows the code to be
770 vectorized by the compiler and it saves the unpredictable
771 branches that would arise when trying to exclude null and dummy
772 entries on every iteration. */
773
774 for (entry = so->table; entry <= &so->table[so->mask]; entry++)
775 hash ^= _shuffle_bits(entry->hash);
776
Raymond Hettingera286a512015-08-01 11:07:11 -0700777 /* Remove the effect of an odd number of NULL entries */
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700778 if ((so->mask + 1 - so->fill) & 1)
779 hash ^= _shuffle_bits(0);
780
781 /* Remove the effect of an odd number of dummy entries */
782 if ((so->fill - so->used) & 1)
783 hash ^= _shuffle_bits(-1);
784
Raymond Hettinger41481952015-08-07 00:43:39 -0700785 /* Factor in the number of active entries */
786 hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;
787
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700788 /* Disperse patterns arising in nested frozensets */
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800789 hash = hash * 69069U + 907133923UL;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700790
Raymond Hettinger36c05002015-08-01 10:57:42 -0700791 /* -1 is reserved as an error code */
Victor Stinner12174a52014-08-15 23:17:38 +0200792 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800793 hash = 590923713UL;
Raymond Hettinger36c05002015-08-01 10:57:42 -0700794
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000795 so->hash = hash;
796 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000797}
798
Raymond Hettingera9d99362005-08-05 00:01:15 +0000799/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000800
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000801typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000802 PyObject_HEAD
803 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
804 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700805 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000806 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000807} setiterobject;
808
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000809static void
810setiter_dealloc(setiterobject *si)
811{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000812 Py_XDECREF(si->si_set);
813 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000814}
815
816static int
817setiter_traverse(setiterobject *si, visitproc visit, void *arg)
818{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000819 Py_VISIT(si->si_set);
820 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000821}
822
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000823static PyObject *
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000824setiter_len(setiterobject *si)
825{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000826 Py_ssize_t len = 0;
827 if (si->si_set != NULL && si->si_used == si->si_set->used)
828 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000829 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000830}
831
Armin Rigof5b3e362006-02-11 21:32:43 +0000832PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000833
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000834static PyObject *setiter_iternext(setiterobject *si);
835
836static PyObject *
837setiter_reduce(setiterobject *si)
838{
839 PyObject *list;
840 setiterobject tmp;
841
842 list = PyList_New(0);
843 if (!list)
844 return NULL;
845
Ezio Melotti0e1af282012-09-28 16:43:40 +0300846 /* copy the iterator state */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000847 tmp = *si;
848 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300849
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000850 /* iterate the temporary into a list */
851 for(;;) {
852 PyObject *element = setiter_iternext(&tmp);
853 if (element) {
854 if (PyList_Append(list, element)) {
855 Py_DECREF(element);
856 Py_DECREF(list);
857 Py_XDECREF(tmp.si_set);
858 return NULL;
859 }
860 Py_DECREF(element);
861 } else
862 break;
863 }
864 Py_XDECREF(tmp.si_set);
865 /* check for error */
866 if (tmp.si_set != NULL) {
867 /* we have an error */
868 Py_DECREF(list);
869 return NULL;
870 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200871 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000872}
873
874PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
875
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000876static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000877 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000878 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000879 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000880};
881
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000882static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000883{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700884 PyObject *key;
885 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200886 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000887 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 if (so == NULL)
890 return NULL;
891 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000892
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000893 if (si->si_used != so->used) {
894 PyErr_SetString(PyExc_RuntimeError,
895 "Set changed size during iteration");
896 si->si_used = -1; /* Make this state sticky */
897 return NULL;
898 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700899
900 i = si->si_pos;
901 assert(i>=0);
902 entry = so->table;
903 mask = so->mask;
904 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
905 i++;
906 si->si_pos = i+1;
907 if (i > mask)
908 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000909 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700910 key = entry[i].key;
911 Py_INCREF(key);
912 return key;
913
914fail:
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700915 si->si_set = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +0300916 Py_DECREF(so);
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700917 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000918}
919
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000920PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000921 PyVarObject_HEAD_INIT(&PyType_Type, 0)
922 "set_iterator", /* tp_name */
923 sizeof(setiterobject), /* tp_basicsize */
924 0, /* tp_itemsize */
925 /* methods */
926 (destructor)setiter_dealloc, /* tp_dealloc */
927 0, /* tp_print */
928 0, /* tp_getattr */
929 0, /* tp_setattr */
930 0, /* tp_reserved */
931 0, /* tp_repr */
932 0, /* tp_as_number */
933 0, /* tp_as_sequence */
934 0, /* tp_as_mapping */
935 0, /* tp_hash */
936 0, /* tp_call */
937 0, /* tp_str */
938 PyObject_GenericGetAttr, /* tp_getattro */
939 0, /* tp_setattro */
940 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700941 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000942 0, /* tp_doc */
943 (traverseproc)setiter_traverse, /* tp_traverse */
944 0, /* tp_clear */
945 0, /* tp_richcompare */
946 0, /* tp_weaklistoffset */
947 PyObject_SelfIter, /* tp_iter */
948 (iternextfunc)setiter_iternext, /* tp_iternext */
949 setiter_methods, /* tp_methods */
950 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000951};
952
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000953static PyObject *
954set_iter(PySetObject *so)
955{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000956 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
957 if (si == NULL)
958 return NULL;
959 Py_INCREF(so);
960 si->si_set = so;
961 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700962 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 si->len = so->used;
964 _PyObject_GC_TRACK(si);
965 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000966}
967
Raymond Hettingerd7946662005-08-01 21:39:29 +0000968static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000969set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000970{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 if (PyAnySet_Check(other))
974 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000975
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000976 if (PyDict_CheckExact(other)) {
977 PyObject *value;
978 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000979 Py_hash_t hash;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200980 Py_ssize_t dictsize = PyDict_GET_SIZE(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000981
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 /* Do one big resize at the start, rather than
983 * incrementally resizing as we insert new keys. Expect
984 * that there will be no (or few) overlapping keys.
985 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700986 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000987 return -1;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800988 if ((so->fill + dictsize)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900989 if (set_table_resize(so, (so->used + dictsize)*2) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000990 return -1;
991 }
992 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700993 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000994 return -1;
995 }
996 return 0;
997 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 it = PyObject_GetIter(other);
1000 if (it == NULL)
1001 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +00001002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001004 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 Py_DECREF(it);
1006 Py_DECREF(key);
1007 return -1;
1008 }
1009 Py_DECREF(key);
1010 }
1011 Py_DECREF(it);
1012 if (PyErr_Occurred())
1013 return -1;
1014 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001015}
1016
1017static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001018set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001019{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001021
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001022 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1023 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001024 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001025 return NULL;
1026 }
1027 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001028}
1029
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001031"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001032
Raymond Hettinger426d9952014-05-18 21:40:20 +01001033/* XXX Todo:
1034 If aligned memory allocations become available, make the
1035 set object 64 byte aligned so that most of the fields
1036 can be retrieved or updated in a single cache line.
1037*/
1038
Raymond Hettingera38123e2003-11-24 22:18:49 +00001039static PyObject *
1040make_new_set(PyTypeObject *type, PyObject *iterable)
1041{
Raymond Hettinger8421d712016-04-29 01:37:05 -07001042 PySetObject *so;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001043
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001044 so = (PySetObject *)type->tp_alloc(type, 0);
1045 if (so == NULL)
1046 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001047
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001048 so->fill = 0;
1049 so->used = 0;
1050 so->mask = PySet_MINSIZE - 1;
1051 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001052 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001053 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001056 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001057 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001058 Py_DECREF(so);
1059 return NULL;
1060 }
1061 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001062
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001064}
1065
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001066static PyObject *
1067make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1068{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1070 if (PyType_IsSubtype(type, &PySet_Type))
1071 type = &PySet_Type;
1072 else
1073 type = &PyFrozenSet_Type;
1074 }
1075 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001076}
1077
Raymond Hettingerd7946662005-08-01 21:39:29 +00001078/* The empty frozenset is a singleton */
1079static PyObject *emptyfrozenset = NULL;
1080
Raymond Hettingera690a992003-11-16 16:17:49 +00001081static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001082frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001084 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001085
Serhiy Storchaka68a001d2017-02-06 10:41:46 +02001086 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset()", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001088
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001089 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1090 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001091
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 if (type != &PyFrozenSet_Type)
1093 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001094
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 if (iterable != NULL) {
1096 /* frozenset(f) is idempotent */
1097 if (PyFrozenSet_CheckExact(iterable)) {
1098 Py_INCREF(iterable);
1099 return iterable;
1100 }
1101 result = make_new_set(type, iterable);
1102 if (result == NULL || PySet_GET_SIZE(result))
1103 return result;
1104 Py_DECREF(result);
1105 }
1106 /* The empty frozenset is a singleton */
1107 if (emptyfrozenset == NULL)
1108 emptyfrozenset = make_new_set(type, NULL);
1109 Py_XINCREF(emptyfrozenset);
1110 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001111}
1112
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001113static PyObject *
1114set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1115{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001116 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001117}
1118
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001119/* set_swap_bodies() switches the contents of any two sets by moving their
1120 internal data pointers and, if needed, copying the internal smalltables.
1121 Semantically equivalent to:
1122
1123 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1124
1125 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001126 Useful for operations that update in-place (by allowing an intermediate
1127 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001128*/
1129
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001130static void
1131set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001132{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001133 Py_ssize_t t;
1134 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001136 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001137
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138 t = a->fill; a->fill = b->fill; b->fill = t;
1139 t = a->used; a->used = b->used; b->used = t;
1140 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 u = a->table;
1143 if (a->table == a->smalltable)
1144 u = b->smalltable;
1145 a->table = b->table;
1146 if (b->table == b->smalltable)
1147 a->table = a->smalltable;
1148 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 if (a->table == a->smalltable || b->table == b->smalltable) {
1151 memcpy(tab, a->smalltable, sizeof(tab));
1152 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1153 memcpy(b->smalltable, tab, sizeof(tab));
1154 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001155
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1157 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1158 h = a->hash; a->hash = b->hash; b->hash = h;
1159 } else {
1160 a->hash = -1;
1161 b->hash = -1;
1162 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001163}
1164
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001165static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001166set_copy(PySetObject *so)
1167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001169}
1170
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001171static PyObject *
1172frozenset_copy(PySetObject *so)
1173{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001174 if (PyFrozenSet_CheckExact(so)) {
1175 Py_INCREF(so);
1176 return (PyObject *)so;
1177 }
1178 return set_copy(so);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001179}
1180
Raymond Hettingera690a992003-11-16 16:17:49 +00001181PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1182
1183static PyObject *
Raymond Hettingerc991db22005-08-11 07:58:45 +00001184set_clear(PySetObject *so)
1185{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 set_clear_internal(so);
1187 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001188}
1189
1190PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1191
1192static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001193set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001194{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001195 PySetObject *result;
1196 PyObject *other;
1197 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 result = (PySetObject *)set_copy(so);
1200 if (result == NULL)
1201 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001203 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1204 other = PyTuple_GET_ITEM(args, i);
1205 if ((PyObject *)so == other)
1206 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001207 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001208 Py_DECREF(result);
1209 return NULL;
1210 }
1211 }
1212 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001213}
1214
1215PyDoc_STRVAR(union_doc,
1216 "Return the union of sets as a new set.\n\
1217\n\
1218(i.e. all elements that are in either set.)");
1219
1220static PyObject *
1221set_or(PySetObject *so, PyObject *other)
1222{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001223 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001224
Brian Curtindfc80e32011-08-10 20:28:54 -05001225 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1226 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001228 result = (PySetObject *)set_copy(so);
1229 if (result == NULL)
1230 return NULL;
1231 if ((PyObject *)so == other)
1232 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001233 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 Py_DECREF(result);
1235 return NULL;
1236 }
1237 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001238}
1239
Raymond Hettingera690a992003-11-16 16:17:49 +00001240static PyObject *
1241set_ior(PySetObject *so, PyObject *other)
1242{
Brian Curtindfc80e32011-08-10 20:28:54 -05001243 if (!PyAnySet_Check(other))
1244 Py_RETURN_NOTIMPLEMENTED;
1245
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001246 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 return NULL;
1248 Py_INCREF(so);
1249 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001250}
1251
1252static PyObject *
1253set_intersection(PySetObject *so, PyObject *other)
1254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 PySetObject *result;
1256 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001257 Py_hash_t hash;
1258 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 if ((PyObject *)so == other)
1261 return set_copy(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1264 if (result == NULL)
1265 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 if (PyAnySet_Check(other)) {
1268 Py_ssize_t pos = 0;
1269 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1272 tmp = (PyObject *)so;
1273 so = (PySetObject *)other;
1274 other = tmp;
1275 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001278 key = entry->key;
1279 hash = entry->hash;
1280 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001281 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 Py_DECREF(result);
1283 return NULL;
1284 }
1285 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001286 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 Py_DECREF(result);
1288 return NULL;
1289 }
1290 }
1291 }
1292 return (PyObject *)result;
1293 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 it = PyObject_GetIter(other);
1296 if (it == NULL) {
1297 Py_DECREF(result);
1298 return NULL;
1299 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001300
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001302 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001303 if (hash == -1)
1304 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001305 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001306 if (rv < 0)
1307 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001309 if (set_add_entry(result, key, hash))
1310 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 }
1312 Py_DECREF(key);
1313 }
1314 Py_DECREF(it);
1315 if (PyErr_Occurred()) {
1316 Py_DECREF(result);
1317 return NULL;
1318 }
1319 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001320 error:
1321 Py_DECREF(it);
1322 Py_DECREF(result);
1323 Py_DECREF(key);
1324 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001325}
1326
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001327static PyObject *
1328set_intersection_multi(PySetObject *so, PyObject *args)
1329{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 Py_ssize_t i;
1331 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 if (PyTuple_GET_SIZE(args) == 0)
1334 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 Py_INCREF(so);
1337 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1338 PyObject *other = PyTuple_GET_ITEM(args, i);
1339 PyObject *newresult = set_intersection((PySetObject *)result, other);
1340 if (newresult == NULL) {
1341 Py_DECREF(result);
1342 return NULL;
1343 }
1344 Py_DECREF(result);
1345 result = newresult;
1346 }
1347 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001348}
1349
Raymond Hettingera690a992003-11-16 16:17:49 +00001350PyDoc_STRVAR(intersection_doc,
1351"Return the intersection of two sets as a new set.\n\
1352\n\
1353(i.e. all elements that are in both sets.)");
1354
1355static PyObject *
1356set_intersection_update(PySetObject *so, PyObject *other)
1357{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001360 tmp = set_intersection(so, other);
1361 if (tmp == NULL)
1362 return NULL;
1363 set_swap_bodies(so, (PySetObject *)tmp);
1364 Py_DECREF(tmp);
1365 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001366}
1367
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001368static PyObject *
1369set_intersection_update_multi(PySetObject *so, PyObject *args)
1370{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 tmp = set_intersection_multi(so, args);
1374 if (tmp == NULL)
1375 return NULL;
1376 set_swap_bodies(so, (PySetObject *)tmp);
1377 Py_DECREF(tmp);
1378 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001379}
1380
Raymond Hettingera690a992003-11-16 16:17:49 +00001381PyDoc_STRVAR(intersection_update_doc,
1382"Update a set with the intersection of itself and another.");
1383
1384static PyObject *
1385set_and(PySetObject *so, PyObject *other)
1386{
Brian Curtindfc80e32011-08-10 20:28:54 -05001387 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1388 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001390}
1391
1392static PyObject *
1393set_iand(PySetObject *so, PyObject *other)
1394{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001395 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001396
Brian Curtindfc80e32011-08-10 20:28:54 -05001397 if (!PyAnySet_Check(other))
1398 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399 result = set_intersection_update(so, other);
1400 if (result == NULL)
1401 return NULL;
1402 Py_DECREF(result);
1403 Py_INCREF(so);
1404 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001405}
1406
Guido van Rossum58da9312007-11-10 23:39:45 +00001407static PyObject *
1408set_isdisjoint(PySetObject *so, PyObject *other)
1409{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001410 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001411 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 if ((PyObject *)so == other) {
1414 if (PySet_GET_SIZE(so) == 0)
1415 Py_RETURN_TRUE;
1416 else
1417 Py_RETURN_FALSE;
1418 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 if (PyAnySet_CheckExact(other)) {
1421 Py_ssize_t pos = 0;
1422 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1425 tmp = (PyObject *)so;
1426 so = (PySetObject *)other;
1427 other = tmp;
1428 }
1429 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001430 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001431 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 return NULL;
1433 if (rv)
1434 Py_RETURN_FALSE;
1435 }
1436 Py_RETURN_TRUE;
1437 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 it = PyObject_GetIter(other);
1440 if (it == NULL)
1441 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001443 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001444 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 if (hash == -1) {
1447 Py_DECREF(key);
1448 Py_DECREF(it);
1449 return NULL;
1450 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001451 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001452 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001453 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 Py_DECREF(it);
1455 return NULL;
1456 }
1457 if (rv) {
1458 Py_DECREF(it);
1459 Py_RETURN_FALSE;
1460 }
1461 }
1462 Py_DECREF(it);
1463 if (PyErr_Occurred())
1464 return NULL;
1465 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001466}
1467
1468PyDoc_STRVAR(isdisjoint_doc,
1469"Return True if two sets have a null intersection.");
1470
Neal Norwitz6576bd82005-11-13 18:41:28 +00001471static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001472set_difference_update_internal(PySetObject *so, PyObject *other)
1473{
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001474 if (PySet_GET_SIZE(so) == 0) {
1475 return 0;
1476 }
1477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 if ((PyObject *)so == other)
1479 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 if (PyAnySet_Check(other)) {
1482 setentry *entry;
1483 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001486 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 return -1;
1488 } else {
1489 PyObject *key, *it;
1490 it = PyObject_GetIter(other);
1491 if (it == NULL)
1492 return -1;
1493
1494 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001495 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 Py_DECREF(it);
1497 Py_DECREF(key);
1498 return -1;
1499 }
1500 Py_DECREF(key);
1501 }
1502 Py_DECREF(it);
1503 if (PyErr_Occurred())
1504 return -1;
1505 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001506 /* If more than 1/4th are dummies, then resize them away. */
1507 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +09001509 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001510}
1511
Raymond Hettingera690a992003-11-16 16:17:49 +00001512static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001513set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001514{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1518 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001519 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 return NULL;
1521 }
1522 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001523}
1524
1525PyDoc_STRVAR(difference_update_doc,
1526"Remove all elements of another set from this set.");
1527
1528static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001529set_copy_and_difference(PySetObject *so, PyObject *other)
1530{
1531 PyObject *result;
1532
1533 result = set_copy(so);
1534 if (result == NULL)
1535 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001536 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001537 return result;
1538 Py_DECREF(result);
1539 return NULL;
1540}
1541
1542static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001543set_difference(PySetObject *so, PyObject *other)
1544{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001546 PyObject *key;
1547 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 setentry *entry;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001549 Py_ssize_t pos = 0, other_size;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001550 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001551
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001552 if (PySet_GET_SIZE(so) == 0) {
1553 return set_copy(so);
1554 }
1555
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001556 if (PyAnySet_Check(other)) {
1557 other_size = PySet_GET_SIZE(other);
1558 }
1559 else if (PyDict_CheckExact(other)) {
1560 other_size = PyDict_GET_SIZE(other);
1561 }
1562 else {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001563 return set_copy_and_difference(so, other);
1564 }
1565
1566 /* If len(so) much more than len(other), it's more efficient to simply copy
1567 * so and then iterate other looking for common elements. */
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001568 if ((PySet_GET_SIZE(so) >> 2) > other_size) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001569 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001570 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001571
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 result = make_new_set_basetype(Py_TYPE(so), NULL);
1573 if (result == NULL)
1574 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001575
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 if (PyDict_CheckExact(other)) {
1577 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001578 key = entry->key;
1579 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001580 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001581 if (rv < 0) {
1582 Py_DECREF(result);
1583 return NULL;
1584 }
1585 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001586 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001587 Py_DECREF(result);
1588 return NULL;
1589 }
1590 }
1591 }
1592 return result;
1593 }
1594
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001595 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001596 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001597 key = entry->key;
1598 hash = entry->hash;
1599 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001600 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 Py_DECREF(result);
1602 return NULL;
1603 }
1604 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001605 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 Py_DECREF(result);
1607 return NULL;
1608 }
1609 }
1610 }
1611 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001612}
1613
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001614static PyObject *
1615set_difference_multi(PySetObject *so, PyObject *args)
1616{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001617 Py_ssize_t i;
1618 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001619
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 if (PyTuple_GET_SIZE(args) == 0)
1621 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 other = PyTuple_GET_ITEM(args, 0);
1624 result = set_difference(so, other);
1625 if (result == NULL)
1626 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1629 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001630 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 Py_DECREF(result);
1632 return NULL;
1633 }
1634 }
1635 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001636}
1637
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001638PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001639"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001640\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001641(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001642static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001643set_sub(PySetObject *so, PyObject *other)
1644{
Brian Curtindfc80e32011-08-10 20:28:54 -05001645 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1646 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001648}
1649
1650static PyObject *
1651set_isub(PySetObject *so, PyObject *other)
1652{
Brian Curtindfc80e32011-08-10 20:28:54 -05001653 if (!PyAnySet_Check(other))
1654 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001655 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 return NULL;
1657 Py_INCREF(so);
1658 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001659}
1660
1661static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001662set_symmetric_difference_update(PySetObject *so, PyObject *other)
1663{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001664 PySetObject *otherset;
1665 PyObject *key;
1666 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001667 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001669 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001670
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001671 if ((PyObject *)so == other)
1672 return set_clear(so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001673
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001674 if (PyDict_CheckExact(other)) {
1675 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001676 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001677 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001678 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001679 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001680 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001681 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001682 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001683 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001684 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001685 Py_DECREF(key);
1686 return NULL;
1687 }
1688 }
Georg Brandl2d444492010-09-03 10:52:55 +00001689 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001690 }
1691 Py_RETURN_NONE;
1692 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001693
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001694 if (PyAnySet_Check(other)) {
1695 Py_INCREF(other);
1696 otherset = (PySetObject *)other;
1697 } else {
1698 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1699 if (otherset == NULL)
1700 return NULL;
1701 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001702
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001703 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001704 key = entry->key;
1705 hash = entry->hash;
1706 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001707 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001708 Py_DECREF(otherset);
1709 return NULL;
1710 }
1711 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001712 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001713 Py_DECREF(otherset);
1714 return NULL;
1715 }
1716 }
1717 }
1718 Py_DECREF(otherset);
1719 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001720}
1721
1722PyDoc_STRVAR(symmetric_difference_update_doc,
1723"Update a set with the symmetric difference of itself and another.");
1724
1725static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001726set_symmetric_difference(PySetObject *so, PyObject *other)
1727{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 PyObject *rv;
1729 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001730
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001731 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1732 if (otherset == NULL)
1733 return NULL;
1734 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
1735 if (rv == NULL)
1736 return NULL;
1737 Py_DECREF(rv);
1738 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001739}
1740
1741PyDoc_STRVAR(symmetric_difference_doc,
1742"Return the symmetric difference of two sets as a new set.\n\
1743\n\
1744(i.e. all elements that are in exactly one of the sets.)");
1745
1746static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001747set_xor(PySetObject *so, PyObject *other)
1748{
Brian Curtindfc80e32011-08-10 20:28:54 -05001749 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1750 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001751 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001752}
1753
1754static PyObject *
1755set_ixor(PySetObject *so, PyObject *other)
1756{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001757 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001758
Brian Curtindfc80e32011-08-10 20:28:54 -05001759 if (!PyAnySet_Check(other))
1760 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 result = set_symmetric_difference_update(so, other);
1762 if (result == NULL)
1763 return NULL;
1764 Py_DECREF(result);
1765 Py_INCREF(so);
1766 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001767}
1768
1769static PyObject *
1770set_issubset(PySetObject *so, PyObject *other)
1771{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001772 setentry *entry;
1773 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001774 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001775
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776 if (!PyAnySet_Check(other)) {
1777 PyObject *tmp, *result;
1778 tmp = make_new_set(&PySet_Type, other);
1779 if (tmp == NULL)
1780 return NULL;
1781 result = set_issubset(so, tmp);
1782 Py_DECREF(tmp);
1783 return result;
1784 }
1785 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1786 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001789 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001790 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001791 return NULL;
1792 if (!rv)
1793 Py_RETURN_FALSE;
1794 }
1795 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001796}
1797
1798PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1799
1800static PyObject *
1801set_issuperset(PySetObject *so, PyObject *other)
1802{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001803 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001804
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001805 if (!PyAnySet_Check(other)) {
1806 tmp = make_new_set(&PySet_Type, other);
1807 if (tmp == NULL)
1808 return NULL;
1809 result = set_issuperset(so, tmp);
1810 Py_DECREF(tmp);
1811 return result;
1812 }
1813 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001814}
1815
1816PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1817
Raymond Hettingera690a992003-11-16 16:17:49 +00001818static PyObject *
1819set_richcompare(PySetObject *v, PyObject *w, int op)
1820{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001821 PyObject *r1;
1822 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001823
Brian Curtindfc80e32011-08-10 20:28:54 -05001824 if(!PyAnySet_Check(w))
1825 Py_RETURN_NOTIMPLEMENTED;
1826
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001827 switch (op) {
1828 case Py_EQ:
1829 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1830 Py_RETURN_FALSE;
1831 if (v->hash != -1 &&
1832 ((PySetObject *)w)->hash != -1 &&
1833 v->hash != ((PySetObject *)w)->hash)
1834 Py_RETURN_FALSE;
1835 return set_issubset(v, w);
1836 case Py_NE:
1837 r1 = set_richcompare(v, w, Py_EQ);
1838 if (r1 == NULL)
1839 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001840 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001841 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001842 if (r2 < 0)
1843 return NULL;
1844 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 case Py_LE:
1846 return set_issubset(v, w);
1847 case Py_GE:
1848 return set_issuperset(v, w);
1849 case Py_LT:
1850 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1851 Py_RETURN_FALSE;
1852 return set_issubset(v, w);
1853 case Py_GT:
1854 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1855 Py_RETURN_FALSE;
1856 return set_issuperset(v, w);
1857 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001858 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001859}
1860
Raymond Hettingera690a992003-11-16 16:17:49 +00001861static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001862set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001863{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001864 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 return NULL;
1866 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001867}
1868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001869PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001870"Add an element to a set.\n\
1871\n\
1872This has no effect if the element is already present.");
1873
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001874static int
1875set_contains(PySetObject *so, PyObject *key)
1876{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 PyObject *tmpkey;
1878 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001881 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001882 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1883 return -1;
1884 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001885 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 if (tmpkey == NULL)
1887 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001888 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001889 Py_DECREF(tmpkey);
1890 }
1891 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001892}
1893
1894static PyObject *
1895set_direct_contains(PySetObject *so, PyObject *key)
1896{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001899 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001900 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901 return NULL;
1902 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001903}
1904
1905PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1906
Raymond Hettingera690a992003-11-16 16:17:49 +00001907static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001908set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001909{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 PyObject *tmpkey;
1911 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001913 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001914 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1916 return NULL;
1917 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001918 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 if (tmpkey == NULL)
1920 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001921 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001923 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 return NULL;
1925 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001928 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001929 return NULL;
1930 }
1931 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001932}
1933
1934PyDoc_STRVAR(remove_doc,
1935"Remove an element from a set; it must be a member.\n\
1936\n\
1937If the element is not a member, raise a KeyError.");
1938
1939static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001940set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001941{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001942 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001944
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001945 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001946 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1948 return NULL;
1949 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001950 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 if (tmpkey == NULL)
1952 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001953 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001954 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001955 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001956 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001957 }
1958 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001959}
1960
1961PyDoc_STRVAR(discard_doc,
1962"Remove an element from a set if it is a member.\n\
1963\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001964If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001965
1966static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001967set_reduce(PySetObject *so)
1968{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001969 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001970 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001972 keys = PySequence_List((PyObject *)so);
1973 if (keys == NULL)
1974 goto done;
1975 args = PyTuple_Pack(1, keys);
1976 if (args == NULL)
1977 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001978 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001979 if (dict == NULL) {
1980 PyErr_Clear();
1981 dict = Py_None;
1982 Py_INCREF(dict);
1983 }
1984 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001985done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001986 Py_XDECREF(args);
1987 Py_XDECREF(keys);
1988 Py_XDECREF(dict);
1989 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001990}
1991
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001992static PyObject *
1993set_sizeof(PySetObject *so)
1994{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001995 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001996
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02001997 res = _PyObject_SIZE(Py_TYPE(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001998 if (so->table != so->smalltable)
1999 res = res + (so->mask + 1) * sizeof(setentry);
2000 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002001}
2002
2003PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002004static int
2005set_init(PySetObject *self, PyObject *args, PyObject *kwds)
2006{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002007 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002008
Serhiy Storchaka68a001d2017-02-06 10:41:46 +02002009 if (!_PyArg_NoKeywords("set()", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002010 return -1;
2011 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
2012 return -1;
Raymond Hettingerb72e21b2016-03-25 02:29:59 -07002013 if (self->fill)
2014 set_clear_internal(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002015 self->hash = -1;
2016 if (iterable == NULL)
2017 return 0;
2018 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002019}
2020
Raymond Hettingera690a992003-11-16 16:17:49 +00002021static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002022 set_len, /* sq_length */
2023 0, /* sq_concat */
2024 0, /* sq_repeat */
2025 0, /* sq_item */
2026 0, /* sq_slice */
2027 0, /* sq_ass_item */
2028 0, /* sq_ass_slice */
2029 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002030};
2031
2032/* set object ********************************************************/
2033
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002034#ifdef Py_DEBUG
2035static PyObject *test_c_api(PySetObject *so);
2036
2037PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2038All is well if assertions don't fail.");
2039#endif
2040
Raymond Hettingera690a992003-11-16 16:17:49 +00002041static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002042 {"add", (PyCFunction)set_add, METH_O,
2043 add_doc},
2044 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2045 clear_doc},
2046 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2047 contains_doc},
2048 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2049 copy_doc},
2050 {"discard", (PyCFunction)set_discard, METH_O,
2051 discard_doc},
2052 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2053 difference_doc},
2054 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2055 difference_update_doc},
2056 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2057 intersection_doc},
2058 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2059 intersection_update_doc},
2060 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2061 isdisjoint_doc},
2062 {"issubset", (PyCFunction)set_issubset, METH_O,
2063 issubset_doc},
2064 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2065 issuperset_doc},
2066 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2067 pop_doc},
2068 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2069 reduce_doc},
2070 {"remove", (PyCFunction)set_remove, METH_O,
2071 remove_doc},
2072 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2073 sizeof_doc},
2074 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2075 symmetric_difference_doc},
2076 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2077 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002078#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002079 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2080 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002081#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002082 {"union", (PyCFunction)set_union, METH_VARARGS,
2083 union_doc},
2084 {"update", (PyCFunction)set_update, METH_VARARGS,
2085 update_doc},
2086 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002087};
2088
2089static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002090 0, /*nb_add*/
2091 (binaryfunc)set_sub, /*nb_subtract*/
2092 0, /*nb_multiply*/
2093 0, /*nb_remainder*/
2094 0, /*nb_divmod*/
2095 0, /*nb_power*/
2096 0, /*nb_negative*/
2097 0, /*nb_positive*/
2098 0, /*nb_absolute*/
2099 0, /*nb_bool*/
2100 0, /*nb_invert*/
2101 0, /*nb_lshift*/
2102 0, /*nb_rshift*/
2103 (binaryfunc)set_and, /*nb_and*/
2104 (binaryfunc)set_xor, /*nb_xor*/
2105 (binaryfunc)set_or, /*nb_or*/
2106 0, /*nb_int*/
2107 0, /*nb_reserved*/
2108 0, /*nb_float*/
2109 0, /*nb_inplace_add*/
2110 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2111 0, /*nb_inplace_multiply*/
2112 0, /*nb_inplace_remainder*/
2113 0, /*nb_inplace_power*/
2114 0, /*nb_inplace_lshift*/
2115 0, /*nb_inplace_rshift*/
2116 (binaryfunc)set_iand, /*nb_inplace_and*/
2117 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2118 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002119};
2120
2121PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002122"set() -> new empty set object\n\
2123set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002124\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002125Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002126
2127PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002128 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2129 "set", /* tp_name */
2130 sizeof(PySetObject), /* tp_basicsize */
2131 0, /* tp_itemsize */
2132 /* methods */
2133 (destructor)set_dealloc, /* tp_dealloc */
2134 0, /* tp_print */
2135 0, /* tp_getattr */
2136 0, /* tp_setattr */
2137 0, /* tp_reserved */
2138 (reprfunc)set_repr, /* tp_repr */
2139 &set_as_number, /* tp_as_number */
2140 &set_as_sequence, /* tp_as_sequence */
2141 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002142 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002143 0, /* tp_call */
2144 0, /* tp_str */
2145 PyObject_GenericGetAttr, /* tp_getattro */
2146 0, /* tp_setattro */
2147 0, /* tp_as_buffer */
2148 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2149 Py_TPFLAGS_BASETYPE, /* tp_flags */
2150 set_doc, /* tp_doc */
2151 (traverseproc)set_traverse, /* tp_traverse */
2152 (inquiry)set_clear_internal, /* tp_clear */
2153 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002154 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2155 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002156 0, /* tp_iternext */
2157 set_methods, /* tp_methods */
2158 0, /* tp_members */
2159 0, /* tp_getset */
2160 0, /* tp_base */
2161 0, /* tp_dict */
2162 0, /* tp_descr_get */
2163 0, /* tp_descr_set */
2164 0, /* tp_dictoffset */
2165 (initproc)set_init, /* tp_init */
2166 PyType_GenericAlloc, /* tp_alloc */
2167 set_new, /* tp_new */
2168 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002169};
2170
2171/* frozenset object ********************************************************/
2172
2173
2174static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002175 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2176 contains_doc},
2177 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2178 copy_doc},
2179 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2180 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002181 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002182 intersection_doc},
2183 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2184 isdisjoint_doc},
2185 {"issubset", (PyCFunction)set_issubset, METH_O,
2186 issubset_doc},
2187 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2188 issuperset_doc},
2189 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2190 reduce_doc},
2191 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2192 sizeof_doc},
2193 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2194 symmetric_difference_doc},
2195 {"union", (PyCFunction)set_union, METH_VARARGS,
2196 union_doc},
2197 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002198};
2199
2200static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002201 0, /*nb_add*/
2202 (binaryfunc)set_sub, /*nb_subtract*/
2203 0, /*nb_multiply*/
2204 0, /*nb_remainder*/
2205 0, /*nb_divmod*/
2206 0, /*nb_power*/
2207 0, /*nb_negative*/
2208 0, /*nb_positive*/
2209 0, /*nb_absolute*/
2210 0, /*nb_bool*/
2211 0, /*nb_invert*/
2212 0, /*nb_lshift*/
2213 0, /*nb_rshift*/
2214 (binaryfunc)set_and, /*nb_and*/
2215 (binaryfunc)set_xor, /*nb_xor*/
2216 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002217};
2218
2219PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002220"frozenset() -> empty frozenset object\n\
2221frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002222\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002223Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002224
2225PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002226 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2227 "frozenset", /* tp_name */
2228 sizeof(PySetObject), /* tp_basicsize */
2229 0, /* tp_itemsize */
2230 /* methods */
2231 (destructor)set_dealloc, /* tp_dealloc */
2232 0, /* tp_print */
2233 0, /* tp_getattr */
2234 0, /* tp_setattr */
2235 0, /* tp_reserved */
2236 (reprfunc)set_repr, /* tp_repr */
2237 &frozenset_as_number, /* tp_as_number */
2238 &set_as_sequence, /* tp_as_sequence */
2239 0, /* tp_as_mapping */
2240 frozenset_hash, /* tp_hash */
2241 0, /* tp_call */
2242 0, /* tp_str */
2243 PyObject_GenericGetAttr, /* tp_getattro */
2244 0, /* tp_setattro */
2245 0, /* tp_as_buffer */
2246 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2247 Py_TPFLAGS_BASETYPE, /* tp_flags */
2248 frozenset_doc, /* tp_doc */
2249 (traverseproc)set_traverse, /* tp_traverse */
2250 (inquiry)set_clear_internal, /* tp_clear */
2251 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002252 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002253 (getiterfunc)set_iter, /* tp_iter */
2254 0, /* tp_iternext */
2255 frozenset_methods, /* tp_methods */
2256 0, /* tp_members */
2257 0, /* tp_getset */
2258 0, /* tp_base */
2259 0, /* tp_dict */
2260 0, /* tp_descr_get */
2261 0, /* tp_descr_set */
2262 0, /* tp_dictoffset */
2263 0, /* tp_init */
2264 PyType_GenericAlloc, /* tp_alloc */
2265 frozenset_new, /* tp_new */
2266 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002267};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002268
2269
2270/***** C API functions *************************************************/
2271
2272PyObject *
2273PySet_New(PyObject *iterable)
2274{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002275 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002276}
2277
2278PyObject *
2279PyFrozenSet_New(PyObject *iterable)
2280{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002281 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002282}
2283
Neal Norwitz8c49c822006-03-04 18:41:19 +00002284Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002285PySet_Size(PyObject *anyset)
2286{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002287 if (!PyAnySet_Check(anyset)) {
2288 PyErr_BadInternalCall();
2289 return -1;
2290 }
2291 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002292}
2293
2294int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002295PySet_Clear(PyObject *set)
2296{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002297 if (!PySet_Check(set)) {
2298 PyErr_BadInternalCall();
2299 return -1;
2300 }
2301 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002302}
2303
2304int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002305PySet_Contains(PyObject *anyset, PyObject *key)
2306{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002307 if (!PyAnySet_Check(anyset)) {
2308 PyErr_BadInternalCall();
2309 return -1;
2310 }
2311 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002312}
2313
2314int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002315PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002316{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002317 if (!PySet_Check(set)) {
2318 PyErr_BadInternalCall();
2319 return -1;
2320 }
2321 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002322}
2323
2324int
Christian Heimesfd66e512008-01-29 12:18:50 +00002325PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002326{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002327 if (!PySet_Check(anyset) &&
2328 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2329 PyErr_BadInternalCall();
2330 return -1;
2331 }
2332 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002333}
2334
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002335int
Raymond Hettinger3625af52016-03-27 01:15:07 -07002336PySet_ClearFreeList(void)
2337{
2338 return 0;
2339}
2340
2341void
2342PySet_Fini(void)
2343{
2344 Py_CLEAR(emptyfrozenset);
2345}
2346
2347int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002348_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002349{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002350 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002352 if (!PyAnySet_Check(set)) {
2353 PyErr_BadInternalCall();
2354 return -1;
2355 }
2356 if (set_next((PySetObject *)set, pos, &entry) == 0)
2357 return 0;
2358 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002359 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002360 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002361}
2362
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002363PyObject *
2364PySet_Pop(PyObject *set)
2365{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002366 if (!PySet_Check(set)) {
2367 PyErr_BadInternalCall();
2368 return NULL;
2369 }
2370 return set_pop((PySetObject *)set);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002371}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002372
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002373int
2374_PySet_Update(PyObject *set, PyObject *iterable)
2375{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002376 if (!PySet_Check(set)) {
2377 PyErr_BadInternalCall();
2378 return -1;
2379 }
2380 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002381}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002382
Raymond Hettingere259f132013-12-15 11:56:14 -08002383/* Exported for the gdb plugin's benefit. */
2384PyObject *_PySet_Dummy = dummy;
2385
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002386#ifdef Py_DEBUG
2387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002388/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002389 Returns True and original set is restored. */
2390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002391#define assertRaises(call_return_value, exception) \
2392 do { \
2393 assert(call_return_value); \
2394 assert(PyErr_ExceptionMatches(exception)); \
2395 PyErr_Clear(); \
2396 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002397
2398static PyObject *
2399test_c_api(PySetObject *so)
2400{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002401 Py_ssize_t count;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +02002402 const char *s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002403 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002404 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002406 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002407 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002409 /* Verify preconditions */
2410 assert(PyAnySet_Check(ob));
2411 assert(PyAnySet_CheckExact(ob));
2412 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002414 /* so.clear(); so |= set("abc"); */
2415 str = PyUnicode_FromString("abc");
2416 if (str == NULL)
2417 return NULL;
2418 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002419 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002420 Py_DECREF(str);
2421 return NULL;
2422 }
2423 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002425 /* Exercise type/size checks */
2426 assert(PySet_Size(ob) == 3);
2427 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002429 /* Raise TypeError for non-iterable constructor arguments */
2430 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2431 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002433 /* Raise TypeError for unhashable key */
2434 dup = PySet_New(ob);
2435 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2436 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2437 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002439 /* Exercise successful pop, contains, add, and discard */
2440 elem = PySet_Pop(ob);
2441 assert(PySet_Contains(ob, elem) == 0);
2442 assert(PySet_GET_SIZE(ob) == 2);
2443 assert(PySet_Add(ob, elem) == 0);
2444 assert(PySet_Contains(ob, elem) == 1);
2445 assert(PySet_GET_SIZE(ob) == 3);
2446 assert(PySet_Discard(ob, elem) == 1);
2447 assert(PySet_GET_SIZE(ob) == 2);
2448 assert(PySet_Discard(ob, elem) == 0);
2449 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002450
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002451 /* Exercise clear */
2452 dup2 = PySet_New(dup);
2453 assert(PySet_Clear(dup2) == 0);
2454 assert(PySet_Size(dup2) == 0);
2455 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002457 /* Raise SystemError on clear or update of frozen set */
2458 f = PyFrozenSet_New(dup);
2459 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2460 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2461 assert(PySet_Add(f, elem) == 0);
2462 Py_INCREF(f);
2463 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2464 Py_DECREF(f);
2465 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002467 /* Exercise direct iteration */
2468 i = 0, count = 0;
2469 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
Serhiy Storchaka06515832016-11-20 09:13:07 +02002470 s = PyUnicode_AsUTF8(x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002471 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2472 count++;
2473 }
2474 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002476 /* Exercise updates */
2477 dup2 = PySet_New(NULL);
2478 assert(_PySet_Update(dup2, dup) == 0);
2479 assert(PySet_Size(dup2) == 3);
2480 assert(_PySet_Update(dup2, dup) == 0);
2481 assert(PySet_Size(dup2) == 3);
2482 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002484 /* Raise SystemError when self argument is not a set or frozenset. */
2485 t = PyTuple_New(0);
2486 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2487 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2488 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002490 /* Raise SystemError when self argument is not a set. */
2491 f = PyFrozenSet_New(dup);
2492 assert(PySet_Size(f) == 3);
2493 assert(PyFrozenSet_CheckExact(f));
2494 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2495 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2496 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002498 /* Raise KeyError when popping from an empty set */
2499 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2500 Py_DECREF(ob);
2501 assert(PySet_GET_SIZE(ob) == 0);
2502 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002504 /* Restore the set from the copy using the PyNumber API */
2505 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2506 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002508 /* Verify constructors accept NULL arguments */
2509 f = PySet_New(NULL);
2510 assert(f != NULL);
2511 assert(PySet_GET_SIZE(f) == 0);
2512 Py_DECREF(f);
2513 f = PyFrozenSet_New(NULL);
2514 assert(f != NULL);
2515 assert(PyFrozenSet_CheckExact(f));
2516 assert(PySet_GET_SIZE(f) == 0);
2517 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002519 Py_DECREF(elem);
2520 Py_DECREF(dup);
2521 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002522}
2523
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002524#undef assertRaises
2525
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002526#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002527
2528/***** Dummy Struct *************************************************/
2529
2530static PyObject *
2531dummy_repr(PyObject *op)
2532{
2533 return PyUnicode_FromString("<dummy key>");
2534}
2535
2536static void
2537dummy_dealloc(PyObject* ignore)
2538{
2539 Py_FatalError("deallocating <dummy key>");
2540}
2541
2542static PyTypeObject _PySetDummy_Type = {
2543 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2544 "<dummy key> type",
2545 0,
2546 0,
2547 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2548 0, /*tp_print*/
2549 0, /*tp_getattr*/
2550 0, /*tp_setattr*/
2551 0, /*tp_reserved*/
2552 dummy_repr, /*tp_repr*/
2553 0, /*tp_as_number*/
2554 0, /*tp_as_sequence*/
2555 0, /*tp_as_mapping*/
2556 0, /*tp_hash */
2557 0, /*tp_call */
2558 0, /*tp_str */
2559 0, /*tp_getattro */
2560 0, /*tp_setattro */
2561 0, /*tp_as_buffer */
2562 Py_TPFLAGS_DEFAULT, /*tp_flags */
2563};
2564
2565static PyObject _dummy_struct = {
2566 _PyObject_EXTRA_INIT
2567 2, &_PySetDummy_Type
2568};
2569