blob: c590bbf03ab550bd073825ed793b31ae87ee7393 [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
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000742static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000743frozenset_hash(PyObject *self)
744{
Raymond Hettinger74fc8c42014-01-05 12:00:31 -0800745 /* Most of the constants in this hash algorithm are randomly choosen
746 large primes with "interesting bit patterns" and that passed
747 tests for good collision statistics on a variety of problematic
748 datasets such as:
749
750 ps = []
751 for r in range(21):
752 ps += itertools.combinations(range(20), r)
753 num_distinct_hashes = len({hash(frozenset(s)) for s in ps})
754
755 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000756 PySetObject *so = (PySetObject *)self;
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800757 Py_uhash_t h, hash = 1927868237UL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758 setentry *entry;
759 Py_ssize_t pos = 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000761 if (so->hash != -1)
762 return so->hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000763
Mark Dickinson57e683e2011-09-24 18:18:40 +0100764 hash *= (Py_uhash_t)PySet_GET_SIZE(self) + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000765 while (set_next(so, &pos, &entry)) {
766 /* Work to increase the bit dispersion for closely spaced hash
Raymond Hettinger06a1c8d2015-01-30 18:02:15 -0800767 values. This is important because some use cases have many
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000768 combinations of a small number of elements with nearby
769 hashes so that many distinct combinations collapse to only
770 a handful of distinct hash values. */
Antoine Pitroufbb1c612010-10-23 17:37:54 +0000771 h = entry->hash;
Raymond Hettinger74fc8c42014-01-05 12:00:31 -0800772 hash ^= ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000773 }
Raymond Hettinger74fc8c42014-01-05 12:00:31 -0800774 /* Make the final result spread-out in a different pattern
Eric V. Smith6ba56652014-01-14 08:15:03 -0500775 than the algorithm for tuples or other python objects. */
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800776 hash = hash * 69069U + 907133923UL;
Victor Stinner12174a52014-08-15 23:17:38 +0200777 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800778 hash = 590923713UL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000779 so->hash = hash;
780 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000781}
782
Raymond Hettingera9d99362005-08-05 00:01:15 +0000783/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000784
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000785typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000786 PyObject_HEAD
787 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
788 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700789 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000790 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000791} setiterobject;
792
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000793static void
794setiter_dealloc(setiterobject *si)
795{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000796 Py_XDECREF(si->si_set);
797 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000798}
799
800static int
801setiter_traverse(setiterobject *si, visitproc visit, void *arg)
802{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000803 Py_VISIT(si->si_set);
804 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000805}
806
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000807static PyObject *
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000808setiter_len(setiterobject *si)
809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000810 Py_ssize_t len = 0;
811 if (si->si_set != NULL && si->si_used == si->si_set->used)
812 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000813 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000814}
815
Armin Rigof5b3e362006-02-11 21:32:43 +0000816PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000817
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000818static PyObject *setiter_iternext(setiterobject *si);
819
820static PyObject *
821setiter_reduce(setiterobject *si)
822{
823 PyObject *list;
824 setiterobject tmp;
825
826 list = PyList_New(0);
827 if (!list)
828 return NULL;
829
Ezio Melotti0e1af282012-09-28 16:43:40 +0300830 /* copy the iterator state */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000831 tmp = *si;
832 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300833
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000834 /* iterate the temporary into a list */
835 for(;;) {
836 PyObject *element = setiter_iternext(&tmp);
837 if (element) {
838 if (PyList_Append(list, element)) {
839 Py_DECREF(element);
840 Py_DECREF(list);
841 Py_XDECREF(tmp.si_set);
842 return NULL;
843 }
844 Py_DECREF(element);
845 } else
846 break;
847 }
848 Py_XDECREF(tmp.si_set);
849 /* check for error */
850 if (tmp.si_set != NULL) {
851 /* we have an error */
852 Py_DECREF(list);
853 return NULL;
854 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200855 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000856}
857
858PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
859
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000860static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000861 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000862 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000863 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000864};
865
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000866static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000867{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700868 PyObject *key;
869 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200870 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000871 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000873 if (so == NULL)
874 return NULL;
875 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000877 if (si->si_used != so->used) {
878 PyErr_SetString(PyExc_RuntimeError,
879 "Set changed size during iteration");
880 si->si_used = -1; /* Make this state sticky */
881 return NULL;
882 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700883
884 i = si->si_pos;
885 assert(i>=0);
886 entry = so->table;
887 mask = so->mask;
888 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
889 i++;
890 si->si_pos = i+1;
891 if (i > mask)
892 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000893 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700894 key = entry[i].key;
895 Py_INCREF(key);
896 return key;
897
898fail:
899 Py_DECREF(so);
900 si->si_set = NULL;
901 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000902}
903
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000904PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000905 PyVarObject_HEAD_INIT(&PyType_Type, 0)
906 "set_iterator", /* tp_name */
907 sizeof(setiterobject), /* tp_basicsize */
908 0, /* tp_itemsize */
909 /* methods */
910 (destructor)setiter_dealloc, /* tp_dealloc */
911 0, /* tp_print */
912 0, /* tp_getattr */
913 0, /* tp_setattr */
914 0, /* tp_reserved */
915 0, /* tp_repr */
916 0, /* tp_as_number */
917 0, /* tp_as_sequence */
918 0, /* tp_as_mapping */
919 0, /* tp_hash */
920 0, /* tp_call */
921 0, /* tp_str */
922 PyObject_GenericGetAttr, /* tp_getattro */
923 0, /* tp_setattro */
924 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700925 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 0, /* tp_doc */
927 (traverseproc)setiter_traverse, /* tp_traverse */
928 0, /* tp_clear */
929 0, /* tp_richcompare */
930 0, /* tp_weaklistoffset */
931 PyObject_SelfIter, /* tp_iter */
932 (iternextfunc)setiter_iternext, /* tp_iternext */
933 setiter_methods, /* tp_methods */
934 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000935};
936
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000937static PyObject *
938set_iter(PySetObject *so)
939{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000940 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
941 if (si == NULL)
942 return NULL;
943 Py_INCREF(so);
944 si->si_set = so;
945 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700946 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000947 si->len = so->used;
948 _PyObject_GC_TRACK(si);
949 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000950}
951
Raymond Hettingerd7946662005-08-01 21:39:29 +0000952static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000953set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000954{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000955 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000956
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 if (PyAnySet_Check(other))
958 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000959
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000960 if (PyDict_CheckExact(other)) {
961 PyObject *value;
962 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000963 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000964 Py_ssize_t dictsize = PyDict_Size(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 /* Do one big resize at the start, rather than
967 * incrementally resizing as we insert new keys. Expect
968 * that there will be no (or few) overlapping keys.
969 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700970 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 return -1;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700972 if ((so->fill + dictsize)*3 >= so->mask*2) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700973 if (set_table_resize(so, so->used + dictsize) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 return -1;
975 }
976 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700977 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 return -1;
979 }
980 return 0;
981 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 it = PyObject_GetIter(other);
984 if (it == NULL)
985 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +0000986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000987 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700988 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 Py_DECREF(it);
990 Py_DECREF(key);
991 return -1;
992 }
993 Py_DECREF(key);
994 }
995 Py_DECREF(it);
996 if (PyErr_Occurred())
997 return -1;
998 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000999}
1000
1001static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001002set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1007 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001008 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001009 return NULL;
1010 }
1011 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001012}
1013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001015"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001016
Raymond Hettinger426d9952014-05-18 21:40:20 +01001017/* XXX Todo:
1018 If aligned memory allocations become available, make the
1019 set object 64 byte aligned so that most of the fields
1020 can be retrieved or updated in a single cache line.
1021*/
1022
Raymond Hettingera38123e2003-11-24 22:18:49 +00001023static PyObject *
1024make_new_set(PyTypeObject *type, PyObject *iterable)
1025{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001026 PySetObject *so = NULL;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 /* create PySetObject structure */
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001029 so = (PySetObject *)type->tp_alloc(type, 0);
1030 if (so == NULL)
1031 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001032
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001033 so->fill = 0;
1034 so->used = 0;
1035 so->mask = PySet_MINSIZE - 1;
1036 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001037 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001038 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001042 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001043 Py_DECREF(so);
1044 return NULL;
1045 }
1046 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001047
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001048 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001049}
1050
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001051static PyObject *
1052make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1053{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1055 if (PyType_IsSubtype(type, &PySet_Type))
1056 type = &PySet_Type;
1057 else
1058 type = &PyFrozenSet_Type;
1059 }
1060 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001061}
1062
Raymond Hettingerd7946662005-08-01 21:39:29 +00001063/* The empty frozenset is a singleton */
1064static PyObject *emptyfrozenset = NULL;
1065
Raymond Hettingera690a992003-11-16 16:17:49 +00001066static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001067frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001068{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset()", kwds))
1072 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001073
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1075 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001076
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 if (type != &PyFrozenSet_Type)
1078 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001079
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001080 if (iterable != NULL) {
1081 /* frozenset(f) is idempotent */
1082 if (PyFrozenSet_CheckExact(iterable)) {
1083 Py_INCREF(iterable);
1084 return iterable;
1085 }
1086 result = make_new_set(type, iterable);
1087 if (result == NULL || PySet_GET_SIZE(result))
1088 return result;
1089 Py_DECREF(result);
1090 }
1091 /* The empty frozenset is a singleton */
1092 if (emptyfrozenset == NULL)
1093 emptyfrozenset = make_new_set(type, NULL);
1094 Py_XINCREF(emptyfrozenset);
1095 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001096}
1097
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001098int
1099PySet_ClearFreeList(void)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001100{
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001101 return 0;
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001102}
1103
1104void
1105PySet_Fini(void)
1106{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001107 Py_CLEAR(emptyfrozenset);
Raymond Hettingera690a992003-11-16 16:17:49 +00001108}
1109
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001110static PyObject *
1111set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1112{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001113 if (type == &PySet_Type && !_PyArg_NoKeywords("set()", kwds))
1114 return NULL;
1115
1116 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001117}
1118
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001119/* set_swap_bodies() switches the contents of any two sets by moving their
1120 internal data pointers and, if needed, copying the internal smalltables.
1121 Semantically equivalent to:
1122
1123 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1124
1125 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001126 Useful for operations that update in-place (by allowing an intermediate
1127 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001128*/
1129
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001130static void
1131set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001132{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001133 Py_ssize_t t;
1134 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001136 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001137
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138 t = a->fill; a->fill = b->fill; b->fill = t;
1139 t = a->used; a->used = b->used; b->used = t;
1140 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 u = a->table;
1143 if (a->table == a->smalltable)
1144 u = b->smalltable;
1145 a->table = b->table;
1146 if (b->table == b->smalltable)
1147 a->table = a->smalltable;
1148 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 if (a->table == a->smalltable || b->table == b->smalltable) {
1151 memcpy(tab, a->smalltable, sizeof(tab));
1152 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1153 memcpy(b->smalltable, tab, sizeof(tab));
1154 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001155
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1157 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1158 h = a->hash; a->hash = b->hash; b->hash = h;
1159 } else {
1160 a->hash = -1;
1161 b->hash = -1;
1162 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001163}
1164
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001165static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001166set_copy(PySetObject *so)
1167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001169}
1170
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001171static PyObject *
1172frozenset_copy(PySetObject *so)
1173{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001174 if (PyFrozenSet_CheckExact(so)) {
1175 Py_INCREF(so);
1176 return (PyObject *)so;
1177 }
1178 return set_copy(so);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001179}
1180
Raymond Hettingera690a992003-11-16 16:17:49 +00001181PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1182
1183static PyObject *
Raymond Hettingerc991db22005-08-11 07:58:45 +00001184set_clear(PySetObject *so)
1185{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 set_clear_internal(so);
1187 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001188}
1189
1190PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1191
1192static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001193set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001194{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001195 PySetObject *result;
1196 PyObject *other;
1197 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 result = (PySetObject *)set_copy(so);
1200 if (result == NULL)
1201 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001203 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1204 other = PyTuple_GET_ITEM(args, i);
1205 if ((PyObject *)so == other)
1206 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001207 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001208 Py_DECREF(result);
1209 return NULL;
1210 }
1211 }
1212 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001213}
1214
1215PyDoc_STRVAR(union_doc,
1216 "Return the union of sets as a new set.\n\
1217\n\
1218(i.e. all elements that are in either set.)");
1219
1220static PyObject *
1221set_or(PySetObject *so, PyObject *other)
1222{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001223 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001224
Brian Curtindfc80e32011-08-10 20:28:54 -05001225 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1226 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001228 result = (PySetObject *)set_copy(so);
1229 if (result == NULL)
1230 return NULL;
1231 if ((PyObject *)so == other)
1232 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001233 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 Py_DECREF(result);
1235 return NULL;
1236 }
1237 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001238}
1239
Raymond Hettingera690a992003-11-16 16:17:49 +00001240static PyObject *
1241set_ior(PySetObject *so, PyObject *other)
1242{
Brian Curtindfc80e32011-08-10 20:28:54 -05001243 if (!PyAnySet_Check(other))
1244 Py_RETURN_NOTIMPLEMENTED;
1245
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001246 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 return NULL;
1248 Py_INCREF(so);
1249 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001250}
1251
1252static PyObject *
1253set_intersection(PySetObject *so, PyObject *other)
1254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 PySetObject *result;
1256 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001257 Py_hash_t hash;
1258 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 if ((PyObject *)so == other)
1261 return set_copy(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1264 if (result == NULL)
1265 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 if (PyAnySet_Check(other)) {
1268 Py_ssize_t pos = 0;
1269 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1272 tmp = (PyObject *)so;
1273 so = (PySetObject *)other;
1274 other = tmp;
1275 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001278 key = entry->key;
1279 hash = entry->hash;
1280 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001281 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 Py_DECREF(result);
1283 return NULL;
1284 }
1285 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001286 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 Py_DECREF(result);
1288 return NULL;
1289 }
1290 }
1291 }
1292 return (PyObject *)result;
1293 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 it = PyObject_GetIter(other);
1296 if (it == NULL) {
1297 Py_DECREF(result);
1298 return NULL;
1299 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001300
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001302 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001303 if (hash == -1)
1304 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001305 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001306 if (rv < 0)
1307 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001309 if (set_add_entry(result, key, hash))
1310 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 }
1312 Py_DECREF(key);
1313 }
1314 Py_DECREF(it);
1315 if (PyErr_Occurred()) {
1316 Py_DECREF(result);
1317 return NULL;
1318 }
1319 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001320 error:
1321 Py_DECREF(it);
1322 Py_DECREF(result);
1323 Py_DECREF(key);
1324 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001325}
1326
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001327static PyObject *
1328set_intersection_multi(PySetObject *so, PyObject *args)
1329{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 Py_ssize_t i;
1331 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 if (PyTuple_GET_SIZE(args) == 0)
1334 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 Py_INCREF(so);
1337 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1338 PyObject *other = PyTuple_GET_ITEM(args, i);
1339 PyObject *newresult = set_intersection((PySetObject *)result, other);
1340 if (newresult == NULL) {
1341 Py_DECREF(result);
1342 return NULL;
1343 }
1344 Py_DECREF(result);
1345 result = newresult;
1346 }
1347 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001348}
1349
Raymond Hettingera690a992003-11-16 16:17:49 +00001350PyDoc_STRVAR(intersection_doc,
1351"Return the intersection of two sets as a new set.\n\
1352\n\
1353(i.e. all elements that are in both sets.)");
1354
1355static PyObject *
1356set_intersection_update(PySetObject *so, PyObject *other)
1357{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001360 tmp = set_intersection(so, other);
1361 if (tmp == NULL)
1362 return NULL;
1363 set_swap_bodies(so, (PySetObject *)tmp);
1364 Py_DECREF(tmp);
1365 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001366}
1367
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001368static PyObject *
1369set_intersection_update_multi(PySetObject *so, PyObject *args)
1370{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 tmp = set_intersection_multi(so, args);
1374 if (tmp == NULL)
1375 return NULL;
1376 set_swap_bodies(so, (PySetObject *)tmp);
1377 Py_DECREF(tmp);
1378 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001379}
1380
Raymond Hettingera690a992003-11-16 16:17:49 +00001381PyDoc_STRVAR(intersection_update_doc,
1382"Update a set with the intersection of itself and another.");
1383
1384static PyObject *
1385set_and(PySetObject *so, PyObject *other)
1386{
Brian Curtindfc80e32011-08-10 20:28:54 -05001387 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1388 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001390}
1391
1392static PyObject *
1393set_iand(PySetObject *so, PyObject *other)
1394{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001395 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001396
Brian Curtindfc80e32011-08-10 20:28:54 -05001397 if (!PyAnySet_Check(other))
1398 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399 result = set_intersection_update(so, other);
1400 if (result == NULL)
1401 return NULL;
1402 Py_DECREF(result);
1403 Py_INCREF(so);
1404 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001405}
1406
Guido van Rossum58da9312007-11-10 23:39:45 +00001407static PyObject *
1408set_isdisjoint(PySetObject *so, PyObject *other)
1409{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001410 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001411 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 if ((PyObject *)so == other) {
1414 if (PySet_GET_SIZE(so) == 0)
1415 Py_RETURN_TRUE;
1416 else
1417 Py_RETURN_FALSE;
1418 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 if (PyAnySet_CheckExact(other)) {
1421 Py_ssize_t pos = 0;
1422 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1425 tmp = (PyObject *)so;
1426 so = (PySetObject *)other;
1427 other = tmp;
1428 }
1429 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001430 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001431 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 return NULL;
1433 if (rv)
1434 Py_RETURN_FALSE;
1435 }
1436 Py_RETURN_TRUE;
1437 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 it = PyObject_GetIter(other);
1440 if (it == NULL)
1441 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001443 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001444 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 if (hash == -1) {
1447 Py_DECREF(key);
1448 Py_DECREF(it);
1449 return NULL;
1450 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001451 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001452 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001453 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 Py_DECREF(it);
1455 return NULL;
1456 }
1457 if (rv) {
1458 Py_DECREF(it);
1459 Py_RETURN_FALSE;
1460 }
1461 }
1462 Py_DECREF(it);
1463 if (PyErr_Occurred())
1464 return NULL;
1465 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001466}
1467
1468PyDoc_STRVAR(isdisjoint_doc,
1469"Return True if two sets have a null intersection.");
1470
Neal Norwitz6576bd82005-11-13 18:41:28 +00001471static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001472set_difference_update_internal(PySetObject *so, PyObject *other)
1473{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 if ((PyObject *)so == other)
1475 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001477 if (PyAnySet_Check(other)) {
1478 setentry *entry;
1479 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001482 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 return -1;
1484 } else {
1485 PyObject *key, *it;
1486 it = PyObject_GetIter(other);
1487 if (it == NULL)
1488 return -1;
1489
1490 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001491 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 Py_DECREF(it);
1493 Py_DECREF(key);
1494 return -1;
1495 }
1496 Py_DECREF(key);
1497 }
1498 Py_DECREF(it);
1499 if (PyErr_Occurred())
1500 return -1;
1501 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001502 /* If more than 1/4th are dummies, then resize them away. */
1503 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 return 0;
Raymond Hettinger48973002015-07-03 20:00:03 -07001505 return set_table_resize(so, so->used);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001506}
1507
Raymond Hettingera690a992003-11-16 16:17:49 +00001508static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001509set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001510{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1514 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001515 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 return NULL;
1517 }
1518 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001519}
1520
1521PyDoc_STRVAR(difference_update_doc,
1522"Remove all elements of another set from this set.");
1523
1524static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001525set_copy_and_difference(PySetObject *so, PyObject *other)
1526{
1527 PyObject *result;
1528
1529 result = set_copy(so);
1530 if (result == NULL)
1531 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001532 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001533 return result;
1534 Py_DECREF(result);
1535 return NULL;
1536}
1537
1538static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001539set_difference(PySetObject *so, PyObject *other)
1540{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001542 PyObject *key;
1543 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001544 setentry *entry;
1545 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001546 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001547
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001549 return set_copy_and_difference(so, other);
1550 }
1551
1552 /* If len(so) much more than len(other), it's more efficient to simply copy
1553 * so and then iterate other looking for common elements. */
1554 if ((PySet_GET_SIZE(so) >> 2) > PyObject_Size(other)) {
1555 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001556 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 result = make_new_set_basetype(Py_TYPE(so), NULL);
1559 if (result == NULL)
1560 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001561
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001562 if (PyDict_CheckExact(other)) {
1563 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001564 key = entry->key;
1565 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001566 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001567 if (rv < 0) {
1568 Py_DECREF(result);
1569 return NULL;
1570 }
1571 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001572 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001573 Py_DECREF(result);
1574 return NULL;
1575 }
1576 }
1577 }
1578 return result;
1579 }
1580
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001581 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001583 key = entry->key;
1584 hash = entry->hash;
1585 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001586 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001587 Py_DECREF(result);
1588 return NULL;
1589 }
1590 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001591 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001592 Py_DECREF(result);
1593 return NULL;
1594 }
1595 }
1596 }
1597 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001598}
1599
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001600static PyObject *
1601set_difference_multi(PySetObject *so, PyObject *args)
1602{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 Py_ssize_t i;
1604 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 if (PyTuple_GET_SIZE(args) == 0)
1607 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001608
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001609 other = PyTuple_GET_ITEM(args, 0);
1610 result = set_difference(so, other);
1611 if (result == NULL)
1612 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001613
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001614 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1615 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001616 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001617 Py_DECREF(result);
1618 return NULL;
1619 }
1620 }
1621 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001622}
1623
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001624PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001625"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001626\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001627(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001628static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001629set_sub(PySetObject *so, PyObject *other)
1630{
Brian Curtindfc80e32011-08-10 20:28:54 -05001631 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1632 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001634}
1635
1636static PyObject *
1637set_isub(PySetObject *so, PyObject *other)
1638{
Brian Curtindfc80e32011-08-10 20:28:54 -05001639 if (!PyAnySet_Check(other))
1640 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001641 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 return NULL;
1643 Py_INCREF(so);
1644 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001645}
1646
1647static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001648set_symmetric_difference_update(PySetObject *so, PyObject *other)
1649{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001650 PySetObject *otherset;
1651 PyObject *key;
1652 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001653 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001655 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001656
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001657 if ((PyObject *)so == other)
1658 return set_clear(so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 if (PyDict_CheckExact(other)) {
1661 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001662 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001663 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001664 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001665 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001666 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001667 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001669 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001670 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001671 Py_DECREF(key);
1672 return NULL;
1673 }
1674 }
Georg Brandl2d444492010-09-03 10:52:55 +00001675 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001676 }
1677 Py_RETURN_NONE;
1678 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001679
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001680 if (PyAnySet_Check(other)) {
1681 Py_INCREF(other);
1682 otherset = (PySetObject *)other;
1683 } else {
1684 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1685 if (otherset == NULL)
1686 return NULL;
1687 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001688
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001689 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001690 key = entry->key;
1691 hash = entry->hash;
1692 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001693 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001694 Py_DECREF(otherset);
1695 return NULL;
1696 }
1697 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001698 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001699 Py_DECREF(otherset);
1700 return NULL;
1701 }
1702 }
1703 }
1704 Py_DECREF(otherset);
1705 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001706}
1707
1708PyDoc_STRVAR(symmetric_difference_update_doc,
1709"Update a set with the symmetric difference of itself and another.");
1710
1711static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001712set_symmetric_difference(PySetObject *so, PyObject *other)
1713{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001714 PyObject *rv;
1715 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001716
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001717 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1718 if (otherset == NULL)
1719 return NULL;
1720 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
1721 if (rv == NULL)
1722 return NULL;
1723 Py_DECREF(rv);
1724 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001725}
1726
1727PyDoc_STRVAR(symmetric_difference_doc,
1728"Return the symmetric difference of two sets as a new set.\n\
1729\n\
1730(i.e. all elements that are in exactly one of the sets.)");
1731
1732static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001733set_xor(PySetObject *so, PyObject *other)
1734{
Brian Curtindfc80e32011-08-10 20:28:54 -05001735 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1736 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001737 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001738}
1739
1740static PyObject *
1741set_ixor(PySetObject *so, PyObject *other)
1742{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001743 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001744
Brian Curtindfc80e32011-08-10 20:28:54 -05001745 if (!PyAnySet_Check(other))
1746 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001747 result = set_symmetric_difference_update(so, other);
1748 if (result == NULL)
1749 return NULL;
1750 Py_DECREF(result);
1751 Py_INCREF(so);
1752 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001753}
1754
1755static PyObject *
1756set_issubset(PySetObject *so, PyObject *other)
1757{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001758 setentry *entry;
1759 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001760 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001761
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001762 if (!PyAnySet_Check(other)) {
1763 PyObject *tmp, *result;
1764 tmp = make_new_set(&PySet_Type, other);
1765 if (tmp == NULL)
1766 return NULL;
1767 result = set_issubset(so, tmp);
1768 Py_DECREF(tmp);
1769 return result;
1770 }
1771 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1772 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001773
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001774 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001775 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001776 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 return NULL;
1778 if (!rv)
1779 Py_RETURN_FALSE;
1780 }
1781 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001782}
1783
1784PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1785
1786static PyObject *
1787set_issuperset(PySetObject *so, PyObject *other)
1788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001790
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001791 if (!PyAnySet_Check(other)) {
1792 tmp = make_new_set(&PySet_Type, other);
1793 if (tmp == NULL)
1794 return NULL;
1795 result = set_issuperset(so, tmp);
1796 Py_DECREF(tmp);
1797 return result;
1798 }
1799 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001800}
1801
1802PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1803
Raymond Hettingera690a992003-11-16 16:17:49 +00001804static PyObject *
1805set_richcompare(PySetObject *v, PyObject *w, int op)
1806{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001807 PyObject *r1;
1808 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001809
Brian Curtindfc80e32011-08-10 20:28:54 -05001810 if(!PyAnySet_Check(w))
1811 Py_RETURN_NOTIMPLEMENTED;
1812
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001813 switch (op) {
1814 case Py_EQ:
1815 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1816 Py_RETURN_FALSE;
1817 if (v->hash != -1 &&
1818 ((PySetObject *)w)->hash != -1 &&
1819 v->hash != ((PySetObject *)w)->hash)
1820 Py_RETURN_FALSE;
1821 return set_issubset(v, w);
1822 case Py_NE:
1823 r1 = set_richcompare(v, w, Py_EQ);
1824 if (r1 == NULL)
1825 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001826 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001827 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001828 if (r2 < 0)
1829 return NULL;
1830 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001831 case Py_LE:
1832 return set_issubset(v, w);
1833 case Py_GE:
1834 return set_issuperset(v, w);
1835 case Py_LT:
1836 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1837 Py_RETURN_FALSE;
1838 return set_issubset(v, w);
1839 case Py_GT:
1840 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1841 Py_RETURN_FALSE;
1842 return set_issuperset(v, w);
1843 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001844 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001845}
1846
Raymond Hettingera690a992003-11-16 16:17:49 +00001847static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001848set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001849{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001850 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001851 return NULL;
1852 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001853}
1854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001856"Add an element to a set.\n\
1857\n\
1858This has no effect if the element is already present.");
1859
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001860static int
1861set_contains(PySetObject *so, PyObject *key)
1862{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 PyObject *tmpkey;
1864 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001867 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1869 return -1;
1870 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001871 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 if (tmpkey == NULL)
1873 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001874 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 Py_DECREF(tmpkey);
1876 }
1877 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001878}
1879
1880static PyObject *
1881set_direct_contains(PySetObject *so, PyObject *key)
1882{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001883 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001886 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 return NULL;
1888 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001889}
1890
1891PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1892
Raymond Hettingera690a992003-11-16 16:17:49 +00001893static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001894set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001895{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 PyObject *tmpkey;
1897 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001899 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001900 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1902 return NULL;
1903 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001904 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 if (tmpkey == NULL)
1906 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001907 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001909 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 return NULL;
1911 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001913 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001914 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 return NULL;
1916 }
1917 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001918}
1919
1920PyDoc_STRVAR(remove_doc,
1921"Remove an element from a set; it must be a member.\n\
1922\n\
1923If the element is not a member, raise a KeyError.");
1924
1925static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001926set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001927{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001928 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001929 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001932 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001933 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1934 return NULL;
1935 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001936 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 if (tmpkey == NULL)
1938 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001939 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001940 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001941 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001942 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 }
1944 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001945}
1946
1947PyDoc_STRVAR(discard_doc,
1948"Remove an element from a set if it is a member.\n\
1949\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001950If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001951
1952static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001953set_reduce(PySetObject *so)
1954{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001956 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001957
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001958 keys = PySequence_List((PyObject *)so);
1959 if (keys == NULL)
1960 goto done;
1961 args = PyTuple_Pack(1, keys);
1962 if (args == NULL)
1963 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001964 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001965 if (dict == NULL) {
1966 PyErr_Clear();
1967 dict = Py_None;
1968 Py_INCREF(dict);
1969 }
1970 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001971done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001972 Py_XDECREF(args);
1973 Py_XDECREF(keys);
1974 Py_XDECREF(dict);
1975 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001976}
1977
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001978static PyObject *
1979set_sizeof(PySetObject *so)
1980{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001981 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001983 res = sizeof(PySetObject);
1984 if (so->table != so->smalltable)
1985 res = res + (so->mask + 1) * sizeof(setentry);
1986 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001987}
1988
1989PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001990static int
1991set_init(PySetObject *self, PyObject *args, PyObject *kwds)
1992{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001993 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001995 if (!PyAnySet_Check(self))
1996 return -1;
1997 if (PySet_Check(self) && !_PyArg_NoKeywords("set()", kwds))
1998 return -1;
1999 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
2000 return -1;
2001 set_clear_internal(self);
2002 self->hash = -1;
2003 if (iterable == NULL)
2004 return 0;
2005 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002006}
2007
Raymond Hettingera690a992003-11-16 16:17:49 +00002008static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002009 set_len, /* sq_length */
2010 0, /* sq_concat */
2011 0, /* sq_repeat */
2012 0, /* sq_item */
2013 0, /* sq_slice */
2014 0, /* sq_ass_item */
2015 0, /* sq_ass_slice */
2016 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002017};
2018
2019/* set object ********************************************************/
2020
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002021#ifdef Py_DEBUG
2022static PyObject *test_c_api(PySetObject *so);
2023
2024PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2025All is well if assertions don't fail.");
2026#endif
2027
Raymond Hettingera690a992003-11-16 16:17:49 +00002028static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002029 {"add", (PyCFunction)set_add, METH_O,
2030 add_doc},
2031 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2032 clear_doc},
2033 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2034 contains_doc},
2035 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2036 copy_doc},
2037 {"discard", (PyCFunction)set_discard, METH_O,
2038 discard_doc},
2039 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2040 difference_doc},
2041 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2042 difference_update_doc},
2043 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2044 intersection_doc},
2045 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2046 intersection_update_doc},
2047 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2048 isdisjoint_doc},
2049 {"issubset", (PyCFunction)set_issubset, METH_O,
2050 issubset_doc},
2051 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2052 issuperset_doc},
2053 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2054 pop_doc},
2055 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2056 reduce_doc},
2057 {"remove", (PyCFunction)set_remove, METH_O,
2058 remove_doc},
2059 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2060 sizeof_doc},
2061 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2062 symmetric_difference_doc},
2063 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2064 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002065#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002066 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2067 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002068#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002069 {"union", (PyCFunction)set_union, METH_VARARGS,
2070 union_doc},
2071 {"update", (PyCFunction)set_update, METH_VARARGS,
2072 update_doc},
2073 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002074};
2075
2076static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002077 0, /*nb_add*/
2078 (binaryfunc)set_sub, /*nb_subtract*/
2079 0, /*nb_multiply*/
2080 0, /*nb_remainder*/
2081 0, /*nb_divmod*/
2082 0, /*nb_power*/
2083 0, /*nb_negative*/
2084 0, /*nb_positive*/
2085 0, /*nb_absolute*/
2086 0, /*nb_bool*/
2087 0, /*nb_invert*/
2088 0, /*nb_lshift*/
2089 0, /*nb_rshift*/
2090 (binaryfunc)set_and, /*nb_and*/
2091 (binaryfunc)set_xor, /*nb_xor*/
2092 (binaryfunc)set_or, /*nb_or*/
2093 0, /*nb_int*/
2094 0, /*nb_reserved*/
2095 0, /*nb_float*/
2096 0, /*nb_inplace_add*/
2097 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2098 0, /*nb_inplace_multiply*/
2099 0, /*nb_inplace_remainder*/
2100 0, /*nb_inplace_power*/
2101 0, /*nb_inplace_lshift*/
2102 0, /*nb_inplace_rshift*/
2103 (binaryfunc)set_iand, /*nb_inplace_and*/
2104 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2105 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002106};
2107
2108PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002109"set() -> new empty set object\n\
2110set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002111\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002112Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002113
2114PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002115 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2116 "set", /* tp_name */
2117 sizeof(PySetObject), /* tp_basicsize */
2118 0, /* tp_itemsize */
2119 /* methods */
2120 (destructor)set_dealloc, /* tp_dealloc */
2121 0, /* tp_print */
2122 0, /* tp_getattr */
2123 0, /* tp_setattr */
2124 0, /* tp_reserved */
2125 (reprfunc)set_repr, /* tp_repr */
2126 &set_as_number, /* tp_as_number */
2127 &set_as_sequence, /* tp_as_sequence */
2128 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002129 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002130 0, /* tp_call */
2131 0, /* tp_str */
2132 PyObject_GenericGetAttr, /* tp_getattro */
2133 0, /* tp_setattro */
2134 0, /* tp_as_buffer */
2135 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2136 Py_TPFLAGS_BASETYPE, /* tp_flags */
2137 set_doc, /* tp_doc */
2138 (traverseproc)set_traverse, /* tp_traverse */
2139 (inquiry)set_clear_internal, /* tp_clear */
2140 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002141 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2142 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002143 0, /* tp_iternext */
2144 set_methods, /* tp_methods */
2145 0, /* tp_members */
2146 0, /* tp_getset */
2147 0, /* tp_base */
2148 0, /* tp_dict */
2149 0, /* tp_descr_get */
2150 0, /* tp_descr_set */
2151 0, /* tp_dictoffset */
2152 (initproc)set_init, /* tp_init */
2153 PyType_GenericAlloc, /* tp_alloc */
2154 set_new, /* tp_new */
2155 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002156};
2157
2158/* frozenset object ********************************************************/
2159
2160
2161static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002162 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2163 contains_doc},
2164 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2165 copy_doc},
2166 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2167 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002168 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002169 intersection_doc},
2170 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2171 isdisjoint_doc},
2172 {"issubset", (PyCFunction)set_issubset, METH_O,
2173 issubset_doc},
2174 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2175 issuperset_doc},
2176 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2177 reduce_doc},
2178 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2179 sizeof_doc},
2180 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2181 symmetric_difference_doc},
2182 {"union", (PyCFunction)set_union, METH_VARARGS,
2183 union_doc},
2184 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002185};
2186
2187static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002188 0, /*nb_add*/
2189 (binaryfunc)set_sub, /*nb_subtract*/
2190 0, /*nb_multiply*/
2191 0, /*nb_remainder*/
2192 0, /*nb_divmod*/
2193 0, /*nb_power*/
2194 0, /*nb_negative*/
2195 0, /*nb_positive*/
2196 0, /*nb_absolute*/
2197 0, /*nb_bool*/
2198 0, /*nb_invert*/
2199 0, /*nb_lshift*/
2200 0, /*nb_rshift*/
2201 (binaryfunc)set_and, /*nb_and*/
2202 (binaryfunc)set_xor, /*nb_xor*/
2203 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002204};
2205
2206PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002207"frozenset() -> empty frozenset object\n\
2208frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002209\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002210Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002211
2212PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002213 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2214 "frozenset", /* tp_name */
2215 sizeof(PySetObject), /* tp_basicsize */
2216 0, /* tp_itemsize */
2217 /* methods */
2218 (destructor)set_dealloc, /* tp_dealloc */
2219 0, /* tp_print */
2220 0, /* tp_getattr */
2221 0, /* tp_setattr */
2222 0, /* tp_reserved */
2223 (reprfunc)set_repr, /* tp_repr */
2224 &frozenset_as_number, /* tp_as_number */
2225 &set_as_sequence, /* tp_as_sequence */
2226 0, /* tp_as_mapping */
2227 frozenset_hash, /* tp_hash */
2228 0, /* tp_call */
2229 0, /* tp_str */
2230 PyObject_GenericGetAttr, /* tp_getattro */
2231 0, /* tp_setattro */
2232 0, /* tp_as_buffer */
2233 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2234 Py_TPFLAGS_BASETYPE, /* tp_flags */
2235 frozenset_doc, /* tp_doc */
2236 (traverseproc)set_traverse, /* tp_traverse */
2237 (inquiry)set_clear_internal, /* tp_clear */
2238 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002239 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002240 (getiterfunc)set_iter, /* tp_iter */
2241 0, /* tp_iternext */
2242 frozenset_methods, /* tp_methods */
2243 0, /* tp_members */
2244 0, /* tp_getset */
2245 0, /* tp_base */
2246 0, /* tp_dict */
2247 0, /* tp_descr_get */
2248 0, /* tp_descr_set */
2249 0, /* tp_dictoffset */
2250 0, /* tp_init */
2251 PyType_GenericAlloc, /* tp_alloc */
2252 frozenset_new, /* tp_new */
2253 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002254};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002255
2256
2257/***** C API functions *************************************************/
2258
2259PyObject *
2260PySet_New(PyObject *iterable)
2261{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002262 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002263}
2264
2265PyObject *
2266PyFrozenSet_New(PyObject *iterable)
2267{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002268 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002269}
2270
Neal Norwitz8c49c822006-03-04 18:41:19 +00002271Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002272PySet_Size(PyObject *anyset)
2273{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002274 if (!PyAnySet_Check(anyset)) {
2275 PyErr_BadInternalCall();
2276 return -1;
2277 }
2278 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002279}
2280
2281int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002282PySet_Clear(PyObject *set)
2283{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002284 if (!PySet_Check(set)) {
2285 PyErr_BadInternalCall();
2286 return -1;
2287 }
2288 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002289}
2290
2291int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002292PySet_Contains(PyObject *anyset, PyObject *key)
2293{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002294 if (!PyAnySet_Check(anyset)) {
2295 PyErr_BadInternalCall();
2296 return -1;
2297 }
2298 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002299}
2300
2301int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002302PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002303{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002304 if (!PySet_Check(set)) {
2305 PyErr_BadInternalCall();
2306 return -1;
2307 }
2308 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002309}
2310
2311int
Christian Heimesfd66e512008-01-29 12:18:50 +00002312PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002313{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002314 if (!PySet_Check(anyset) &&
2315 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2316 PyErr_BadInternalCall();
2317 return -1;
2318 }
2319 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002320}
2321
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002322int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002323_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002324{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002325 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002326
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002327 if (!PyAnySet_Check(set)) {
2328 PyErr_BadInternalCall();
2329 return -1;
2330 }
2331 if (set_next((PySetObject *)set, pos, &entry) == 0)
2332 return 0;
2333 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002334 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002335 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002336}
2337
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002338PyObject *
2339PySet_Pop(PyObject *set)
2340{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002341 if (!PySet_Check(set)) {
2342 PyErr_BadInternalCall();
2343 return NULL;
2344 }
2345 return set_pop((PySetObject *)set);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002346}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002347
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002348int
2349_PySet_Update(PyObject *set, PyObject *iterable)
2350{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002351 if (!PySet_Check(set)) {
2352 PyErr_BadInternalCall();
2353 return -1;
2354 }
2355 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002356}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002357
Raymond Hettingere259f132013-12-15 11:56:14 -08002358/* Exported for the gdb plugin's benefit. */
2359PyObject *_PySet_Dummy = dummy;
2360
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002361#ifdef Py_DEBUG
2362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002363/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002364 Returns True and original set is restored. */
2365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002366#define assertRaises(call_return_value, exception) \
2367 do { \
2368 assert(call_return_value); \
2369 assert(PyErr_ExceptionMatches(exception)); \
2370 PyErr_Clear(); \
2371 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002372
2373static PyObject *
2374test_c_api(PySetObject *so)
2375{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002376 Py_ssize_t count;
2377 char *s;
2378 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002379 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002380 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002381 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002382 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002384 /* Verify preconditions */
2385 assert(PyAnySet_Check(ob));
2386 assert(PyAnySet_CheckExact(ob));
2387 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002389 /* so.clear(); so |= set("abc"); */
2390 str = PyUnicode_FromString("abc");
2391 if (str == NULL)
2392 return NULL;
2393 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002394 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002395 Py_DECREF(str);
2396 return NULL;
2397 }
2398 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002400 /* Exercise type/size checks */
2401 assert(PySet_Size(ob) == 3);
2402 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 /* Raise TypeError for non-iterable constructor arguments */
2405 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2406 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 /* Raise TypeError for unhashable key */
2409 dup = PySet_New(ob);
2410 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2411 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2412 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002414 /* Exercise successful pop, contains, add, and discard */
2415 elem = PySet_Pop(ob);
2416 assert(PySet_Contains(ob, elem) == 0);
2417 assert(PySet_GET_SIZE(ob) == 2);
2418 assert(PySet_Add(ob, elem) == 0);
2419 assert(PySet_Contains(ob, elem) == 1);
2420 assert(PySet_GET_SIZE(ob) == 3);
2421 assert(PySet_Discard(ob, elem) == 1);
2422 assert(PySet_GET_SIZE(ob) == 2);
2423 assert(PySet_Discard(ob, elem) == 0);
2424 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002426 /* Exercise clear */
2427 dup2 = PySet_New(dup);
2428 assert(PySet_Clear(dup2) == 0);
2429 assert(PySet_Size(dup2) == 0);
2430 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002432 /* Raise SystemError on clear or update of frozen set */
2433 f = PyFrozenSet_New(dup);
2434 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2435 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2436 assert(PySet_Add(f, elem) == 0);
2437 Py_INCREF(f);
2438 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2439 Py_DECREF(f);
2440 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002442 /* Exercise direct iteration */
2443 i = 0, count = 0;
2444 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
2445 s = _PyUnicode_AsString(x);
2446 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2447 count++;
2448 }
2449 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002450
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002451 /* Exercise updates */
2452 dup2 = PySet_New(NULL);
2453 assert(_PySet_Update(dup2, dup) == 0);
2454 assert(PySet_Size(dup2) == 3);
2455 assert(_PySet_Update(dup2, dup) == 0);
2456 assert(PySet_Size(dup2) == 3);
2457 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002458
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002459 /* Raise SystemError when self argument is not a set or frozenset. */
2460 t = PyTuple_New(0);
2461 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2462 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2463 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002465 /* Raise SystemError when self argument is not a set. */
2466 f = PyFrozenSet_New(dup);
2467 assert(PySet_Size(f) == 3);
2468 assert(PyFrozenSet_CheckExact(f));
2469 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2470 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2471 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002472
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002473 /* Raise KeyError when popping from an empty set */
2474 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2475 Py_DECREF(ob);
2476 assert(PySet_GET_SIZE(ob) == 0);
2477 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002479 /* Restore the set from the copy using the PyNumber API */
2480 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2481 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002483 /* Verify constructors accept NULL arguments */
2484 f = PySet_New(NULL);
2485 assert(f != NULL);
2486 assert(PySet_GET_SIZE(f) == 0);
2487 Py_DECREF(f);
2488 f = PyFrozenSet_New(NULL);
2489 assert(f != NULL);
2490 assert(PyFrozenSet_CheckExact(f));
2491 assert(PySet_GET_SIZE(f) == 0);
2492 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002494 Py_DECREF(elem);
2495 Py_DECREF(dup);
2496 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002497}
2498
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002499#undef assertRaises
2500
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002501#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002502
2503/***** Dummy Struct *************************************************/
2504
2505static PyObject *
2506dummy_repr(PyObject *op)
2507{
2508 return PyUnicode_FromString("<dummy key>");
2509}
2510
2511static void
2512dummy_dealloc(PyObject* ignore)
2513{
2514 Py_FatalError("deallocating <dummy key>");
2515}
2516
2517static PyTypeObject _PySetDummy_Type = {
2518 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2519 "<dummy key> type",
2520 0,
2521 0,
2522 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2523 0, /*tp_print*/
2524 0, /*tp_getattr*/
2525 0, /*tp_setattr*/
2526 0, /*tp_reserved*/
2527 dummy_repr, /*tp_repr*/
2528 0, /*tp_as_number*/
2529 0, /*tp_as_sequence*/
2530 0, /*tp_as_mapping*/
2531 0, /*tp_hash */
2532 0, /*tp_call */
2533 0, /*tp_str */
2534 0, /*tp_getattro */
2535 0, /*tp_setattro */
2536 0, /*tp_as_buffer */
2537 Py_TPFLAGS_DEFAULT, /*tp_flags */
2538};
2539
2540static PyObject _dummy_struct = {
2541 _PyObject_EXTRA_INIT
2542 2, &_PySetDummy_Type
2543};
2544