blob: 083cbea412f5d3817b41c424bf3b06be55a2f989 [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 Hettingerbd9b2002015-01-18 16:10:30 -08007 Copyright (c) 2003-2015 Python Software Foundation.
Raymond Hettingera9d99362005-08-05 00:01:15 +00008 All rights reserved.
Raymond Hettingerae7b00e2013-09-07 15:05:00 -07009
10 The basic lookup function used by all operations.
11 This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
12
13 The initial probe index is computed as hash mod the table size.
14 Subsequent probe indices are computed as explained in Objects/dictobject.c.
15
16 To improve cache locality, each probe inspects a series of consecutive
17 nearby entries before moving on to probes elsewhere in memory. This leaves
18 us with a hybrid of linear probing and open addressing. The linear probing
19 reduces the cost of hash collisions because consecutive memory accesses
20 tend to be much cheaper than scattered probes. After LINEAR_PROBES steps,
21 we then use open addressing with the upper bits from the hash value. This
22 helps break-up long chains of collisions.
23
24 All arithmetic on hash should ignore overflow.
25
Raymond Hettinger4d45c102015-01-25 16:27:40 -080026 Unlike the dictionary implementation, the lookkey function can return
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070027 NULL if the rich comparison returns an error.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000028*/
29
Raymond Hettingera690a992003-11-16 16:17:49 +000030#include "Python.h"
Raymond Hettingera9d99362005-08-05 00:01:15 +000031#include "structmember.h"
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000032
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000033/* Object used as dummy key to fill deleted entries */
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -050034static PyObject _dummy_struct;
35
36#define dummy (&_dummy_struct)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000037
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000038
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -070039/* ======================================================================== */
40/* ======= Begin logic for probing the hash table ========================= */
41
Raymond Hettinger710a67e2013-09-21 20:17:31 -070042/* Set this to zero to turn-off linear probing */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070043#ifndef LINEAR_PROBES
Raymond Hettinger742d8712013-09-08 00:25:57 -070044#define LINEAR_PROBES 9
Raymond Hettinger8408dc52013-09-15 14:57:15 -070045#endif
Raymond Hettinger742d8712013-09-08 00:25:57 -070046
47/* This must be >= 1 */
48#define PERTURB_SHIFT 5
49
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000050static setentry *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020051set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000052{
Raymond Hettinger70559b52015-07-23 07:42:23 -040053 setentry *table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020054 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070055 size_t perturb;
Raymond Hettingerafe89092013-08-28 20:59:31 -070056 size_t mask = so->mask;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -080057 size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070058 size_t j;
Raymond Hettinger4ef05282013-09-21 15:39:49 -070059 int cmp;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000060
Raymond Hettinger70559b52015-07-23 07:42:23 -040061 entry = &so->table[i];
Raymond Hettingerafe89092013-08-28 20:59:31 -070062 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000063 return entry;
Raymond Hettinger237b34b2013-08-17 02:31:53 -070064
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070065 perturb = hash;
66
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -070067 while (1) {
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080068 if (entry->hash == hash) {
Raymond Hettingerafe89092013-08-28 20:59:31 -070069 PyObject *startkey = entry->key;
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080070 /* startkey cannot be a dummy because the dummy hash field is -1 */
71 assert(startkey != dummy);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -080072 if (startkey == key)
73 return entry;
Raymond Hettinger93035c42015-01-25 16:12:49 -080074 if (PyUnicode_CheckExact(startkey)
75 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -070076 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger93035c42015-01-25 16:12:49 -080077 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -040078 table = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000079 Py_INCREF(startkey);
80 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
81 Py_DECREF(startkey);
Raymond Hettinger426d9952014-05-18 21:40:20 +010082 if (cmp < 0) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083 return NULL;
Raymond Hettinger426d9952014-05-18 21:40:20 +010084 if (table != so->table || entry->key != startkey) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000085 return set_lookkey(so, key, hash);
Raymond Hettinger426d9952014-05-18 21:40:20 +010086 if (cmp > 0) /* likely */
Raymond Hettingerafe89092013-08-28 20:59:31 -070087 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -060088 mask = so->mask; /* help avoid a register spill */
Raymond Hettingerafe89092013-08-28 20:59:31 -070089 }
Raymond Hettingerafe89092013-08-28 20:59:31 -070090
Raymond Hettingerc658d852015-02-02 08:35:00 -080091 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -080092 for (j = 0 ; j < LINEAR_PROBES ; j++) {
Raymond Hettingerc658d852015-02-02 08:35:00 -080093 entry++;
Raymond Hettinger8651a502015-05-27 10:37:20 -070094 if (entry->hash == 0 && entry->key == NULL)
95 return entry;
Raymond Hettingerc658d852015-02-02 08:35:00 -080096 if (entry->hash == hash) {
97 PyObject *startkey = entry->key;
98 assert(startkey != dummy);
99 if (startkey == key)
100 return entry;
101 if (PyUnicode_CheckExact(startkey)
102 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700103 && _PyUnicode_EQ(startkey, key))
Raymond Hettingerc658d852015-02-02 08:35:00 -0800104 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400105 table = so->table;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800106 Py_INCREF(startkey);
107 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
108 Py_DECREF(startkey);
109 if (cmp < 0)
110 return NULL;
111 if (table != so->table || entry->key != startkey)
112 return set_lookkey(so, key, hash);
113 if (cmp > 0)
114 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -0600115 mask = so->mask;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800116 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700117 }
118 }
119
120 perturb >>= PERTURB_SHIFT;
121 i = (i * 5 + 1 + perturb) & mask;
122
Raymond Hettinger70559b52015-07-23 07:42:23 -0400123 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700124 if (entry->key == NULL)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700125 return entry;
126 }
127}
128
Raymond Hettinger15f08692015-07-03 17:21:17 -0700129static int set_table_resize(PySetObject *, Py_ssize_t);
130
Raymond Hettinger8651a502015-05-27 10:37:20 -0700131static int
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400132set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700133{
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400134 setentry *table;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700135 setentry *freeslot;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700136 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700137 size_t perturb;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400138 size_t mask;
139 size_t i; /* Unsigned for defined overflow behavior */
Raymond Hettinger8651a502015-05-27 10:37:20 -0700140 size_t j;
141 int cmp;
142
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400143 /* Pre-increment is necessary to prevent arbitrary code in the rich
144 comparison from deallocating the key just before the insertion. */
145 Py_INCREF(key);
146
147 restart:
148
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400149 mask = so->mask;
150 i = (size_t)hash & mask;
151
Raymond Hettinger70559b52015-07-23 07:42:23 -0400152 entry = &so->table[i];
Raymond Hettinger8651a502015-05-27 10:37:20 -0700153 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700154 goto found_unused;
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700155
156 freeslot = NULL;
157 perturb = hash;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700158
159 while (1) {
160 if (entry->hash == hash) {
161 PyObject *startkey = entry->key;
162 /* startkey cannot be a dummy because the dummy hash field is -1 */
163 assert(startkey != dummy);
164 if (startkey == key)
165 goto found_active;
166 if (PyUnicode_CheckExact(startkey)
167 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700168 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700169 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400170 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700171 Py_INCREF(startkey);
172 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
173 Py_DECREF(startkey);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700174 if (cmp > 0) /* likely */
175 goto found_active;
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700176 if (cmp < 0)
177 goto comparison_error;
178 /* Continuing the search from the current entry only makes
179 sense if the table and entry are unchanged; otherwise,
180 we have to restart from the beginning */
181 if (table != so->table || entry->key != startkey)
182 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700183 mask = so->mask; /* help avoid a register spill */
184 }
Raymond Hettinger70559b52015-07-23 07:42:23 -0400185 else if (entry->hash == -1 && freeslot == NULL)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700186 freeslot = entry;
187
188 if (i + LINEAR_PROBES <= mask) {
189 for (j = 0 ; j < LINEAR_PROBES ; j++) {
190 entry++;
191 if (entry->hash == 0 && entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700192 goto found_unused_or_dummy;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700193 if (entry->hash == hash) {
194 PyObject *startkey = entry->key;
195 assert(startkey != dummy);
196 if (startkey == key)
197 goto found_active;
198 if (PyUnicode_CheckExact(startkey)
199 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700200 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700201 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400202 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700203 Py_INCREF(startkey);
204 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
205 Py_DECREF(startkey);
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700206 if (cmp > 0)
207 goto found_active;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700208 if (cmp < 0)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400209 goto comparison_error;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700210 if (table != so->table || entry->key != startkey)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400211 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700212 mask = so->mask;
213 }
Raymond Hettinger91672612015-06-26 02:50:21 -0700214 else if (entry->hash == -1 && freeslot == NULL)
Raymond Hettingerc658d852015-02-02 08:35:00 -0800215 freeslot = entry;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700216 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000217 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700218
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700219 perturb >>= PERTURB_SHIFT;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -0800220 i = (i * 5 + 1 + perturb) & mask;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700221
Raymond Hettinger70559b52015-07-23 07:42:23 -0400222 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700223 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700224 goto found_unused_or_dummy;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000225 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700226
Raymond Hettinger15f08692015-07-03 17:21:17 -0700227 found_unused_or_dummy:
228 if (freeslot == NULL)
229 goto found_unused;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700230 so->used++;
231 freeslot->key = key;
232 freeslot->hash = hash;
233 return 0;
234
235 found_unused:
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700236 so->fill++;
237 so->used++;
238 entry->key = key;
239 entry->hash = hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700240 if ((size_t)so->fill*3 < mask*2)
241 return 0;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400242 return set_table_resize(so, so->used);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700243
244 found_active:
Raymond Hettinger482c05c2015-07-20 01:23:32 -0400245 Py_DECREF(key);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700246 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000247
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400248 comparison_error:
Raymond Hettinger061091a2015-07-15 23:54:02 -0700249 Py_DECREF(key);
250 return -1;
251}
252
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000253/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000254Internal routine used by set_table_resize() to insert an item which is
255known to be absent from the set. This routine also assumes that
256the set contains no deleted entries. Besides the performance benefit,
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800257there is also safety benefit since using set_add_entry() risks making
258a callback in the middle of a set_table_resize(), see issue 1456209.
259The caller is responsible for updating the key's reference count and
260the setobject's fill and used fields.
Thomas Wouters89f507f2006-12-13 04:49:30 +0000261*/
262static void
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200263set_insert_clean(PySetObject *so, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000264{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000265 setentry *table = so->table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200266 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700267 size_t perturb = hash;
268 size_t mask = (size_t)so->mask;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800269 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700270 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000271
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700272 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800273 entry = &table[i];
274 if (entry->key == NULL)
275 goto found_null;
276 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800277 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800278 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800279 if (entry->key == NULL)
280 goto found_null;
281 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700282 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700283 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800284 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000285 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700286 found_null:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 entry->key = key;
288 entry->hash = hash;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000289}
290
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700291/* ======== End logic for probing the hash table ========================== */
292/* ======================================================================== */
293
Thomas Wouters89f507f2006-12-13 04:49:30 +0000294/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000295Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000296keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000297actually be smaller than the old one.
298*/
299static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000300set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000301{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302 Py_ssize_t newsize;
303 setentry *oldtable, *newtable, *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800304 Py_ssize_t oldfill = so->fill;
305 Py_ssize_t oldused = so->used;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 int is_oldtable_malloced;
307 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 assert(minused >= 0);
Raymond Hettinger48973002015-07-03 20:00:03 -0700310 minused = (minused > 50000) ? minused * 2 : minused * 4;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100313 /* XXX speed-up with intrinsics */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000314 for (newsize = PySet_MINSIZE;
315 newsize <= minused && newsize > 0;
316 newsize <<= 1)
317 ;
318 if (newsize <= 0) {
319 PyErr_NoMemory();
320 return -1;
321 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 /* Get space for a new table. */
324 oldtable = so->table;
325 assert(oldtable != NULL);
326 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000328 if (newsize == PySet_MINSIZE) {
329 /* A large table is shrinking, or we can't get any smaller. */
330 newtable = so->smalltable;
331 if (newtable == oldtable) {
332 if (so->fill == so->used) {
333 /* No dummies, so no point doing anything. */
334 return 0;
335 }
336 /* We're not going to resize it, but rebuild the
337 table anyway to purge old dummy entries.
338 Subtle: This is *necessary* if fill==size,
339 as set_lookkey needs at least one virgin slot to
340 terminate failing searches. If fill < size, it's
341 merely desirable, as dummies slow searches. */
342 assert(so->fill > so->used);
343 memcpy(small_copy, oldtable, sizeof(small_copy));
344 oldtable = small_copy;
345 }
346 }
347 else {
348 newtable = PyMem_NEW(setentry, newsize);
349 if (newtable == NULL) {
350 PyErr_NoMemory();
351 return -1;
352 }
353 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 /* Make the set empty, using the new table. */
356 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 memset(newtable, 0, sizeof(setentry) * newsize);
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800358 so->fill = oldused;
359 so->used = oldused;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800360 so->mask = newsize - 1;
361 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 /* Copy the data over; this is refcount-neutral for active entries;
364 dummy entries aren't copied over, of course */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800365 if (oldfill == oldused) {
366 for (entry = oldtable; oldused > 0; entry++) {
367 if (entry->key != NULL) {
368 oldused--;
369 set_insert_clean(so, entry->key, entry->hash);
370 }
371 }
372 } else {
373 for (entry = oldtable; oldused > 0; entry++) {
374 if (entry->key != NULL && entry->key != dummy) {
375 oldused--;
376 set_insert_clean(so, entry->key, entry->hash);
377 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 }
379 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 if (is_oldtable_malloced)
382 PyMem_DEL(oldtable);
383 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000384}
385
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000386static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700387set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000388{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700389 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000390
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700391 entry = set_lookkey(so, key, hash);
392 if (entry != NULL)
393 return entry->key != NULL;
394 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000395}
396
397#define DISCARD_NOTFOUND 0
398#define DISCARD_FOUND 1
399
400static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700401set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800402{
403 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000405
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700406 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 if (entry == NULL)
408 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700409 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000410 return DISCARD_NOTFOUND;
411 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800413 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000414 so->used--;
415 Py_DECREF(old_key);
416 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000417}
418
419static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700420set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000421{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200422 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000423
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700424 if (!PyUnicode_CheckExact(key) ||
425 (hash = ((PyASCIIObject *) key)->hash) == -1) {
426 hash = PyObject_Hash(key);
427 if (hash == -1)
428 return -1;
429 }
430 return set_add_entry(so, key, hash);
431}
432
433static int
434set_contains_key(PySetObject *so, PyObject *key)
435{
436 Py_hash_t hash;
437
438 if (!PyUnicode_CheckExact(key) ||
439 (hash = ((PyASCIIObject *) key)->hash) == -1) {
440 hash = PyObject_Hash(key);
441 if (hash == -1)
442 return -1;
443 }
444 return set_contains_entry(so, key, hash);
445}
446
447static int
448set_discard_key(PySetObject *so, PyObject *key)
449{
450 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000452 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200453 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 hash = PyObject_Hash(key);
455 if (hash == -1)
456 return -1;
457 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700458 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000459}
460
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700461static void
462set_empty_to_minsize(PySetObject *so)
463{
464 memset(so->smalltable, 0, sizeof(so->smalltable));
465 so->fill = 0;
466 so->used = 0;
467 so->mask = PySet_MINSIZE - 1;
468 so->table = so->smalltable;
469 so->hash = -1;
470}
471
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000472static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000473set_clear_internal(PySetObject *so)
474{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800475 setentry *entry;
476 setentry *table = so->table;
477 Py_ssize_t fill = so->fill;
478 Py_ssize_t used = so->used;
479 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000481
Raymond Hettinger583cd032013-09-07 22:06:35 -0700482 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 /* This is delicate. During the process of clearing the set,
486 * decrefs can cause the set to mutate. To avoid fatal confusion
487 * (voice of experience), we have to make the set empty before
488 * clearing the slots, and never refer to anything via so->ref while
489 * clearing.
490 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000491 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700492 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 else if (fill > 0) {
495 /* It's a small table with something that needs to be cleared.
496 * Afraid the only safe way is to copy the set entries into
497 * another small table first.
498 */
499 memcpy(small_copy, table, sizeof(small_copy));
500 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700501 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000502 }
503 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 /* Now we can finally clear things. If C had refcounts, we could
506 * assert that the refcount on table is 1 now, i.e. that this function
507 * has unique access to it, so decref side-effects can't alter it.
508 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800509 for (entry = table; used > 0; entry++) {
510 if (entry->key && entry->key != dummy) {
511 used--;
512 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000513 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000516 if (table_is_malloced)
517 PyMem_DEL(table);
518 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000519}
520
521/*
522 * Iterate over a set table. Use like so:
523 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000524 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000525 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000526 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000527 * while (set_next(yourset, &pos, &entry)) {
528 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000529 * }
530 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000531 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000533 */
534static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000535set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000536{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 Py_ssize_t i;
538 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700539 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000540
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 assert (PyAnySet_Check(so));
542 i = *pos_ptr;
543 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000544 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700545 entry = &so->table[i];
546 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700548 entry++;
549 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 *pos_ptr = i+1;
551 if (i > mask)
552 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700553 assert(entry != NULL);
554 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000555 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000556}
557
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000558static void
559set_dealloc(PySetObject *so)
560{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200561 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800562 Py_ssize_t used = so->used;
563
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000564 PyObject_GC_UnTrack(so);
565 Py_TRASHCAN_SAFE_BEGIN(so)
566 if (so->weakreflist != NULL)
567 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000568
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800569 for (entry = so->table; used > 0; entry++) {
570 if (entry->key && entry->key != dummy) {
571 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700572 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 }
574 }
575 if (so->table != so->smalltable)
576 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700577 Py_TYPE(so)->tp_free(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 Py_TRASHCAN_SAFE_END(so)
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000579}
580
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000581static PyObject *
582set_repr(PySetObject *so)
583{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200584 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000585 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000586
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000587 if (status != 0) {
588 if (status < 0)
589 return NULL;
590 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
591 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000592
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 /* shortcut for the empty set */
594 if (!so->used) {
595 Py_ReprLeave((PyObject*)so);
596 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
597 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000598
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000599 keys = PySequence_List((PyObject *)so);
600 if (keys == NULL)
601 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000602
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200603 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604 listrepr = PyObject_Repr(keys);
605 Py_DECREF(keys);
606 if (listrepr == NULL)
607 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200608 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200610 if (tmp == NULL)
611 goto done;
612 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200613
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200614 if (Py_TYPE(so) != &PySet_Type)
615 result = PyUnicode_FromFormat("%s({%U})",
616 Py_TYPE(so)->tp_name,
617 listrepr);
618 else
619 result = PyUnicode_FromFormat("{%U}", listrepr);
620 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000621done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622 Py_ReprLeave((PyObject*)so);
623 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000624}
625
Martin v. Löwis18e16552006-02-15 17:27:45 +0000626static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000627set_len(PyObject *so)
628{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000630}
631
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000632static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000633set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000634{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000636 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200637 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700638 setentry *so_entry;
639 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 assert (PyAnySet_Check(so));
642 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000643
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000644 other = (PySetObject*)otherset;
645 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700646 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000647 return 0;
648 /* Do one big resize at the start, rather than
649 * incrementally resizing as we insert new keys. Expect
650 * that there will be no (or few) overlapping keys.
651 */
Raymond Hettinger15f08692015-07-03 17:21:17 -0700652 if ((so->fill + other->used)*3 >= so->mask*2) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700653 if (set_table_resize(so, so->used + other->used) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 return -1;
655 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700656 so_entry = so->table;
657 other_entry = other->table;
658
659 /* If our table is empty, and both tables have the same size, and
660 there are no dummies to eliminate, then just copy the pointers. */
661 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
662 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
663 key = other_entry->key;
664 if (key != NULL) {
665 assert(so_entry->key == NULL);
666 Py_INCREF(key);
667 so_entry->key = key;
668 so_entry->hash = other_entry->hash;
669 }
670 }
671 so->fill = other->fill;
672 so->used = other->used;
673 return 0;
674 }
675
676 /* If our table is empty, we can use set_insert_clean() */
677 if (so->fill == 0) {
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800678 so->fill = other->used;
679 so->used = other->used;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700680 for (i = 0; i <= other->mask; i++, other_entry++) {
681 key = other_entry->key;
682 if (key != NULL && key != dummy) {
683 Py_INCREF(key);
684 set_insert_clean(so, key, other_entry->hash);
685 }
686 }
687 return 0;
688 }
689
690 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700691 for (i = 0; i <= other->mask; i++) {
692 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700693 key = other_entry->key;
694 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700695 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000696 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000697 }
698 }
699 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000700}
701
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000702static PyObject *
703set_pop(PySetObject *so)
704{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800705 /* Make sure the search finger is in bounds */
706 Py_ssize_t i = so->finger & so->mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200707 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000708 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000709
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000710 assert (PyAnySet_Check(so));
711 if (so->used == 0) {
712 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
713 return NULL;
714 }
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000715
Raymond Hettinger1202a472015-01-18 13:12:42 -0800716 while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
717 i++;
Raymond Hettingered741d42015-01-18 21:25:15 -0800718 if (i > so->mask)
719 i = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 }
721 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000722 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800723 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724 so->used--;
Raymond Hettinger1202a472015-01-18 13:12:42 -0800725 so->finger = i + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000727}
728
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000729PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
730Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000731
732static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000733set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000734{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 Py_ssize_t pos = 0;
736 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000737
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 while (set_next(so, &pos, &entry))
739 Py_VISIT(entry->key);
740 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000741}
742
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700743/* Work to increase the bit dispersion for closely spaced hash values.
744 This is important because some use cases have many combinations of a
745 small number of elements with nearby hashes so that many distinct
746 combinations collapse to only a handful of distinct hash values. */
747
748static Py_uhash_t
749_shuffle_bits(Py_uhash_t h)
750{
751 return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
752}
753
754/* Most of the constants in this hash algorithm are randomly chosen
755 large primes with "interesting bit patterns" and that passed tests
756 for good collision statistics on a variety of problematic datasets
757 including powersets and graph structures (such as David Eppstein's
758 graph recipes in Lib/test/test_set.py) */
759
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000760static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000761frozenset_hash(PyObject *self)
762{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000763 PySetObject *so = (PySetObject *)self;
Raymond Hettinger41481952015-08-07 00:43:39 -0700764 Py_uhash_t hash = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000765 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000766
Raymond Hettingerb501a272015-08-06 22:15:22 -0700767 if (so->hash != -1)
768 return so->hash;
769
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700770 /* Xor-in shuffled bits from every entry's hash field because xor is
771 commutative and a frozenset hash should be independent of order.
772
773 For speed, include null entries and dummy entries and then
774 subtract out their effect afterwards so that the final hash
775 depends only on active entries. This allows the code to be
776 vectorized by the compiler and it saves the unpredictable
777 branches that would arise when trying to exclude null and dummy
778 entries on every iteration. */
779
780 for (entry = so->table; entry <= &so->table[so->mask]; entry++)
781 hash ^= _shuffle_bits(entry->hash);
782
Raymond Hettingera286a512015-08-01 11:07:11 -0700783 /* Remove the effect of an odd number of NULL entries */
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700784 if ((so->mask + 1 - so->fill) & 1)
785 hash ^= _shuffle_bits(0);
786
787 /* Remove the effect of an odd number of dummy entries */
788 if ((so->fill - so->used) & 1)
789 hash ^= _shuffle_bits(-1);
790
Raymond Hettinger41481952015-08-07 00:43:39 -0700791 /* Factor in the number of active entries */
792 hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;
793
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700794 /* Disperse patterns arising in nested frozensets */
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800795 hash = hash * 69069U + 907133923UL;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700796
Raymond Hettinger36c05002015-08-01 10:57:42 -0700797 /* -1 is reserved as an error code */
Victor Stinner12174a52014-08-15 23:17:38 +0200798 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800799 hash = 590923713UL;
Raymond Hettinger36c05002015-08-01 10:57:42 -0700800
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000801 so->hash = hash;
802 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000803}
804
Raymond Hettingera9d99362005-08-05 00:01:15 +0000805/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000806
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000807typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000808 PyObject_HEAD
809 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
810 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700811 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000812 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000813} setiterobject;
814
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000815static void
816setiter_dealloc(setiterobject *si)
817{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000818 Py_XDECREF(si->si_set);
819 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000820}
821
822static int
823setiter_traverse(setiterobject *si, visitproc visit, void *arg)
824{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000825 Py_VISIT(si->si_set);
826 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000827}
828
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000829static PyObject *
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000830setiter_len(setiterobject *si)
831{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000832 Py_ssize_t len = 0;
833 if (si->si_set != NULL && si->si_used == si->si_set->used)
834 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000835 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000836}
837
Armin Rigof5b3e362006-02-11 21:32:43 +0000838PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000839
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000840static PyObject *setiter_iternext(setiterobject *si);
841
842static PyObject *
843setiter_reduce(setiterobject *si)
844{
845 PyObject *list;
846 setiterobject tmp;
847
848 list = PyList_New(0);
849 if (!list)
850 return NULL;
851
Ezio Melotti0e1af282012-09-28 16:43:40 +0300852 /* copy the iterator state */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000853 tmp = *si;
854 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300855
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000856 /* iterate the temporary into a list */
857 for(;;) {
858 PyObject *element = setiter_iternext(&tmp);
859 if (element) {
860 if (PyList_Append(list, element)) {
861 Py_DECREF(element);
862 Py_DECREF(list);
863 Py_XDECREF(tmp.si_set);
864 return NULL;
865 }
866 Py_DECREF(element);
867 } else
868 break;
869 }
870 Py_XDECREF(tmp.si_set);
871 /* check for error */
872 if (tmp.si_set != NULL) {
873 /* we have an error */
874 Py_DECREF(list);
875 return NULL;
876 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200877 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000878}
879
880PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
881
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000882static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000883 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000884 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000885 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000886};
887
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000888static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000889{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700890 PyObject *key;
891 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200892 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000893 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000895 if (so == NULL)
896 return NULL;
897 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000899 if (si->si_used != so->used) {
900 PyErr_SetString(PyExc_RuntimeError,
901 "Set changed size during iteration");
902 si->si_used = -1; /* Make this state sticky */
903 return NULL;
904 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700905
906 i = si->si_pos;
907 assert(i>=0);
908 entry = so->table;
909 mask = so->mask;
910 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
911 i++;
912 si->si_pos = i+1;
913 if (i > mask)
914 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000915 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700916 key = entry[i].key;
917 Py_INCREF(key);
918 return key;
919
920fail:
921 Py_DECREF(so);
922 si->si_set = NULL;
923 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000924}
925
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000926PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000927 PyVarObject_HEAD_INIT(&PyType_Type, 0)
928 "set_iterator", /* tp_name */
929 sizeof(setiterobject), /* tp_basicsize */
930 0, /* tp_itemsize */
931 /* methods */
932 (destructor)setiter_dealloc, /* tp_dealloc */
933 0, /* tp_print */
934 0, /* tp_getattr */
935 0, /* tp_setattr */
936 0, /* tp_reserved */
937 0, /* tp_repr */
938 0, /* tp_as_number */
939 0, /* tp_as_sequence */
940 0, /* tp_as_mapping */
941 0, /* tp_hash */
942 0, /* tp_call */
943 0, /* tp_str */
944 PyObject_GenericGetAttr, /* tp_getattro */
945 0, /* tp_setattro */
946 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700947 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000948 0, /* tp_doc */
949 (traverseproc)setiter_traverse, /* tp_traverse */
950 0, /* tp_clear */
951 0, /* tp_richcompare */
952 0, /* tp_weaklistoffset */
953 PyObject_SelfIter, /* tp_iter */
954 (iternextfunc)setiter_iternext, /* tp_iternext */
955 setiter_methods, /* tp_methods */
956 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000957};
958
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000959static PyObject *
960set_iter(PySetObject *so)
961{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000962 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
963 if (si == NULL)
964 return NULL;
965 Py_INCREF(so);
966 si->si_set = so;
967 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700968 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 si->len = so->used;
970 _PyObject_GC_TRACK(si);
971 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000972}
973
Raymond Hettingerd7946662005-08-01 21:39:29 +0000974static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000975set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000976{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000978
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000979 if (PyAnySet_Check(other))
980 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000981
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 if (PyDict_CheckExact(other)) {
983 PyObject *value;
984 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000985 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000986 Py_ssize_t dictsize = PyDict_Size(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 /* Do one big resize at the start, rather than
989 * incrementally resizing as we insert new keys. Expect
990 * that there will be no (or few) overlapping keys.
991 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700992 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000993 return -1;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700994 if ((so->fill + dictsize)*3 >= so->mask*2) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700995 if (set_table_resize(so, so->used + dictsize) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000996 return -1;
997 }
998 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700999 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001000 return -1;
1001 }
1002 return 0;
1003 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 it = PyObject_GetIter(other);
1006 if (it == NULL)
1007 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +00001008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001009 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001010 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001011 Py_DECREF(it);
1012 Py_DECREF(key);
1013 return -1;
1014 }
1015 Py_DECREF(key);
1016 }
1017 Py_DECREF(it);
1018 if (PyErr_Occurred())
1019 return -1;
1020 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001021}
1022
1023static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001024set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001025{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001026 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1029 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001030 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001031 return NULL;
1032 }
1033 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001034}
1035
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001037"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001038
Raymond Hettinger426d9952014-05-18 21:40:20 +01001039/* XXX Todo:
1040 If aligned memory allocations become available, make the
1041 set object 64 byte aligned so that most of the fields
1042 can be retrieved or updated in a single cache line.
1043*/
1044
Raymond Hettingera38123e2003-11-24 22:18:49 +00001045static PyObject *
1046make_new_set(PyTypeObject *type, PyObject *iterable)
1047{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001048 PySetObject *so = NULL;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001049
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001050 /* create PySetObject structure */
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001051 so = (PySetObject *)type->tp_alloc(type, 0);
1052 if (so == NULL)
1053 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001054
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001055 so->fill = 0;
1056 so->used = 0;
1057 so->mask = PySet_MINSIZE - 1;
1058 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001059 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001060 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001062
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001064 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 Py_DECREF(so);
1066 return NULL;
1067 }
1068 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001071}
1072
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001073static PyObject *
1074make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1075{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001076 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1077 if (PyType_IsSubtype(type, &PySet_Type))
1078 type = &PySet_Type;
1079 else
1080 type = &PyFrozenSet_Type;
1081 }
1082 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001083}
1084
Raymond Hettingerd7946662005-08-01 21:39:29 +00001085/* The empty frozenset is a singleton */
1086static PyObject *emptyfrozenset = NULL;
1087
Raymond Hettingera690a992003-11-16 16:17:49 +00001088static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001089frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001090{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001091 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001093 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset()", kwds))
1094 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1097 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 if (type != &PyFrozenSet_Type)
1100 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 if (iterable != NULL) {
1103 /* frozenset(f) is idempotent */
1104 if (PyFrozenSet_CheckExact(iterable)) {
1105 Py_INCREF(iterable);
1106 return iterable;
1107 }
1108 result = make_new_set(type, iterable);
1109 if (result == NULL || PySet_GET_SIZE(result))
1110 return result;
1111 Py_DECREF(result);
1112 }
1113 /* The empty frozenset is a singleton */
1114 if (emptyfrozenset == NULL)
1115 emptyfrozenset = make_new_set(type, NULL);
1116 Py_XINCREF(emptyfrozenset);
1117 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001118}
1119
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001120int
1121PySet_ClearFreeList(void)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001122{
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001123 return 0;
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001124}
1125
1126void
1127PySet_Fini(void)
1128{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001129 Py_CLEAR(emptyfrozenset);
Raymond Hettingera690a992003-11-16 16:17:49 +00001130}
1131
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001132static PyObject *
1133set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1134{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 if (type == &PySet_Type && !_PyArg_NoKeywords("set()", kwds))
1136 return NULL;
1137
1138 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001139}
1140
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001141/* set_swap_bodies() switches the contents of any two sets by moving their
1142 internal data pointers and, if needed, copying the internal smalltables.
1143 Semantically equivalent to:
1144
1145 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1146
1147 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001148 Useful for operations that update in-place (by allowing an intermediate
1149 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001150*/
1151
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001152static void
1153set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001154{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 Py_ssize_t t;
1156 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001157 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001158 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001160 t = a->fill; a->fill = b->fill; b->fill = t;
1161 t = a->used; a->used = b->used; b->used = t;
1162 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 u = a->table;
1165 if (a->table == a->smalltable)
1166 u = b->smalltable;
1167 a->table = b->table;
1168 if (b->table == b->smalltable)
1169 a->table = a->smalltable;
1170 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 if (a->table == a->smalltable || b->table == b->smalltable) {
1173 memcpy(tab, a->smalltable, sizeof(tab));
1174 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1175 memcpy(b->smalltable, tab, sizeof(tab));
1176 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1179 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1180 h = a->hash; a->hash = b->hash; b->hash = h;
1181 } else {
1182 a->hash = -1;
1183 b->hash = -1;
1184 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001185}
1186
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001187static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001188set_copy(PySetObject *so)
1189{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001191}
1192
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001193static PyObject *
1194frozenset_copy(PySetObject *so)
1195{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001196 if (PyFrozenSet_CheckExact(so)) {
1197 Py_INCREF(so);
1198 return (PyObject *)so;
1199 }
1200 return set_copy(so);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001201}
1202
Raymond Hettingera690a992003-11-16 16:17:49 +00001203PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1204
1205static PyObject *
Raymond Hettingerc991db22005-08-11 07:58:45 +00001206set_clear(PySetObject *so)
1207{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001208 set_clear_internal(so);
1209 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001210}
1211
1212PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1213
1214static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001215set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001216{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 PySetObject *result;
1218 PyObject *other;
1219 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001221 result = (PySetObject *)set_copy(so);
1222 if (result == NULL)
1223 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001225 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1226 other = PyTuple_GET_ITEM(args, i);
1227 if ((PyObject *)so == other)
1228 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001229 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001230 Py_DECREF(result);
1231 return NULL;
1232 }
1233 }
1234 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001235}
1236
1237PyDoc_STRVAR(union_doc,
1238 "Return the union of sets as a new set.\n\
1239\n\
1240(i.e. all elements that are in either set.)");
1241
1242static PyObject *
1243set_or(PySetObject *so, PyObject *other)
1244{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001246
Brian Curtindfc80e32011-08-10 20:28:54 -05001247 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1248 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 result = (PySetObject *)set_copy(so);
1251 if (result == NULL)
1252 return NULL;
1253 if ((PyObject *)so == other)
1254 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001255 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 Py_DECREF(result);
1257 return NULL;
1258 }
1259 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001260}
1261
Raymond Hettingera690a992003-11-16 16:17:49 +00001262static PyObject *
1263set_ior(PySetObject *so, PyObject *other)
1264{
Brian Curtindfc80e32011-08-10 20:28:54 -05001265 if (!PyAnySet_Check(other))
1266 Py_RETURN_NOTIMPLEMENTED;
1267
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001268 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001269 return NULL;
1270 Py_INCREF(so);
1271 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001272}
1273
1274static PyObject *
1275set_intersection(PySetObject *so, PyObject *other)
1276{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 PySetObject *result;
1278 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001279 Py_hash_t hash;
1280 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 if ((PyObject *)so == other)
1283 return set_copy(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001285 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1286 if (result == NULL)
1287 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 if (PyAnySet_Check(other)) {
1290 Py_ssize_t pos = 0;
1291 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001292
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001293 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1294 tmp = (PyObject *)so;
1295 so = (PySetObject *)other;
1296 other = tmp;
1297 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001300 key = entry->key;
1301 hash = entry->hash;
1302 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001303 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 Py_DECREF(result);
1305 return NULL;
1306 }
1307 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001308 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001309 Py_DECREF(result);
1310 return NULL;
1311 }
1312 }
1313 }
1314 return (PyObject *)result;
1315 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 it = PyObject_GetIter(other);
1318 if (it == NULL) {
1319 Py_DECREF(result);
1320 return NULL;
1321 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001324 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001325 if (hash == -1)
1326 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001327 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001328 if (rv < 0)
1329 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001331 if (set_add_entry(result, key, hash))
1332 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 }
1334 Py_DECREF(key);
1335 }
1336 Py_DECREF(it);
1337 if (PyErr_Occurred()) {
1338 Py_DECREF(result);
1339 return NULL;
1340 }
1341 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001342 error:
1343 Py_DECREF(it);
1344 Py_DECREF(result);
1345 Py_DECREF(key);
1346 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001347}
1348
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001349static PyObject *
1350set_intersection_multi(PySetObject *so, PyObject *args)
1351{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001352 Py_ssize_t i;
1353 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 if (PyTuple_GET_SIZE(args) == 0)
1356 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 Py_INCREF(so);
1359 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1360 PyObject *other = PyTuple_GET_ITEM(args, i);
1361 PyObject *newresult = set_intersection((PySetObject *)result, other);
1362 if (newresult == NULL) {
1363 Py_DECREF(result);
1364 return NULL;
1365 }
1366 Py_DECREF(result);
1367 result = newresult;
1368 }
1369 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001370}
1371
Raymond Hettingera690a992003-11-16 16:17:49 +00001372PyDoc_STRVAR(intersection_doc,
1373"Return the intersection of two sets as a new set.\n\
1374\n\
1375(i.e. all elements that are in both sets.)");
1376
1377static PyObject *
1378set_intersection_update(PySetObject *so, PyObject *other)
1379{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001380 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382 tmp = set_intersection(so, other);
1383 if (tmp == NULL)
1384 return NULL;
1385 set_swap_bodies(so, (PySetObject *)tmp);
1386 Py_DECREF(tmp);
1387 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001388}
1389
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001390static PyObject *
1391set_intersection_update_multi(PySetObject *so, PyObject *args)
1392{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001395 tmp = set_intersection_multi(so, args);
1396 if (tmp == NULL)
1397 return NULL;
1398 set_swap_bodies(so, (PySetObject *)tmp);
1399 Py_DECREF(tmp);
1400 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001401}
1402
Raymond Hettingera690a992003-11-16 16:17:49 +00001403PyDoc_STRVAR(intersection_update_doc,
1404"Update a set with the intersection of itself and another.");
1405
1406static PyObject *
1407set_and(PySetObject *so, PyObject *other)
1408{
Brian Curtindfc80e32011-08-10 20:28:54 -05001409 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1410 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001412}
1413
1414static PyObject *
1415set_iand(PySetObject *so, PyObject *other)
1416{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001418
Brian Curtindfc80e32011-08-10 20:28:54 -05001419 if (!PyAnySet_Check(other))
1420 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 result = set_intersection_update(so, other);
1422 if (result == NULL)
1423 return NULL;
1424 Py_DECREF(result);
1425 Py_INCREF(so);
1426 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001427}
1428
Guido van Rossum58da9312007-11-10 23:39:45 +00001429static PyObject *
1430set_isdisjoint(PySetObject *so, PyObject *other)
1431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001433 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001434
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 if ((PyObject *)so == other) {
1436 if (PySet_GET_SIZE(so) == 0)
1437 Py_RETURN_TRUE;
1438 else
1439 Py_RETURN_FALSE;
1440 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001442 if (PyAnySet_CheckExact(other)) {
1443 Py_ssize_t pos = 0;
1444 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1447 tmp = (PyObject *)so;
1448 so = (PySetObject *)other;
1449 other = tmp;
1450 }
1451 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001452 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001453 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 return NULL;
1455 if (rv)
1456 Py_RETURN_FALSE;
1457 }
1458 Py_RETURN_TRUE;
1459 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 it = PyObject_GetIter(other);
1462 if (it == NULL)
1463 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001466 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001467
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001468 if (hash == -1) {
1469 Py_DECREF(key);
1470 Py_DECREF(it);
1471 return NULL;
1472 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001473 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001475 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 Py_DECREF(it);
1477 return NULL;
1478 }
1479 if (rv) {
1480 Py_DECREF(it);
1481 Py_RETURN_FALSE;
1482 }
1483 }
1484 Py_DECREF(it);
1485 if (PyErr_Occurred())
1486 return NULL;
1487 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001488}
1489
1490PyDoc_STRVAR(isdisjoint_doc,
1491"Return True if two sets have a null intersection.");
1492
Neal Norwitz6576bd82005-11-13 18:41:28 +00001493static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001494set_difference_update_internal(PySetObject *so, PyObject *other)
1495{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 if ((PyObject *)so == other)
1497 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 if (PyAnySet_Check(other)) {
1500 setentry *entry;
1501 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001504 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 return -1;
1506 } else {
1507 PyObject *key, *it;
1508 it = PyObject_GetIter(other);
1509 if (it == NULL)
1510 return -1;
1511
1512 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001513 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514 Py_DECREF(it);
1515 Py_DECREF(key);
1516 return -1;
1517 }
1518 Py_DECREF(key);
1519 }
1520 Py_DECREF(it);
1521 if (PyErr_Occurred())
1522 return -1;
1523 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001524 /* If more than 1/4th are dummies, then resize them away. */
1525 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001526 return 0;
Raymond Hettinger48973002015-07-03 20:00:03 -07001527 return set_table_resize(so, so->used);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001528}
1529
Raymond Hettingera690a992003-11-16 16:17:49 +00001530static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001531set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001532{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001533 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1536 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001537 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 return NULL;
1539 }
1540 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001541}
1542
1543PyDoc_STRVAR(difference_update_doc,
1544"Remove all elements of another set from this set.");
1545
1546static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001547set_copy_and_difference(PySetObject *so, PyObject *other)
1548{
1549 PyObject *result;
1550
1551 result = set_copy(so);
1552 if (result == NULL)
1553 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001554 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001555 return result;
1556 Py_DECREF(result);
1557 return NULL;
1558}
1559
1560static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001561set_difference(PySetObject *so, PyObject *other)
1562{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001563 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001564 PyObject *key;
1565 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 setentry *entry;
1567 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001568 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001569
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001570 if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001571 return set_copy_and_difference(so, other);
1572 }
1573
1574 /* If len(so) much more than len(other), it's more efficient to simply copy
1575 * so and then iterate other looking for common elements. */
1576 if ((PySet_GET_SIZE(so) >> 2) > PyObject_Size(other)) {
1577 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 result = make_new_set_basetype(Py_TYPE(so), NULL);
1581 if (result == NULL)
1582 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001583
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001584 if (PyDict_CheckExact(other)) {
1585 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001586 key = entry->key;
1587 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001588 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001589 if (rv < 0) {
1590 Py_DECREF(result);
1591 return NULL;
1592 }
1593 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001594 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 Py_DECREF(result);
1596 return NULL;
1597 }
1598 }
1599 }
1600 return result;
1601 }
1602
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001603 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001605 key = entry->key;
1606 hash = entry->hash;
1607 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001608 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001609 Py_DECREF(result);
1610 return NULL;
1611 }
1612 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001613 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001614 Py_DECREF(result);
1615 return NULL;
1616 }
1617 }
1618 }
1619 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001620}
1621
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001622static PyObject *
1623set_difference_multi(PySetObject *so, PyObject *args)
1624{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625 Py_ssize_t i;
1626 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628 if (PyTuple_GET_SIZE(args) == 0)
1629 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 other = PyTuple_GET_ITEM(args, 0);
1632 result = set_difference(so, other);
1633 if (result == NULL)
1634 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001636 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1637 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001638 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 Py_DECREF(result);
1640 return NULL;
1641 }
1642 }
1643 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001644}
1645
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001646PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001647"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001648\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001649(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001650static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001651set_sub(PySetObject *so, PyObject *other)
1652{
Brian Curtindfc80e32011-08-10 20:28:54 -05001653 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1654 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001655 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001656}
1657
1658static PyObject *
1659set_isub(PySetObject *so, PyObject *other)
1660{
Brian Curtindfc80e32011-08-10 20:28:54 -05001661 if (!PyAnySet_Check(other))
1662 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001663 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001664 return NULL;
1665 Py_INCREF(so);
1666 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001667}
1668
1669static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001670set_symmetric_difference_update(PySetObject *so, PyObject *other)
1671{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001672 PySetObject *otherset;
1673 PyObject *key;
1674 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001675 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001676 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001677 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001679 if ((PyObject *)so == other)
1680 return set_clear(so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001681
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001682 if (PyDict_CheckExact(other)) {
1683 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001684 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001685 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001686 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001687 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001688 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001689 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001690 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001691 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001692 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001693 Py_DECREF(key);
1694 return NULL;
1695 }
1696 }
Georg Brandl2d444492010-09-03 10:52:55 +00001697 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001698 }
1699 Py_RETURN_NONE;
1700 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001701
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001702 if (PyAnySet_Check(other)) {
1703 Py_INCREF(other);
1704 otherset = (PySetObject *)other;
1705 } else {
1706 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1707 if (otherset == NULL)
1708 return NULL;
1709 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001710
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001711 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001712 key = entry->key;
1713 hash = entry->hash;
1714 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001715 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001716 Py_DECREF(otherset);
1717 return NULL;
1718 }
1719 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001720 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001721 Py_DECREF(otherset);
1722 return NULL;
1723 }
1724 }
1725 }
1726 Py_DECREF(otherset);
1727 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001728}
1729
1730PyDoc_STRVAR(symmetric_difference_update_doc,
1731"Update a set with the symmetric difference of itself and another.");
1732
1733static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001734set_symmetric_difference(PySetObject *so, PyObject *other)
1735{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001736 PyObject *rv;
1737 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001738
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001739 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1740 if (otherset == NULL)
1741 return NULL;
1742 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
1743 if (rv == NULL)
1744 return NULL;
1745 Py_DECREF(rv);
1746 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001747}
1748
1749PyDoc_STRVAR(symmetric_difference_doc,
1750"Return the symmetric difference of two sets as a new set.\n\
1751\n\
1752(i.e. all elements that are in exactly one of the sets.)");
1753
1754static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001755set_xor(PySetObject *so, PyObject *other)
1756{
Brian Curtindfc80e32011-08-10 20:28:54 -05001757 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1758 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001759 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001760}
1761
1762static PyObject *
1763set_ixor(PySetObject *so, PyObject *other)
1764{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001765 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001766
Brian Curtindfc80e32011-08-10 20:28:54 -05001767 if (!PyAnySet_Check(other))
1768 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001769 result = set_symmetric_difference_update(so, other);
1770 if (result == NULL)
1771 return NULL;
1772 Py_DECREF(result);
1773 Py_INCREF(so);
1774 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001775}
1776
1777static PyObject *
1778set_issubset(PySetObject *so, PyObject *other)
1779{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780 setentry *entry;
1781 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001782 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001784 if (!PyAnySet_Check(other)) {
1785 PyObject *tmp, *result;
1786 tmp = make_new_set(&PySet_Type, other);
1787 if (tmp == NULL)
1788 return NULL;
1789 result = set_issubset(so, tmp);
1790 Py_DECREF(tmp);
1791 return result;
1792 }
1793 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1794 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001795
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001796 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001797 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001798 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001799 return NULL;
1800 if (!rv)
1801 Py_RETURN_FALSE;
1802 }
1803 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001804}
1805
1806PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1807
1808static PyObject *
1809set_issuperset(PySetObject *so, PyObject *other)
1810{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001811 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001812
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001813 if (!PyAnySet_Check(other)) {
1814 tmp = make_new_set(&PySet_Type, other);
1815 if (tmp == NULL)
1816 return NULL;
1817 result = set_issuperset(so, tmp);
1818 Py_DECREF(tmp);
1819 return result;
1820 }
1821 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001822}
1823
1824PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1825
Raymond Hettingera690a992003-11-16 16:17:49 +00001826static PyObject *
1827set_richcompare(PySetObject *v, PyObject *w, int op)
1828{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001829 PyObject *r1;
1830 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001831
Brian Curtindfc80e32011-08-10 20:28:54 -05001832 if(!PyAnySet_Check(w))
1833 Py_RETURN_NOTIMPLEMENTED;
1834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 switch (op) {
1836 case Py_EQ:
1837 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1838 Py_RETURN_FALSE;
1839 if (v->hash != -1 &&
1840 ((PySetObject *)w)->hash != -1 &&
1841 v->hash != ((PySetObject *)w)->hash)
1842 Py_RETURN_FALSE;
1843 return set_issubset(v, w);
1844 case Py_NE:
1845 r1 = set_richcompare(v, w, Py_EQ);
1846 if (r1 == NULL)
1847 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001848 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001849 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001850 if (r2 < 0)
1851 return NULL;
1852 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001853 case Py_LE:
1854 return set_issubset(v, w);
1855 case Py_GE:
1856 return set_issuperset(v, w);
1857 case Py_LT:
1858 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1859 Py_RETURN_FALSE;
1860 return set_issubset(v, w);
1861 case Py_GT:
1862 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1863 Py_RETURN_FALSE;
1864 return set_issuperset(v, w);
1865 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001866 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001867}
1868
Raymond Hettingera690a992003-11-16 16:17:49 +00001869static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001870set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001871{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001872 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873 return NULL;
1874 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001875}
1876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001878"Add an element to a set.\n\
1879\n\
1880This has no effect if the element is already present.");
1881
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001882static int
1883set_contains(PySetObject *so, PyObject *key)
1884{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 PyObject *tmpkey;
1886 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001889 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1891 return -1;
1892 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001893 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 if (tmpkey == NULL)
1895 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001896 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 Py_DECREF(tmpkey);
1898 }
1899 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001900}
1901
1902static PyObject *
1903set_direct_contains(PySetObject *so, PyObject *key)
1904{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001906
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001907 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001908 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 return NULL;
1910 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001911}
1912
1913PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1914
Raymond Hettingera690a992003-11-16 16:17:49 +00001915static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001916set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001917{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001918 PyObject *tmpkey;
1919 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001920
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001921 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001922 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1924 return NULL;
1925 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001926 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927 if (tmpkey == NULL)
1928 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001929 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001931 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001932 return NULL;
1933 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001934
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001935 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001936 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 return NULL;
1938 }
1939 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001940}
1941
1942PyDoc_STRVAR(remove_doc,
1943"Remove an element from a set; it must be a member.\n\
1944\n\
1945If the element is not a member, raise a KeyError.");
1946
1947static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001948set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001949{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001950 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001952
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001953 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001954 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1956 return NULL;
1957 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001958 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001959 if (tmpkey == NULL)
1960 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001961 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001962 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001963 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001964 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001965 }
1966 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001967}
1968
1969PyDoc_STRVAR(discard_doc,
1970"Remove an element from a set if it is a member.\n\
1971\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001972If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001973
1974static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001975set_reduce(PySetObject *so)
1976{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001977 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001978 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 keys = PySequence_List((PyObject *)so);
1981 if (keys == NULL)
1982 goto done;
1983 args = PyTuple_Pack(1, keys);
1984 if (args == NULL)
1985 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001986 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001987 if (dict == NULL) {
1988 PyErr_Clear();
1989 dict = Py_None;
1990 Py_INCREF(dict);
1991 }
1992 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001993done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001994 Py_XDECREF(args);
1995 Py_XDECREF(keys);
1996 Py_XDECREF(dict);
1997 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001998}
1999
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002000static PyObject *
2001set_sizeof(PySetObject *so)
2002{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002005 res = sizeof(PySetObject);
2006 if (so->table != so->smalltable)
2007 res = res + (so->mask + 1) * sizeof(setentry);
2008 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002009}
2010
2011PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002012static int
2013set_init(PySetObject *self, PyObject *args, PyObject *kwds)
2014{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002015 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002017 if (!PyAnySet_Check(self))
2018 return -1;
2019 if (PySet_Check(self) && !_PyArg_NoKeywords("set()", kwds))
2020 return -1;
2021 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
2022 return -1;
2023 set_clear_internal(self);
2024 self->hash = -1;
2025 if (iterable == NULL)
2026 return 0;
2027 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002028}
2029
Raymond Hettingera690a992003-11-16 16:17:49 +00002030static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002031 set_len, /* sq_length */
2032 0, /* sq_concat */
2033 0, /* sq_repeat */
2034 0, /* sq_item */
2035 0, /* sq_slice */
2036 0, /* sq_ass_item */
2037 0, /* sq_ass_slice */
2038 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002039};
2040
2041/* set object ********************************************************/
2042
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002043#ifdef Py_DEBUG
2044static PyObject *test_c_api(PySetObject *so);
2045
2046PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2047All is well if assertions don't fail.");
2048#endif
2049
Raymond Hettingera690a992003-11-16 16:17:49 +00002050static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002051 {"add", (PyCFunction)set_add, METH_O,
2052 add_doc},
2053 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2054 clear_doc},
2055 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2056 contains_doc},
2057 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2058 copy_doc},
2059 {"discard", (PyCFunction)set_discard, METH_O,
2060 discard_doc},
2061 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2062 difference_doc},
2063 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2064 difference_update_doc},
2065 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2066 intersection_doc},
2067 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2068 intersection_update_doc},
2069 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2070 isdisjoint_doc},
2071 {"issubset", (PyCFunction)set_issubset, METH_O,
2072 issubset_doc},
2073 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2074 issuperset_doc},
2075 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2076 pop_doc},
2077 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2078 reduce_doc},
2079 {"remove", (PyCFunction)set_remove, METH_O,
2080 remove_doc},
2081 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2082 sizeof_doc},
2083 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2084 symmetric_difference_doc},
2085 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2086 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002087#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002088 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2089 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002090#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002091 {"union", (PyCFunction)set_union, METH_VARARGS,
2092 union_doc},
2093 {"update", (PyCFunction)set_update, METH_VARARGS,
2094 update_doc},
2095 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002096};
2097
2098static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 0, /*nb_add*/
2100 (binaryfunc)set_sub, /*nb_subtract*/
2101 0, /*nb_multiply*/
2102 0, /*nb_remainder*/
2103 0, /*nb_divmod*/
2104 0, /*nb_power*/
2105 0, /*nb_negative*/
2106 0, /*nb_positive*/
2107 0, /*nb_absolute*/
2108 0, /*nb_bool*/
2109 0, /*nb_invert*/
2110 0, /*nb_lshift*/
2111 0, /*nb_rshift*/
2112 (binaryfunc)set_and, /*nb_and*/
2113 (binaryfunc)set_xor, /*nb_xor*/
2114 (binaryfunc)set_or, /*nb_or*/
2115 0, /*nb_int*/
2116 0, /*nb_reserved*/
2117 0, /*nb_float*/
2118 0, /*nb_inplace_add*/
2119 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2120 0, /*nb_inplace_multiply*/
2121 0, /*nb_inplace_remainder*/
2122 0, /*nb_inplace_power*/
2123 0, /*nb_inplace_lshift*/
2124 0, /*nb_inplace_rshift*/
2125 (binaryfunc)set_iand, /*nb_inplace_and*/
2126 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2127 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002128};
2129
2130PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002131"set() -> new empty set object\n\
2132set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002133\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002134Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002135
2136PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002137 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2138 "set", /* tp_name */
2139 sizeof(PySetObject), /* tp_basicsize */
2140 0, /* tp_itemsize */
2141 /* methods */
2142 (destructor)set_dealloc, /* tp_dealloc */
2143 0, /* tp_print */
2144 0, /* tp_getattr */
2145 0, /* tp_setattr */
2146 0, /* tp_reserved */
2147 (reprfunc)set_repr, /* tp_repr */
2148 &set_as_number, /* tp_as_number */
2149 &set_as_sequence, /* tp_as_sequence */
2150 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002151 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002152 0, /* tp_call */
2153 0, /* tp_str */
2154 PyObject_GenericGetAttr, /* tp_getattro */
2155 0, /* tp_setattro */
2156 0, /* tp_as_buffer */
2157 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2158 Py_TPFLAGS_BASETYPE, /* tp_flags */
2159 set_doc, /* tp_doc */
2160 (traverseproc)set_traverse, /* tp_traverse */
2161 (inquiry)set_clear_internal, /* tp_clear */
2162 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002163 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2164 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002165 0, /* tp_iternext */
2166 set_methods, /* tp_methods */
2167 0, /* tp_members */
2168 0, /* tp_getset */
2169 0, /* tp_base */
2170 0, /* tp_dict */
2171 0, /* tp_descr_get */
2172 0, /* tp_descr_set */
2173 0, /* tp_dictoffset */
2174 (initproc)set_init, /* tp_init */
2175 PyType_GenericAlloc, /* tp_alloc */
2176 set_new, /* tp_new */
2177 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002178};
2179
2180/* frozenset object ********************************************************/
2181
2182
2183static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2185 contains_doc},
2186 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2187 copy_doc},
2188 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2189 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002190 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 intersection_doc},
2192 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2193 isdisjoint_doc},
2194 {"issubset", (PyCFunction)set_issubset, METH_O,
2195 issubset_doc},
2196 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2197 issuperset_doc},
2198 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2199 reduce_doc},
2200 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2201 sizeof_doc},
2202 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2203 symmetric_difference_doc},
2204 {"union", (PyCFunction)set_union, METH_VARARGS,
2205 union_doc},
2206 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002207};
2208
2209static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002210 0, /*nb_add*/
2211 (binaryfunc)set_sub, /*nb_subtract*/
2212 0, /*nb_multiply*/
2213 0, /*nb_remainder*/
2214 0, /*nb_divmod*/
2215 0, /*nb_power*/
2216 0, /*nb_negative*/
2217 0, /*nb_positive*/
2218 0, /*nb_absolute*/
2219 0, /*nb_bool*/
2220 0, /*nb_invert*/
2221 0, /*nb_lshift*/
2222 0, /*nb_rshift*/
2223 (binaryfunc)set_and, /*nb_and*/
2224 (binaryfunc)set_xor, /*nb_xor*/
2225 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002226};
2227
2228PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002229"frozenset() -> empty frozenset object\n\
2230frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002231\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002232Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002233
2234PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002235 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2236 "frozenset", /* tp_name */
2237 sizeof(PySetObject), /* tp_basicsize */
2238 0, /* tp_itemsize */
2239 /* methods */
2240 (destructor)set_dealloc, /* tp_dealloc */
2241 0, /* tp_print */
2242 0, /* tp_getattr */
2243 0, /* tp_setattr */
2244 0, /* tp_reserved */
2245 (reprfunc)set_repr, /* tp_repr */
2246 &frozenset_as_number, /* tp_as_number */
2247 &set_as_sequence, /* tp_as_sequence */
2248 0, /* tp_as_mapping */
2249 frozenset_hash, /* tp_hash */
2250 0, /* tp_call */
2251 0, /* tp_str */
2252 PyObject_GenericGetAttr, /* tp_getattro */
2253 0, /* tp_setattro */
2254 0, /* tp_as_buffer */
2255 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2256 Py_TPFLAGS_BASETYPE, /* tp_flags */
2257 frozenset_doc, /* tp_doc */
2258 (traverseproc)set_traverse, /* tp_traverse */
2259 (inquiry)set_clear_internal, /* tp_clear */
2260 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002261 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002262 (getiterfunc)set_iter, /* tp_iter */
2263 0, /* tp_iternext */
2264 frozenset_methods, /* tp_methods */
2265 0, /* tp_members */
2266 0, /* tp_getset */
2267 0, /* tp_base */
2268 0, /* tp_dict */
2269 0, /* tp_descr_get */
2270 0, /* tp_descr_set */
2271 0, /* tp_dictoffset */
2272 0, /* tp_init */
2273 PyType_GenericAlloc, /* tp_alloc */
2274 frozenset_new, /* tp_new */
2275 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002276};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002277
2278
2279/***** C API functions *************************************************/
2280
2281PyObject *
2282PySet_New(PyObject *iterable)
2283{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002284 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002285}
2286
2287PyObject *
2288PyFrozenSet_New(PyObject *iterable)
2289{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002290 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002291}
2292
Neal Norwitz8c49c822006-03-04 18:41:19 +00002293Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002294PySet_Size(PyObject *anyset)
2295{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002296 if (!PyAnySet_Check(anyset)) {
2297 PyErr_BadInternalCall();
2298 return -1;
2299 }
2300 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002301}
2302
2303int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002304PySet_Clear(PyObject *set)
2305{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002306 if (!PySet_Check(set)) {
2307 PyErr_BadInternalCall();
2308 return -1;
2309 }
2310 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002311}
2312
2313int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002314PySet_Contains(PyObject *anyset, PyObject *key)
2315{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002316 if (!PyAnySet_Check(anyset)) {
2317 PyErr_BadInternalCall();
2318 return -1;
2319 }
2320 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002321}
2322
2323int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002324PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002325{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002326 if (!PySet_Check(set)) {
2327 PyErr_BadInternalCall();
2328 return -1;
2329 }
2330 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002331}
2332
2333int
Christian Heimesfd66e512008-01-29 12:18:50 +00002334PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002335{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002336 if (!PySet_Check(anyset) &&
2337 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2338 PyErr_BadInternalCall();
2339 return -1;
2340 }
2341 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002342}
2343
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002344int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002345_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002346{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002347 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002349 if (!PyAnySet_Check(set)) {
2350 PyErr_BadInternalCall();
2351 return -1;
2352 }
2353 if (set_next((PySetObject *)set, pos, &entry) == 0)
2354 return 0;
2355 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002356 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002357 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002358}
2359
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002360PyObject *
2361PySet_Pop(PyObject *set)
2362{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002363 if (!PySet_Check(set)) {
2364 PyErr_BadInternalCall();
2365 return NULL;
2366 }
2367 return set_pop((PySetObject *)set);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002368}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002369
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002370int
2371_PySet_Update(PyObject *set, PyObject *iterable)
2372{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002373 if (!PySet_Check(set)) {
2374 PyErr_BadInternalCall();
2375 return -1;
2376 }
2377 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002378}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002379
Raymond Hettingere259f132013-12-15 11:56:14 -08002380/* Exported for the gdb plugin's benefit. */
2381PyObject *_PySet_Dummy = dummy;
2382
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002383#ifdef Py_DEBUG
2384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002385/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002386 Returns True and original set is restored. */
2387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002388#define assertRaises(call_return_value, exception) \
2389 do { \
2390 assert(call_return_value); \
2391 assert(PyErr_ExceptionMatches(exception)); \
2392 PyErr_Clear(); \
2393 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002394
2395static PyObject *
2396test_c_api(PySetObject *so)
2397{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002398 Py_ssize_t count;
2399 char *s;
2400 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002401 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002402 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002403 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002406 /* Verify preconditions */
2407 assert(PyAnySet_Check(ob));
2408 assert(PyAnySet_CheckExact(ob));
2409 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002411 /* so.clear(); so |= set("abc"); */
2412 str = PyUnicode_FromString("abc");
2413 if (str == NULL)
2414 return NULL;
2415 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002416 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002417 Py_DECREF(str);
2418 return NULL;
2419 }
2420 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002422 /* Exercise type/size checks */
2423 assert(PySet_Size(ob) == 3);
2424 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002426 /* Raise TypeError for non-iterable constructor arguments */
2427 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2428 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002430 /* Raise TypeError for unhashable key */
2431 dup = PySet_New(ob);
2432 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2433 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2434 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002436 /* Exercise successful pop, contains, add, and discard */
2437 elem = PySet_Pop(ob);
2438 assert(PySet_Contains(ob, elem) == 0);
2439 assert(PySet_GET_SIZE(ob) == 2);
2440 assert(PySet_Add(ob, elem) == 0);
2441 assert(PySet_Contains(ob, elem) == 1);
2442 assert(PySet_GET_SIZE(ob) == 3);
2443 assert(PySet_Discard(ob, elem) == 1);
2444 assert(PySet_GET_SIZE(ob) == 2);
2445 assert(PySet_Discard(ob, elem) == 0);
2446 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002448 /* Exercise clear */
2449 dup2 = PySet_New(dup);
2450 assert(PySet_Clear(dup2) == 0);
2451 assert(PySet_Size(dup2) == 0);
2452 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002453
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002454 /* Raise SystemError on clear or update of frozen set */
2455 f = PyFrozenSet_New(dup);
2456 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2457 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2458 assert(PySet_Add(f, elem) == 0);
2459 Py_INCREF(f);
2460 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2461 Py_DECREF(f);
2462 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002464 /* Exercise direct iteration */
2465 i = 0, count = 0;
2466 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
2467 s = _PyUnicode_AsString(x);
2468 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2469 count++;
2470 }
2471 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002472
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002473 /* Exercise updates */
2474 dup2 = PySet_New(NULL);
2475 assert(_PySet_Update(dup2, dup) == 0);
2476 assert(PySet_Size(dup2) == 3);
2477 assert(_PySet_Update(dup2, dup) == 0);
2478 assert(PySet_Size(dup2) == 3);
2479 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002481 /* Raise SystemError when self argument is not a set or frozenset. */
2482 t = PyTuple_New(0);
2483 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2484 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2485 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002487 /* Raise SystemError when self argument is not a set. */
2488 f = PyFrozenSet_New(dup);
2489 assert(PySet_Size(f) == 3);
2490 assert(PyFrozenSet_CheckExact(f));
2491 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2492 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2493 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002495 /* Raise KeyError when popping from an empty set */
2496 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2497 Py_DECREF(ob);
2498 assert(PySet_GET_SIZE(ob) == 0);
2499 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002501 /* Restore the set from the copy using the PyNumber API */
2502 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2503 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002505 /* Verify constructors accept NULL arguments */
2506 f = PySet_New(NULL);
2507 assert(f != NULL);
2508 assert(PySet_GET_SIZE(f) == 0);
2509 Py_DECREF(f);
2510 f = PyFrozenSet_New(NULL);
2511 assert(f != NULL);
2512 assert(PyFrozenSet_CheckExact(f));
2513 assert(PySet_GET_SIZE(f) == 0);
2514 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002516 Py_DECREF(elem);
2517 Py_DECREF(dup);
2518 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002519}
2520
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002521#undef assertRaises
2522
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002523#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002524
2525/***** Dummy Struct *************************************************/
2526
2527static PyObject *
2528dummy_repr(PyObject *op)
2529{
2530 return PyUnicode_FromString("<dummy key>");
2531}
2532
2533static void
2534dummy_dealloc(PyObject* ignore)
2535{
2536 Py_FatalError("deallocating <dummy key>");
2537}
2538
2539static PyTypeObject _PySetDummy_Type = {
2540 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2541 "<dummy key> type",
2542 0,
2543 0,
2544 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2545 0, /*tp_print*/
2546 0, /*tp_getattr*/
2547 0, /*tp_setattr*/
2548 0, /*tp_reserved*/
2549 dummy_repr, /*tp_repr*/
2550 0, /*tp_as_number*/
2551 0, /*tp_as_sequence*/
2552 0, /*tp_as_mapping*/
2553 0, /*tp_hash */
2554 0, /*tp_call */
2555 0, /*tp_str */
2556 0, /*tp_getattro */
2557 0, /*tp_setattro */
2558 0, /*tp_as_buffer */
2559 Py_TPFLAGS_DEFAULT, /*tp_flags */
2560};
2561
2562static PyObject _dummy_struct = {
2563 _PyObject_EXTRA_INIT
2564 2, &_PySetDummy_Type
2565};
2566