blob: 03bb230961cc0f79ff70eb9ca0fcb2700fa4886c [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,
257using set_insert_clean() in set_table_resize() is dangerous (SF bug #1456209).
258Note that no refcounts are changed by this routine; if needed, the caller
259is responsible for incref'ing `key`.
260*/
261static void
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200262set_insert_clean(PySetObject *so, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000263{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 setentry *table = so->table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200265 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700266 size_t perturb = hash;
267 size_t mask = (size_t)so->mask;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800268 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700269 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000270
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700271 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800272 entry = &table[i];
273 if (entry->key == NULL)
274 goto found_null;
275 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800276 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800277 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800278 if (entry->key == NULL)
279 goto found_null;
280 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700281 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700282 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800283 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700285 found_null:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 entry->key = key;
287 entry->hash = hash;
Raymond Hettinger4ef05282013-09-21 15:39:49 -0700288 so->fill++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289 so->used++;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000290}
291
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700292/* ======== End logic for probing the hash table ========================== */
293/* ======================================================================== */
294
Thomas Wouters89f507f2006-12-13 04:49:30 +0000295/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000296Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000297keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000298actually be smaller than the old one.
299*/
300static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000301set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000302{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000303 Py_ssize_t newsize;
304 setentry *oldtable, *newtable, *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800305 Py_ssize_t oldfill = so->fill;
306 Py_ssize_t oldused = so->used;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 int is_oldtable_malloced;
308 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 assert(minused >= 0);
Raymond Hettinger48973002015-07-03 20:00:03 -0700311 minused = (minused > 50000) ? minused * 2 : minused * 4;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100314 /* XXX speed-up with intrinsics */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 for (newsize = PySet_MINSIZE;
316 newsize <= minused && newsize > 0;
317 newsize <<= 1)
318 ;
319 if (newsize <= 0) {
320 PyErr_NoMemory();
321 return -1;
322 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000324 /* Get space for a new table. */
325 oldtable = so->table;
326 assert(oldtable != NULL);
327 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 if (newsize == PySet_MINSIZE) {
330 /* A large table is shrinking, or we can't get any smaller. */
331 newtable = so->smalltable;
332 if (newtable == oldtable) {
333 if (so->fill == so->used) {
334 /* No dummies, so no point doing anything. */
335 return 0;
336 }
337 /* We're not going to resize it, but rebuild the
338 table anyway to purge old dummy entries.
339 Subtle: This is *necessary* if fill==size,
340 as set_lookkey needs at least one virgin slot to
341 terminate failing searches. If fill < size, it's
342 merely desirable, as dummies slow searches. */
343 assert(so->fill > so->used);
344 memcpy(small_copy, oldtable, sizeof(small_copy));
345 oldtable = small_copy;
346 }
347 }
348 else {
349 newtable = PyMem_NEW(setentry, newsize);
350 if (newtable == NULL) {
351 PyErr_NoMemory();
352 return -1;
353 }
354 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000356 /* Make the set empty, using the new table. */
357 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000358 memset(newtable, 0, sizeof(setentry) * newsize);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 so->fill = 0;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800360 so->used = 0;
361 so->mask = newsize - 1;
362 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 /* Copy the data over; this is refcount-neutral for active entries;
365 dummy entries aren't copied over, of course */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800366 if (oldfill == oldused) {
367 for (entry = oldtable; oldused > 0; entry++) {
368 if (entry->key != NULL) {
369 oldused--;
370 set_insert_clean(so, entry->key, entry->hash);
371 }
372 }
373 } else {
374 for (entry = oldtable; oldused > 0; entry++) {
375 if (entry->key != NULL && entry->key != dummy) {
376 oldused--;
377 set_insert_clean(so, entry->key, entry->hash);
378 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 }
380 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 if (is_oldtable_malloced)
383 PyMem_DEL(oldtable);
384 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000385}
386
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000387static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700388set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000389{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700390 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000391
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700392 entry = set_lookkey(so, key, hash);
393 if (entry != NULL)
394 return entry->key != NULL;
395 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000396}
397
398#define DISCARD_NOTFOUND 0
399#define DISCARD_FOUND 1
400
401static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700402set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800403{
404 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000406
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700407 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 if (entry == NULL)
409 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700410 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000411 return DISCARD_NOTFOUND;
412 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800414 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000415 so->used--;
416 Py_DECREF(old_key);
417 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000418}
419
420static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700421set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000422{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200423 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000424
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700425 if (!PyUnicode_CheckExact(key) ||
426 (hash = ((PyASCIIObject *) key)->hash) == -1) {
427 hash = PyObject_Hash(key);
428 if (hash == -1)
429 return -1;
430 }
431 return set_add_entry(so, key, hash);
432}
433
434static int
435set_contains_key(PySetObject *so, PyObject *key)
436{
437 Py_hash_t hash;
438
439 if (!PyUnicode_CheckExact(key) ||
440 (hash = ((PyASCIIObject *) key)->hash) == -1) {
441 hash = PyObject_Hash(key);
442 if (hash == -1)
443 return -1;
444 }
445 return set_contains_entry(so, key, hash);
446}
447
448static int
449set_discard_key(PySetObject *so, PyObject *key)
450{
451 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200454 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000455 hash = PyObject_Hash(key);
456 if (hash == -1)
457 return -1;
458 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700459 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000460}
461
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700462static void
463set_empty_to_minsize(PySetObject *so)
464{
465 memset(so->smalltable, 0, sizeof(so->smalltable));
466 so->fill = 0;
467 so->used = 0;
468 so->mask = PySet_MINSIZE - 1;
469 so->table = so->smalltable;
470 so->hash = -1;
471}
472
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000473static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000474set_clear_internal(PySetObject *so)
475{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800476 setentry *entry;
477 setentry *table = so->table;
478 Py_ssize_t fill = so->fill;
479 Py_ssize_t used = so->used;
480 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000482
Raymond Hettinger583cd032013-09-07 22:06:35 -0700483 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 /* This is delicate. During the process of clearing the set,
487 * decrefs can cause the set to mutate. To avoid fatal confusion
488 * (voice of experience), we have to make the set empty before
489 * clearing the slots, and never refer to anything via so->ref while
490 * clearing.
491 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700493 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 else if (fill > 0) {
496 /* It's a small table with something that needs to be cleared.
497 * Afraid the only safe way is to copy the set entries into
498 * another small table first.
499 */
500 memcpy(small_copy, table, sizeof(small_copy));
501 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700502 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000503 }
504 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 /* Now we can finally clear things. If C had refcounts, we could
507 * assert that the refcount on table is 1 now, i.e. that this function
508 * has unique access to it, so decref side-effects can't alter it.
509 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800510 for (entry = table; used > 0; entry++) {
511 if (entry->key && entry->key != dummy) {
512 used--;
513 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000517 if (table_is_malloced)
518 PyMem_DEL(table);
519 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000520}
521
522/*
523 * Iterate over a set table. Use like so:
524 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000525 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000526 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000527 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000528 * while (set_next(yourset, &pos, &entry)) {
529 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000530 * }
531 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000532 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000534 */
535static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000536set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000537{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 Py_ssize_t i;
539 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700540 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 assert (PyAnySet_Check(so));
543 i = *pos_ptr;
544 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700546 entry = &so->table[i];
547 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700549 entry++;
550 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 *pos_ptr = i+1;
552 if (i > mask)
553 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700554 assert(entry != NULL);
555 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000556 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000557}
558
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000559static void
560set_dealloc(PySetObject *so)
561{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200562 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800563 Py_ssize_t used = so->used;
564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000565 PyObject_GC_UnTrack(so);
566 Py_TRASHCAN_SAFE_BEGIN(so)
567 if (so->weakreflist != NULL)
568 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000569
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800570 for (entry = so->table; used > 0; entry++) {
571 if (entry->key && entry->key != dummy) {
572 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700573 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000574 }
575 }
576 if (so->table != so->smalltable)
577 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700578 Py_TYPE(so)->tp_free(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000579 Py_TRASHCAN_SAFE_END(so)
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000580}
581
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000582static PyObject *
583set_repr(PySetObject *so)
584{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200585 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 if (status != 0) {
589 if (status < 0)
590 return NULL;
591 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
592 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000594 /* shortcut for the empty set */
595 if (!so->used) {
596 Py_ReprLeave((PyObject*)so);
597 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
598 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 keys = PySequence_List((PyObject *)so);
601 if (keys == NULL)
602 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000603
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200604 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 listrepr = PyObject_Repr(keys);
606 Py_DECREF(keys);
607 if (listrepr == NULL)
608 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200609 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200611 if (tmp == NULL)
612 goto done;
613 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200614
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200615 if (Py_TYPE(so) != &PySet_Type)
616 result = PyUnicode_FromFormat("%s({%U})",
617 Py_TYPE(so)->tp_name,
618 listrepr);
619 else
620 result = PyUnicode_FromFormat("{%U}", listrepr);
621 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000622done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 Py_ReprLeave((PyObject*)so);
624 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000625}
626
Martin v. Löwis18e16552006-02-15 17:27:45 +0000627static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000628set_len(PyObject *so)
629{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000631}
632
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000633static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000634set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000635{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000636 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000637 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200638 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700639 setentry *so_entry;
640 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000641
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000642 assert (PyAnySet_Check(so));
643 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000644
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000645 other = (PySetObject*)otherset;
646 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700647 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 return 0;
649 /* Do one big resize at the start, rather than
650 * incrementally resizing as we insert new keys. Expect
651 * that there will be no (or few) overlapping keys.
652 */
Raymond Hettinger15f08692015-07-03 17:21:17 -0700653 if ((so->fill + other->used)*3 >= so->mask*2) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700654 if (set_table_resize(so, so->used + other->used) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000655 return -1;
656 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700657 so_entry = so->table;
658 other_entry = other->table;
659
660 /* If our table is empty, and both tables have the same size, and
661 there are no dummies to eliminate, then just copy the pointers. */
662 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
663 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
664 key = other_entry->key;
665 if (key != NULL) {
666 assert(so_entry->key == NULL);
667 Py_INCREF(key);
668 so_entry->key = key;
669 so_entry->hash = other_entry->hash;
670 }
671 }
672 so->fill = other->fill;
673 so->used = other->used;
674 return 0;
675 }
676
677 /* If our table is empty, we can use set_insert_clean() */
678 if (so->fill == 0) {
679 for (i = 0; i <= other->mask; i++, other_entry++) {
680 key = other_entry->key;
681 if (key != NULL && key != dummy) {
682 Py_INCREF(key);
683 set_insert_clean(so, key, other_entry->hash);
684 }
685 }
686 return 0;
687 }
688
689 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700690 for (i = 0; i <= other->mask; i++) {
691 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700692 key = other_entry->key;
693 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700694 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000696 }
697 }
698 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000699}
700
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000701static PyObject *
702set_pop(PySetObject *so)
703{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800704 /* Make sure the search finger is in bounds */
705 Py_ssize_t i = so->finger & so->mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200706 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000708
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000709 assert (PyAnySet_Check(so));
710 if (so->used == 0) {
711 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
712 return NULL;
713 }
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000714
Raymond Hettinger1202a472015-01-18 13:12:42 -0800715 while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
716 i++;
Raymond Hettingered741d42015-01-18 21:25:15 -0800717 if (i > so->mask)
718 i = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 }
720 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800722 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 so->used--;
Raymond Hettinger1202a472015-01-18 13:12:42 -0800724 so->finger = i + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000726}
727
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000728PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
729Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000730
731static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000732set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000733{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 Py_ssize_t pos = 0;
735 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000736
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000737 while (set_next(so, &pos, &entry))
738 Py_VISIT(entry->key);
739 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000740}
741
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700742/* Work to increase the bit dispersion for closely spaced hash values.
743 This is important because some use cases have many combinations of a
744 small number of elements with nearby hashes so that many distinct
745 combinations collapse to only a handful of distinct hash values. */
746
747static Py_uhash_t
748_shuffle_bits(Py_uhash_t h)
749{
750 return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
751}
752
753/* Most of the constants in this hash algorithm are randomly chosen
754 large primes with "interesting bit patterns" and that passed tests
755 for good collision statistics on a variety of problematic datasets
756 including powersets and graph structures (such as David Eppstein's
757 graph recipes in Lib/test/test_set.py) */
758
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000759static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000760frozenset_hash(PyObject *self)
761{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 PySetObject *so = (PySetObject *)self;
Raymond Hettinger41481952015-08-07 00:43:39 -0700763 Py_uhash_t hash = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000764 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000765
Raymond Hettingerb501a272015-08-06 22:15:22 -0700766 if (so->hash != -1)
767 return so->hash;
768
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700769 /* Xor-in shuffled bits from every entry's hash field because xor is
770 commutative and a frozenset hash should be independent of order.
771
772 For speed, include null entries and dummy entries and then
773 subtract out their effect afterwards so that the final hash
774 depends only on active entries. This allows the code to be
775 vectorized by the compiler and it saves the unpredictable
776 branches that would arise when trying to exclude null and dummy
777 entries on every iteration. */
778
779 for (entry = so->table; entry <= &so->table[so->mask]; entry++)
780 hash ^= _shuffle_bits(entry->hash);
781
Raymond Hettingera286a512015-08-01 11:07:11 -0700782 /* Remove the effect of an odd number of NULL entries */
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700783 if ((so->mask + 1 - so->fill) & 1)
784 hash ^= _shuffle_bits(0);
785
786 /* Remove the effect of an odd number of dummy entries */
787 if ((so->fill - so->used) & 1)
788 hash ^= _shuffle_bits(-1);
789
Raymond Hettinger41481952015-08-07 00:43:39 -0700790 /* Factor in the number of active entries */
791 hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;
792
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700793 /* Disperse patterns arising in nested frozensets */
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800794 hash = hash * 69069U + 907133923UL;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700795
Raymond Hettinger36c05002015-08-01 10:57:42 -0700796 /* -1 is reserved as an error code */
Victor Stinner12174a52014-08-15 23:17:38 +0200797 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800798 hash = 590923713UL;
Raymond Hettinger36c05002015-08-01 10:57:42 -0700799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 so->hash = hash;
801 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000802}
803
Raymond Hettingera9d99362005-08-05 00:01:15 +0000804/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000805
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000806typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000807 PyObject_HEAD
808 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
809 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700810 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000811 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000812} setiterobject;
813
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000814static void
815setiter_dealloc(setiterobject *si)
816{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000817 Py_XDECREF(si->si_set);
818 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000819}
820
821static int
822setiter_traverse(setiterobject *si, visitproc visit, void *arg)
823{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000824 Py_VISIT(si->si_set);
825 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000826}
827
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000828static PyObject *
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000829setiter_len(setiterobject *si)
830{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000831 Py_ssize_t len = 0;
832 if (si->si_set != NULL && si->si_used == si->si_set->used)
833 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000834 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000835}
836
Armin Rigof5b3e362006-02-11 21:32:43 +0000837PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000838
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000839static PyObject *setiter_iternext(setiterobject *si);
840
841static PyObject *
842setiter_reduce(setiterobject *si)
843{
844 PyObject *list;
845 setiterobject tmp;
846
847 list = PyList_New(0);
848 if (!list)
849 return NULL;
850
Ezio Melotti0e1af282012-09-28 16:43:40 +0300851 /* copy the iterator state */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000852 tmp = *si;
853 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300854
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000855 /* iterate the temporary into a list */
856 for(;;) {
857 PyObject *element = setiter_iternext(&tmp);
858 if (element) {
859 if (PyList_Append(list, element)) {
860 Py_DECREF(element);
861 Py_DECREF(list);
862 Py_XDECREF(tmp.si_set);
863 return NULL;
864 }
865 Py_DECREF(element);
866 } else
867 break;
868 }
869 Py_XDECREF(tmp.si_set);
870 /* check for error */
871 if (tmp.si_set != NULL) {
872 /* we have an error */
873 Py_DECREF(list);
874 return NULL;
875 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200876 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000877}
878
879PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
880
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000881static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000882 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000883 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000884 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000885};
886
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000887static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000888{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700889 PyObject *key;
890 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200891 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000892 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000894 if (so == NULL)
895 return NULL;
896 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000897
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000898 if (si->si_used != so->used) {
899 PyErr_SetString(PyExc_RuntimeError,
900 "Set changed size during iteration");
901 si->si_used = -1; /* Make this state sticky */
902 return NULL;
903 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700904
905 i = si->si_pos;
906 assert(i>=0);
907 entry = so->table;
908 mask = so->mask;
909 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
910 i++;
911 si->si_pos = i+1;
912 if (i > mask)
913 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000914 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700915 key = entry[i].key;
916 Py_INCREF(key);
917 return key;
918
919fail:
920 Py_DECREF(so);
921 si->si_set = NULL;
922 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000923}
924
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000925PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 PyVarObject_HEAD_INIT(&PyType_Type, 0)
927 "set_iterator", /* tp_name */
928 sizeof(setiterobject), /* tp_basicsize */
929 0, /* tp_itemsize */
930 /* methods */
931 (destructor)setiter_dealloc, /* tp_dealloc */
932 0, /* tp_print */
933 0, /* tp_getattr */
934 0, /* tp_setattr */
935 0, /* tp_reserved */
936 0, /* tp_repr */
937 0, /* tp_as_number */
938 0, /* tp_as_sequence */
939 0, /* tp_as_mapping */
940 0, /* tp_hash */
941 0, /* tp_call */
942 0, /* tp_str */
943 PyObject_GenericGetAttr, /* tp_getattro */
944 0, /* tp_setattro */
945 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700946 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000947 0, /* tp_doc */
948 (traverseproc)setiter_traverse, /* tp_traverse */
949 0, /* tp_clear */
950 0, /* tp_richcompare */
951 0, /* tp_weaklistoffset */
952 PyObject_SelfIter, /* tp_iter */
953 (iternextfunc)setiter_iternext, /* tp_iternext */
954 setiter_methods, /* tp_methods */
955 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000956};
957
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000958static PyObject *
959set_iter(PySetObject *so)
960{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
962 if (si == NULL)
963 return NULL;
964 Py_INCREF(so);
965 si->si_set = so;
966 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700967 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000968 si->len = so->used;
969 _PyObject_GC_TRACK(si);
970 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000971}
972
Raymond Hettingerd7946662005-08-01 21:39:29 +0000973static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000974set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000975{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000976 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 if (PyAnySet_Check(other))
979 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981 if (PyDict_CheckExact(other)) {
982 PyObject *value;
983 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000984 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 Py_ssize_t dictsize = PyDict_Size(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000987 /* Do one big resize at the start, rather than
988 * incrementally resizing as we insert new keys. Expect
989 * that there will be no (or few) overlapping keys.
990 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700991 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000992 return -1;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700993 if ((so->fill + dictsize)*3 >= so->mask*2) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700994 if (set_table_resize(so, so->used + dictsize) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000995 return -1;
996 }
997 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700998 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 return -1;
1000 }
1001 return 0;
1002 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 it = PyObject_GetIter(other);
1005 if (it == NULL)
1006 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +00001007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001009 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001010 Py_DECREF(it);
1011 Py_DECREF(key);
1012 return -1;
1013 }
1014 Py_DECREF(key);
1015 }
1016 Py_DECREF(it);
1017 if (PyErr_Occurred())
1018 return -1;
1019 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001020}
1021
1022static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001023set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001024{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001025 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001026
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1028 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001029 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 return NULL;
1031 }
1032 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001033}
1034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001035PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001036"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001037
Raymond Hettinger426d9952014-05-18 21:40:20 +01001038/* XXX Todo:
1039 If aligned memory allocations become available, make the
1040 set object 64 byte aligned so that most of the fields
1041 can be retrieved or updated in a single cache line.
1042*/
1043
Raymond Hettingera38123e2003-11-24 22:18:49 +00001044static PyObject *
1045make_new_set(PyTypeObject *type, PyObject *iterable)
1046{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001047 PySetObject *so = NULL;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001048
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 /* create PySetObject structure */
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001050 so = (PySetObject *)type->tp_alloc(type, 0);
1051 if (so == NULL)
1052 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001053
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001054 so->fill = 0;
1055 so->used = 0;
1056 so->mask = PySet_MINSIZE - 1;
1057 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001058 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001059 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001063 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001064 Py_DECREF(so);
1065 return NULL;
1066 }
1067 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001070}
1071
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001072static PyObject *
1073make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1074{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001075 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1076 if (PyType_IsSubtype(type, &PySet_Type))
1077 type = &PySet_Type;
1078 else
1079 type = &PyFrozenSet_Type;
1080 }
1081 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001082}
1083
Raymond Hettingerd7946662005-08-01 21:39:29 +00001084/* The empty frozenset is a singleton */
1085static PyObject *emptyfrozenset = NULL;
1086
Raymond Hettingera690a992003-11-16 16:17:49 +00001087static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001088frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001089{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001090 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001091
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset()", kwds))
1093 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001094
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1096 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001098 if (type != &PyFrozenSet_Type)
1099 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001100
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001101 if (iterable != NULL) {
1102 /* frozenset(f) is idempotent */
1103 if (PyFrozenSet_CheckExact(iterable)) {
1104 Py_INCREF(iterable);
1105 return iterable;
1106 }
1107 result = make_new_set(type, iterable);
1108 if (result == NULL || PySet_GET_SIZE(result))
1109 return result;
1110 Py_DECREF(result);
1111 }
1112 /* The empty frozenset is a singleton */
1113 if (emptyfrozenset == NULL)
1114 emptyfrozenset = make_new_set(type, NULL);
1115 Py_XINCREF(emptyfrozenset);
1116 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001117}
1118
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001119int
1120PySet_ClearFreeList(void)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001121{
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001122 return 0;
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001123}
1124
1125void
1126PySet_Fini(void)
1127{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001128 Py_CLEAR(emptyfrozenset);
Raymond Hettingera690a992003-11-16 16:17:49 +00001129}
1130
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001131static PyObject *
1132set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1133{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001134 if (type == &PySet_Type && !_PyArg_NoKeywords("set()", kwds))
1135 return NULL;
1136
1137 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001138}
1139
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001140/* set_swap_bodies() switches the contents of any two sets by moving their
1141 internal data pointers and, if needed, copying the internal smalltables.
1142 Semantically equivalent to:
1143
1144 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1145
1146 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001147 Useful for operations that update in-place (by allowing an intermediate
1148 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001149*/
1150
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001151static void
1152set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001153{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001154 Py_ssize_t t;
1155 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001157 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 t = a->fill; a->fill = b->fill; b->fill = t;
1160 t = a->used; a->used = b->used; b->used = t;
1161 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001163 u = a->table;
1164 if (a->table == a->smalltable)
1165 u = b->smalltable;
1166 a->table = b->table;
1167 if (b->table == b->smalltable)
1168 a->table = a->smalltable;
1169 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001171 if (a->table == a->smalltable || b->table == b->smalltable) {
1172 memcpy(tab, a->smalltable, sizeof(tab));
1173 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1174 memcpy(b->smalltable, tab, sizeof(tab));
1175 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001177 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1178 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1179 h = a->hash; a->hash = b->hash; b->hash = h;
1180 } else {
1181 a->hash = -1;
1182 b->hash = -1;
1183 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001184}
1185
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001186static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001187set_copy(PySetObject *so)
1188{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001190}
1191
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001192static PyObject *
1193frozenset_copy(PySetObject *so)
1194{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001195 if (PyFrozenSet_CheckExact(so)) {
1196 Py_INCREF(so);
1197 return (PyObject *)so;
1198 }
1199 return set_copy(so);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001200}
1201
Raymond Hettingera690a992003-11-16 16:17:49 +00001202PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1203
1204static PyObject *
Raymond Hettingerc991db22005-08-11 07:58:45 +00001205set_clear(PySetObject *so)
1206{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 set_clear_internal(so);
1208 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001209}
1210
1211PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1212
1213static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001214set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001215{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 PySetObject *result;
1217 PyObject *other;
1218 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001220 result = (PySetObject *)set_copy(so);
1221 if (result == NULL)
1222 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001223
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001224 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1225 other = PyTuple_GET_ITEM(args, i);
1226 if ((PyObject *)so == other)
1227 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001228 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001229 Py_DECREF(result);
1230 return NULL;
1231 }
1232 }
1233 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001234}
1235
1236PyDoc_STRVAR(union_doc,
1237 "Return the union of sets as a new set.\n\
1238\n\
1239(i.e. all elements that are in either set.)");
1240
1241static PyObject *
1242set_or(PySetObject *so, PyObject *other)
1243{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001245
Brian Curtindfc80e32011-08-10 20:28:54 -05001246 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1247 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 result = (PySetObject *)set_copy(so);
1250 if (result == NULL)
1251 return NULL;
1252 if ((PyObject *)so == other)
1253 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001254 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 Py_DECREF(result);
1256 return NULL;
1257 }
1258 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001259}
1260
Raymond Hettingera690a992003-11-16 16:17:49 +00001261static PyObject *
1262set_ior(PySetObject *so, PyObject *other)
1263{
Brian Curtindfc80e32011-08-10 20:28:54 -05001264 if (!PyAnySet_Check(other))
1265 Py_RETURN_NOTIMPLEMENTED;
1266
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001267 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 return NULL;
1269 Py_INCREF(so);
1270 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001271}
1272
1273static PyObject *
1274set_intersection(PySetObject *so, PyObject *other)
1275{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001276 PySetObject *result;
1277 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001278 Py_hash_t hash;
1279 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 if ((PyObject *)so == other)
1282 return set_copy(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1285 if (result == NULL)
1286 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 if (PyAnySet_Check(other)) {
1289 Py_ssize_t pos = 0;
1290 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1293 tmp = (PyObject *)so;
1294 so = (PySetObject *)other;
1295 other = tmp;
1296 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001299 key = entry->key;
1300 hash = entry->hash;
1301 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001302 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 Py_DECREF(result);
1304 return NULL;
1305 }
1306 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001307 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 Py_DECREF(result);
1309 return NULL;
1310 }
1311 }
1312 }
1313 return (PyObject *)result;
1314 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 it = PyObject_GetIter(other);
1317 if (it == NULL) {
1318 Py_DECREF(result);
1319 return NULL;
1320 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001323 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001324 if (hash == -1)
1325 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001326 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001327 if (rv < 0)
1328 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001330 if (set_add_entry(result, key, hash))
1331 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001332 }
1333 Py_DECREF(key);
1334 }
1335 Py_DECREF(it);
1336 if (PyErr_Occurred()) {
1337 Py_DECREF(result);
1338 return NULL;
1339 }
1340 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001341 error:
1342 Py_DECREF(it);
1343 Py_DECREF(result);
1344 Py_DECREF(key);
1345 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001346}
1347
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001348static PyObject *
1349set_intersection_multi(PySetObject *so, PyObject *args)
1350{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 Py_ssize_t i;
1352 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 if (PyTuple_GET_SIZE(args) == 0)
1355 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001357 Py_INCREF(so);
1358 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1359 PyObject *other = PyTuple_GET_ITEM(args, i);
1360 PyObject *newresult = set_intersection((PySetObject *)result, other);
1361 if (newresult == NULL) {
1362 Py_DECREF(result);
1363 return NULL;
1364 }
1365 Py_DECREF(result);
1366 result = newresult;
1367 }
1368 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001369}
1370
Raymond Hettingera690a992003-11-16 16:17:49 +00001371PyDoc_STRVAR(intersection_doc,
1372"Return the intersection of two sets as a new set.\n\
1373\n\
1374(i.e. all elements that are in both sets.)");
1375
1376static PyObject *
1377set_intersection_update(PySetObject *so, PyObject *other)
1378{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 tmp = set_intersection(so, other);
1382 if (tmp == NULL)
1383 return NULL;
1384 set_swap_bodies(so, (PySetObject *)tmp);
1385 Py_DECREF(tmp);
1386 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001387}
1388
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001389static PyObject *
1390set_intersection_update_multi(PySetObject *so, PyObject *args)
1391{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 tmp = set_intersection_multi(so, args);
1395 if (tmp == NULL)
1396 return NULL;
1397 set_swap_bodies(so, (PySetObject *)tmp);
1398 Py_DECREF(tmp);
1399 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001400}
1401
Raymond Hettingera690a992003-11-16 16:17:49 +00001402PyDoc_STRVAR(intersection_update_doc,
1403"Update a set with the intersection of itself and another.");
1404
1405static PyObject *
1406set_and(PySetObject *so, PyObject *other)
1407{
Brian Curtindfc80e32011-08-10 20:28:54 -05001408 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1409 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001410 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001411}
1412
1413static PyObject *
1414set_iand(PySetObject *so, PyObject *other)
1415{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001417
Brian Curtindfc80e32011-08-10 20:28:54 -05001418 if (!PyAnySet_Check(other))
1419 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 result = set_intersection_update(so, other);
1421 if (result == NULL)
1422 return NULL;
1423 Py_DECREF(result);
1424 Py_INCREF(so);
1425 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001426}
1427
Guido van Rossum58da9312007-11-10 23:39:45 +00001428static PyObject *
1429set_isdisjoint(PySetObject *so, PyObject *other)
1430{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001432 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001433
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001434 if ((PyObject *)so == other) {
1435 if (PySet_GET_SIZE(so) == 0)
1436 Py_RETURN_TRUE;
1437 else
1438 Py_RETURN_FALSE;
1439 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 if (PyAnySet_CheckExact(other)) {
1442 Py_ssize_t pos = 0;
1443 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001444
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001445 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1446 tmp = (PyObject *)so;
1447 so = (PySetObject *)other;
1448 other = tmp;
1449 }
1450 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001451 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001452 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001453 return NULL;
1454 if (rv)
1455 Py_RETURN_FALSE;
1456 }
1457 Py_RETURN_TRUE;
1458 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 it = PyObject_GetIter(other);
1461 if (it == NULL)
1462 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001465 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001467 if (hash == -1) {
1468 Py_DECREF(key);
1469 Py_DECREF(it);
1470 return NULL;
1471 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001472 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001473 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001474 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 Py_DECREF(it);
1476 return NULL;
1477 }
1478 if (rv) {
1479 Py_DECREF(it);
1480 Py_RETURN_FALSE;
1481 }
1482 }
1483 Py_DECREF(it);
1484 if (PyErr_Occurred())
1485 return NULL;
1486 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001487}
1488
1489PyDoc_STRVAR(isdisjoint_doc,
1490"Return True if two sets have a null intersection.");
1491
Neal Norwitz6576bd82005-11-13 18:41:28 +00001492static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001493set_difference_update_internal(PySetObject *so, PyObject *other)
1494{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001495 if ((PyObject *)so == other)
1496 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 if (PyAnySet_Check(other)) {
1499 setentry *entry;
1500 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001503 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 return -1;
1505 } else {
1506 PyObject *key, *it;
1507 it = PyObject_GetIter(other);
1508 if (it == NULL)
1509 return -1;
1510
1511 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001512 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 Py_DECREF(it);
1514 Py_DECREF(key);
1515 return -1;
1516 }
1517 Py_DECREF(key);
1518 }
1519 Py_DECREF(it);
1520 if (PyErr_Occurred())
1521 return -1;
1522 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001523 /* If more than 1/4th are dummies, then resize them away. */
1524 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001525 return 0;
Raymond Hettinger48973002015-07-03 20:00:03 -07001526 return set_table_resize(so, so->used);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001527}
1528
Raymond Hettingera690a992003-11-16 16:17:49 +00001529static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001530set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001531{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001532 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001534 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1535 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001536 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 return NULL;
1538 }
1539 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001540}
1541
1542PyDoc_STRVAR(difference_update_doc,
1543"Remove all elements of another set from this set.");
1544
1545static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001546set_copy_and_difference(PySetObject *so, PyObject *other)
1547{
1548 PyObject *result;
1549
1550 result = set_copy(so);
1551 if (result == NULL)
1552 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001553 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001554 return result;
1555 Py_DECREF(result);
1556 return NULL;
1557}
1558
1559static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001560set_difference(PySetObject *so, PyObject *other)
1561{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001562 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001563 PyObject *key;
1564 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001565 setentry *entry;
1566 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001567 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001568
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001569 if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001570 return set_copy_and_difference(so, other);
1571 }
1572
1573 /* If len(so) much more than len(other), it's more efficient to simply copy
1574 * so and then iterate other looking for common elements. */
1575 if ((PySet_GET_SIZE(so) >> 2) > PyObject_Size(other)) {
1576 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001578
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 result = make_new_set_basetype(Py_TYPE(so), NULL);
1580 if (result == NULL)
1581 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 if (PyDict_CheckExact(other)) {
1584 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001585 key = entry->key;
1586 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001587 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001588 if (rv < 0) {
1589 Py_DECREF(result);
1590 return NULL;
1591 }
1592 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001593 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 Py_DECREF(result);
1595 return NULL;
1596 }
1597 }
1598 }
1599 return result;
1600 }
1601
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001602 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001604 key = entry->key;
1605 hash = entry->hash;
1606 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001607 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 Py_DECREF(result);
1609 return NULL;
1610 }
1611 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001612 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 Py_DECREF(result);
1614 return NULL;
1615 }
1616 }
1617 }
1618 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001619}
1620
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001621static PyObject *
1622set_difference_multi(PySetObject *so, PyObject *args)
1623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 Py_ssize_t i;
1625 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 if (PyTuple_GET_SIZE(args) == 0)
1628 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 other = PyTuple_GET_ITEM(args, 0);
1631 result = set_difference(so, other);
1632 if (result == NULL)
1633 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1636 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001637 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001638 Py_DECREF(result);
1639 return NULL;
1640 }
1641 }
1642 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001643}
1644
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001645PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001646"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001647\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001648(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001649static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001650set_sub(PySetObject *so, PyObject *other)
1651{
Brian Curtindfc80e32011-08-10 20:28:54 -05001652 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1653 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001655}
1656
1657static PyObject *
1658set_isub(PySetObject *so, PyObject *other)
1659{
Brian Curtindfc80e32011-08-10 20:28:54 -05001660 if (!PyAnySet_Check(other))
1661 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001662 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001663 return NULL;
1664 Py_INCREF(so);
1665 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001666}
1667
1668static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001669set_symmetric_difference_update(PySetObject *so, PyObject *other)
1670{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001671 PySetObject *otherset;
1672 PyObject *key;
1673 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001674 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001675 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001676 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001677
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001678 if ((PyObject *)so == other)
1679 return set_clear(so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001680
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001681 if (PyDict_CheckExact(other)) {
1682 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001683 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001684 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001685 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001686 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001687 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001688 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001689 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001690 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001691 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001692 Py_DECREF(key);
1693 return NULL;
1694 }
1695 }
Georg Brandl2d444492010-09-03 10:52:55 +00001696 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001697 }
1698 Py_RETURN_NONE;
1699 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001700
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001701 if (PyAnySet_Check(other)) {
1702 Py_INCREF(other);
1703 otherset = (PySetObject *)other;
1704 } else {
1705 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1706 if (otherset == NULL)
1707 return NULL;
1708 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001709
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001710 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001711 key = entry->key;
1712 hash = entry->hash;
1713 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001714 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001715 Py_DECREF(otherset);
1716 return NULL;
1717 }
1718 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001719 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001720 Py_DECREF(otherset);
1721 return NULL;
1722 }
1723 }
1724 }
1725 Py_DECREF(otherset);
1726 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001727}
1728
1729PyDoc_STRVAR(symmetric_difference_update_doc,
1730"Update a set with the symmetric difference of itself and another.");
1731
1732static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001733set_symmetric_difference(PySetObject *so, PyObject *other)
1734{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001735 PyObject *rv;
1736 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001737
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001738 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1739 if (otherset == NULL)
1740 return NULL;
1741 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
1742 if (rv == NULL)
1743 return NULL;
1744 Py_DECREF(rv);
1745 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001746}
1747
1748PyDoc_STRVAR(symmetric_difference_doc,
1749"Return the symmetric difference of two sets as a new set.\n\
1750\n\
1751(i.e. all elements that are in exactly one of the sets.)");
1752
1753static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001754set_xor(PySetObject *so, PyObject *other)
1755{
Brian Curtindfc80e32011-08-10 20:28:54 -05001756 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1757 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001758 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001759}
1760
1761static PyObject *
1762set_ixor(PySetObject *so, PyObject *other)
1763{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001764 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001765
Brian Curtindfc80e32011-08-10 20:28:54 -05001766 if (!PyAnySet_Check(other))
1767 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001768 result = set_symmetric_difference_update(so, other);
1769 if (result == NULL)
1770 return NULL;
1771 Py_DECREF(result);
1772 Py_INCREF(so);
1773 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001774}
1775
1776static PyObject *
1777set_issubset(PySetObject *so, PyObject *other)
1778{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 setentry *entry;
1780 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001781 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001782
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001783 if (!PyAnySet_Check(other)) {
1784 PyObject *tmp, *result;
1785 tmp = make_new_set(&PySet_Type, other);
1786 if (tmp == NULL)
1787 return NULL;
1788 result = set_issubset(so, tmp);
1789 Py_DECREF(tmp);
1790 return result;
1791 }
1792 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1793 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001794
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001795 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001796 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001797 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001798 return NULL;
1799 if (!rv)
1800 Py_RETURN_FALSE;
1801 }
1802 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001803}
1804
1805PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1806
1807static PyObject *
1808set_issuperset(PySetObject *so, PyObject *other)
1809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001810 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001811
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001812 if (!PyAnySet_Check(other)) {
1813 tmp = make_new_set(&PySet_Type, other);
1814 if (tmp == NULL)
1815 return NULL;
1816 result = set_issuperset(so, tmp);
1817 Py_DECREF(tmp);
1818 return result;
1819 }
1820 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001821}
1822
1823PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1824
Raymond Hettingera690a992003-11-16 16:17:49 +00001825static PyObject *
1826set_richcompare(PySetObject *v, PyObject *w, int op)
1827{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001828 PyObject *r1;
1829 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001830
Brian Curtindfc80e32011-08-10 20:28:54 -05001831 if(!PyAnySet_Check(w))
1832 Py_RETURN_NOTIMPLEMENTED;
1833
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 switch (op) {
1835 case Py_EQ:
1836 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1837 Py_RETURN_FALSE;
1838 if (v->hash != -1 &&
1839 ((PySetObject *)w)->hash != -1 &&
1840 v->hash != ((PySetObject *)w)->hash)
1841 Py_RETURN_FALSE;
1842 return set_issubset(v, w);
1843 case Py_NE:
1844 r1 = set_richcompare(v, w, Py_EQ);
1845 if (r1 == NULL)
1846 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001847 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001849 if (r2 < 0)
1850 return NULL;
1851 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 case Py_LE:
1853 return set_issubset(v, w);
1854 case Py_GE:
1855 return set_issuperset(v, w);
1856 case Py_LT:
1857 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1858 Py_RETURN_FALSE;
1859 return set_issubset(v, w);
1860 case Py_GT:
1861 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1862 Py_RETURN_FALSE;
1863 return set_issuperset(v, w);
1864 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001865 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001866}
1867
Raymond Hettingera690a992003-11-16 16:17:49 +00001868static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001869set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001870{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001871 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 return NULL;
1873 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001874}
1875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001877"Add an element to a set.\n\
1878\n\
1879This has no effect if the element is already present.");
1880
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001881static int
1882set_contains(PySetObject *so, PyObject *key)
1883{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 PyObject *tmpkey;
1885 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001888 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001889 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1890 return -1;
1891 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001892 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 if (tmpkey == NULL)
1894 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001895 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 Py_DECREF(tmpkey);
1897 }
1898 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001899}
1900
1901static PyObject *
1902set_direct_contains(PySetObject *so, PyObject *key)
1903{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001904 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001905
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001907 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 return NULL;
1909 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001910}
1911
1912PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1913
Raymond Hettingera690a992003-11-16 16:17:49 +00001914static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001915set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001916{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001917 PyObject *tmpkey;
1918 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001919
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001920 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001921 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1923 return NULL;
1924 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001925 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 if (tmpkey == NULL)
1927 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001928 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001929 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001930 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 return NULL;
1932 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001934 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001935 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 return NULL;
1937 }
1938 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001939}
1940
1941PyDoc_STRVAR(remove_doc,
1942"Remove an element from a set; it must be a member.\n\
1943\n\
1944If the element is not a member, raise a KeyError.");
1945
1946static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001947set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001948{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001949 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001950 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001953 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001954 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1955 return NULL;
1956 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001957 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001958 if (tmpkey == NULL)
1959 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001960 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001961 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001962 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001963 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001964 }
1965 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001966}
1967
1968PyDoc_STRVAR(discard_doc,
1969"Remove an element from a set if it is a member.\n\
1970\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001971If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001972
1973static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001974set_reduce(PySetObject *so)
1975{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001976 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001977 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001978
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001979 keys = PySequence_List((PyObject *)so);
1980 if (keys == NULL)
1981 goto done;
1982 args = PyTuple_Pack(1, keys);
1983 if (args == NULL)
1984 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001985 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001986 if (dict == NULL) {
1987 PyErr_Clear();
1988 dict = Py_None;
1989 Py_INCREF(dict);
1990 }
1991 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001992done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001993 Py_XDECREF(args);
1994 Py_XDECREF(keys);
1995 Py_XDECREF(dict);
1996 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001997}
1998
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001999static PyObject *
2000set_sizeof(PySetObject *so)
2001{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002002 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002004 res = sizeof(PySetObject);
2005 if (so->table != so->smalltable)
2006 res = res + (so->mask + 1) * sizeof(setentry);
2007 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002008}
2009
2010PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002011static int
2012set_init(PySetObject *self, PyObject *args, PyObject *kwds)
2013{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002014 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002015
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002016 if (!PyAnySet_Check(self))
2017 return -1;
2018 if (PySet_Check(self) && !_PyArg_NoKeywords("set()", kwds))
2019 return -1;
2020 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
2021 return -1;
2022 set_clear_internal(self);
2023 self->hash = -1;
2024 if (iterable == NULL)
2025 return 0;
2026 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002027}
2028
Raymond Hettingera690a992003-11-16 16:17:49 +00002029static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002030 set_len, /* sq_length */
2031 0, /* sq_concat */
2032 0, /* sq_repeat */
2033 0, /* sq_item */
2034 0, /* sq_slice */
2035 0, /* sq_ass_item */
2036 0, /* sq_ass_slice */
2037 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002038};
2039
2040/* set object ********************************************************/
2041
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002042#ifdef Py_DEBUG
2043static PyObject *test_c_api(PySetObject *so);
2044
2045PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2046All is well if assertions don't fail.");
2047#endif
2048
Raymond Hettingera690a992003-11-16 16:17:49 +00002049static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002050 {"add", (PyCFunction)set_add, METH_O,
2051 add_doc},
2052 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2053 clear_doc},
2054 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2055 contains_doc},
2056 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2057 copy_doc},
2058 {"discard", (PyCFunction)set_discard, METH_O,
2059 discard_doc},
2060 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2061 difference_doc},
2062 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2063 difference_update_doc},
2064 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2065 intersection_doc},
2066 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2067 intersection_update_doc},
2068 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2069 isdisjoint_doc},
2070 {"issubset", (PyCFunction)set_issubset, METH_O,
2071 issubset_doc},
2072 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2073 issuperset_doc},
2074 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2075 pop_doc},
2076 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2077 reduce_doc},
2078 {"remove", (PyCFunction)set_remove, METH_O,
2079 remove_doc},
2080 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2081 sizeof_doc},
2082 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2083 symmetric_difference_doc},
2084 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2085 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002086#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002087 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2088 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002089#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002090 {"union", (PyCFunction)set_union, METH_VARARGS,
2091 union_doc},
2092 {"update", (PyCFunction)set_update, METH_VARARGS,
2093 update_doc},
2094 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002095};
2096
2097static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002098 0, /*nb_add*/
2099 (binaryfunc)set_sub, /*nb_subtract*/
2100 0, /*nb_multiply*/
2101 0, /*nb_remainder*/
2102 0, /*nb_divmod*/
2103 0, /*nb_power*/
2104 0, /*nb_negative*/
2105 0, /*nb_positive*/
2106 0, /*nb_absolute*/
2107 0, /*nb_bool*/
2108 0, /*nb_invert*/
2109 0, /*nb_lshift*/
2110 0, /*nb_rshift*/
2111 (binaryfunc)set_and, /*nb_and*/
2112 (binaryfunc)set_xor, /*nb_xor*/
2113 (binaryfunc)set_or, /*nb_or*/
2114 0, /*nb_int*/
2115 0, /*nb_reserved*/
2116 0, /*nb_float*/
2117 0, /*nb_inplace_add*/
2118 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2119 0, /*nb_inplace_multiply*/
2120 0, /*nb_inplace_remainder*/
2121 0, /*nb_inplace_power*/
2122 0, /*nb_inplace_lshift*/
2123 0, /*nb_inplace_rshift*/
2124 (binaryfunc)set_iand, /*nb_inplace_and*/
2125 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2126 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002127};
2128
2129PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002130"set() -> new empty set object\n\
2131set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002132\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002133Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002134
2135PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002136 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2137 "set", /* tp_name */
2138 sizeof(PySetObject), /* tp_basicsize */
2139 0, /* tp_itemsize */
2140 /* methods */
2141 (destructor)set_dealloc, /* tp_dealloc */
2142 0, /* tp_print */
2143 0, /* tp_getattr */
2144 0, /* tp_setattr */
2145 0, /* tp_reserved */
2146 (reprfunc)set_repr, /* tp_repr */
2147 &set_as_number, /* tp_as_number */
2148 &set_as_sequence, /* tp_as_sequence */
2149 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002150 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 0, /* tp_call */
2152 0, /* tp_str */
2153 PyObject_GenericGetAttr, /* tp_getattro */
2154 0, /* tp_setattro */
2155 0, /* tp_as_buffer */
2156 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2157 Py_TPFLAGS_BASETYPE, /* tp_flags */
2158 set_doc, /* tp_doc */
2159 (traverseproc)set_traverse, /* tp_traverse */
2160 (inquiry)set_clear_internal, /* tp_clear */
2161 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002162 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2163 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 0, /* tp_iternext */
2165 set_methods, /* tp_methods */
2166 0, /* tp_members */
2167 0, /* tp_getset */
2168 0, /* tp_base */
2169 0, /* tp_dict */
2170 0, /* tp_descr_get */
2171 0, /* tp_descr_set */
2172 0, /* tp_dictoffset */
2173 (initproc)set_init, /* tp_init */
2174 PyType_GenericAlloc, /* tp_alloc */
2175 set_new, /* tp_new */
2176 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002177};
2178
2179/* frozenset object ********************************************************/
2180
2181
2182static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002183 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2184 contains_doc},
2185 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2186 copy_doc},
2187 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2188 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002189 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002190 intersection_doc},
2191 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2192 isdisjoint_doc},
2193 {"issubset", (PyCFunction)set_issubset, METH_O,
2194 issubset_doc},
2195 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2196 issuperset_doc},
2197 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2198 reduce_doc},
2199 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2200 sizeof_doc},
2201 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2202 symmetric_difference_doc},
2203 {"union", (PyCFunction)set_union, METH_VARARGS,
2204 union_doc},
2205 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002206};
2207
2208static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002209 0, /*nb_add*/
2210 (binaryfunc)set_sub, /*nb_subtract*/
2211 0, /*nb_multiply*/
2212 0, /*nb_remainder*/
2213 0, /*nb_divmod*/
2214 0, /*nb_power*/
2215 0, /*nb_negative*/
2216 0, /*nb_positive*/
2217 0, /*nb_absolute*/
2218 0, /*nb_bool*/
2219 0, /*nb_invert*/
2220 0, /*nb_lshift*/
2221 0, /*nb_rshift*/
2222 (binaryfunc)set_and, /*nb_and*/
2223 (binaryfunc)set_xor, /*nb_xor*/
2224 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002225};
2226
2227PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002228"frozenset() -> empty frozenset object\n\
2229frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002230\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002231Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002232
2233PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002234 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2235 "frozenset", /* tp_name */
2236 sizeof(PySetObject), /* tp_basicsize */
2237 0, /* tp_itemsize */
2238 /* methods */
2239 (destructor)set_dealloc, /* tp_dealloc */
2240 0, /* tp_print */
2241 0, /* tp_getattr */
2242 0, /* tp_setattr */
2243 0, /* tp_reserved */
2244 (reprfunc)set_repr, /* tp_repr */
2245 &frozenset_as_number, /* tp_as_number */
2246 &set_as_sequence, /* tp_as_sequence */
2247 0, /* tp_as_mapping */
2248 frozenset_hash, /* tp_hash */
2249 0, /* tp_call */
2250 0, /* tp_str */
2251 PyObject_GenericGetAttr, /* tp_getattro */
2252 0, /* tp_setattro */
2253 0, /* tp_as_buffer */
2254 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2255 Py_TPFLAGS_BASETYPE, /* tp_flags */
2256 frozenset_doc, /* tp_doc */
2257 (traverseproc)set_traverse, /* tp_traverse */
2258 (inquiry)set_clear_internal, /* tp_clear */
2259 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002260 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002261 (getiterfunc)set_iter, /* tp_iter */
2262 0, /* tp_iternext */
2263 frozenset_methods, /* tp_methods */
2264 0, /* tp_members */
2265 0, /* tp_getset */
2266 0, /* tp_base */
2267 0, /* tp_dict */
2268 0, /* tp_descr_get */
2269 0, /* tp_descr_set */
2270 0, /* tp_dictoffset */
2271 0, /* tp_init */
2272 PyType_GenericAlloc, /* tp_alloc */
2273 frozenset_new, /* tp_new */
2274 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002275};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002276
2277
2278/***** C API functions *************************************************/
2279
2280PyObject *
2281PySet_New(PyObject *iterable)
2282{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002283 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002284}
2285
2286PyObject *
2287PyFrozenSet_New(PyObject *iterable)
2288{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002289 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002290}
2291
Neal Norwitz8c49c822006-03-04 18:41:19 +00002292Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002293PySet_Size(PyObject *anyset)
2294{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002295 if (!PyAnySet_Check(anyset)) {
2296 PyErr_BadInternalCall();
2297 return -1;
2298 }
2299 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002300}
2301
2302int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002303PySet_Clear(PyObject *set)
2304{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002305 if (!PySet_Check(set)) {
2306 PyErr_BadInternalCall();
2307 return -1;
2308 }
2309 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002310}
2311
2312int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002313PySet_Contains(PyObject *anyset, PyObject *key)
2314{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002315 if (!PyAnySet_Check(anyset)) {
2316 PyErr_BadInternalCall();
2317 return -1;
2318 }
2319 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002320}
2321
2322int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002323PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002324{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002325 if (!PySet_Check(set)) {
2326 PyErr_BadInternalCall();
2327 return -1;
2328 }
2329 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002330}
2331
2332int
Christian Heimesfd66e512008-01-29 12:18:50 +00002333PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002335 if (!PySet_Check(anyset) &&
2336 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2337 PyErr_BadInternalCall();
2338 return -1;
2339 }
2340 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002341}
2342
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002343int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002344_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002345{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002346 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002348 if (!PyAnySet_Check(set)) {
2349 PyErr_BadInternalCall();
2350 return -1;
2351 }
2352 if (set_next((PySetObject *)set, pos, &entry) == 0)
2353 return 0;
2354 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002355 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002356 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002357}
2358
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002359PyObject *
2360PySet_Pop(PyObject *set)
2361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002362 if (!PySet_Check(set)) {
2363 PyErr_BadInternalCall();
2364 return NULL;
2365 }
2366 return set_pop((PySetObject *)set);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002367}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002368
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002369int
2370_PySet_Update(PyObject *set, PyObject *iterable)
2371{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002372 if (!PySet_Check(set)) {
2373 PyErr_BadInternalCall();
2374 return -1;
2375 }
2376 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002377}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002378
Raymond Hettingere259f132013-12-15 11:56:14 -08002379/* Exported for the gdb plugin's benefit. */
2380PyObject *_PySet_Dummy = dummy;
2381
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002382#ifdef Py_DEBUG
2383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002384/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002385 Returns True and original set is restored. */
2386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002387#define assertRaises(call_return_value, exception) \
2388 do { \
2389 assert(call_return_value); \
2390 assert(PyErr_ExceptionMatches(exception)); \
2391 PyErr_Clear(); \
2392 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002393
2394static PyObject *
2395test_c_api(PySetObject *so)
2396{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002397 Py_ssize_t count;
2398 char *s;
2399 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002400 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002401 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002402 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002403 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405 /* Verify preconditions */
2406 assert(PyAnySet_Check(ob));
2407 assert(PyAnySet_CheckExact(ob));
2408 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002410 /* so.clear(); so |= set("abc"); */
2411 str = PyUnicode_FromString("abc");
2412 if (str == NULL)
2413 return NULL;
2414 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002415 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002416 Py_DECREF(str);
2417 return NULL;
2418 }
2419 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 /* Exercise type/size checks */
2422 assert(PySet_Size(ob) == 3);
2423 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002425 /* Raise TypeError for non-iterable constructor arguments */
2426 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2427 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002429 /* Raise TypeError for unhashable key */
2430 dup = PySet_New(ob);
2431 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2432 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2433 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002434
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002435 /* Exercise successful pop, contains, add, and discard */
2436 elem = PySet_Pop(ob);
2437 assert(PySet_Contains(ob, elem) == 0);
2438 assert(PySet_GET_SIZE(ob) == 2);
2439 assert(PySet_Add(ob, elem) == 0);
2440 assert(PySet_Contains(ob, elem) == 1);
2441 assert(PySet_GET_SIZE(ob) == 3);
2442 assert(PySet_Discard(ob, elem) == 1);
2443 assert(PySet_GET_SIZE(ob) == 2);
2444 assert(PySet_Discard(ob, elem) == 0);
2445 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002447 /* Exercise clear */
2448 dup2 = PySet_New(dup);
2449 assert(PySet_Clear(dup2) == 0);
2450 assert(PySet_Size(dup2) == 0);
2451 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002453 /* Raise SystemError on clear or update of frozen set */
2454 f = PyFrozenSet_New(dup);
2455 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2456 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2457 assert(PySet_Add(f, elem) == 0);
2458 Py_INCREF(f);
2459 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2460 Py_DECREF(f);
2461 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002462
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002463 /* Exercise direct iteration */
2464 i = 0, count = 0;
2465 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
2466 s = _PyUnicode_AsString(x);
2467 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2468 count++;
2469 }
2470 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002472 /* Exercise updates */
2473 dup2 = PySet_New(NULL);
2474 assert(_PySet_Update(dup2, dup) == 0);
2475 assert(PySet_Size(dup2) == 3);
2476 assert(_PySet_Update(dup2, dup) == 0);
2477 assert(PySet_Size(dup2) == 3);
2478 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002480 /* Raise SystemError when self argument is not a set or frozenset. */
2481 t = PyTuple_New(0);
2482 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2483 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2484 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002486 /* Raise SystemError when self argument is not a set. */
2487 f = PyFrozenSet_New(dup);
2488 assert(PySet_Size(f) == 3);
2489 assert(PyFrozenSet_CheckExact(f));
2490 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2491 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2492 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002494 /* Raise KeyError when popping from an empty set */
2495 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2496 Py_DECREF(ob);
2497 assert(PySet_GET_SIZE(ob) == 0);
2498 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002500 /* Restore the set from the copy using the PyNumber API */
2501 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2502 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002504 /* Verify constructors accept NULL arguments */
2505 f = PySet_New(NULL);
2506 assert(f != NULL);
2507 assert(PySet_GET_SIZE(f) == 0);
2508 Py_DECREF(f);
2509 f = PyFrozenSet_New(NULL);
2510 assert(f != NULL);
2511 assert(PyFrozenSet_CheckExact(f));
2512 assert(PySet_GET_SIZE(f) == 0);
2513 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002515 Py_DECREF(elem);
2516 Py_DECREF(dup);
2517 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002518}
2519
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002520#undef assertRaises
2521
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002522#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002523
2524/***** Dummy Struct *************************************************/
2525
2526static PyObject *
2527dummy_repr(PyObject *op)
2528{
2529 return PyUnicode_FromString("<dummy key>");
2530}
2531
2532static void
2533dummy_dealloc(PyObject* ignore)
2534{
2535 Py_FatalError("deallocating <dummy key>");
2536}
2537
2538static PyTypeObject _PySetDummy_Type = {
2539 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2540 "<dummy key> type",
2541 0,
2542 0,
2543 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2544 0, /*tp_print*/
2545 0, /*tp_getattr*/
2546 0, /*tp_setattr*/
2547 0, /*tp_reserved*/
2548 dummy_repr, /*tp_repr*/
2549 0, /*tp_as_number*/
2550 0, /*tp_as_sequence*/
2551 0, /*tp_as_mapping*/
2552 0, /*tp_hash */
2553 0, /*tp_call */
2554 0, /*tp_str */
2555 0, /*tp_getattro */
2556 0, /*tp_setattro */
2557 0, /*tp_as_buffer */
2558 Py_TPFLAGS_DEFAULT, /*tp_flags */
2559};
2560
2561static PyObject _dummy_struct = {
2562 _PyObject_EXTRA_INIT
2563 2, &_PySetDummy_Type
2564};
2565