blob: 79e84511926e15bbf853adfec00ed3a6a4a40a56 [file] [log] [blame]
Raymond Hettingerc991db22005-08-11 07:58:45 +00001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002/* set object implementation
Raymond Hettingerae7b00e2013-09-07 15:05:00 -07003
Raymond Hettingera9d99362005-08-05 00:01:15 +00004 Written and maintained by Raymond D. Hettinger <python@rcn.com>
5 Derived from Lib/sets.py and Objects/dictobject.c.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00006
Raymond Hettingerae7b00e2013-09-07 15:05:00 -07007 The basic lookup function used by all operations.
8 This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
9
10 The initial probe index is computed as hash mod the table size.
11 Subsequent probe indices are computed as explained in Objects/dictobject.c.
12
13 To improve cache locality, each probe inspects a series of consecutive
14 nearby entries before moving on to probes elsewhere in memory. This leaves
Raymond Hettinger64263df2017-09-04 18:54:16 -070015 us with a hybrid of linear probing and randomized probing. The linear probing
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070016 reduces the cost of hash collisions because consecutive memory accesses
17 tend to be much cheaper than scattered probes. After LINEAR_PROBES steps,
Raymond Hettinger64263df2017-09-04 18:54:16 -070018 we then use more of the upper bits from the hash value and apply a simple
19 linear congruential random number genearator. This helps break-up long
20 chains of collisions.
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070021
22 All arithmetic on hash should ignore overflow.
23
Raymond Hettinger4d45c102015-01-25 16:27:40 -080024 Unlike the dictionary implementation, the lookkey function can return
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070025 NULL if the rich comparison returns an error.
Serhiy Storchaka13ad3b72017-09-14 09:38:36 +030026
Raymond Hettinger64263df2017-09-04 18:54:16 -070027 Use cases for sets differ considerably from dictionaries where looked-up
28 keys are more likely to be present. In contrast, sets are primarily
29 about membership testing where the presence of an element is not known in
30 advance. Accordingly, the set implementation needs to optimize for both
31 the found and not-found case.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000032*/
33
Raymond Hettingera690a992003-11-16 16:17:49 +000034#include "Python.h"
Victor Stinner4a21e572020-04-15 02:35:41 +020035#include "pycore_object.h" // _PyObject_GC_UNTRACK()
36#include <stddef.h> // offsetof()
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000037
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000038/* Object used as dummy key to fill deleted entries */
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -050039static PyObject _dummy_struct;
40
41#define dummy (&_dummy_struct)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000042
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000043
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -070044/* ======================================================================== */
45/* ======= Begin logic for probing the hash table ========================= */
46
Raymond Hettinger710a67e2013-09-21 20:17:31 -070047/* Set this to zero to turn-off linear probing */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070048#ifndef LINEAR_PROBES
Raymond Hettinger742d8712013-09-08 00:25:57 -070049#define LINEAR_PROBES 9
Raymond Hettinger8408dc52013-09-15 14:57:15 -070050#endif
Raymond Hettinger742d8712013-09-08 00:25:57 -070051
52/* This must be >= 1 */
53#define PERTURB_SHIFT 5
54
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000055static setentry *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020056set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000057{
Raymond Hettinger70559b52015-07-23 07:42:23 -040058 setentry *table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020059 setentry *entry;
Raymond Hettinger2cc9b842020-05-10 14:53:29 -070060 size_t perturb = hash;
Raymond Hettingerafe89092013-08-28 20:59:31 -070061 size_t mask = so->mask;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -080062 size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */
Raymond Hettinger2cc9b842020-05-10 14:53:29 -070063 int probes;
Raymond Hettinger4ef05282013-09-21 15:39:49 -070064 int cmp;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000065
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -070066 while (1) {
Raymond Hettinger2cc9b842020-05-10 14:53:29 -070067 entry = &so->table[i];
68 probes = (i + LINEAR_PROBES <= mask) ? LINEAR_PROBES: 0;
69 do {
70 if (entry->hash == 0 && entry->key == NULL)
Raymond Hettinger08e3dc02014-12-26 20:14:00 -080071 return entry;
Raymond Hettinger2cc9b842020-05-10 14:53:29 -070072 if (entry->hash == hash) {
73 PyObject *startkey = entry->key;
74 assert(startkey != dummy);
75 if (startkey == key)
Raymond Hettinger8651a502015-05-27 10:37:20 -070076 return entry;
Raymond Hettinger2cc9b842020-05-10 14:53:29 -070077 if (PyUnicode_CheckExact(startkey)
78 && PyUnicode_CheckExact(key)
79 && _PyUnicode_EQ(startkey, key))
80 return entry;
81 table = so->table;
82 Py_INCREF(startkey);
83 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
84 Py_DECREF(startkey);
85 if (cmp < 0)
86 return NULL;
87 if (table != so->table || entry->key != startkey)
88 return set_lookkey(so, key, hash);
89 if (cmp > 0)
90 return entry;
91 mask = so->mask;
Raymond Hettinger8651a502015-05-27 10:37:20 -070092 }
Raymond Hettinger2cc9b842020-05-10 14:53:29 -070093 entry++;
94 } while (probes--);
Raymond Hettinger8651a502015-05-27 10:37:20 -070095 perturb >>= PERTURB_SHIFT;
96 i = (i * 5 + 1 + perturb) & mask;
Raymond Hettinger8651a502015-05-27 10:37:20 -070097 }
98}
99
Raymond Hettinger15f08692015-07-03 17:21:17 -0700100static int set_table_resize(PySetObject *, Py_ssize_t);
101
Raymond Hettinger8651a502015-05-27 10:37:20 -0700102static int
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400103set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700104{
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400105 setentry *table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700106 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700107 size_t perturb;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400108 size_t mask;
109 size_t i; /* Unsigned for defined overflow behavior */
Raymond Hettinger2cc9b842020-05-10 14:53:29 -0700110 int probes;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700111 int cmp;
112
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400113 /* Pre-increment is necessary to prevent arbitrary code in the rich
114 comparison from deallocating the key just before the insertion. */
115 Py_INCREF(key);
116
117 restart:
118
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400119 mask = so->mask;
120 i = (size_t)hash & mask;
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700121 perturb = hash;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700122
123 while (1) {
Raymond Hettinger2cc9b842020-05-10 14:53:29 -0700124 entry = &so->table[i];
125 probes = (i + LINEAR_PROBES <= mask) ? LINEAR_PROBES: 0;
126 do {
127 if (entry->hash == 0 && entry->key == NULL)
128 goto found_unused;
129 if (entry->hash == hash) {
130 PyObject *startkey = entry->key;
131 assert(startkey != dummy);
132 if (startkey == key)
133 goto found_active;
134 if (PyUnicode_CheckExact(startkey)
135 && PyUnicode_CheckExact(key)
136 && _PyUnicode_EQ(startkey, key))
137 goto found_active;
138 table = so->table;
139 Py_INCREF(startkey);
140 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
141 Py_DECREF(startkey);
142 if (cmp > 0)
143 goto found_active;
144 if (cmp < 0)
145 goto comparison_error;
146 if (table != so->table || entry->key != startkey)
147 goto restart;
148 mask = so->mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700149 }
Raymond Hettinger2cc9b842020-05-10 14:53:29 -0700150 entry++;
151 } while (probes--);
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700152 perturb >>= PERTURB_SHIFT;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -0800153 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700155
Raymond Hettinger15f08692015-07-03 17:21:17 -0700156 found_unused:
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700157 so->fill++;
158 so->used++;
159 entry->key = key;
160 entry->hash = hash;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800161 if ((size_t)so->fill*5 < mask*3)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700162 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +0900163 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700164
165 found_active:
Raymond Hettinger482c05c2015-07-20 01:23:32 -0400166 Py_DECREF(key);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700167 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000168
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400169 comparison_error:
Raymond Hettinger061091a2015-07-15 23:54:02 -0700170 Py_DECREF(key);
171 return -1;
172}
173
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000174/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000175Internal routine used by set_table_resize() to insert an item which is
Raymond Hettingerd699d5e2020-05-03 11:25:46 -0700176known to be absent from the set. Besides the performance benefit,
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800177there is also safety benefit since using set_add_entry() risks making
178a callback in the middle of a set_table_resize(), see issue 1456209.
179The caller is responsible for updating the key's reference count and
180the setobject's fill and used fields.
Thomas Wouters89f507f2006-12-13 04:49:30 +0000181*/
182static void
Raymond Hettinger5088f602015-12-13 18:45:01 -0800183set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000184{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200185 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700186 size_t perturb = hash;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800187 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700188 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000189
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700190 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800191 entry = &table[i];
192 if (entry->key == NULL)
193 goto found_null;
194 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800195 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800196 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800197 if (entry->key == NULL)
198 goto found_null;
199 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700200 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700201 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800202 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000203 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700204 found_null:
Raymond Hettinger5088f602015-12-13 18:45:01 -0800205 entry->key = key;
Raymond Hettinger86d322f2015-12-13 19:27:17 -0800206 entry->hash = hash;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000207}
208
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700209/* ======== End logic for probing the hash table ========================== */
210/* ======================================================================== */
211
Thomas Wouters89f507f2006-12-13 04:49:30 +0000212/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000213Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000214keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000215actually be smaller than the old one.
216*/
217static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000218set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000219{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000220 setentry *oldtable, *newtable, *entry;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800221 Py_ssize_t oldmask = so->mask;
222 size_t newmask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000223 int is_oldtable_malloced;
224 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 assert(minused >= 0);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000228 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100229 /* XXX speed-up with intrinsics */
Sergey Fedoseev6c7d67c2018-09-12 04:18:01 +0500230 size_t newsize = PySet_MINSIZE;
231 while (newsize <= (size_t)minused) {
232 newsize <<= 1; // The largest possible value is PY_SSIZE_T_MAX + 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000233 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000235 /* Get space for a new table. */
236 oldtable = so->table;
237 assert(oldtable != NULL);
238 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000240 if (newsize == PySet_MINSIZE) {
241 /* A large table is shrinking, or we can't get any smaller. */
242 newtable = so->smalltable;
243 if (newtable == oldtable) {
244 if (so->fill == so->used) {
245 /* No dummies, so no point doing anything. */
246 return 0;
247 }
248 /* We're not going to resize it, but rebuild the
249 table anyway to purge old dummy entries.
250 Subtle: This is *necessary* if fill==size,
251 as set_lookkey needs at least one virgin slot to
252 terminate failing searches. If fill < size, it's
253 merely desirable, as dummies slow searches. */
254 assert(so->fill > so->used);
255 memcpy(small_copy, oldtable, sizeof(small_copy));
256 oldtable = small_copy;
257 }
258 }
259 else {
260 newtable = PyMem_NEW(setentry, newsize);
261 if (newtable == NULL) {
262 PyErr_NoMemory();
263 return -1;
264 }
265 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 /* Make the set empty, using the new table. */
268 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 memset(newtable, 0, sizeof(setentry) * newsize);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800270 so->mask = newsize - 1;
271 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000273 /* Copy the data over; this is refcount-neutral for active entries;
274 dummy entries aren't copied over, of course */
Raymond Hettinger5088f602015-12-13 18:45:01 -0800275 newmask = (size_t)so->mask;
Raymond Hettingere1af6962017-02-02 08:24:48 -0800276 if (so->fill == so->used) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800277 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800278 if (entry->key != NULL) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800279 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800280 }
281 }
282 } else {
Raymond Hettingere1af6962017-02-02 08:24:48 -0800283 so->fill = so->used;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800284 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800285 if (entry->key != NULL && entry->key != dummy) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800286 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800287 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 }
289 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 if (is_oldtable_malloced)
Victor Stinner00d7abd2020-12-01 09:56:42 +0100292 PyMem_Free(oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000293 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000294}
295
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000296static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700297set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000298{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700299 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000300
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700301 entry = set_lookkey(so, key, hash);
302 if (entry != NULL)
303 return entry->key != NULL;
304 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000305}
306
307#define DISCARD_NOTFOUND 0
308#define DISCARD_FOUND 1
309
310static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700311set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800312{
313 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000314 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000315
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700316 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 if (entry == NULL)
318 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700319 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 return DISCARD_NOTFOUND;
321 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800323 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000324 so->used--;
325 Py_DECREF(old_key);
326 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000327}
328
329static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700330set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000331{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200332 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000333
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700334 if (!PyUnicode_CheckExact(key) ||
335 (hash = ((PyASCIIObject *) key)->hash) == -1) {
336 hash = PyObject_Hash(key);
337 if (hash == -1)
338 return -1;
339 }
340 return set_add_entry(so, key, hash);
341}
342
343static int
344set_contains_key(PySetObject *so, PyObject *key)
345{
346 Py_hash_t hash;
347
348 if (!PyUnicode_CheckExact(key) ||
349 (hash = ((PyASCIIObject *) key)->hash) == -1) {
350 hash = PyObject_Hash(key);
351 if (hash == -1)
352 return -1;
353 }
354 return set_contains_entry(so, key, hash);
355}
356
357static int
358set_discard_key(PySetObject *so, PyObject *key)
359{
360 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200363 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 hash = PyObject_Hash(key);
365 if (hash == -1)
366 return -1;
367 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700368 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000369}
370
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700371static void
372set_empty_to_minsize(PySetObject *so)
373{
374 memset(so->smalltable, 0, sizeof(so->smalltable));
375 so->fill = 0;
376 so->used = 0;
377 so->mask = PySet_MINSIZE - 1;
378 so->table = so->smalltable;
379 so->hash = -1;
380}
381
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000382static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000383set_clear_internal(PySetObject *so)
384{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800385 setentry *entry;
386 setentry *table = so->table;
387 Py_ssize_t fill = so->fill;
388 Py_ssize_t used = so->used;
389 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000390 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000391
Raymond Hettinger583cd032013-09-07 22:06:35 -0700392 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000393 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000395 /* This is delicate. During the process of clearing the set,
396 * decrefs can cause the set to mutate. To avoid fatal confusion
397 * (voice of experience), we have to make the set empty before
398 * clearing the slots, and never refer to anything via so->ref while
399 * clearing.
400 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000401 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700402 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 else if (fill > 0) {
405 /* It's a small table with something that needs to be cleared.
406 * Afraid the only safe way is to copy the set entries into
407 * another small table first.
408 */
409 memcpy(small_copy, table, sizeof(small_copy));
410 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700411 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 }
413 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000415 /* Now we can finally clear things. If C had refcounts, we could
416 * assert that the refcount on table is 1 now, i.e. that this function
417 * has unique access to it, so decref side-effects can't alter it.
418 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800419 for (entry = table; used > 0; entry++) {
420 if (entry->key && entry->key != dummy) {
421 used--;
422 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 if (table_is_malloced)
Victor Stinner00d7abd2020-12-01 09:56:42 +0100427 PyMem_Free(table);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000428 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000429}
430
431/*
432 * Iterate over a set table. Use like so:
433 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000434 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000435 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000436 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000437 * while (set_next(yourset, &pos, &entry)) {
438 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000439 * }
440 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000441 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000443 */
444static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000445set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000446{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 Py_ssize_t i;
448 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700449 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000450
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 assert (PyAnySet_Check(so));
452 i = *pos_ptr;
453 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700455 entry = &so->table[i];
456 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000457 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700458 entry++;
459 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460 *pos_ptr = i+1;
461 if (i > mask)
462 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700463 assert(entry != NULL);
464 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000465 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000466}
467
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000468static void
469set_dealloc(PySetObject *so)
470{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200471 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800472 Py_ssize_t used = so->used;
473
INADA Naokia6296d32017-08-24 14:55:17 +0900474 /* bpo-31095: UnTrack is needed before calling any callbacks */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 PyObject_GC_UnTrack(so);
Jeroen Demeyer351c6742019-05-10 19:21:11 +0200476 Py_TRASHCAN_BEGIN(so, set_dealloc)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 if (so->weakreflist != NULL)
478 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000479
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800480 for (entry = so->table; used > 0; entry++) {
481 if (entry->key && entry->key != dummy) {
482 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700483 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 }
485 }
486 if (so->table != so->smalltable)
Victor Stinner00d7abd2020-12-01 09:56:42 +0100487 PyMem_Free(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700488 Py_TYPE(so)->tp_free(so);
Jeroen Demeyer351c6742019-05-10 19:21:11 +0200489 Py_TRASHCAN_END
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000490}
491
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000492static PyObject *
493set_repr(PySetObject *so)
494{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200495 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 if (status != 0) {
499 if (status < 0)
500 return NULL;
501 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
502 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 /* shortcut for the empty set */
505 if (!so->used) {
506 Py_ReprLeave((PyObject*)so);
507 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
508 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 keys = PySequence_List((PyObject *)so);
511 if (keys == NULL)
512 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000513
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200514 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 listrepr = PyObject_Repr(keys);
516 Py_DECREF(keys);
517 if (listrepr == NULL)
518 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200519 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200521 if (tmp == NULL)
522 goto done;
523 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200524
Andy Lester55728702020-03-06 16:53:17 -0600525 if (!Py_IS_TYPE(so, &PySet_Type))
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200526 result = PyUnicode_FromFormat("%s({%U})",
527 Py_TYPE(so)->tp_name,
528 listrepr);
529 else
530 result = PyUnicode_FromFormat("{%U}", listrepr);
531 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000532done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 Py_ReprLeave((PyObject*)so);
534 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000535}
536
Martin v. Löwis18e16552006-02-15 17:27:45 +0000537static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000538set_len(PyObject *so)
539{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000541}
542
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000543static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000544set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000545{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000546 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000547 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200548 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700549 setentry *so_entry;
550 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 assert (PyAnySet_Check(so));
553 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000555 other = (PySetObject*)otherset;
556 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700557 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000558 return 0;
559 /* Do one big resize at the start, rather than
560 * incrementally resizing as we insert new keys. Expect
561 * that there will be no (or few) overlapping keys.
562 */
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800563 if ((so->fill + other->used)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900564 if (set_table_resize(so, (so->used + other->used)*2) != 0)
565 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700567 so_entry = so->table;
568 other_entry = other->table;
569
570 /* If our table is empty, and both tables have the same size, and
571 there are no dummies to eliminate, then just copy the pointers. */
572 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
573 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
574 key = other_entry->key;
575 if (key != NULL) {
576 assert(so_entry->key == NULL);
577 Py_INCREF(key);
578 so_entry->key = key;
579 so_entry->hash = other_entry->hash;
580 }
581 }
582 so->fill = other->fill;
583 so->used = other->used;
584 return 0;
585 }
586
587 /* If our table is empty, we can use set_insert_clean() */
588 if (so->fill == 0) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800589 setentry *newtable = so->table;
590 size_t newmask = (size_t)so->mask;
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800591 so->fill = other->used;
592 so->used = other->used;
Raymond Hettingere4495872015-12-15 00:42:30 -0800593 for (i = other->mask + 1; i > 0 ; i--, other_entry++) {
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700594 key = other_entry->key;
595 if (key != NULL && key != dummy) {
596 Py_INCREF(key);
Raymond Hettinger5088f602015-12-13 18:45:01 -0800597 set_insert_clean(newtable, newmask, key, other_entry->hash);
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700598 }
599 }
600 return 0;
601 }
602
603 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700604 for (i = 0; i <= other->mask; i++) {
605 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700606 key = other_entry->key;
607 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700608 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 }
611 }
612 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000613}
614
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000615static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530616set_pop(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000617{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800618 /* Make sure the search finger is in bounds */
Raymond Hettingerf9ec1b92018-11-11 14:35:47 -0800619 setentry *entry = so->table + (so->finger & so->mask);
620 setentry *limit = so->table + so->mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000621 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 if (so->used == 0) {
624 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
625 return NULL;
626 }
Raymond Hettingercf5863f2018-11-09 02:31:56 -0800627 while (entry->key == NULL || entry->key==dummy) {
628 entry++;
629 if (entry > limit)
630 entry = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 }
632 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800634 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 so->used--;
Raymond Hettingercf5863f2018-11-09 02:31:56 -0800636 so->finger = entry - so->table + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000638}
639
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000640PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
641Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000642
643static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000644set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000645{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000646 Py_ssize_t pos = 0;
647 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000648
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000649 while (set_next(so, &pos, &entry))
650 Py_VISIT(entry->key);
651 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000652}
653
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700654/* Work to increase the bit dispersion for closely spaced hash values.
655 This is important because some use cases have many combinations of a
656 small number of elements with nearby hashes so that many distinct
657 combinations collapse to only a handful of distinct hash values. */
658
659static Py_uhash_t
660_shuffle_bits(Py_uhash_t h)
661{
662 return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
663}
664
665/* Most of the constants in this hash algorithm are randomly chosen
666 large primes with "interesting bit patterns" and that passed tests
667 for good collision statistics on a variety of problematic datasets
668 including powersets and graph structures (such as David Eppstein's
669 graph recipes in Lib/test/test_set.py) */
670
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000671static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000672frozenset_hash(PyObject *self)
673{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 PySetObject *so = (PySetObject *)self;
Raymond Hettinger41481952015-08-07 00:43:39 -0700675 Py_uhash_t hash = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000677
Raymond Hettingerb501a272015-08-06 22:15:22 -0700678 if (so->hash != -1)
679 return so->hash;
680
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700681 /* Xor-in shuffled bits from every entry's hash field because xor is
682 commutative and a frozenset hash should be independent of order.
683
684 For speed, include null entries and dummy entries and then
685 subtract out their effect afterwards so that the final hash
686 depends only on active entries. This allows the code to be
687 vectorized by the compiler and it saves the unpredictable
688 branches that would arise when trying to exclude null and dummy
689 entries on every iteration. */
690
691 for (entry = so->table; entry <= &so->table[so->mask]; entry++)
692 hash ^= _shuffle_bits(entry->hash);
693
Raymond Hettingera286a512015-08-01 11:07:11 -0700694 /* Remove the effect of an odd number of NULL entries */
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700695 if ((so->mask + 1 - so->fill) & 1)
696 hash ^= _shuffle_bits(0);
697
698 /* Remove the effect of an odd number of dummy entries */
699 if ((so->fill - so->used) & 1)
700 hash ^= _shuffle_bits(-1);
701
Raymond Hettinger41481952015-08-07 00:43:39 -0700702 /* Factor in the number of active entries */
703 hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;
704
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700705 /* Disperse patterns arising in nested frozensets */
Raymond Hettingerfa788062018-01-18 13:23:27 -0800706 hash ^= (hash >> 11) ^ (hash >> 25);
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800707 hash = hash * 69069U + 907133923UL;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700708
Raymond Hettinger36c05002015-08-01 10:57:42 -0700709 /* -1 is reserved as an error code */
Victor Stinner12174a52014-08-15 23:17:38 +0200710 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800711 hash = 590923713UL;
Raymond Hettinger36c05002015-08-01 10:57:42 -0700712
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000713 so->hash = hash;
714 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000715}
716
Raymond Hettingera9d99362005-08-05 00:01:15 +0000717/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000718
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000719typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 PyObject_HEAD
721 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
722 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700723 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000725} setiterobject;
726
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000727static void
728setiter_dealloc(setiterobject *si)
729{
INADA Naokia6296d32017-08-24 14:55:17 +0900730 /* bpo-31095: UnTrack is needed before calling any callbacks */
731 _PyObject_GC_UNTRACK(si);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000732 Py_XDECREF(si->si_set);
733 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000734}
735
736static int
737setiter_traverse(setiterobject *si, visitproc visit, void *arg)
738{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739 Py_VISIT(si->si_set);
740 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000741}
742
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000743static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530744setiter_len(setiterobject *si, PyObject *Py_UNUSED(ignored))
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000745{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 Py_ssize_t len = 0;
747 if (si->si_set != NULL && si->si_used == si->si_set->used)
748 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000749 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000750}
751
Armin Rigof5b3e362006-02-11 21:32:43 +0000752PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000753
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000754static PyObject *setiter_iternext(setiterobject *si);
755
756static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530757setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000758{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200759 _Py_IDENTIFIER(iter);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300760 /* copy the iterator state */
Sergey Fedoseev63958442018-10-20 05:43:33 +0500761 setiterobject tmp = *si;
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000762 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300763
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000764 /* iterate the temporary into a list */
Sergey Fedoseev63958442018-10-20 05:43:33 +0500765 PyObject *list = PySequence_List((PyObject*)&tmp);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000766 Py_XDECREF(tmp.si_set);
Sergey Fedoseev63958442018-10-20 05:43:33 +0500767 if (list == NULL) {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000768 return NULL;
769 }
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200770 return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000771}
772
773PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
774
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000775static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000776 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000777 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000778 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000779};
780
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000781static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000782{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700783 PyObject *key;
784 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200785 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000786 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000788 if (so == NULL)
789 return NULL;
790 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000791
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000792 if (si->si_used != so->used) {
793 PyErr_SetString(PyExc_RuntimeError,
794 "Set changed size during iteration");
795 si->si_used = -1; /* Make this state sticky */
796 return NULL;
797 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700798
799 i = si->si_pos;
800 assert(i>=0);
801 entry = so->table;
802 mask = so->mask;
803 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
804 i++;
805 si->si_pos = i+1;
806 if (i > mask)
807 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000808 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700809 key = entry[i].key;
810 Py_INCREF(key);
811 return key;
812
813fail:
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700814 si->si_set = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +0300815 Py_DECREF(so);
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700816 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000817}
818
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000819PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000820 PyVarObject_HEAD_INIT(&PyType_Type, 0)
821 "set_iterator", /* tp_name */
822 sizeof(setiterobject), /* tp_basicsize */
823 0, /* tp_itemsize */
824 /* methods */
825 (destructor)setiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200826 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000827 0, /* tp_getattr */
828 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200829 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000830 0, /* tp_repr */
831 0, /* tp_as_number */
832 0, /* tp_as_sequence */
833 0, /* tp_as_mapping */
834 0, /* tp_hash */
835 0, /* tp_call */
836 0, /* tp_str */
837 PyObject_GenericGetAttr, /* tp_getattro */
838 0, /* tp_setattro */
839 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700840 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 0, /* tp_doc */
842 (traverseproc)setiter_traverse, /* tp_traverse */
843 0, /* tp_clear */
844 0, /* tp_richcompare */
845 0, /* tp_weaklistoffset */
846 PyObject_SelfIter, /* tp_iter */
847 (iternextfunc)setiter_iternext, /* tp_iternext */
848 setiter_methods, /* tp_methods */
849 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000850};
851
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000852static PyObject *
853set_iter(PySetObject *so)
854{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000855 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
856 if (si == NULL)
857 return NULL;
858 Py_INCREF(so);
859 si->si_set = so;
860 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700861 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000862 si->len = so->used;
863 _PyObject_GC_TRACK(si);
864 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000865}
866
Raymond Hettingerd7946662005-08-01 21:39:29 +0000867static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000868set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000869{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000870 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000872 if (PyAnySet_Check(other))
873 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000875 if (PyDict_CheckExact(other)) {
876 PyObject *value;
877 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000878 Py_hash_t hash;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200879 Py_ssize_t dictsize = PyDict_GET_SIZE(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000881 /* Do one big resize at the start, rather than
882 * incrementally resizing as we insert new keys. Expect
883 * that there will be no (or few) overlapping keys.
884 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700885 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 return -1;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800887 if ((so->fill + dictsize)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900888 if (set_table_resize(so, (so->used + dictsize)*2) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 return -1;
890 }
891 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700892 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000893 return -1;
894 }
895 return 0;
896 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000897
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000898 it = PyObject_GetIter(other);
899 if (it == NULL)
900 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +0000901
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000902 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700903 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000904 Py_DECREF(it);
905 Py_DECREF(key);
906 return -1;
907 }
908 Py_DECREF(key);
909 }
910 Py_DECREF(it);
911 if (PyErr_Occurred())
912 return -1;
913 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000914}
915
916static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000917set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +0000918{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000919 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000920
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000921 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
922 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700923 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000924 return NULL;
925 }
926 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +0000927}
928
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000929PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000930"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +0000931
Raymond Hettinger426d9952014-05-18 21:40:20 +0100932/* XXX Todo:
933 If aligned memory allocations become available, make the
934 set object 64 byte aligned so that most of the fields
935 can be retrieved or updated in a single cache line.
936*/
937
Raymond Hettingera38123e2003-11-24 22:18:49 +0000938static PyObject *
939make_new_set(PyTypeObject *type, PyObject *iterable)
940{
Dong-hee Na1c605672020-03-19 02:30:50 +0900941 assert(PyType_Check(type));
Raymond Hettinger8421d712016-04-29 01:37:05 -0700942 PySetObject *so;
Raymond Hettingera38123e2003-11-24 22:18:49 +0000943
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700944 so = (PySetObject *)type->tp_alloc(type, 0);
945 if (so == NULL)
946 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000947
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700948 so->fill = 0;
949 so->used = 0;
950 so->mask = PySet_MINSIZE - 1;
951 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700952 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -0800953 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +0000955
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000956 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700957 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000958 Py_DECREF(so);
959 return NULL;
960 }
961 }
Raymond Hettingera38123e2003-11-24 22:18:49 +0000962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +0000964}
965
Raymond Hettinger7d99f092008-11-16 11:44:54 +0000966static PyObject *
967make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
968{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
970 if (PyType_IsSubtype(type, &PySet_Type))
971 type = &PySet_Type;
972 else
973 type = &PyFrozenSet_Type;
974 }
975 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +0000976}
977
Raymond Hettingera690a992003-11-16 16:17:49 +0000978static PyObject *
Dong-hee Na1c605672020-03-19 02:30:50 +0900979make_new_frozenset(PyTypeObject *type, PyObject *iterable)
Raymond Hettingera690a992003-11-16 16:17:49 +0000980{
Dong-hee Na1c605672020-03-19 02:30:50 +0900981 if (type != &PyFrozenSet_Type) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 return make_new_set(type, iterable);
Dong-hee Na1c605672020-03-19 02:30:50 +0900983 }
Raymond Hettingerd7946662005-08-01 21:39:29 +0000984
Raymond Hettingerf9bd05e2020-06-23 08:42:55 -0700985 if (iterable != NULL && PyFrozenSet_CheckExact(iterable)) {
986 /* frozenset(f) is idempotent */
987 Py_INCREF(iterable);
988 return iterable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 }
Raymond Hettingerf9bd05e2020-06-23 08:42:55 -0700990 return make_new_set((PyTypeObject *)type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +0000991}
992
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000993static PyObject *
Dong-hee Na1c605672020-03-19 02:30:50 +0900994frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
995{
996 PyObject *iterable = NULL;
997
998 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset", kwds)) {
999 return NULL;
1000 }
1001
1002 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable)) {
1003 return NULL;
1004 }
1005
1006 return make_new_frozenset(type, iterable);
1007}
1008
1009static PyObject *
1010frozenset_vectorcall(PyObject *type, PyObject * const*args,
1011 size_t nargsf, PyObject *kwnames)
1012{
1013 if (!_PyArg_NoKwnames("frozenset", kwnames)) {
1014 return NULL;
1015 }
1016
1017 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
1018 if (!_PyArg_CheckPositional("frozenset", nargs, 0, 1)) {
1019 return NULL;
1020 }
1021
1022 PyObject *iterable = (nargs ? args[0] : NULL);
1023 return make_new_frozenset((PyTypeObject *)type, iterable);
1024}
1025
1026static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001027set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1028{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001029 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001030}
1031
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001032/* set_swap_bodies() switches the contents of any two sets by moving their
1033 internal data pointers and, if needed, copying the internal smalltables.
1034 Semantically equivalent to:
1035
1036 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1037
1038 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001039 Useful for operations that update in-place (by allowing an intermediate
1040 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001041*/
1042
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001043static void
1044set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001045{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046 Py_ssize_t t;
1047 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001048 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001049 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001050
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001051 t = a->fill; a->fill = b->fill; b->fill = t;
1052 t = a->used; a->used = b->used; b->used = t;
1053 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001054
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 u = a->table;
1056 if (a->table == a->smalltable)
1057 u = b->smalltable;
1058 a->table = b->table;
1059 if (b->table == b->smalltable)
1060 a->table = a->smalltable;
1061 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001062
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 if (a->table == a->smalltable || b->table == b->smalltable) {
1064 memcpy(tab, a->smalltable, sizeof(tab));
1065 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1066 memcpy(b->smalltable, tab, sizeof(tab));
1067 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1070 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1071 h = a->hash; a->hash = b->hash; b->hash = h;
1072 } else {
1073 a->hash = -1;
1074 b->hash = -1;
1075 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001076}
1077
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001078static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301079set_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001081 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001082}
1083
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001084static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301085frozenset_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001086{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 if (PyFrozenSet_CheckExact(so)) {
1088 Py_INCREF(so);
1089 return (PyObject *)so;
1090 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301091 return set_copy(so, NULL);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001092}
1093
Raymond Hettingera690a992003-11-16 16:17:49 +00001094PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1095
1096static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301097set_clear(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc991db22005-08-11 07:58:45 +00001098{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 set_clear_internal(so);
1100 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001101}
1102
1103PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1104
1105static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001106set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001107{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001108 PySetObject *result;
1109 PyObject *other;
1110 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001111
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301112 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001113 if (result == NULL)
1114 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001116 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1117 other = PyTuple_GET_ITEM(args, i);
1118 if ((PyObject *)so == other)
1119 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001120 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001121 Py_DECREF(result);
1122 return NULL;
1123 }
1124 }
1125 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001126}
1127
1128PyDoc_STRVAR(union_doc,
1129 "Return the union of sets as a new set.\n\
1130\n\
1131(i.e. all elements that are in either set.)");
1132
1133static PyObject *
1134set_or(PySetObject *so, PyObject *other)
1135{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001137
Brian Curtindfc80e32011-08-10 20:28:54 -05001138 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1139 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001140
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301141 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 if (result == NULL)
1143 return NULL;
1144 if ((PyObject *)so == other)
1145 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001146 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 Py_DECREF(result);
1148 return NULL;
1149 }
1150 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001151}
1152
Raymond Hettingera690a992003-11-16 16:17:49 +00001153static PyObject *
1154set_ior(PySetObject *so, PyObject *other)
1155{
Brian Curtindfc80e32011-08-10 20:28:54 -05001156 if (!PyAnySet_Check(other))
1157 Py_RETURN_NOTIMPLEMENTED;
1158
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001159 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001160 return NULL;
1161 Py_INCREF(so);
1162 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001163}
1164
1165static PyObject *
1166set_intersection(PySetObject *so, PyObject *other)
1167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 PySetObject *result;
1169 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001170 Py_hash_t hash;
1171 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001173 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301174 return set_copy(so, NULL);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001176 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1177 if (result == NULL)
1178 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001180 if (PyAnySet_Check(other)) {
1181 Py_ssize_t pos = 0;
1182 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001184 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1185 tmp = (PyObject *)so;
1186 so = (PySetObject *)other;
1187 other = tmp;
1188 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001191 key = entry->key;
1192 hash = entry->hash;
1193 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001194 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001195 Py_DECREF(result);
1196 return NULL;
1197 }
1198 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001199 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 Py_DECREF(result);
1201 return NULL;
1202 }
1203 }
1204 }
1205 return (PyObject *)result;
1206 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001208 it = PyObject_GetIter(other);
1209 if (it == NULL) {
1210 Py_DECREF(result);
1211 return NULL;
1212 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001214 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001215 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001216 if (hash == -1)
1217 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001218 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001219 if (rv < 0)
1220 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001221 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001222 if (set_add_entry(result, key, hash))
1223 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001224 }
1225 Py_DECREF(key);
1226 }
1227 Py_DECREF(it);
1228 if (PyErr_Occurred()) {
1229 Py_DECREF(result);
1230 return NULL;
1231 }
1232 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001233 error:
1234 Py_DECREF(it);
1235 Py_DECREF(result);
1236 Py_DECREF(key);
1237 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001238}
1239
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001240static PyObject *
1241set_intersection_multi(PySetObject *so, PyObject *args)
1242{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001243 Py_ssize_t i;
1244 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301247 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 Py_INCREF(so);
1250 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1251 PyObject *other = PyTuple_GET_ITEM(args, i);
1252 PyObject *newresult = set_intersection((PySetObject *)result, other);
1253 if (newresult == NULL) {
1254 Py_DECREF(result);
1255 return NULL;
1256 }
1257 Py_DECREF(result);
1258 result = newresult;
1259 }
1260 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001261}
1262
Raymond Hettingera690a992003-11-16 16:17:49 +00001263PyDoc_STRVAR(intersection_doc,
1264"Return the intersection of two sets as a new set.\n\
1265\n\
1266(i.e. all elements that are in both sets.)");
1267
1268static PyObject *
1269set_intersection_update(PySetObject *so, PyObject *other)
1270{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 tmp = set_intersection(so, other);
1274 if (tmp == NULL)
1275 return NULL;
1276 set_swap_bodies(so, (PySetObject *)tmp);
1277 Py_DECREF(tmp);
1278 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001279}
1280
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001281static PyObject *
1282set_intersection_update_multi(PySetObject *so, PyObject *args)
1283{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001286 tmp = set_intersection_multi(so, args);
1287 if (tmp == NULL)
1288 return NULL;
1289 set_swap_bodies(so, (PySetObject *)tmp);
1290 Py_DECREF(tmp);
1291 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001292}
1293
Raymond Hettingera690a992003-11-16 16:17:49 +00001294PyDoc_STRVAR(intersection_update_doc,
1295"Update a set with the intersection of itself and another.");
1296
1297static PyObject *
1298set_and(PySetObject *so, PyObject *other)
1299{
Brian Curtindfc80e32011-08-10 20:28:54 -05001300 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1301 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001303}
1304
1305static PyObject *
1306set_iand(PySetObject *so, PyObject *other)
1307{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001309
Brian Curtindfc80e32011-08-10 20:28:54 -05001310 if (!PyAnySet_Check(other))
1311 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 result = set_intersection_update(so, other);
1313 if (result == NULL)
1314 return NULL;
1315 Py_DECREF(result);
1316 Py_INCREF(so);
1317 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001318}
1319
Guido van Rossum58da9312007-11-10 23:39:45 +00001320static PyObject *
1321set_isdisjoint(PySetObject *so, PyObject *other)
1322{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001324 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 if ((PyObject *)so == other) {
1327 if (PySet_GET_SIZE(so) == 0)
1328 Py_RETURN_TRUE;
1329 else
1330 Py_RETURN_FALSE;
1331 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 if (PyAnySet_CheckExact(other)) {
1334 Py_ssize_t pos = 0;
1335 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1338 tmp = (PyObject *)so;
1339 so = (PySetObject *)other;
1340 other = tmp;
1341 }
1342 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001343 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001344 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 return NULL;
1346 if (rv)
1347 Py_RETURN_FALSE;
1348 }
1349 Py_RETURN_TRUE;
1350 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001352 it = PyObject_GetIter(other);
1353 if (it == NULL)
1354 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001357 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001359 if (hash == -1) {
1360 Py_DECREF(key);
1361 Py_DECREF(it);
1362 return NULL;
1363 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001364 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001366 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 Py_DECREF(it);
1368 return NULL;
1369 }
1370 if (rv) {
1371 Py_DECREF(it);
1372 Py_RETURN_FALSE;
1373 }
1374 }
1375 Py_DECREF(it);
1376 if (PyErr_Occurred())
1377 return NULL;
1378 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001379}
1380
1381PyDoc_STRVAR(isdisjoint_doc,
1382"Return True if two sets have a null intersection.");
1383
Neal Norwitz6576bd82005-11-13 18:41:28 +00001384static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001385set_difference_update_internal(PySetObject *so, PyObject *other)
1386{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 if ((PyObject *)so == other)
1388 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390 if (PyAnySet_Check(other)) {
1391 setentry *entry;
1392 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001393
Raymond Hettinger88ea1662019-08-29 09:02:58 -07001394 /* Optimization: When the other set is more than 8 times
1395 larger than the base set, replace the other set with
1396 interesection of the two sets.
1397 */
1398 if ((PySet_GET_SIZE(other) >> 3) > PySet_GET_SIZE(so)) {
1399 other = set_intersection(so, other);
1400 if (other == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001401 return -1;
Raymond Hettinger88ea1662019-08-29 09:02:58 -07001402 } else {
1403 Py_INCREF(other);
1404 }
1405
1406 while (set_next((PySetObject *)other, &pos, &entry))
1407 if (set_discard_entry(so, entry->key, entry->hash) < 0) {
1408 Py_DECREF(other);
1409 return -1;
1410 }
1411
1412 Py_DECREF(other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 } else {
1414 PyObject *key, *it;
1415 it = PyObject_GetIter(other);
1416 if (it == NULL)
1417 return -1;
1418
1419 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001420 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 Py_DECREF(it);
1422 Py_DECREF(key);
1423 return -1;
1424 }
1425 Py_DECREF(key);
1426 }
1427 Py_DECREF(it);
1428 if (PyErr_Occurred())
1429 return -1;
1430 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001431 /* If more than 1/4th are dummies, then resize them away. */
1432 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +09001434 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001435}
1436
Raymond Hettingera690a992003-11-16 16:17:49 +00001437static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001438set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001439{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001442 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1443 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001444 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001445 return NULL;
1446 }
1447 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001448}
1449
1450PyDoc_STRVAR(difference_update_doc,
1451"Remove all elements of another set from this set.");
1452
1453static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001454set_copy_and_difference(PySetObject *so, PyObject *other)
1455{
1456 PyObject *result;
1457
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301458 result = set_copy(so, NULL);
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001459 if (result == NULL)
1460 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001461 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001462 return result;
1463 Py_DECREF(result);
1464 return NULL;
1465}
1466
1467static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001468set_difference(PySetObject *so, PyObject *other)
1469{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001471 PyObject *key;
1472 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001473 setentry *entry;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001474 Py_ssize_t pos = 0, other_size;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001475 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001476
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001477 if (PyAnySet_Check(other)) {
1478 other_size = PySet_GET_SIZE(other);
1479 }
1480 else if (PyDict_CheckExact(other)) {
1481 other_size = PyDict_GET_SIZE(other);
1482 }
1483 else {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001484 return set_copy_and_difference(so, other);
1485 }
1486
1487 /* If len(so) much more than len(other), it's more efficient to simply copy
1488 * so and then iterate other looking for common elements. */
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001489 if ((PySet_GET_SIZE(so) >> 2) > other_size) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001490 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001491 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001493 result = make_new_set_basetype(Py_TYPE(so), NULL);
1494 if (result == NULL)
1495 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001497 if (PyDict_CheckExact(other)) {
1498 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001499 key = entry->key;
1500 hash = entry->hash;
Serhiy Storchakafb5db7e2020-10-26 08:43:39 +02001501 rv = _PyDict_Contains_KnownHash(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001502 if (rv < 0) {
1503 Py_DECREF(result);
1504 return NULL;
1505 }
1506 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001507 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 Py_DECREF(result);
1509 return NULL;
1510 }
1511 }
1512 }
1513 return result;
1514 }
1515
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001516 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001518 key = entry->key;
1519 hash = entry->hash;
1520 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001521 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001522 Py_DECREF(result);
1523 return NULL;
1524 }
1525 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001526 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001527 Py_DECREF(result);
1528 return NULL;
1529 }
1530 }
1531 }
1532 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001533}
1534
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001535static PyObject *
1536set_difference_multi(PySetObject *so, PyObject *args)
1537{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 Py_ssize_t i;
1539 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001540
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301542 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001543
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001544 other = PyTuple_GET_ITEM(args, 0);
1545 result = set_difference(so, other);
1546 if (result == NULL)
1547 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001548
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1550 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001551 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001552 Py_DECREF(result);
1553 return NULL;
1554 }
1555 }
1556 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001557}
1558
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001559PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001560"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001561\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001562(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001563static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001564set_sub(PySetObject *so, PyObject *other)
1565{
Brian Curtindfc80e32011-08-10 20:28:54 -05001566 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1567 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001568 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001569}
1570
1571static PyObject *
1572set_isub(PySetObject *so, PyObject *other)
1573{
Brian Curtindfc80e32011-08-10 20:28:54 -05001574 if (!PyAnySet_Check(other))
1575 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001576 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 return NULL;
1578 Py_INCREF(so);
1579 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001580}
1581
1582static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001583set_symmetric_difference_update(PySetObject *so, PyObject *other)
1584{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 PySetObject *otherset;
1586 PyObject *key;
1587 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001588 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001590 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001591
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001592 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301593 return set_clear(so, NULL);
Raymond Hettingera690a992003-11-16 16:17:49 +00001594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 if (PyDict_CheckExact(other)) {
1596 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001598 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001599 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001600 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001601 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001602 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001604 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001605 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001606 Py_DECREF(key);
1607 return NULL;
1608 }
1609 }
Georg Brandl2d444492010-09-03 10:52:55 +00001610 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 }
1612 Py_RETURN_NONE;
1613 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001614
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 if (PyAnySet_Check(other)) {
1616 Py_INCREF(other);
1617 otherset = (PySetObject *)other;
1618 } else {
1619 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1620 if (otherset == NULL)
1621 return NULL;
1622 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001625 key = entry->key;
1626 hash = entry->hash;
1627 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001628 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 Py_DECREF(otherset);
1630 return NULL;
1631 }
1632 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001633 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001634 Py_DECREF(otherset);
1635 return NULL;
1636 }
1637 }
1638 }
1639 Py_DECREF(otherset);
1640 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001641}
1642
1643PyDoc_STRVAR(symmetric_difference_update_doc,
1644"Update a set with the symmetric difference of itself and another.");
1645
1646static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001647set_symmetric_difference(PySetObject *so, PyObject *other)
1648{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001649 PyObject *rv;
1650 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001651
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1653 if (otherset == NULL)
1654 return NULL;
1655 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
lekma491bbed2018-05-02 11:29:10 +02001656 if (rv == NULL) {
1657 Py_DECREF(otherset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001658 return NULL;
lekma491bbed2018-05-02 11:29:10 +02001659 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 Py_DECREF(rv);
1661 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001662}
1663
1664PyDoc_STRVAR(symmetric_difference_doc,
1665"Return the symmetric difference of two sets as a new set.\n\
1666\n\
1667(i.e. all elements that are in exactly one of the sets.)");
1668
1669static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001670set_xor(PySetObject *so, PyObject *other)
1671{
Brian Curtindfc80e32011-08-10 20:28:54 -05001672 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1673 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001674 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001675}
1676
1677static PyObject *
1678set_ixor(PySetObject *so, PyObject *other)
1679{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001680 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001681
Brian Curtindfc80e32011-08-10 20:28:54 -05001682 if (!PyAnySet_Check(other))
1683 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001684 result = set_symmetric_difference_update(so, other);
1685 if (result == NULL)
1686 return NULL;
1687 Py_DECREF(result);
1688 Py_INCREF(so);
1689 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001690}
1691
1692static PyObject *
1693set_issubset(PySetObject *so, PyObject *other)
1694{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001695 setentry *entry;
1696 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001697 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001698
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001699 if (!PyAnySet_Check(other)) {
1700 PyObject *tmp, *result;
1701 tmp = make_new_set(&PySet_Type, other);
1702 if (tmp == NULL)
1703 return NULL;
1704 result = set_issubset(so, tmp);
1705 Py_DECREF(tmp);
1706 return result;
1707 }
1708 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1709 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001710
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001711 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001712 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001713 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001714 return NULL;
1715 if (!rv)
1716 Py_RETURN_FALSE;
1717 }
1718 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001719}
1720
1721PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1722
1723static PyObject *
1724set_issuperset(PySetObject *so, PyObject *other)
1725{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001726 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001727
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 if (!PyAnySet_Check(other)) {
1729 tmp = make_new_set(&PySet_Type, other);
1730 if (tmp == NULL)
1731 return NULL;
1732 result = set_issuperset(so, tmp);
1733 Py_DECREF(tmp);
1734 return result;
1735 }
1736 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001737}
1738
1739PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1740
Raymond Hettingera690a992003-11-16 16:17:49 +00001741static PyObject *
1742set_richcompare(PySetObject *v, PyObject *w, int op)
1743{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001744 PyObject *r1;
1745 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001746
Brian Curtindfc80e32011-08-10 20:28:54 -05001747 if(!PyAnySet_Check(w))
1748 Py_RETURN_NOTIMPLEMENTED;
1749
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001750 switch (op) {
1751 case Py_EQ:
1752 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1753 Py_RETURN_FALSE;
1754 if (v->hash != -1 &&
1755 ((PySetObject *)w)->hash != -1 &&
1756 v->hash != ((PySetObject *)w)->hash)
1757 Py_RETURN_FALSE;
1758 return set_issubset(v, w);
1759 case Py_NE:
1760 r1 = set_richcompare(v, w, Py_EQ);
1761 if (r1 == NULL)
1762 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001763 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001764 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001765 if (r2 < 0)
1766 return NULL;
1767 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001768 case Py_LE:
1769 return set_issubset(v, w);
1770 case Py_GE:
1771 return set_issuperset(v, w);
1772 case Py_LT:
1773 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1774 Py_RETURN_FALSE;
1775 return set_issubset(v, w);
1776 case Py_GT:
1777 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1778 Py_RETURN_FALSE;
1779 return set_issuperset(v, w);
1780 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001781 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001782}
1783
Raymond Hettingera690a992003-11-16 16:17:49 +00001784static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001785set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001786{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001787 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788 return NULL;
1789 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001790}
1791
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001792PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001793"Add an element to a set.\n\
1794\n\
1795This has no effect if the element is already present.");
1796
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001797static int
1798set_contains(PySetObject *so, PyObject *key)
1799{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001800 PyObject *tmpkey;
1801 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001802
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001803 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001804 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001805 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1806 return -1;
1807 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001808 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001809 if (tmpkey == NULL)
1810 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001811 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001812 Py_DECREF(tmpkey);
1813 }
1814 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001815}
1816
1817static PyObject *
1818set_direct_contains(PySetObject *so, PyObject *key)
1819{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001820 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001821
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001822 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001823 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001824 return NULL;
1825 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001826}
1827
1828PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1829
Raymond Hettingera690a992003-11-16 16:17:49 +00001830static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001831set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001832{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001833 PyObject *tmpkey;
1834 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001837 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1839 return NULL;
1840 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001841 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001842 if (tmpkey == NULL)
1843 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001844 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001846 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 return NULL;
1848 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001851 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 return NULL;
1853 }
1854 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001855}
1856
1857PyDoc_STRVAR(remove_doc,
1858"Remove an element from a set; it must be a member.\n\
1859\n\
1860If the element is not a member, raise a KeyError.");
1861
1862static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001863set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001864{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001865 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001869 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001870 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1871 return NULL;
1872 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001873 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001874 if (tmpkey == NULL)
1875 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001876 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001878 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001879 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 }
1881 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001882}
1883
1884PyDoc_STRVAR(discard_doc,
1885"Remove an element from a set if it is a member.\n\
1886\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001888
1889static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301890set_reduce(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001891{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001893 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 keys = PySequence_List((PyObject *)so);
1896 if (keys == NULL)
1897 goto done;
1898 args = PyTuple_Pack(1, keys);
1899 if (args == NULL)
1900 goto done;
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001901 if (_PyObject_LookupAttrId((PyObject *)so, &PyId___dict__, &dict) < 0) {
1902 goto done;
1903 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001904 if (dict == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 dict = Py_None;
1906 Py_INCREF(dict);
1907 }
1908 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001909done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 Py_XDECREF(args);
1911 Py_XDECREF(keys);
1912 Py_XDECREF(dict);
1913 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001914}
1915
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001916static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301917set_sizeof(PySetObject *so, PyObject *Py_UNUSED(ignored))
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001918{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001920
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02001921 res = _PyObject_SIZE(Py_TYPE(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 if (so->table != so->smalltable)
1923 res = res + (so->mask + 1) * sizeof(setentry);
1924 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001925}
1926
1927PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001928static int
1929set_init(PySetObject *self, PyObject *args, PyObject *kwds)
1930{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001932
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001933 if (!_PyArg_NoKeywords("set", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001934 return -1;
1935 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
1936 return -1;
Raymond Hettingerb72e21b2016-03-25 02:29:59 -07001937 if (self->fill)
1938 set_clear_internal(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001939 self->hash = -1;
1940 if (iterable == NULL)
1941 return 0;
1942 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001943}
1944
Dong-hee Na6ff79f652020-03-17 02:17:38 +09001945static PyObject*
1946set_vectorcall(PyObject *type, PyObject * const*args,
1947 size_t nargsf, PyObject *kwnames)
1948{
1949 assert(PyType_Check(type));
1950
1951 if (!_PyArg_NoKwnames("set", kwnames)) {
1952 return NULL;
1953 }
1954
1955 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
1956 if (!_PyArg_CheckPositional("set", nargs, 0, 1)) {
1957 return NULL;
1958 }
1959
1960 if (nargs) {
1961 return make_new_set((PyTypeObject *)type, args[0]);
1962 }
1963
1964 return make_new_set((PyTypeObject *)type, NULL);
1965}
1966
Raymond Hettingera690a992003-11-16 16:17:49 +00001967static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968 set_len, /* sq_length */
1969 0, /* sq_concat */
1970 0, /* sq_repeat */
1971 0, /* sq_item */
1972 0, /* sq_slice */
1973 0, /* sq_ass_item */
1974 0, /* sq_ass_slice */
1975 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00001976};
1977
1978/* set object ********************************************************/
1979
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00001980#ifdef Py_DEBUG
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301981static PyObject *test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored));
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00001982
1983PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
1984All is well if assertions don't fail.");
1985#endif
1986
Raymond Hettingera690a992003-11-16 16:17:49 +00001987static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001988 {"add", (PyCFunction)set_add, METH_O,
1989 add_doc},
1990 {"clear", (PyCFunction)set_clear, METH_NOARGS,
1991 clear_doc},
1992 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
1993 contains_doc},
1994 {"copy", (PyCFunction)set_copy, METH_NOARGS,
1995 copy_doc},
1996 {"discard", (PyCFunction)set_discard, METH_O,
1997 discard_doc},
1998 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
1999 difference_doc},
2000 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2001 difference_update_doc},
2002 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2003 intersection_doc},
2004 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2005 intersection_update_doc},
2006 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2007 isdisjoint_doc},
2008 {"issubset", (PyCFunction)set_issubset, METH_O,
2009 issubset_doc},
2010 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2011 issuperset_doc},
2012 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2013 pop_doc},
2014 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2015 reduce_doc},
2016 {"remove", (PyCFunction)set_remove, METH_O,
2017 remove_doc},
2018 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2019 sizeof_doc},
2020 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2021 symmetric_difference_doc},
2022 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2023 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002024#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2026 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002027#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002028 {"union", (PyCFunction)set_union, METH_VARARGS,
2029 union_doc},
2030 {"update", (PyCFunction)set_update, METH_VARARGS,
2031 update_doc},
Guido van Rossum48b069a2020-04-07 09:50:06 -07002032 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002033 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002034};
2035
2036static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002037 0, /*nb_add*/
2038 (binaryfunc)set_sub, /*nb_subtract*/
2039 0, /*nb_multiply*/
2040 0, /*nb_remainder*/
2041 0, /*nb_divmod*/
2042 0, /*nb_power*/
2043 0, /*nb_negative*/
2044 0, /*nb_positive*/
2045 0, /*nb_absolute*/
2046 0, /*nb_bool*/
2047 0, /*nb_invert*/
2048 0, /*nb_lshift*/
2049 0, /*nb_rshift*/
2050 (binaryfunc)set_and, /*nb_and*/
2051 (binaryfunc)set_xor, /*nb_xor*/
2052 (binaryfunc)set_or, /*nb_or*/
2053 0, /*nb_int*/
2054 0, /*nb_reserved*/
2055 0, /*nb_float*/
2056 0, /*nb_inplace_add*/
2057 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2058 0, /*nb_inplace_multiply*/
2059 0, /*nb_inplace_remainder*/
2060 0, /*nb_inplace_power*/
2061 0, /*nb_inplace_lshift*/
2062 0, /*nb_inplace_rshift*/
2063 (binaryfunc)set_iand, /*nb_inplace_and*/
2064 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2065 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002066};
2067
2068PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002069"set() -> new empty set object\n\
2070set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002071\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002072Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002073
2074PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002075 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2076 "set", /* tp_name */
2077 sizeof(PySetObject), /* tp_basicsize */
2078 0, /* tp_itemsize */
2079 /* methods */
2080 (destructor)set_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002081 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002082 0, /* tp_getattr */
2083 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002084 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002085 (reprfunc)set_repr, /* tp_repr */
2086 &set_as_number, /* tp_as_number */
2087 &set_as_sequence, /* tp_as_sequence */
2088 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002089 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002090 0, /* tp_call */
2091 0, /* tp_str */
2092 PyObject_GenericGetAttr, /* tp_getattro */
2093 0, /* tp_setattro */
2094 0, /* tp_as_buffer */
2095 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2096 Py_TPFLAGS_BASETYPE, /* tp_flags */
2097 set_doc, /* tp_doc */
2098 (traverseproc)set_traverse, /* tp_traverse */
2099 (inquiry)set_clear_internal, /* tp_clear */
2100 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002101 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2102 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002103 0, /* tp_iternext */
2104 set_methods, /* tp_methods */
2105 0, /* tp_members */
2106 0, /* tp_getset */
2107 0, /* tp_base */
2108 0, /* tp_dict */
2109 0, /* tp_descr_get */
2110 0, /* tp_descr_set */
2111 0, /* tp_dictoffset */
2112 (initproc)set_init, /* tp_init */
2113 PyType_GenericAlloc, /* tp_alloc */
2114 set_new, /* tp_new */
2115 PyObject_GC_Del, /* tp_free */
Dong-hee Na6ff79f652020-03-17 02:17:38 +09002116 .tp_vectorcall = set_vectorcall,
Raymond Hettingera690a992003-11-16 16:17:49 +00002117};
2118
2119/* frozenset object ********************************************************/
2120
2121
2122static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2124 contains_doc},
2125 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2126 copy_doc},
2127 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2128 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002129 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002130 intersection_doc},
2131 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2132 isdisjoint_doc},
2133 {"issubset", (PyCFunction)set_issubset, METH_O,
2134 issubset_doc},
2135 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2136 issuperset_doc},
2137 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2138 reduce_doc},
2139 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2140 sizeof_doc},
2141 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2142 symmetric_difference_doc},
2143 {"union", (PyCFunction)set_union, METH_VARARGS,
2144 union_doc},
Guido van Rossum48b069a2020-04-07 09:50:06 -07002145 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002146 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002147};
2148
2149static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002150 0, /*nb_add*/
2151 (binaryfunc)set_sub, /*nb_subtract*/
2152 0, /*nb_multiply*/
2153 0, /*nb_remainder*/
2154 0, /*nb_divmod*/
2155 0, /*nb_power*/
2156 0, /*nb_negative*/
2157 0, /*nb_positive*/
2158 0, /*nb_absolute*/
2159 0, /*nb_bool*/
2160 0, /*nb_invert*/
2161 0, /*nb_lshift*/
2162 0, /*nb_rshift*/
2163 (binaryfunc)set_and, /*nb_and*/
2164 (binaryfunc)set_xor, /*nb_xor*/
2165 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002166};
2167
2168PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002169"frozenset() -> empty frozenset object\n\
2170frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002171\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002172Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002173
2174PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002175 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2176 "frozenset", /* tp_name */
2177 sizeof(PySetObject), /* tp_basicsize */
2178 0, /* tp_itemsize */
2179 /* methods */
2180 (destructor)set_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002181 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002182 0, /* tp_getattr */
2183 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002184 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002185 (reprfunc)set_repr, /* tp_repr */
2186 &frozenset_as_number, /* tp_as_number */
2187 &set_as_sequence, /* tp_as_sequence */
2188 0, /* tp_as_mapping */
2189 frozenset_hash, /* tp_hash */
2190 0, /* tp_call */
2191 0, /* tp_str */
2192 PyObject_GenericGetAttr, /* tp_getattro */
2193 0, /* tp_setattro */
2194 0, /* tp_as_buffer */
2195 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2196 Py_TPFLAGS_BASETYPE, /* tp_flags */
2197 frozenset_doc, /* tp_doc */
2198 (traverseproc)set_traverse, /* tp_traverse */
2199 (inquiry)set_clear_internal, /* tp_clear */
2200 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002201 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002202 (getiterfunc)set_iter, /* tp_iter */
2203 0, /* tp_iternext */
2204 frozenset_methods, /* tp_methods */
2205 0, /* tp_members */
2206 0, /* tp_getset */
2207 0, /* tp_base */
2208 0, /* tp_dict */
2209 0, /* tp_descr_get */
2210 0, /* tp_descr_set */
2211 0, /* tp_dictoffset */
2212 0, /* tp_init */
2213 PyType_GenericAlloc, /* tp_alloc */
2214 frozenset_new, /* tp_new */
2215 PyObject_GC_Del, /* tp_free */
Dong-hee Na1c605672020-03-19 02:30:50 +09002216 .tp_vectorcall = frozenset_vectorcall,
Raymond Hettingera690a992003-11-16 16:17:49 +00002217};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002218
2219
2220/***** C API functions *************************************************/
2221
2222PyObject *
2223PySet_New(PyObject *iterable)
2224{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002225 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002226}
2227
2228PyObject *
2229PyFrozenSet_New(PyObject *iterable)
2230{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002231 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002232}
2233
Neal Norwitz8c49c822006-03-04 18:41:19 +00002234Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002235PySet_Size(PyObject *anyset)
2236{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002237 if (!PyAnySet_Check(anyset)) {
2238 PyErr_BadInternalCall();
2239 return -1;
2240 }
2241 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002242}
2243
2244int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002245PySet_Clear(PyObject *set)
2246{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 if (!PySet_Check(set)) {
2248 PyErr_BadInternalCall();
2249 return -1;
2250 }
2251 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002252}
2253
2254int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002255PySet_Contains(PyObject *anyset, PyObject *key)
2256{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002257 if (!PyAnySet_Check(anyset)) {
2258 PyErr_BadInternalCall();
2259 return -1;
2260 }
2261 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002262}
2263
2264int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002265PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002266{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002267 if (!PySet_Check(set)) {
2268 PyErr_BadInternalCall();
2269 return -1;
2270 }
2271 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002272}
2273
2274int
Christian Heimesfd66e512008-01-29 12:18:50 +00002275PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002276{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002277 if (!PySet_Check(anyset) &&
2278 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2279 PyErr_BadInternalCall();
2280 return -1;
2281 }
2282 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002283}
2284
Raymond Hettinger3625af52016-03-27 01:15:07 -07002285int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002286_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002287{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002288 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002290 if (!PyAnySet_Check(set)) {
2291 PyErr_BadInternalCall();
2292 return -1;
2293 }
2294 if (set_next((PySetObject *)set, pos, &entry) == 0)
2295 return 0;
2296 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002297 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002298 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002299}
2300
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002301PyObject *
2302PySet_Pop(PyObject *set)
2303{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002304 if (!PySet_Check(set)) {
2305 PyErr_BadInternalCall();
2306 return NULL;
2307 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302308 return set_pop((PySetObject *)set, NULL);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002309}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002310
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002311int
2312_PySet_Update(PyObject *set, PyObject *iterable)
2313{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002314 if (!PySet_Check(set)) {
2315 PyErr_BadInternalCall();
2316 return -1;
2317 }
2318 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002319}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002320
Raymond Hettingere259f132013-12-15 11:56:14 -08002321/* Exported for the gdb plugin's benefit. */
2322PyObject *_PySet_Dummy = dummy;
2323
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002324#ifdef Py_DEBUG
2325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002326/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002327 Returns True and original set is restored. */
2328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002329#define assertRaises(call_return_value, exception) \
2330 do { \
2331 assert(call_return_value); \
2332 assert(PyErr_ExceptionMatches(exception)); \
2333 PyErr_Clear(); \
2334 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002335
2336static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302337test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002338{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002339 Py_ssize_t count;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +02002340 const char *s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002341 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002342 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002343 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002344 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002345 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002347 /* Verify preconditions */
2348 assert(PyAnySet_Check(ob));
2349 assert(PyAnySet_CheckExact(ob));
2350 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002352 /* so.clear(); so |= set("abc"); */
2353 str = PyUnicode_FromString("abc");
2354 if (str == NULL)
2355 return NULL;
2356 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002357 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002358 Py_DECREF(str);
2359 return NULL;
2360 }
2361 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002363 /* Exercise type/size checks */
2364 assert(PySet_Size(ob) == 3);
2365 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002367 /* Raise TypeError for non-iterable constructor arguments */
2368 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2369 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002371 /* Raise TypeError for unhashable key */
2372 dup = PySet_New(ob);
2373 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2374 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2375 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002377 /* Exercise successful pop, contains, add, and discard */
2378 elem = PySet_Pop(ob);
2379 assert(PySet_Contains(ob, elem) == 0);
2380 assert(PySet_GET_SIZE(ob) == 2);
2381 assert(PySet_Add(ob, elem) == 0);
2382 assert(PySet_Contains(ob, elem) == 1);
2383 assert(PySet_GET_SIZE(ob) == 3);
2384 assert(PySet_Discard(ob, elem) == 1);
2385 assert(PySet_GET_SIZE(ob) == 2);
2386 assert(PySet_Discard(ob, elem) == 0);
2387 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002389 /* Exercise clear */
2390 dup2 = PySet_New(dup);
2391 assert(PySet_Clear(dup2) == 0);
2392 assert(PySet_Size(dup2) == 0);
2393 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002395 /* Raise SystemError on clear or update of frozen set */
2396 f = PyFrozenSet_New(dup);
2397 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2398 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2399 assert(PySet_Add(f, elem) == 0);
2400 Py_INCREF(f);
2401 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2402 Py_DECREF(f);
2403 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405 /* Exercise direct iteration */
2406 i = 0, count = 0;
2407 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
Serhiy Storchaka06515832016-11-20 09:13:07 +02002408 s = PyUnicode_AsUTF8(x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002409 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2410 count++;
2411 }
2412 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002414 /* Exercise updates */
2415 dup2 = PySet_New(NULL);
2416 assert(_PySet_Update(dup2, dup) == 0);
2417 assert(PySet_Size(dup2) == 3);
2418 assert(_PySet_Update(dup2, dup) == 0);
2419 assert(PySet_Size(dup2) == 3);
2420 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002422 /* Raise SystemError when self argument is not a set or frozenset. */
2423 t = PyTuple_New(0);
2424 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2425 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2426 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002428 /* Raise SystemError when self argument is not a set. */
2429 f = PyFrozenSet_New(dup);
2430 assert(PySet_Size(f) == 3);
2431 assert(PyFrozenSet_CheckExact(f));
2432 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2433 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2434 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002436 /* Raise KeyError when popping from an empty set */
2437 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2438 Py_DECREF(ob);
2439 assert(PySet_GET_SIZE(ob) == 0);
2440 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002442 /* Restore the set from the copy using the PyNumber API */
2443 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2444 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002446 /* Verify constructors accept NULL arguments */
2447 f = PySet_New(NULL);
2448 assert(f != NULL);
2449 assert(PySet_GET_SIZE(f) == 0);
2450 Py_DECREF(f);
2451 f = PyFrozenSet_New(NULL);
2452 assert(f != NULL);
2453 assert(PyFrozenSet_CheckExact(f));
2454 assert(PySet_GET_SIZE(f) == 0);
2455 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002457 Py_DECREF(elem);
2458 Py_DECREF(dup);
2459 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002460}
2461
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002462#undef assertRaises
2463
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002464#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002465
2466/***** Dummy Struct *************************************************/
2467
2468static PyObject *
2469dummy_repr(PyObject *op)
2470{
2471 return PyUnicode_FromString("<dummy key>");
2472}
2473
Victor Stinner2a4903f2020-01-30 13:09:11 +01002474static void _Py_NO_RETURN
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002475dummy_dealloc(PyObject* ignore)
2476{
2477 Py_FatalError("deallocating <dummy key>");
2478}
2479
2480static PyTypeObject _PySetDummy_Type = {
2481 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2482 "<dummy key> type",
2483 0,
2484 0,
2485 dummy_dealloc, /*tp_dealloc*/ /*never called*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002486 0, /*tp_vectorcall_offset*/
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002487 0, /*tp_getattr*/
2488 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002489 0, /*tp_as_async*/
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002490 dummy_repr, /*tp_repr*/
2491 0, /*tp_as_number*/
2492 0, /*tp_as_sequence*/
2493 0, /*tp_as_mapping*/
2494 0, /*tp_hash */
2495 0, /*tp_call */
2496 0, /*tp_str */
2497 0, /*tp_getattro */
2498 0, /*tp_setattro */
2499 0, /*tp_as_buffer */
2500 Py_TPFLAGS_DEFAULT, /*tp_flags */
2501};
2502
2503static PyObject _dummy_struct = {
2504 _PyObject_EXTRA_INIT
2505 2, &_PySetDummy_Type
2506};
2507