blob: 0e443c48e42c927e3a0ef5edaf2916d84ab3820b [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);
174 if (cmp < 0) /* unlikely */
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400175 goto comparison_error;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700176 if (table != so->table || entry->key != startkey) /* unlikely */
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400177 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700178 if (cmp > 0) /* likely */
179 goto found_active;
180 mask = so->mask; /* help avoid a register spill */
181 }
Raymond Hettinger70559b52015-07-23 07:42:23 -0400182 else if (entry->hash == -1 && freeslot == NULL)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700183 freeslot = entry;
184
185 if (i + LINEAR_PROBES <= mask) {
186 for (j = 0 ; j < LINEAR_PROBES ; j++) {
187 entry++;
188 if (entry->hash == 0 && entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700189 goto found_unused_or_dummy;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700190 if (entry->hash == hash) {
191 PyObject *startkey = entry->key;
192 assert(startkey != dummy);
193 if (startkey == key)
194 goto found_active;
195 if (PyUnicode_CheckExact(startkey)
196 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700197 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700198 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400199 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700200 Py_INCREF(startkey);
201 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
202 Py_DECREF(startkey);
203 if (cmp < 0)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400204 goto comparison_error;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700205 if (table != so->table || entry->key != startkey)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400206 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700207 if (cmp > 0)
208 goto found_active;
209 mask = so->mask;
210 }
Raymond Hettinger91672612015-06-26 02:50:21 -0700211 else if (entry->hash == -1 && freeslot == NULL)
Raymond Hettingerc658d852015-02-02 08:35:00 -0800212 freeslot = entry;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700213 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700215
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700216 perturb >>= PERTURB_SHIFT;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -0800217 i = (i * 5 + 1 + perturb) & mask;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700218
Raymond Hettinger70559b52015-07-23 07:42:23 -0400219 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700220 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700221 goto found_unused_or_dummy;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700223
Raymond Hettinger15f08692015-07-03 17:21:17 -0700224 found_unused_or_dummy:
225 if (freeslot == NULL)
226 goto found_unused;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700227 so->used++;
228 freeslot->key = key;
229 freeslot->hash = hash;
230 return 0;
231
232 found_unused:
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700233 so->fill++;
234 so->used++;
235 entry->key = key;
236 entry->hash = hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700237 if ((size_t)so->fill*3 < mask*2)
238 return 0;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400239 return set_table_resize(so, so->used);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700240
241 found_active:
Raymond Hettinger482c05c2015-07-20 01:23:32 -0400242 Py_DECREF(key);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700243 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000244
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400245 comparison_error:
Raymond Hettinger061091a2015-07-15 23:54:02 -0700246 Py_DECREF(key);
247 return -1;
248}
249
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000250/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000251Internal routine used by set_table_resize() to insert an item which is
252known to be absent from the set. This routine also assumes that
253the set contains no deleted entries. Besides the performance benefit,
254using set_insert_clean() in set_table_resize() is dangerous (SF bug #1456209).
255Note that no refcounts are changed by this routine; if needed, the caller
256is responsible for incref'ing `key`.
257*/
258static void
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200259set_insert_clean(PySetObject *so, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000260{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 setentry *table = so->table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200262 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700263 size_t perturb = hash;
264 size_t mask = (size_t)so->mask;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800265 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700266 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000267
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700268 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800269 entry = &table[i];
270 if (entry->key == NULL)
271 goto found_null;
272 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800273 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800274 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800275 if (entry->key == NULL)
276 goto found_null;
277 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700278 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700279 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800280 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700282 found_null:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 entry->key = key;
284 entry->hash = hash;
Raymond Hettinger4ef05282013-09-21 15:39:49 -0700285 so->fill++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 so->used++;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000287}
288
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700289/* ======== End logic for probing the hash table ========================== */
290/* ======================================================================== */
291
Thomas Wouters89f507f2006-12-13 04:49:30 +0000292/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000293Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000294keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000295actually be smaller than the old one.
296*/
297static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000298set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000299{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 Py_ssize_t newsize;
301 setentry *oldtable, *newtable, *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800302 Py_ssize_t oldfill = so->fill;
303 Py_ssize_t oldused = so->used;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 int is_oldtable_malloced;
305 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 assert(minused >= 0);
Raymond Hettinger48973002015-07-03 20:00:03 -0700308 minused = (minused > 50000) ? minused * 2 : minused * 4;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100311 /* XXX speed-up with intrinsics */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 for (newsize = PySet_MINSIZE;
313 newsize <= minused && newsize > 0;
314 newsize <<= 1)
315 ;
316 if (newsize <= 0) {
317 PyErr_NoMemory();
318 return -1;
319 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000321 /* Get space for a new table. */
322 oldtable = so->table;
323 assert(oldtable != NULL);
324 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 if (newsize == PySet_MINSIZE) {
327 /* A large table is shrinking, or we can't get any smaller. */
328 newtable = so->smalltable;
329 if (newtable == oldtable) {
330 if (so->fill == so->used) {
331 /* No dummies, so no point doing anything. */
332 return 0;
333 }
334 /* We're not going to resize it, but rebuild the
335 table anyway to purge old dummy entries.
336 Subtle: This is *necessary* if fill==size,
337 as set_lookkey needs at least one virgin slot to
338 terminate failing searches. If fill < size, it's
339 merely desirable, as dummies slow searches. */
340 assert(so->fill > so->used);
341 memcpy(small_copy, oldtable, sizeof(small_copy));
342 oldtable = small_copy;
343 }
344 }
345 else {
346 newtable = PyMem_NEW(setentry, newsize);
347 if (newtable == NULL) {
348 PyErr_NoMemory();
349 return -1;
350 }
351 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 /* Make the set empty, using the new table. */
354 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 memset(newtable, 0, sizeof(setentry) * newsize);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000356 so->fill = 0;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800357 so->used = 0;
358 so->mask = newsize - 1;
359 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361 /* Copy the data over; this is refcount-neutral for active entries;
362 dummy entries aren't copied over, of course */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800363 if (oldfill == oldused) {
364 for (entry = oldtable; oldused > 0; entry++) {
365 if (entry->key != NULL) {
366 oldused--;
367 set_insert_clean(so, entry->key, entry->hash);
368 }
369 }
370 } else {
371 for (entry = oldtable; oldused > 0; entry++) {
372 if (entry->key != NULL && entry->key != dummy) {
373 oldused--;
374 set_insert_clean(so, entry->key, entry->hash);
375 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376 }
377 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 if (is_oldtable_malloced)
380 PyMem_DEL(oldtable);
381 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000382}
383
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000384static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700385set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000386{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700387 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000388
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700389 entry = set_lookkey(so, key, hash);
390 if (entry != NULL)
391 return entry->key != NULL;
392 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000393}
394
395#define DISCARD_NOTFOUND 0
396#define DISCARD_FOUND 1
397
398static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700399set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800400{
401 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000403
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700404 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 if (entry == NULL)
406 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700407 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 return DISCARD_NOTFOUND;
409 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000410 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800411 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 so->used--;
413 Py_DECREF(old_key);
414 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000415}
416
417static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700418set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000419{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200420 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000421
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700422 if (!PyUnicode_CheckExact(key) ||
423 (hash = ((PyASCIIObject *) key)->hash) == -1) {
424 hash = PyObject_Hash(key);
425 if (hash == -1)
426 return -1;
427 }
428 return set_add_entry(so, key, hash);
429}
430
431static int
432set_contains_key(PySetObject *so, PyObject *key)
433{
434 Py_hash_t hash;
435
436 if (!PyUnicode_CheckExact(key) ||
437 (hash = ((PyASCIIObject *) key)->hash) == -1) {
438 hash = PyObject_Hash(key);
439 if (hash == -1)
440 return -1;
441 }
442 return set_contains_entry(so, key, hash);
443}
444
445static int
446set_discard_key(PySetObject *so, PyObject *key)
447{
448 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200451 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000452 hash = PyObject_Hash(key);
453 if (hash == -1)
454 return -1;
455 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700456 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000457}
458
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700459static void
460set_empty_to_minsize(PySetObject *so)
461{
462 memset(so->smalltable, 0, sizeof(so->smalltable));
463 so->fill = 0;
464 so->used = 0;
465 so->mask = PySet_MINSIZE - 1;
466 so->table = so->smalltable;
467 so->hash = -1;
468}
469
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000470static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000471set_clear_internal(PySetObject *so)
472{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800473 setentry *entry;
474 setentry *table = so->table;
475 Py_ssize_t fill = so->fill;
476 Py_ssize_t used = so->used;
477 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000479
Raymond Hettinger583cd032013-09-07 22:06:35 -0700480 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 /* This is delicate. During the process of clearing the set,
484 * decrefs can cause the set to mutate. To avoid fatal confusion
485 * (voice of experience), we have to make the set empty before
486 * clearing the slots, and never refer to anything via so->ref while
487 * clearing.
488 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700490 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 else if (fill > 0) {
493 /* It's a small table with something that needs to be cleared.
494 * Afraid the only safe way is to copy the set entries into
495 * another small table first.
496 */
497 memcpy(small_copy, table, sizeof(small_copy));
498 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700499 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500 }
501 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000503 /* Now we can finally clear things. If C had refcounts, we could
504 * assert that the refcount on table is 1 now, i.e. that this function
505 * has unique access to it, so decref side-effects can't alter it.
506 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800507 for (entry = table; used > 0; entry++) {
508 if (entry->key && entry->key != dummy) {
509 used--;
510 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 if (table_is_malloced)
515 PyMem_DEL(table);
516 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000517}
518
519/*
520 * Iterate over a set table. Use like so:
521 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000522 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000523 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000524 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000525 * while (set_next(yourset, &pos, &entry)) {
526 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000527 * }
528 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000529 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000530 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000531 */
532static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000533set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000534{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 Py_ssize_t i;
536 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700537 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 assert (PyAnySet_Check(so));
540 i = *pos_ptr;
541 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700543 entry = &so->table[i];
544 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700546 entry++;
547 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 *pos_ptr = i+1;
549 if (i > mask)
550 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700551 assert(entry != NULL);
552 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000553 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000554}
555
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000556static void
557set_dealloc(PySetObject *so)
558{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200559 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800560 Py_ssize_t used = so->used;
561
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000562 PyObject_GC_UnTrack(so);
563 Py_TRASHCAN_SAFE_BEGIN(so)
564 if (so->weakreflist != NULL)
565 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000566
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800567 for (entry = so->table; used > 0; entry++) {
568 if (entry->key && entry->key != dummy) {
569 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700570 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000571 }
572 }
573 if (so->table != so->smalltable)
574 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700575 Py_TYPE(so)->tp_free(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000576 Py_TRASHCAN_SAFE_END(so)
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000577}
578
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000579static PyObject *
580set_repr(PySetObject *so)
581{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200582 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000584
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000585 if (status != 0) {
586 if (status < 0)
587 return NULL;
588 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
589 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000591 /* shortcut for the empty set */
592 if (!so->used) {
593 Py_ReprLeave((PyObject*)so);
594 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
595 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000597 keys = PySequence_List((PyObject *)so);
598 if (keys == NULL)
599 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000600
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200601 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 listrepr = PyObject_Repr(keys);
603 Py_DECREF(keys);
604 if (listrepr == NULL)
605 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200606 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200608 if (tmp == NULL)
609 goto done;
610 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200611
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200612 if (Py_TYPE(so) != &PySet_Type)
613 result = PyUnicode_FromFormat("%s({%U})",
614 Py_TYPE(so)->tp_name,
615 listrepr);
616 else
617 result = PyUnicode_FromFormat("{%U}", listrepr);
618 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000619done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000620 Py_ReprLeave((PyObject*)so);
621 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000622}
623
Martin v. Löwis18e16552006-02-15 17:27:45 +0000624static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000625set_len(PyObject *so)
626{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000627 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000628}
629
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000630static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000631set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000634 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200635 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700636 setentry *so_entry;
637 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000639 assert (PyAnySet_Check(so));
640 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000641
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000642 other = (PySetObject*)otherset;
643 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700644 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000645 return 0;
646 /* Do one big resize at the start, rather than
647 * incrementally resizing as we insert new keys. Expect
648 * that there will be no (or few) overlapping keys.
649 */
Raymond Hettinger15f08692015-07-03 17:21:17 -0700650 if ((so->fill + other->used)*3 >= so->mask*2) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700651 if (set_table_resize(so, so->used + other->used) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000652 return -1;
653 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700654 so_entry = so->table;
655 other_entry = other->table;
656
657 /* If our table is empty, and both tables have the same size, and
658 there are no dummies to eliminate, then just copy the pointers. */
659 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
660 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
661 key = other_entry->key;
662 if (key != NULL) {
663 assert(so_entry->key == NULL);
664 Py_INCREF(key);
665 so_entry->key = key;
666 so_entry->hash = other_entry->hash;
667 }
668 }
669 so->fill = other->fill;
670 so->used = other->used;
671 return 0;
672 }
673
674 /* If our table is empty, we can use set_insert_clean() */
675 if (so->fill == 0) {
676 for (i = 0; i <= other->mask; i++, other_entry++) {
677 key = other_entry->key;
678 if (key != NULL && key != dummy) {
679 Py_INCREF(key);
680 set_insert_clean(so, key, other_entry->hash);
681 }
682 }
683 return 0;
684 }
685
686 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700687 for (i = 0; i <= other->mask; i++) {
688 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700689 key = other_entry->key;
690 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700691 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000692 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000693 }
694 }
695 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000696}
697
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000698static PyObject *
699set_pop(PySetObject *so)
700{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800701 /* Make sure the search finger is in bounds */
702 Py_ssize_t i = so->finger & so->mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200703 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000704 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000705
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 assert (PyAnySet_Check(so));
707 if (so->used == 0) {
708 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
709 return NULL;
710 }
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000711
Raymond Hettinger1202a472015-01-18 13:12:42 -0800712 while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
713 i++;
Raymond Hettingered741d42015-01-18 21:25:15 -0800714 if (i > so->mask)
715 i = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 }
717 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800719 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 so->used--;
Raymond Hettinger1202a472015-01-18 13:12:42 -0800721 so->finger = i + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000722 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000723}
724
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000725PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
726Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000727
728static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000729set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000730{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000731 Py_ssize_t pos = 0;
732 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000733
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 while (set_next(so, &pos, &entry))
735 Py_VISIT(entry->key);
736 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000737}
738
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000739static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000740frozenset_hash(PyObject *self)
741{
Raymond Hettinger74fc8c42014-01-05 12:00:31 -0800742 /* Most of the constants in this hash algorithm are randomly choosen
743 large primes with "interesting bit patterns" and that passed
744 tests for good collision statistics on a variety of problematic
745 datasets such as:
746
747 ps = []
748 for r in range(21):
749 ps += itertools.combinations(range(20), r)
750 num_distinct_hashes = len({hash(frozenset(s)) for s in ps})
751
752 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000753 PySetObject *so = (PySetObject *)self;
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800754 Py_uhash_t h, hash = 1927868237UL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000755 setentry *entry;
756 Py_ssize_t pos = 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000757
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758 if (so->hash != -1)
759 return so->hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000760
Mark Dickinson57e683e2011-09-24 18:18:40 +0100761 hash *= (Py_uhash_t)PySet_GET_SIZE(self) + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 while (set_next(so, &pos, &entry)) {
763 /* Work to increase the bit dispersion for closely spaced hash
Raymond Hettinger06a1c8d2015-01-30 18:02:15 -0800764 values. This is important because some use cases have many
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000765 combinations of a small number of elements with nearby
766 hashes so that many distinct combinations collapse to only
767 a handful of distinct hash values. */
Antoine Pitroufbb1c612010-10-23 17:37:54 +0000768 h = entry->hash;
Raymond Hettinger74fc8c42014-01-05 12:00:31 -0800769 hash ^= ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000770 }
Raymond Hettinger74fc8c42014-01-05 12:00:31 -0800771 /* Make the final result spread-out in a different pattern
Eric V. Smith6ba56652014-01-14 08:15:03 -0500772 than the algorithm for tuples or other python objects. */
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800773 hash = hash * 69069U + 907133923UL;
Victor Stinner12174a52014-08-15 23:17:38 +0200774 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800775 hash = 590923713UL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000776 so->hash = hash;
777 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000778}
779
Raymond Hettingera9d99362005-08-05 00:01:15 +0000780/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000781
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000782typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000783 PyObject_HEAD
784 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
785 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700786 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000787 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000788} setiterobject;
789
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000790static void
791setiter_dealloc(setiterobject *si)
792{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000793 Py_XDECREF(si->si_set);
794 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000795}
796
797static int
798setiter_traverse(setiterobject *si, visitproc visit, void *arg)
799{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 Py_VISIT(si->si_set);
801 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000802}
803
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000804static PyObject *
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000805setiter_len(setiterobject *si)
806{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000807 Py_ssize_t len = 0;
808 if (si->si_set != NULL && si->si_used == si->si_set->used)
809 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000810 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000811}
812
Armin Rigof5b3e362006-02-11 21:32:43 +0000813PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000814
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000815static PyObject *setiter_iternext(setiterobject *si);
816
817static PyObject *
818setiter_reduce(setiterobject *si)
819{
820 PyObject *list;
821 setiterobject tmp;
822
823 list = PyList_New(0);
824 if (!list)
825 return NULL;
826
Ezio Melotti0e1af282012-09-28 16:43:40 +0300827 /* copy the iterator state */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000828 tmp = *si;
829 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300830
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000831 /* iterate the temporary into a list */
832 for(;;) {
833 PyObject *element = setiter_iternext(&tmp);
834 if (element) {
835 if (PyList_Append(list, element)) {
836 Py_DECREF(element);
837 Py_DECREF(list);
838 Py_XDECREF(tmp.si_set);
839 return NULL;
840 }
841 Py_DECREF(element);
842 } else
843 break;
844 }
845 Py_XDECREF(tmp.si_set);
846 /* check for error */
847 if (tmp.si_set != NULL) {
848 /* we have an error */
849 Py_DECREF(list);
850 return NULL;
851 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200852 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000853}
854
855PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
856
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000857static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000858 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000859 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000860 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000861};
862
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000863static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000864{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700865 PyObject *key;
866 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200867 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000868 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000870 if (so == NULL)
871 return NULL;
872 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000873
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000874 if (si->si_used != so->used) {
875 PyErr_SetString(PyExc_RuntimeError,
876 "Set changed size during iteration");
877 si->si_used = -1; /* Make this state sticky */
878 return NULL;
879 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700880
881 i = si->si_pos;
882 assert(i>=0);
883 entry = so->table;
884 mask = so->mask;
885 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
886 i++;
887 si->si_pos = i+1;
888 if (i > mask)
889 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000890 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700891 key = entry[i].key;
892 Py_INCREF(key);
893 return key;
894
895fail:
896 Py_DECREF(so);
897 si->si_set = NULL;
898 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000899}
900
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000901PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000902 PyVarObject_HEAD_INIT(&PyType_Type, 0)
903 "set_iterator", /* tp_name */
904 sizeof(setiterobject), /* tp_basicsize */
905 0, /* tp_itemsize */
906 /* methods */
907 (destructor)setiter_dealloc, /* tp_dealloc */
908 0, /* tp_print */
909 0, /* tp_getattr */
910 0, /* tp_setattr */
911 0, /* tp_reserved */
912 0, /* tp_repr */
913 0, /* tp_as_number */
914 0, /* tp_as_sequence */
915 0, /* tp_as_mapping */
916 0, /* tp_hash */
917 0, /* tp_call */
918 0, /* tp_str */
919 PyObject_GenericGetAttr, /* tp_getattro */
920 0, /* tp_setattro */
921 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700922 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000923 0, /* tp_doc */
924 (traverseproc)setiter_traverse, /* tp_traverse */
925 0, /* tp_clear */
926 0, /* tp_richcompare */
927 0, /* tp_weaklistoffset */
928 PyObject_SelfIter, /* tp_iter */
929 (iternextfunc)setiter_iternext, /* tp_iternext */
930 setiter_methods, /* tp_methods */
931 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000932};
933
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000934static PyObject *
935set_iter(PySetObject *so)
936{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000937 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
938 if (si == NULL)
939 return NULL;
940 Py_INCREF(so);
941 si->si_set = so;
942 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700943 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000944 si->len = so->used;
945 _PyObject_GC_TRACK(si);
946 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000947}
948
Raymond Hettingerd7946662005-08-01 21:39:29 +0000949static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000950set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000951{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000952 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 if (PyAnySet_Check(other))
955 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000956
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 if (PyDict_CheckExact(other)) {
958 PyObject *value;
959 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000960 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 Py_ssize_t dictsize = PyDict_Size(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 /* Do one big resize at the start, rather than
964 * incrementally resizing as we insert new keys. Expect
965 * that there will be no (or few) overlapping keys.
966 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700967 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000968 return -1;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700969 if ((so->fill + dictsize)*3 >= so->mask*2) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700970 if (set_table_resize(so, so->used + dictsize) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 return -1;
972 }
973 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700974 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000975 return -1;
976 }
977 return 0;
978 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000980 it = PyObject_GetIter(other);
981 if (it == NULL)
982 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +0000983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700985 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000986 Py_DECREF(it);
987 Py_DECREF(key);
988 return -1;
989 }
990 Py_DECREF(key);
991 }
992 Py_DECREF(it);
993 if (PyErr_Occurred())
994 return -1;
995 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000996}
997
998static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000999set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001000{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001001 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1004 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001005 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 return NULL;
1007 }
1008 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001009}
1010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001011PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001012"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001013
Raymond Hettinger426d9952014-05-18 21:40:20 +01001014/* XXX Todo:
1015 If aligned memory allocations become available, make the
1016 set object 64 byte aligned so that most of the fields
1017 can be retrieved or updated in a single cache line.
1018*/
1019
Raymond Hettingera38123e2003-11-24 22:18:49 +00001020static PyObject *
1021make_new_set(PyTypeObject *type, PyObject *iterable)
1022{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001023 PySetObject *so = NULL;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001024
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001025 /* create PySetObject structure */
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001026 so = (PySetObject *)type->tp_alloc(type, 0);
1027 if (so == NULL)
1028 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001029
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001030 so->fill = 0;
1031 so->used = 0;
1032 so->mask = PySet_MINSIZE - 1;
1033 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001034 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001035 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001037
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001038 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001039 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001040 Py_DECREF(so);
1041 return NULL;
1042 }
1043 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001045 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001046}
1047
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001048static PyObject *
1049make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1050{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001051 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1052 if (PyType_IsSubtype(type, &PySet_Type))
1053 type = &PySet_Type;
1054 else
1055 type = &PyFrozenSet_Type;
1056 }
1057 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001058}
1059
Raymond Hettingerd7946662005-08-01 21:39:29 +00001060/* The empty frozenset is a singleton */
1061static PyObject *emptyfrozenset = NULL;
1062
Raymond Hettingera690a992003-11-16 16:17:49 +00001063static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001064frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001065{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001068 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset()", kwds))
1069 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1072 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001073
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 if (type != &PyFrozenSet_Type)
1075 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001076
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 if (iterable != NULL) {
1078 /* frozenset(f) is idempotent */
1079 if (PyFrozenSet_CheckExact(iterable)) {
1080 Py_INCREF(iterable);
1081 return iterable;
1082 }
1083 result = make_new_set(type, iterable);
1084 if (result == NULL || PySet_GET_SIZE(result))
1085 return result;
1086 Py_DECREF(result);
1087 }
1088 /* The empty frozenset is a singleton */
1089 if (emptyfrozenset == NULL)
1090 emptyfrozenset = make_new_set(type, NULL);
1091 Py_XINCREF(emptyfrozenset);
1092 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001093}
1094
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001095int
1096PySet_ClearFreeList(void)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001097{
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001098 return 0;
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001099}
1100
1101void
1102PySet_Fini(void)
1103{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 Py_CLEAR(emptyfrozenset);
Raymond Hettingera690a992003-11-16 16:17:49 +00001105}
1106
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001107static PyObject *
1108set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1109{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001110 if (type == &PySet_Type && !_PyArg_NoKeywords("set()", kwds))
1111 return NULL;
1112
1113 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001114}
1115
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001116/* set_swap_bodies() switches the contents of any two sets by moving their
1117 internal data pointers and, if needed, copying the internal smalltables.
1118 Semantically equivalent to:
1119
1120 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1121
1122 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001123 Useful for operations that update in-place (by allowing an intermediate
1124 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001125*/
1126
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001127static void
1128set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001129{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001130 Py_ssize_t t;
1131 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001132 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001133 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 t = a->fill; a->fill = b->fill; b->fill = t;
1136 t = a->used; a->used = b->used; b->used = t;
1137 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001139 u = a->table;
1140 if (a->table == a->smalltable)
1141 u = b->smalltable;
1142 a->table = b->table;
1143 if (b->table == b->smalltable)
1144 a->table = a->smalltable;
1145 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001146
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 if (a->table == a->smalltable || b->table == b->smalltable) {
1148 memcpy(tab, a->smalltable, sizeof(tab));
1149 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1150 memcpy(b->smalltable, tab, sizeof(tab));
1151 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001152
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1154 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1155 h = a->hash; a->hash = b->hash; b->hash = h;
1156 } else {
1157 a->hash = -1;
1158 b->hash = -1;
1159 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001160}
1161
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001162static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001163set_copy(PySetObject *so)
1164{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001166}
1167
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001168static PyObject *
1169frozenset_copy(PySetObject *so)
1170{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001171 if (PyFrozenSet_CheckExact(so)) {
1172 Py_INCREF(so);
1173 return (PyObject *)so;
1174 }
1175 return set_copy(so);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001176}
1177
Raymond Hettingera690a992003-11-16 16:17:49 +00001178PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1179
1180static PyObject *
Raymond Hettingerc991db22005-08-11 07:58:45 +00001181set_clear(PySetObject *so)
1182{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001183 set_clear_internal(so);
1184 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001185}
1186
1187PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1188
1189static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001190set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001191{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001192 PySetObject *result;
1193 PyObject *other;
1194 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001196 result = (PySetObject *)set_copy(so);
1197 if (result == NULL)
1198 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1201 other = PyTuple_GET_ITEM(args, i);
1202 if ((PyObject *)so == other)
1203 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001204 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001205 Py_DECREF(result);
1206 return NULL;
1207 }
1208 }
1209 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001210}
1211
1212PyDoc_STRVAR(union_doc,
1213 "Return the union of sets as a new set.\n\
1214\n\
1215(i.e. all elements that are in either set.)");
1216
1217static PyObject *
1218set_or(PySetObject *so, PyObject *other)
1219{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001220 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001221
Brian Curtindfc80e32011-08-10 20:28:54 -05001222 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1223 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001225 result = (PySetObject *)set_copy(so);
1226 if (result == NULL)
1227 return NULL;
1228 if ((PyObject *)so == other)
1229 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001230 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001231 Py_DECREF(result);
1232 return NULL;
1233 }
1234 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001235}
1236
Raymond Hettingera690a992003-11-16 16:17:49 +00001237static PyObject *
1238set_ior(PySetObject *so, PyObject *other)
1239{
Brian Curtindfc80e32011-08-10 20:28:54 -05001240 if (!PyAnySet_Check(other))
1241 Py_RETURN_NOTIMPLEMENTED;
1242
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001243 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 return NULL;
1245 Py_INCREF(so);
1246 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001247}
1248
1249static PyObject *
1250set_intersection(PySetObject *so, PyObject *other)
1251{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 PySetObject *result;
1253 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001254 Py_hash_t hash;
1255 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 if ((PyObject *)so == other)
1258 return set_copy(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1261 if (result == NULL)
1262 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 if (PyAnySet_Check(other)) {
1265 Py_ssize_t pos = 0;
1266 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1269 tmp = (PyObject *)so;
1270 so = (PySetObject *)other;
1271 other = tmp;
1272 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001275 key = entry->key;
1276 hash = entry->hash;
1277 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001278 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 Py_DECREF(result);
1280 return NULL;
1281 }
1282 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001283 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 Py_DECREF(result);
1285 return NULL;
1286 }
1287 }
1288 }
1289 return (PyObject *)result;
1290 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 it = PyObject_GetIter(other);
1293 if (it == NULL) {
1294 Py_DECREF(result);
1295 return NULL;
1296 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001299 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001300 if (hash == -1)
1301 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001302 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001303 if (rv < 0)
1304 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001306 if (set_add_entry(result, key, hash))
1307 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 }
1309 Py_DECREF(key);
1310 }
1311 Py_DECREF(it);
1312 if (PyErr_Occurred()) {
1313 Py_DECREF(result);
1314 return NULL;
1315 }
1316 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001317 error:
1318 Py_DECREF(it);
1319 Py_DECREF(result);
1320 Py_DECREF(key);
1321 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001322}
1323
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001324static PyObject *
1325set_intersection_multi(PySetObject *so, PyObject *args)
1326{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 Py_ssize_t i;
1328 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 if (PyTuple_GET_SIZE(args) == 0)
1331 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 Py_INCREF(so);
1334 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1335 PyObject *other = PyTuple_GET_ITEM(args, i);
1336 PyObject *newresult = set_intersection((PySetObject *)result, other);
1337 if (newresult == NULL) {
1338 Py_DECREF(result);
1339 return NULL;
1340 }
1341 Py_DECREF(result);
1342 result = newresult;
1343 }
1344 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001345}
1346
Raymond Hettingera690a992003-11-16 16:17:49 +00001347PyDoc_STRVAR(intersection_doc,
1348"Return the intersection of two sets as a new set.\n\
1349\n\
1350(i.e. all elements that are in both sets.)");
1351
1352static PyObject *
1353set_intersection_update(PySetObject *so, PyObject *other)
1354{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001357 tmp = set_intersection(so, other);
1358 if (tmp == NULL)
1359 return NULL;
1360 set_swap_bodies(so, (PySetObject *)tmp);
1361 Py_DECREF(tmp);
1362 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001363}
1364
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001365static PyObject *
1366set_intersection_update_multi(PySetObject *so, PyObject *args)
1367{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001368 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 tmp = set_intersection_multi(so, args);
1371 if (tmp == NULL)
1372 return NULL;
1373 set_swap_bodies(so, (PySetObject *)tmp);
1374 Py_DECREF(tmp);
1375 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001376}
1377
Raymond Hettingera690a992003-11-16 16:17:49 +00001378PyDoc_STRVAR(intersection_update_doc,
1379"Update a set with the intersection of itself and another.");
1380
1381static PyObject *
1382set_and(PySetObject *so, PyObject *other)
1383{
Brian Curtindfc80e32011-08-10 20:28:54 -05001384 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1385 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001387}
1388
1389static PyObject *
1390set_iand(PySetObject *so, PyObject *other)
1391{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001393
Brian Curtindfc80e32011-08-10 20:28:54 -05001394 if (!PyAnySet_Check(other))
1395 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 result = set_intersection_update(so, other);
1397 if (result == NULL)
1398 return NULL;
1399 Py_DECREF(result);
1400 Py_INCREF(so);
1401 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001402}
1403
Guido van Rossum58da9312007-11-10 23:39:45 +00001404static PyObject *
1405set_isdisjoint(PySetObject *so, PyObject *other)
1406{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001407 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001408 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001410 if ((PyObject *)so == other) {
1411 if (PySet_GET_SIZE(so) == 0)
1412 Py_RETURN_TRUE;
1413 else
1414 Py_RETURN_FALSE;
1415 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 if (PyAnySet_CheckExact(other)) {
1418 Py_ssize_t pos = 0;
1419 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1422 tmp = (PyObject *)so;
1423 so = (PySetObject *)other;
1424 other = tmp;
1425 }
1426 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001427 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001428 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 return NULL;
1430 if (rv)
1431 Py_RETURN_FALSE;
1432 }
1433 Py_RETURN_TRUE;
1434 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 it = PyObject_GetIter(other);
1437 if (it == NULL)
1438 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001441 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001443 if (hash == -1) {
1444 Py_DECREF(key);
1445 Py_DECREF(it);
1446 return NULL;
1447 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001448 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001449 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001450 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001451 Py_DECREF(it);
1452 return NULL;
1453 }
1454 if (rv) {
1455 Py_DECREF(it);
1456 Py_RETURN_FALSE;
1457 }
1458 }
1459 Py_DECREF(it);
1460 if (PyErr_Occurred())
1461 return NULL;
1462 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001463}
1464
1465PyDoc_STRVAR(isdisjoint_doc,
1466"Return True if two sets have a null intersection.");
1467
Neal Norwitz6576bd82005-11-13 18:41:28 +00001468static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001469set_difference_update_internal(PySetObject *so, PyObject *other)
1470{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 if ((PyObject *)so == other)
1472 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 if (PyAnySet_Check(other)) {
1475 setentry *entry;
1476 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001479 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 return -1;
1481 } else {
1482 PyObject *key, *it;
1483 it = PyObject_GetIter(other);
1484 if (it == NULL)
1485 return -1;
1486
1487 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001488 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 Py_DECREF(it);
1490 Py_DECREF(key);
1491 return -1;
1492 }
1493 Py_DECREF(key);
1494 }
1495 Py_DECREF(it);
1496 if (PyErr_Occurred())
1497 return -1;
1498 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001499 /* If more than 1/4th are dummies, then resize them away. */
1500 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 return 0;
Raymond Hettinger48973002015-07-03 20:00:03 -07001502 return set_table_resize(so, so->used);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001503}
1504
Raymond Hettingera690a992003-11-16 16:17:49 +00001505static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001506set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001507{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1511 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001512 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 return NULL;
1514 }
1515 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001516}
1517
1518PyDoc_STRVAR(difference_update_doc,
1519"Remove all elements of another set from this set.");
1520
1521static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001522set_copy_and_difference(PySetObject *so, PyObject *other)
1523{
1524 PyObject *result;
1525
1526 result = set_copy(so);
1527 if (result == NULL)
1528 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001529 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001530 return result;
1531 Py_DECREF(result);
1532 return NULL;
1533}
1534
1535static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001536set_difference(PySetObject *so, PyObject *other)
1537{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001539 PyObject *key;
1540 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541 setentry *entry;
1542 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001543 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001546 return set_copy_and_difference(so, other);
1547 }
1548
1549 /* If len(so) much more than len(other), it's more efficient to simply copy
1550 * so and then iterate other looking for common elements. */
1551 if ((PySet_GET_SIZE(so) >> 2) > PyObject_Size(other)) {
1552 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001553 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001555 result = make_new_set_basetype(Py_TYPE(so), NULL);
1556 if (result == NULL)
1557 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001558
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001559 if (PyDict_CheckExact(other)) {
1560 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001561 key = entry->key;
1562 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001563 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001564 if (rv < 0) {
1565 Py_DECREF(result);
1566 return NULL;
1567 }
1568 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001569 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001570 Py_DECREF(result);
1571 return NULL;
1572 }
1573 }
1574 }
1575 return result;
1576 }
1577
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001578 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001580 key = entry->key;
1581 hash = entry->hash;
1582 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001583 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001584 Py_DECREF(result);
1585 return NULL;
1586 }
1587 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001588 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 Py_DECREF(result);
1590 return NULL;
1591 }
1592 }
1593 }
1594 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001595}
1596
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001597static PyObject *
1598set_difference_multi(PySetObject *so, PyObject *args)
1599{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 Py_ssize_t i;
1601 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001602
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 if (PyTuple_GET_SIZE(args) == 0)
1604 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 other = PyTuple_GET_ITEM(args, 0);
1607 result = set_difference(so, other);
1608 if (result == NULL)
1609 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001610
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1612 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001613 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001614 Py_DECREF(result);
1615 return NULL;
1616 }
1617 }
1618 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001619}
1620
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001621PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001622"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001623\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001624(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001625static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001626set_sub(PySetObject *so, PyObject *other)
1627{
Brian Curtindfc80e32011-08-10 20:28:54 -05001628 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1629 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001631}
1632
1633static PyObject *
1634set_isub(PySetObject *so, PyObject *other)
1635{
Brian Curtindfc80e32011-08-10 20:28:54 -05001636 if (!PyAnySet_Check(other))
1637 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001638 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 return NULL;
1640 Py_INCREF(so);
1641 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001642}
1643
1644static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001645set_symmetric_difference_update(PySetObject *so, PyObject *other)
1646{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 PySetObject *otherset;
1648 PyObject *key;
1649 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001650 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001652 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001653
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654 if ((PyObject *)so == other)
1655 return set_clear(so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001656
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001657 if (PyDict_CheckExact(other)) {
1658 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001659 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001660 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001661 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001662 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001663 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001664 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001665 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001666 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001667 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001668 Py_DECREF(key);
1669 return NULL;
1670 }
1671 }
Georg Brandl2d444492010-09-03 10:52:55 +00001672 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001673 }
1674 Py_RETURN_NONE;
1675 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001677 if (PyAnySet_Check(other)) {
1678 Py_INCREF(other);
1679 otherset = (PySetObject *)other;
1680 } else {
1681 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1682 if (otherset == NULL)
1683 return NULL;
1684 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001685
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001686 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001687 key = entry->key;
1688 hash = entry->hash;
1689 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001690 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001691 Py_DECREF(otherset);
1692 return NULL;
1693 }
1694 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001695 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001696 Py_DECREF(otherset);
1697 return NULL;
1698 }
1699 }
1700 }
1701 Py_DECREF(otherset);
1702 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001703}
1704
1705PyDoc_STRVAR(symmetric_difference_update_doc,
1706"Update a set with the symmetric difference of itself and another.");
1707
1708static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001709set_symmetric_difference(PySetObject *so, PyObject *other)
1710{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001711 PyObject *rv;
1712 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001713
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001714 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1715 if (otherset == NULL)
1716 return NULL;
1717 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
1718 if (rv == NULL)
1719 return NULL;
1720 Py_DECREF(rv);
1721 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001722}
1723
1724PyDoc_STRVAR(symmetric_difference_doc,
1725"Return the symmetric difference of two sets as a new set.\n\
1726\n\
1727(i.e. all elements that are in exactly one of the sets.)");
1728
1729static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001730set_xor(PySetObject *so, PyObject *other)
1731{
Brian Curtindfc80e32011-08-10 20:28:54 -05001732 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1733 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001734 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001735}
1736
1737static PyObject *
1738set_ixor(PySetObject *so, PyObject *other)
1739{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001741
Brian Curtindfc80e32011-08-10 20:28:54 -05001742 if (!PyAnySet_Check(other))
1743 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001744 result = set_symmetric_difference_update(so, other);
1745 if (result == NULL)
1746 return NULL;
1747 Py_DECREF(result);
1748 Py_INCREF(so);
1749 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001750}
1751
1752static PyObject *
1753set_issubset(PySetObject *so, PyObject *other)
1754{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001755 setentry *entry;
1756 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001757 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001758
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001759 if (!PyAnySet_Check(other)) {
1760 PyObject *tmp, *result;
1761 tmp = make_new_set(&PySet_Type, other);
1762 if (tmp == NULL)
1763 return NULL;
1764 result = set_issubset(so, tmp);
1765 Py_DECREF(tmp);
1766 return result;
1767 }
1768 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1769 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001770
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001771 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001772 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001773 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001774 return NULL;
1775 if (!rv)
1776 Py_RETURN_FALSE;
1777 }
1778 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001779}
1780
1781PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1782
1783static PyObject *
1784set_issuperset(PySetObject *so, PyObject *other)
1785{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788 if (!PyAnySet_Check(other)) {
1789 tmp = make_new_set(&PySet_Type, other);
1790 if (tmp == NULL)
1791 return NULL;
1792 result = set_issuperset(so, tmp);
1793 Py_DECREF(tmp);
1794 return result;
1795 }
1796 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001797}
1798
1799PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1800
Raymond Hettingera690a992003-11-16 16:17:49 +00001801static PyObject *
1802set_richcompare(PySetObject *v, PyObject *w, int op)
1803{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001804 PyObject *r1;
1805 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001806
Brian Curtindfc80e32011-08-10 20:28:54 -05001807 if(!PyAnySet_Check(w))
1808 Py_RETURN_NOTIMPLEMENTED;
1809
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001810 switch (op) {
1811 case Py_EQ:
1812 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1813 Py_RETURN_FALSE;
1814 if (v->hash != -1 &&
1815 ((PySetObject *)w)->hash != -1 &&
1816 v->hash != ((PySetObject *)w)->hash)
1817 Py_RETURN_FALSE;
1818 return set_issubset(v, w);
1819 case Py_NE:
1820 r1 = set_richcompare(v, w, Py_EQ);
1821 if (r1 == NULL)
1822 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001823 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001824 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001825 if (r2 < 0)
1826 return NULL;
1827 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001828 case Py_LE:
1829 return set_issubset(v, w);
1830 case Py_GE:
1831 return set_issuperset(v, w);
1832 case Py_LT:
1833 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1834 Py_RETURN_FALSE;
1835 return set_issubset(v, w);
1836 case Py_GT:
1837 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1838 Py_RETURN_FALSE;
1839 return set_issuperset(v, w);
1840 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001841 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001842}
1843
Raymond Hettingera690a992003-11-16 16:17:49 +00001844static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001845set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001846{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001847 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 return NULL;
1849 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001850}
1851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001853"Add an element to a set.\n\
1854\n\
1855This has no effect if the element is already present.");
1856
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001857static int
1858set_contains(PySetObject *so, PyObject *key)
1859{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001860 PyObject *tmpkey;
1861 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001864 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1866 return -1;
1867 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001868 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001869 if (tmpkey == NULL)
1870 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001871 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 Py_DECREF(tmpkey);
1873 }
1874 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001875}
1876
1877static PyObject *
1878set_direct_contains(PySetObject *so, PyObject *key)
1879{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001882 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001883 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 return NULL;
1885 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001886}
1887
1888PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1889
Raymond Hettingera690a992003-11-16 16:17:49 +00001890static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001891set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001892{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 PyObject *tmpkey;
1894 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001897 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001898 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1899 return NULL;
1900 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001901 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 if (tmpkey == NULL)
1903 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001904 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001906 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001907 return NULL;
1908 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001911 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001912 return NULL;
1913 }
1914 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001915}
1916
1917PyDoc_STRVAR(remove_doc,
1918"Remove an element from a set; it must be a member.\n\
1919\n\
1920If the element is not a member, raise a KeyError.");
1921
1922static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001923set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001924{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001925 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001928 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001929 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1931 return NULL;
1932 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001933 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001934 if (tmpkey == NULL)
1935 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001936 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001938 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001939 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001940 }
1941 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001942}
1943
1944PyDoc_STRVAR(discard_doc,
1945"Remove an element from a set if it is a member.\n\
1946\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001948
1949static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001950set_reduce(PySetObject *so)
1951{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001953 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001954
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 keys = PySequence_List((PyObject *)so);
1956 if (keys == NULL)
1957 goto done;
1958 args = PyTuple_Pack(1, keys);
1959 if (args == NULL)
1960 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001961 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001962 if (dict == NULL) {
1963 PyErr_Clear();
1964 dict = Py_None;
1965 Py_INCREF(dict);
1966 }
1967 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001968done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001969 Py_XDECREF(args);
1970 Py_XDECREF(keys);
1971 Py_XDECREF(dict);
1972 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001973}
1974
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001975static PyObject *
1976set_sizeof(PySetObject *so)
1977{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001978 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 res = sizeof(PySetObject);
1981 if (so->table != so->smalltable)
1982 res = res + (so->mask + 1) * sizeof(setentry);
1983 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001984}
1985
1986PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001987static int
1988set_init(PySetObject *self, PyObject *args, PyObject *kwds)
1989{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001990 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001992 if (!PyAnySet_Check(self))
1993 return -1;
1994 if (PySet_Check(self) && !_PyArg_NoKeywords("set()", kwds))
1995 return -1;
1996 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
1997 return -1;
1998 set_clear_internal(self);
1999 self->hash = -1;
2000 if (iterable == NULL)
2001 return 0;
2002 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002003}
2004
Raymond Hettingera690a992003-11-16 16:17:49 +00002005static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 set_len, /* sq_length */
2007 0, /* sq_concat */
2008 0, /* sq_repeat */
2009 0, /* sq_item */
2010 0, /* sq_slice */
2011 0, /* sq_ass_item */
2012 0, /* sq_ass_slice */
2013 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002014};
2015
2016/* set object ********************************************************/
2017
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002018#ifdef Py_DEBUG
2019static PyObject *test_c_api(PySetObject *so);
2020
2021PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2022All is well if assertions don't fail.");
2023#endif
2024
Raymond Hettingera690a992003-11-16 16:17:49 +00002025static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002026 {"add", (PyCFunction)set_add, METH_O,
2027 add_doc},
2028 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2029 clear_doc},
2030 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2031 contains_doc},
2032 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2033 copy_doc},
2034 {"discard", (PyCFunction)set_discard, METH_O,
2035 discard_doc},
2036 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2037 difference_doc},
2038 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2039 difference_update_doc},
2040 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2041 intersection_doc},
2042 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2043 intersection_update_doc},
2044 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2045 isdisjoint_doc},
2046 {"issubset", (PyCFunction)set_issubset, METH_O,
2047 issubset_doc},
2048 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2049 issuperset_doc},
2050 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2051 pop_doc},
2052 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2053 reduce_doc},
2054 {"remove", (PyCFunction)set_remove, METH_O,
2055 remove_doc},
2056 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2057 sizeof_doc},
2058 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2059 symmetric_difference_doc},
2060 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2061 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002062#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002063 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2064 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002065#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002066 {"union", (PyCFunction)set_union, METH_VARARGS,
2067 union_doc},
2068 {"update", (PyCFunction)set_update, METH_VARARGS,
2069 update_doc},
2070 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002071};
2072
2073static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002074 0, /*nb_add*/
2075 (binaryfunc)set_sub, /*nb_subtract*/
2076 0, /*nb_multiply*/
2077 0, /*nb_remainder*/
2078 0, /*nb_divmod*/
2079 0, /*nb_power*/
2080 0, /*nb_negative*/
2081 0, /*nb_positive*/
2082 0, /*nb_absolute*/
2083 0, /*nb_bool*/
2084 0, /*nb_invert*/
2085 0, /*nb_lshift*/
2086 0, /*nb_rshift*/
2087 (binaryfunc)set_and, /*nb_and*/
2088 (binaryfunc)set_xor, /*nb_xor*/
2089 (binaryfunc)set_or, /*nb_or*/
2090 0, /*nb_int*/
2091 0, /*nb_reserved*/
2092 0, /*nb_float*/
2093 0, /*nb_inplace_add*/
2094 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2095 0, /*nb_inplace_multiply*/
2096 0, /*nb_inplace_remainder*/
2097 0, /*nb_inplace_power*/
2098 0, /*nb_inplace_lshift*/
2099 0, /*nb_inplace_rshift*/
2100 (binaryfunc)set_iand, /*nb_inplace_and*/
2101 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2102 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002103};
2104
2105PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002106"set() -> new empty set object\n\
2107set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002108\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002109Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002110
2111PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002112 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2113 "set", /* tp_name */
2114 sizeof(PySetObject), /* tp_basicsize */
2115 0, /* tp_itemsize */
2116 /* methods */
2117 (destructor)set_dealloc, /* tp_dealloc */
2118 0, /* tp_print */
2119 0, /* tp_getattr */
2120 0, /* tp_setattr */
2121 0, /* tp_reserved */
2122 (reprfunc)set_repr, /* tp_repr */
2123 &set_as_number, /* tp_as_number */
2124 &set_as_sequence, /* tp_as_sequence */
2125 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002126 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002127 0, /* tp_call */
2128 0, /* tp_str */
2129 PyObject_GenericGetAttr, /* tp_getattro */
2130 0, /* tp_setattro */
2131 0, /* tp_as_buffer */
2132 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2133 Py_TPFLAGS_BASETYPE, /* tp_flags */
2134 set_doc, /* tp_doc */
2135 (traverseproc)set_traverse, /* tp_traverse */
2136 (inquiry)set_clear_internal, /* tp_clear */
2137 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002138 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2139 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002140 0, /* tp_iternext */
2141 set_methods, /* tp_methods */
2142 0, /* tp_members */
2143 0, /* tp_getset */
2144 0, /* tp_base */
2145 0, /* tp_dict */
2146 0, /* tp_descr_get */
2147 0, /* tp_descr_set */
2148 0, /* tp_dictoffset */
2149 (initproc)set_init, /* tp_init */
2150 PyType_GenericAlloc, /* tp_alloc */
2151 set_new, /* tp_new */
2152 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002153};
2154
2155/* frozenset object ********************************************************/
2156
2157
2158static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2160 contains_doc},
2161 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2162 copy_doc},
2163 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2164 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002165 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002166 intersection_doc},
2167 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2168 isdisjoint_doc},
2169 {"issubset", (PyCFunction)set_issubset, METH_O,
2170 issubset_doc},
2171 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2172 issuperset_doc},
2173 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2174 reduce_doc},
2175 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2176 sizeof_doc},
2177 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2178 symmetric_difference_doc},
2179 {"union", (PyCFunction)set_union, METH_VARARGS,
2180 union_doc},
2181 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002182};
2183
2184static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002185 0, /*nb_add*/
2186 (binaryfunc)set_sub, /*nb_subtract*/
2187 0, /*nb_multiply*/
2188 0, /*nb_remainder*/
2189 0, /*nb_divmod*/
2190 0, /*nb_power*/
2191 0, /*nb_negative*/
2192 0, /*nb_positive*/
2193 0, /*nb_absolute*/
2194 0, /*nb_bool*/
2195 0, /*nb_invert*/
2196 0, /*nb_lshift*/
2197 0, /*nb_rshift*/
2198 (binaryfunc)set_and, /*nb_and*/
2199 (binaryfunc)set_xor, /*nb_xor*/
2200 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002201};
2202
2203PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002204"frozenset() -> empty frozenset object\n\
2205frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002206\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002207Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002208
2209PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002210 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2211 "frozenset", /* tp_name */
2212 sizeof(PySetObject), /* tp_basicsize */
2213 0, /* tp_itemsize */
2214 /* methods */
2215 (destructor)set_dealloc, /* tp_dealloc */
2216 0, /* tp_print */
2217 0, /* tp_getattr */
2218 0, /* tp_setattr */
2219 0, /* tp_reserved */
2220 (reprfunc)set_repr, /* tp_repr */
2221 &frozenset_as_number, /* tp_as_number */
2222 &set_as_sequence, /* tp_as_sequence */
2223 0, /* tp_as_mapping */
2224 frozenset_hash, /* tp_hash */
2225 0, /* tp_call */
2226 0, /* tp_str */
2227 PyObject_GenericGetAttr, /* tp_getattro */
2228 0, /* tp_setattro */
2229 0, /* tp_as_buffer */
2230 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2231 Py_TPFLAGS_BASETYPE, /* tp_flags */
2232 frozenset_doc, /* tp_doc */
2233 (traverseproc)set_traverse, /* tp_traverse */
2234 (inquiry)set_clear_internal, /* tp_clear */
2235 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002236 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002237 (getiterfunc)set_iter, /* tp_iter */
2238 0, /* tp_iternext */
2239 frozenset_methods, /* tp_methods */
2240 0, /* tp_members */
2241 0, /* tp_getset */
2242 0, /* tp_base */
2243 0, /* tp_dict */
2244 0, /* tp_descr_get */
2245 0, /* tp_descr_set */
2246 0, /* tp_dictoffset */
2247 0, /* tp_init */
2248 PyType_GenericAlloc, /* tp_alloc */
2249 frozenset_new, /* tp_new */
2250 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002251};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002252
2253
2254/***** C API functions *************************************************/
2255
2256PyObject *
2257PySet_New(PyObject *iterable)
2258{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002259 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002260}
2261
2262PyObject *
2263PyFrozenSet_New(PyObject *iterable)
2264{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002265 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002266}
2267
Neal Norwitz8c49c822006-03-04 18:41:19 +00002268Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002269PySet_Size(PyObject *anyset)
2270{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002271 if (!PyAnySet_Check(anyset)) {
2272 PyErr_BadInternalCall();
2273 return -1;
2274 }
2275 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002276}
2277
2278int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002279PySet_Clear(PyObject *set)
2280{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002281 if (!PySet_Check(set)) {
2282 PyErr_BadInternalCall();
2283 return -1;
2284 }
2285 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002286}
2287
2288int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002289PySet_Contains(PyObject *anyset, PyObject *key)
2290{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002291 if (!PyAnySet_Check(anyset)) {
2292 PyErr_BadInternalCall();
2293 return -1;
2294 }
2295 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002296}
2297
2298int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002299PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002300{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002301 if (!PySet_Check(set)) {
2302 PyErr_BadInternalCall();
2303 return -1;
2304 }
2305 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002306}
2307
2308int
Christian Heimesfd66e512008-01-29 12:18:50 +00002309PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002310{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002311 if (!PySet_Check(anyset) &&
2312 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2313 PyErr_BadInternalCall();
2314 return -1;
2315 }
2316 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002317}
2318
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002319int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002320_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002321{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002322 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002324 if (!PyAnySet_Check(set)) {
2325 PyErr_BadInternalCall();
2326 return -1;
2327 }
2328 if (set_next((PySetObject *)set, pos, &entry) == 0)
2329 return 0;
2330 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002331 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002332 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002333}
2334
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002335PyObject *
2336PySet_Pop(PyObject *set)
2337{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002338 if (!PySet_Check(set)) {
2339 PyErr_BadInternalCall();
2340 return NULL;
2341 }
2342 return set_pop((PySetObject *)set);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002343}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002344
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002345int
2346_PySet_Update(PyObject *set, PyObject *iterable)
2347{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002348 if (!PySet_Check(set)) {
2349 PyErr_BadInternalCall();
2350 return -1;
2351 }
2352 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002353}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002354
Raymond Hettingere259f132013-12-15 11:56:14 -08002355/* Exported for the gdb plugin's benefit. */
2356PyObject *_PySet_Dummy = dummy;
2357
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002358#ifdef Py_DEBUG
2359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002360/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002361 Returns True and original set is restored. */
2362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002363#define assertRaises(call_return_value, exception) \
2364 do { \
2365 assert(call_return_value); \
2366 assert(PyErr_ExceptionMatches(exception)); \
2367 PyErr_Clear(); \
2368 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002369
2370static PyObject *
2371test_c_api(PySetObject *so)
2372{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002373 Py_ssize_t count;
2374 char *s;
2375 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002376 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002377 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002378 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002379 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002381 /* Verify preconditions */
2382 assert(PyAnySet_Check(ob));
2383 assert(PyAnySet_CheckExact(ob));
2384 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002386 /* so.clear(); so |= set("abc"); */
2387 str = PyUnicode_FromString("abc");
2388 if (str == NULL)
2389 return NULL;
2390 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002391 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002392 Py_DECREF(str);
2393 return NULL;
2394 }
2395 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002397 /* Exercise type/size checks */
2398 assert(PySet_Size(ob) == 3);
2399 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002400
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002401 /* Raise TypeError for non-iterable constructor arguments */
2402 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2403 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405 /* Raise TypeError for unhashable key */
2406 dup = PySet_New(ob);
2407 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2408 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2409 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002411 /* Exercise successful pop, contains, add, and discard */
2412 elem = PySet_Pop(ob);
2413 assert(PySet_Contains(ob, elem) == 0);
2414 assert(PySet_GET_SIZE(ob) == 2);
2415 assert(PySet_Add(ob, elem) == 0);
2416 assert(PySet_Contains(ob, elem) == 1);
2417 assert(PySet_GET_SIZE(ob) == 3);
2418 assert(PySet_Discard(ob, elem) == 1);
2419 assert(PySet_GET_SIZE(ob) == 2);
2420 assert(PySet_Discard(ob, elem) == 0);
2421 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002423 /* Exercise clear */
2424 dup2 = PySet_New(dup);
2425 assert(PySet_Clear(dup2) == 0);
2426 assert(PySet_Size(dup2) == 0);
2427 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002429 /* Raise SystemError on clear or update of frozen set */
2430 f = PyFrozenSet_New(dup);
2431 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2432 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2433 assert(PySet_Add(f, elem) == 0);
2434 Py_INCREF(f);
2435 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2436 Py_DECREF(f);
2437 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002439 /* Exercise direct iteration */
2440 i = 0, count = 0;
2441 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
2442 s = _PyUnicode_AsString(x);
2443 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2444 count++;
2445 }
2446 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002448 /* Exercise updates */
2449 dup2 = PySet_New(NULL);
2450 assert(_PySet_Update(dup2, dup) == 0);
2451 assert(PySet_Size(dup2) == 3);
2452 assert(_PySet_Update(dup2, dup) == 0);
2453 assert(PySet_Size(dup2) == 3);
2454 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002455
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002456 /* Raise SystemError when self argument is not a set or frozenset. */
2457 t = PyTuple_New(0);
2458 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2459 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2460 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002462 /* Raise SystemError when self argument is not a set. */
2463 f = PyFrozenSet_New(dup);
2464 assert(PySet_Size(f) == 3);
2465 assert(PyFrozenSet_CheckExact(f));
2466 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2467 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2468 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002470 /* Raise KeyError when popping from an empty set */
2471 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2472 Py_DECREF(ob);
2473 assert(PySet_GET_SIZE(ob) == 0);
2474 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002476 /* Restore the set from the copy using the PyNumber API */
2477 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2478 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002480 /* Verify constructors accept NULL arguments */
2481 f = PySet_New(NULL);
2482 assert(f != NULL);
2483 assert(PySet_GET_SIZE(f) == 0);
2484 Py_DECREF(f);
2485 f = PyFrozenSet_New(NULL);
2486 assert(f != NULL);
2487 assert(PyFrozenSet_CheckExact(f));
2488 assert(PySet_GET_SIZE(f) == 0);
2489 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002491 Py_DECREF(elem);
2492 Py_DECREF(dup);
2493 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002494}
2495
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002496#undef assertRaises
2497
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002498#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002499
2500/***** Dummy Struct *************************************************/
2501
2502static PyObject *
2503dummy_repr(PyObject *op)
2504{
2505 return PyUnicode_FromString("<dummy key>");
2506}
2507
2508static void
2509dummy_dealloc(PyObject* ignore)
2510{
2511 Py_FatalError("deallocating <dummy key>");
2512}
2513
2514static PyTypeObject _PySetDummy_Type = {
2515 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2516 "<dummy key> type",
2517 0,
2518 0,
2519 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2520 0, /*tp_print*/
2521 0, /*tp_getattr*/
2522 0, /*tp_setattr*/
2523 0, /*tp_reserved*/
2524 dummy_repr, /*tp_repr*/
2525 0, /*tp_as_number*/
2526 0, /*tp_as_sequence*/
2527 0, /*tp_as_mapping*/
2528 0, /*tp_hash */
2529 0, /*tp_call */
2530 0, /*tp_str */
2531 0, /*tp_getattro */
2532 0, /*tp_setattro */
2533 0, /*tp_as_buffer */
2534 Py_TPFLAGS_DEFAULT, /*tp_flags */
2535};
2536
2537static PyObject _dummy_struct = {
2538 _PyObject_EXTRA_INIT
2539 2, &_PySetDummy_Type
2540};
2541