blob: 76b1944db455886d68ce7ab56fb6d5b1ba0b23ad [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)
292 PyMem_DEL(oldtable);
293 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)
427 PyMem_DEL(table);
428 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)
487 PyMem_DEL(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 Hettingerd7946662005-08-01 21:39:29 +0000978/* The empty frozenset is a singleton */
979static PyObject *emptyfrozenset = NULL;
980
Raymond Hettingera690a992003-11-16 16:17:49 +0000981static PyObject *
Dong-hee Na1c605672020-03-19 02:30:50 +0900982make_new_frozenset(PyTypeObject *type, PyObject *iterable)
Raymond Hettingera690a992003-11-16 16:17:49 +0000983{
Dong-hee Na1c605672020-03-19 02:30:50 +0900984 if (type != &PyFrozenSet_Type) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 return make_new_set(type, iterable);
Dong-hee Na1c605672020-03-19 02:30:50 +0900986 }
Raymond Hettingerd7946662005-08-01 21:39:29 +0000987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 if (iterable != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 if (PyFrozenSet_CheckExact(iterable)) {
Dong-hee Na1c605672020-03-19 02:30:50 +0900990 /* frozenset(f) is idempotent */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000991 Py_INCREF(iterable);
992 return iterable;
993 }
Dong-hee Na1c605672020-03-19 02:30:50 +0900994 PyObject *res = make_new_set((PyTypeObject *)type, iterable);
995 if (res == NULL || PySet_GET_SIZE(res) != 0) {
996 return res;
997 }
998 /* If the created frozenset is empty, return the empty frozenset singleton instead */
999 Py_DECREF(res);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001000 }
Dong-hee Na1c605672020-03-19 02:30:50 +09001001
1002 // The empty frozenset is a singleton
1003 if (emptyfrozenset == NULL) {
1004 emptyfrozenset = make_new_set((PyTypeObject *)type, NULL);
1005 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 Py_XINCREF(emptyfrozenset);
1007 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001008}
1009
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001010static PyObject *
Dong-hee Na1c605672020-03-19 02:30:50 +09001011frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1012{
1013 PyObject *iterable = NULL;
1014
1015 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset", kwds)) {
1016 return NULL;
1017 }
1018
1019 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable)) {
1020 return NULL;
1021 }
1022
1023 return make_new_frozenset(type, iterable);
1024}
1025
1026static PyObject *
1027frozenset_vectorcall(PyObject *type, PyObject * const*args,
1028 size_t nargsf, PyObject *kwnames)
1029{
1030 if (!_PyArg_NoKwnames("frozenset", kwnames)) {
1031 return NULL;
1032 }
1033
1034 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
1035 if (!_PyArg_CheckPositional("frozenset", nargs, 0, 1)) {
1036 return NULL;
1037 }
1038
1039 PyObject *iterable = (nargs ? args[0] : NULL);
1040 return make_new_frozenset((PyTypeObject *)type, iterable);
1041}
1042
1043static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001044set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1045{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001047}
1048
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001049/* set_swap_bodies() switches the contents of any two sets by moving their
1050 internal data pointers and, if needed, copying the internal smalltables.
1051 Semantically equivalent to:
1052
1053 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1054
1055 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001056 Useful for operations that update in-place (by allowing an intermediate
1057 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001058*/
1059
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001060static void
1061set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001062{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 Py_ssize_t t;
1064 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001066 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001068 t = a->fill; a->fill = b->fill; b->fill = t;
1069 t = a->used; a->used = b->used; b->used = t;
1070 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001071
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 u = a->table;
1073 if (a->table == a->smalltable)
1074 u = b->smalltable;
1075 a->table = b->table;
1076 if (b->table == b->smalltable)
1077 a->table = a->smalltable;
1078 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001079
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001080 if (a->table == a->smalltable || b->table == b->smalltable) {
1081 memcpy(tab, a->smalltable, sizeof(tab));
1082 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1083 memcpy(b->smalltable, tab, sizeof(tab));
1084 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001085
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001086 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1087 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1088 h = a->hash; a->hash = b->hash; b->hash = h;
1089 } else {
1090 a->hash = -1;
1091 b->hash = -1;
1092 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001093}
1094
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001095static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301096set_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001097{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001098 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001099}
1100
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001101static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301102frozenset_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001103{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 if (PyFrozenSet_CheckExact(so)) {
1105 Py_INCREF(so);
1106 return (PyObject *)so;
1107 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301108 return set_copy(so, NULL);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001109}
1110
Raymond Hettingera690a992003-11-16 16:17:49 +00001111PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1112
1113static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301114set_clear(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc991db22005-08-11 07:58:45 +00001115{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001116 set_clear_internal(so);
1117 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001118}
1119
1120PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1121
1122static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001123set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001124{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001125 PySetObject *result;
1126 PyObject *other;
1127 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001128
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301129 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001130 if (result == NULL)
1131 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001133 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1134 other = PyTuple_GET_ITEM(args, i);
1135 if ((PyObject *)so == other)
1136 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001137 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138 Py_DECREF(result);
1139 return NULL;
1140 }
1141 }
1142 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001143}
1144
1145PyDoc_STRVAR(union_doc,
1146 "Return the union of sets as a new set.\n\
1147\n\
1148(i.e. all elements that are in either set.)");
1149
1150static PyObject *
1151set_or(PySetObject *so, PyObject *other)
1152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001154
Brian Curtindfc80e32011-08-10 20:28:54 -05001155 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1156 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001157
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301158 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 if (result == NULL)
1160 return NULL;
1161 if ((PyObject *)so == other)
1162 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001163 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 Py_DECREF(result);
1165 return NULL;
1166 }
1167 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001168}
1169
Raymond Hettingera690a992003-11-16 16:17:49 +00001170static PyObject *
1171set_ior(PySetObject *so, PyObject *other)
1172{
Brian Curtindfc80e32011-08-10 20:28:54 -05001173 if (!PyAnySet_Check(other))
1174 Py_RETURN_NOTIMPLEMENTED;
1175
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001176 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001177 return NULL;
1178 Py_INCREF(so);
1179 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001180}
1181
1182static PyObject *
1183set_intersection(PySetObject *so, PyObject *other)
1184{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 PySetObject *result;
1186 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001187 Py_hash_t hash;
1188 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301191 return set_copy(so, NULL);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1194 if (result == NULL)
1195 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 if (PyAnySet_Check(other)) {
1198 Py_ssize_t pos = 0;
1199 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001201 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1202 tmp = (PyObject *)so;
1203 so = (PySetObject *)other;
1204 other = tmp;
1205 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001208 key = entry->key;
1209 hash = entry->hash;
1210 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001211 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 Py_DECREF(result);
1213 return NULL;
1214 }
1215 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001216 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 Py_DECREF(result);
1218 return NULL;
1219 }
1220 }
1221 }
1222 return (PyObject *)result;
1223 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001225 it = PyObject_GetIter(other);
1226 if (it == NULL) {
1227 Py_DECREF(result);
1228 return NULL;
1229 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001231 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001232 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001233 if (hash == -1)
1234 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001235 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001236 if (rv < 0)
1237 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001239 if (set_add_entry(result, key, hash))
1240 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 }
1242 Py_DECREF(key);
1243 }
1244 Py_DECREF(it);
1245 if (PyErr_Occurred()) {
1246 Py_DECREF(result);
1247 return NULL;
1248 }
1249 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001250 error:
1251 Py_DECREF(it);
1252 Py_DECREF(result);
1253 Py_DECREF(key);
1254 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001255}
1256
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001257static PyObject *
1258set_intersection_multi(PySetObject *so, PyObject *args)
1259{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 Py_ssize_t i;
1261 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301264 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 Py_INCREF(so);
1267 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1268 PyObject *other = PyTuple_GET_ITEM(args, i);
1269 PyObject *newresult = set_intersection((PySetObject *)result, other);
1270 if (newresult == NULL) {
1271 Py_DECREF(result);
1272 return NULL;
1273 }
1274 Py_DECREF(result);
1275 result = newresult;
1276 }
1277 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001278}
1279
Raymond Hettingera690a992003-11-16 16:17:49 +00001280PyDoc_STRVAR(intersection_doc,
1281"Return the intersection of two sets as a new set.\n\
1282\n\
1283(i.e. all elements that are in both sets.)");
1284
1285static PyObject *
1286set_intersection_update(PySetObject *so, PyObject *other)
1287{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001290 tmp = set_intersection(so, other);
1291 if (tmp == NULL)
1292 return NULL;
1293 set_swap_bodies(so, (PySetObject *)tmp);
1294 Py_DECREF(tmp);
1295 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001296}
1297
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001298static PyObject *
1299set_intersection_update_multi(PySetObject *so, PyObject *args)
1300{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 tmp = set_intersection_multi(so, args);
1304 if (tmp == NULL)
1305 return NULL;
1306 set_swap_bodies(so, (PySetObject *)tmp);
1307 Py_DECREF(tmp);
1308 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001309}
1310
Raymond Hettingera690a992003-11-16 16:17:49 +00001311PyDoc_STRVAR(intersection_update_doc,
1312"Update a set with the intersection of itself and another.");
1313
1314static PyObject *
1315set_and(PySetObject *so, PyObject *other)
1316{
Brian Curtindfc80e32011-08-10 20:28:54 -05001317 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1318 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001320}
1321
1322static PyObject *
1323set_iand(PySetObject *so, PyObject *other)
1324{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001326
Brian Curtindfc80e32011-08-10 20:28:54 -05001327 if (!PyAnySet_Check(other))
1328 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 result = set_intersection_update(so, other);
1330 if (result == NULL)
1331 return NULL;
1332 Py_DECREF(result);
1333 Py_INCREF(so);
1334 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001335}
1336
Guido van Rossum58da9312007-11-10 23:39:45 +00001337static PyObject *
1338set_isdisjoint(PySetObject *so, PyObject *other)
1339{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001341 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 if ((PyObject *)so == other) {
1344 if (PySet_GET_SIZE(so) == 0)
1345 Py_RETURN_TRUE;
1346 else
1347 Py_RETURN_FALSE;
1348 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001350 if (PyAnySet_CheckExact(other)) {
1351 Py_ssize_t pos = 0;
1352 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1355 tmp = (PyObject *)so;
1356 so = (PySetObject *)other;
1357 other = tmp;
1358 }
1359 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001360 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001361 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001362 return NULL;
1363 if (rv)
1364 Py_RETURN_FALSE;
1365 }
1366 Py_RETURN_TRUE;
1367 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 it = PyObject_GetIter(other);
1370 if (it == NULL)
1371 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001374 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 if (hash == -1) {
1377 Py_DECREF(key);
1378 Py_DECREF(it);
1379 return NULL;
1380 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001381 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001383 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 Py_DECREF(it);
1385 return NULL;
1386 }
1387 if (rv) {
1388 Py_DECREF(it);
1389 Py_RETURN_FALSE;
1390 }
1391 }
1392 Py_DECREF(it);
1393 if (PyErr_Occurred())
1394 return NULL;
1395 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001396}
1397
1398PyDoc_STRVAR(isdisjoint_doc,
1399"Return True if two sets have a null intersection.");
1400
Neal Norwitz6576bd82005-11-13 18:41:28 +00001401static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001402set_difference_update_internal(PySetObject *so, PyObject *other)
1403{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001404 if ((PyObject *)so == other)
1405 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001406
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001407 if (PyAnySet_Check(other)) {
1408 setentry *entry;
1409 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001410
Raymond Hettinger88ea1662019-08-29 09:02:58 -07001411 /* Optimization: When the other set is more than 8 times
1412 larger than the base set, replace the other set with
1413 interesection of the two sets.
1414 */
1415 if ((PySet_GET_SIZE(other) >> 3) > PySet_GET_SIZE(so)) {
1416 other = set_intersection(so, other);
1417 if (other == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 return -1;
Raymond Hettinger88ea1662019-08-29 09:02:58 -07001419 } else {
1420 Py_INCREF(other);
1421 }
1422
1423 while (set_next((PySetObject *)other, &pos, &entry))
1424 if (set_discard_entry(so, entry->key, entry->hash) < 0) {
1425 Py_DECREF(other);
1426 return -1;
1427 }
1428
1429 Py_DECREF(other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 } else {
1431 PyObject *key, *it;
1432 it = PyObject_GetIter(other);
1433 if (it == NULL)
1434 return -1;
1435
1436 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001437 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 Py_DECREF(it);
1439 Py_DECREF(key);
1440 return -1;
1441 }
1442 Py_DECREF(key);
1443 }
1444 Py_DECREF(it);
1445 if (PyErr_Occurred())
1446 return -1;
1447 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001448 /* If more than 1/4th are dummies, then resize them away. */
1449 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +09001451 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001452}
1453
Raymond Hettingera690a992003-11-16 16:17:49 +00001454static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001455set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001456{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001458
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1460 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001461 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462 return NULL;
1463 }
1464 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001465}
1466
1467PyDoc_STRVAR(difference_update_doc,
1468"Remove all elements of another set from this set.");
1469
1470static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001471set_copy_and_difference(PySetObject *so, PyObject *other)
1472{
1473 PyObject *result;
1474
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301475 result = set_copy(so, NULL);
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001476 if (result == NULL)
1477 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001478 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001479 return result;
1480 Py_DECREF(result);
1481 return NULL;
1482}
1483
1484static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001485set_difference(PySetObject *so, PyObject *other)
1486{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001488 PyObject *key;
1489 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 setentry *entry;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001491 Py_ssize_t pos = 0, other_size;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001492 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001493
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001494 if (PyAnySet_Check(other)) {
1495 other_size = PySet_GET_SIZE(other);
1496 }
1497 else if (PyDict_CheckExact(other)) {
1498 other_size = PyDict_GET_SIZE(other);
1499 }
1500 else {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001501 return set_copy_and_difference(so, other);
1502 }
1503
1504 /* If len(so) much more than len(other), it's more efficient to simply copy
1505 * so and then iterate other looking for common elements. */
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001506 if ((PySet_GET_SIZE(so) >> 2) > other_size) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001507 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 result = make_new_set_basetype(Py_TYPE(so), NULL);
1511 if (result == NULL)
1512 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514 if (PyDict_CheckExact(other)) {
1515 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001516 key = entry->key;
1517 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001518 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001519 if (rv < 0) {
1520 Py_DECREF(result);
1521 return NULL;
1522 }
1523 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001524 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001525 Py_DECREF(result);
1526 return NULL;
1527 }
1528 }
1529 }
1530 return result;
1531 }
1532
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001533 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001534 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001535 key = entry->key;
1536 hash = entry->hash;
1537 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001538 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001539 Py_DECREF(result);
1540 return NULL;
1541 }
1542 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001543 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001544 Py_DECREF(result);
1545 return NULL;
1546 }
1547 }
1548 }
1549 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001550}
1551
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001552static PyObject *
1553set_difference_multi(PySetObject *so, PyObject *args)
1554{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001555 Py_ssize_t i;
1556 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301559 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 other = PyTuple_GET_ITEM(args, 0);
1562 result = set_difference(so, other);
1563 if (result == NULL)
1564 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1567 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001568 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001569 Py_DECREF(result);
1570 return NULL;
1571 }
1572 }
1573 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001574}
1575
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001576PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001577"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001578\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001579(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001580static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001581set_sub(PySetObject *so, PyObject *other)
1582{
Brian Curtindfc80e32011-08-10 20:28:54 -05001583 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1584 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001586}
1587
1588static PyObject *
1589set_isub(PySetObject *so, PyObject *other)
1590{
Brian Curtindfc80e32011-08-10 20:28:54 -05001591 if (!PyAnySet_Check(other))
1592 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001593 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 return NULL;
1595 Py_INCREF(so);
1596 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001597}
1598
1599static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001600set_symmetric_difference_update(PySetObject *so, PyObject *other)
1601{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001602 PySetObject *otherset;
1603 PyObject *key;
1604 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001605 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001607 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001608
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001609 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301610 return set_clear(so, NULL);
Raymond Hettingera690a992003-11-16 16:17:49 +00001611
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001612 if (PyDict_CheckExact(other)) {
1613 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001614 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001615 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001616 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001617 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001618 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001619 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001621 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001622 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001623 Py_DECREF(key);
1624 return NULL;
1625 }
1626 }
Georg Brandl2d444492010-09-03 10:52:55 +00001627 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628 }
1629 Py_RETURN_NONE;
1630 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 if (PyAnySet_Check(other)) {
1633 Py_INCREF(other);
1634 otherset = (PySetObject *)other;
1635 } else {
1636 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1637 if (otherset == NULL)
1638 return NULL;
1639 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001641 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001642 key = entry->key;
1643 hash = entry->hash;
1644 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001645 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001646 Py_DECREF(otherset);
1647 return NULL;
1648 }
1649 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001650 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 Py_DECREF(otherset);
1652 return NULL;
1653 }
1654 }
1655 }
1656 Py_DECREF(otherset);
1657 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001658}
1659
1660PyDoc_STRVAR(symmetric_difference_update_doc,
1661"Update a set with the symmetric difference of itself and another.");
1662
1663static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001664set_symmetric_difference(PySetObject *so, PyObject *other)
1665{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001666 PyObject *rv;
1667 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001668
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001669 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1670 if (otherset == NULL)
1671 return NULL;
1672 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
lekma491bbed2018-05-02 11:29:10 +02001673 if (rv == NULL) {
1674 Py_DECREF(otherset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001675 return NULL;
lekma491bbed2018-05-02 11:29:10 +02001676 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001677 Py_DECREF(rv);
1678 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001679}
1680
1681PyDoc_STRVAR(symmetric_difference_doc,
1682"Return the symmetric difference of two sets as a new set.\n\
1683\n\
1684(i.e. all elements that are in exactly one of the sets.)");
1685
1686static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001687set_xor(PySetObject *so, PyObject *other)
1688{
Brian Curtindfc80e32011-08-10 20:28:54 -05001689 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1690 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001691 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001692}
1693
1694static PyObject *
1695set_ixor(PySetObject *so, PyObject *other)
1696{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001697 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001698
Brian Curtindfc80e32011-08-10 20:28:54 -05001699 if (!PyAnySet_Check(other))
1700 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001701 result = set_symmetric_difference_update(so, other);
1702 if (result == NULL)
1703 return NULL;
1704 Py_DECREF(result);
1705 Py_INCREF(so);
1706 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001707}
1708
1709static PyObject *
1710set_issubset(PySetObject *so, PyObject *other)
1711{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001712 setentry *entry;
1713 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001714 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001715
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001716 if (!PyAnySet_Check(other)) {
1717 PyObject *tmp, *result;
1718 tmp = make_new_set(&PySet_Type, other);
1719 if (tmp == NULL)
1720 return NULL;
1721 result = set_issubset(so, tmp);
1722 Py_DECREF(tmp);
1723 return result;
1724 }
1725 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1726 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001727
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001729 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001730 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001731 return NULL;
1732 if (!rv)
1733 Py_RETURN_FALSE;
1734 }
1735 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001736}
1737
1738PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1739
1740static PyObject *
1741set_issuperset(PySetObject *so, PyObject *other)
1742{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001743 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001745 if (!PyAnySet_Check(other)) {
1746 tmp = make_new_set(&PySet_Type, other);
1747 if (tmp == NULL)
1748 return NULL;
1749 result = set_issuperset(so, tmp);
1750 Py_DECREF(tmp);
1751 return result;
1752 }
1753 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001754}
1755
1756PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1757
Raymond Hettingera690a992003-11-16 16:17:49 +00001758static PyObject *
1759set_richcompare(PySetObject *v, PyObject *w, int op)
1760{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001761 PyObject *r1;
1762 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001763
Brian Curtindfc80e32011-08-10 20:28:54 -05001764 if(!PyAnySet_Check(w))
1765 Py_RETURN_NOTIMPLEMENTED;
1766
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001767 switch (op) {
1768 case Py_EQ:
1769 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1770 Py_RETURN_FALSE;
1771 if (v->hash != -1 &&
1772 ((PySetObject *)w)->hash != -1 &&
1773 v->hash != ((PySetObject *)w)->hash)
1774 Py_RETURN_FALSE;
1775 return set_issubset(v, w);
1776 case Py_NE:
1777 r1 = set_richcompare(v, w, Py_EQ);
1778 if (r1 == NULL)
1779 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001780 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001781 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001782 if (r2 < 0)
1783 return NULL;
1784 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001785 case Py_LE:
1786 return set_issubset(v, w);
1787 case Py_GE:
1788 return set_issuperset(v, w);
1789 case Py_LT:
1790 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1791 Py_RETURN_FALSE;
1792 return set_issubset(v, w);
1793 case Py_GT:
1794 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1795 Py_RETURN_FALSE;
1796 return set_issuperset(v, w);
1797 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001798 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001799}
1800
Raymond Hettingera690a992003-11-16 16:17:49 +00001801static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001802set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001803{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001804 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001805 return NULL;
1806 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001807}
1808
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001809PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001810"Add an element to a set.\n\
1811\n\
1812This has no effect if the element is already present.");
1813
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001814static int
1815set_contains(PySetObject *so, PyObject *key)
1816{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001817 PyObject *tmpkey;
1818 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001819
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001820 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001821 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001822 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1823 return -1;
1824 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001825 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001826 if (tmpkey == NULL)
1827 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001828 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001829 Py_DECREF(tmpkey);
1830 }
1831 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001832}
1833
1834static PyObject *
1835set_direct_contains(PySetObject *so, PyObject *key)
1836{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001837 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001839 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001840 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001841 return NULL;
1842 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001843}
1844
1845PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1846
Raymond Hettingera690a992003-11-16 16:17:49 +00001847static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001848set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001849{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 PyObject *tmpkey;
1851 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001853 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001854 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1856 return NULL;
1857 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001858 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 if (tmpkey == NULL)
1860 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001862 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001863 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 return NULL;
1865 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001868 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001869 return NULL;
1870 }
1871 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001872}
1873
1874PyDoc_STRVAR(remove_doc,
1875"Remove an element from a set; it must be a member.\n\
1876\n\
1877If the element is not a member, raise a KeyError.");
1878
1879static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001880set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001881{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001882 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001883 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001886 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1888 return NULL;
1889 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001890 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 if (tmpkey == NULL)
1892 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001893 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001895 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001896 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 }
1898 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001899}
1900
1901PyDoc_STRVAR(discard_doc,
1902"Remove an element from a set if it is a member.\n\
1903\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001904If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001905
1906static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301907set_reduce(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001908{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001910 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001911
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001912 keys = PySequence_List((PyObject *)so);
1913 if (keys == NULL)
1914 goto done;
1915 args = PyTuple_Pack(1, keys);
1916 if (args == NULL)
1917 goto done;
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001918 if (_PyObject_LookupAttrId((PyObject *)so, &PyId___dict__, &dict) < 0) {
1919 goto done;
1920 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001921 if (dict == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 dict = Py_None;
1923 Py_INCREF(dict);
1924 }
1925 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001926done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927 Py_XDECREF(args);
1928 Py_XDECREF(keys);
1929 Py_XDECREF(dict);
1930 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001931}
1932
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001933static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301934set_sizeof(PySetObject *so, PyObject *Py_UNUSED(ignored))
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001935{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001937
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02001938 res = _PyObject_SIZE(Py_TYPE(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001939 if (so->table != so->smalltable)
1940 res = res + (so->mask + 1) * sizeof(setentry);
1941 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001942}
1943
1944PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001945static int
1946set_init(PySetObject *self, PyObject *args, PyObject *kwds)
1947{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001948 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001949
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001950 if (!_PyArg_NoKeywords("set", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 return -1;
1952 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
1953 return -1;
Raymond Hettingerb72e21b2016-03-25 02:29:59 -07001954 if (self->fill)
1955 set_clear_internal(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001956 self->hash = -1;
1957 if (iterable == NULL)
1958 return 0;
1959 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001960}
1961
Dong-hee Na6ff79f652020-03-17 02:17:38 +09001962static PyObject*
1963set_vectorcall(PyObject *type, PyObject * const*args,
1964 size_t nargsf, PyObject *kwnames)
1965{
1966 assert(PyType_Check(type));
1967
1968 if (!_PyArg_NoKwnames("set", kwnames)) {
1969 return NULL;
1970 }
1971
1972 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
1973 if (!_PyArg_CheckPositional("set", nargs, 0, 1)) {
1974 return NULL;
1975 }
1976
1977 if (nargs) {
1978 return make_new_set((PyTypeObject *)type, args[0]);
1979 }
1980
1981 return make_new_set((PyTypeObject *)type, NULL);
1982}
1983
Raymond Hettingera690a992003-11-16 16:17:49 +00001984static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001985 set_len, /* sq_length */
1986 0, /* sq_concat */
1987 0, /* sq_repeat */
1988 0, /* sq_item */
1989 0, /* sq_slice */
1990 0, /* sq_ass_item */
1991 0, /* sq_ass_slice */
1992 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00001993};
1994
1995/* set object ********************************************************/
1996
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00001997#ifdef Py_DEBUG
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301998static PyObject *test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored));
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00001999
2000PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2001All is well if assertions don't fail.");
2002#endif
2003
Raymond Hettingera690a992003-11-16 16:17:49 +00002004static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002005 {"add", (PyCFunction)set_add, METH_O,
2006 add_doc},
2007 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2008 clear_doc},
2009 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2010 contains_doc},
2011 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2012 copy_doc},
2013 {"discard", (PyCFunction)set_discard, METH_O,
2014 discard_doc},
2015 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2016 difference_doc},
2017 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2018 difference_update_doc},
2019 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2020 intersection_doc},
2021 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2022 intersection_update_doc},
2023 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2024 isdisjoint_doc},
2025 {"issubset", (PyCFunction)set_issubset, METH_O,
2026 issubset_doc},
2027 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2028 issuperset_doc},
2029 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2030 pop_doc},
2031 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2032 reduce_doc},
2033 {"remove", (PyCFunction)set_remove, METH_O,
2034 remove_doc},
2035 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2036 sizeof_doc},
2037 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2038 symmetric_difference_doc},
2039 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2040 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002041#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002042 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2043 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002044#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002045 {"union", (PyCFunction)set_union, METH_VARARGS,
2046 union_doc},
2047 {"update", (PyCFunction)set_update, METH_VARARGS,
2048 update_doc},
Guido van Rossum48b069a2020-04-07 09:50:06 -07002049 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002050 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002051};
2052
2053static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002054 0, /*nb_add*/
2055 (binaryfunc)set_sub, /*nb_subtract*/
2056 0, /*nb_multiply*/
2057 0, /*nb_remainder*/
2058 0, /*nb_divmod*/
2059 0, /*nb_power*/
2060 0, /*nb_negative*/
2061 0, /*nb_positive*/
2062 0, /*nb_absolute*/
2063 0, /*nb_bool*/
2064 0, /*nb_invert*/
2065 0, /*nb_lshift*/
2066 0, /*nb_rshift*/
2067 (binaryfunc)set_and, /*nb_and*/
2068 (binaryfunc)set_xor, /*nb_xor*/
2069 (binaryfunc)set_or, /*nb_or*/
2070 0, /*nb_int*/
2071 0, /*nb_reserved*/
2072 0, /*nb_float*/
2073 0, /*nb_inplace_add*/
2074 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2075 0, /*nb_inplace_multiply*/
2076 0, /*nb_inplace_remainder*/
2077 0, /*nb_inplace_power*/
2078 0, /*nb_inplace_lshift*/
2079 0, /*nb_inplace_rshift*/
2080 (binaryfunc)set_iand, /*nb_inplace_and*/
2081 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2082 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002083};
2084
2085PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002086"set() -> new empty set object\n\
2087set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002088\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002089Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002090
2091PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002092 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2093 "set", /* tp_name */
2094 sizeof(PySetObject), /* tp_basicsize */
2095 0, /* tp_itemsize */
2096 /* methods */
2097 (destructor)set_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002098 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 0, /* tp_getattr */
2100 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002101 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002102 (reprfunc)set_repr, /* tp_repr */
2103 &set_as_number, /* tp_as_number */
2104 &set_as_sequence, /* tp_as_sequence */
2105 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002106 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002107 0, /* tp_call */
2108 0, /* tp_str */
2109 PyObject_GenericGetAttr, /* tp_getattro */
2110 0, /* tp_setattro */
2111 0, /* tp_as_buffer */
2112 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2113 Py_TPFLAGS_BASETYPE, /* tp_flags */
2114 set_doc, /* tp_doc */
2115 (traverseproc)set_traverse, /* tp_traverse */
2116 (inquiry)set_clear_internal, /* tp_clear */
2117 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002118 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2119 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002120 0, /* tp_iternext */
2121 set_methods, /* tp_methods */
2122 0, /* tp_members */
2123 0, /* tp_getset */
2124 0, /* tp_base */
2125 0, /* tp_dict */
2126 0, /* tp_descr_get */
2127 0, /* tp_descr_set */
2128 0, /* tp_dictoffset */
2129 (initproc)set_init, /* tp_init */
2130 PyType_GenericAlloc, /* tp_alloc */
2131 set_new, /* tp_new */
2132 PyObject_GC_Del, /* tp_free */
Dong-hee Na6ff79f652020-03-17 02:17:38 +09002133 .tp_vectorcall = set_vectorcall,
Raymond Hettingera690a992003-11-16 16:17:49 +00002134};
2135
2136/* frozenset object ********************************************************/
2137
2138
2139static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002140 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2141 contains_doc},
2142 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2143 copy_doc},
2144 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2145 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002146 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002147 intersection_doc},
2148 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2149 isdisjoint_doc},
2150 {"issubset", (PyCFunction)set_issubset, METH_O,
2151 issubset_doc},
2152 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2153 issuperset_doc},
2154 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2155 reduce_doc},
2156 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2157 sizeof_doc},
2158 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2159 symmetric_difference_doc},
2160 {"union", (PyCFunction)set_union, METH_VARARGS,
2161 union_doc},
Guido van Rossum48b069a2020-04-07 09:50:06 -07002162 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002163 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002164};
2165
2166static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002167 0, /*nb_add*/
2168 (binaryfunc)set_sub, /*nb_subtract*/
2169 0, /*nb_multiply*/
2170 0, /*nb_remainder*/
2171 0, /*nb_divmod*/
2172 0, /*nb_power*/
2173 0, /*nb_negative*/
2174 0, /*nb_positive*/
2175 0, /*nb_absolute*/
2176 0, /*nb_bool*/
2177 0, /*nb_invert*/
2178 0, /*nb_lshift*/
2179 0, /*nb_rshift*/
2180 (binaryfunc)set_and, /*nb_and*/
2181 (binaryfunc)set_xor, /*nb_xor*/
2182 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002183};
2184
2185PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002186"frozenset() -> empty frozenset object\n\
2187frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002188\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002189Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002190
2191PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002192 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2193 "frozenset", /* tp_name */
2194 sizeof(PySetObject), /* tp_basicsize */
2195 0, /* tp_itemsize */
2196 /* methods */
2197 (destructor)set_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002198 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002199 0, /* tp_getattr */
2200 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002201 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002202 (reprfunc)set_repr, /* tp_repr */
2203 &frozenset_as_number, /* tp_as_number */
2204 &set_as_sequence, /* tp_as_sequence */
2205 0, /* tp_as_mapping */
2206 frozenset_hash, /* tp_hash */
2207 0, /* tp_call */
2208 0, /* tp_str */
2209 PyObject_GenericGetAttr, /* tp_getattro */
2210 0, /* tp_setattro */
2211 0, /* tp_as_buffer */
2212 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2213 Py_TPFLAGS_BASETYPE, /* tp_flags */
2214 frozenset_doc, /* tp_doc */
2215 (traverseproc)set_traverse, /* tp_traverse */
2216 (inquiry)set_clear_internal, /* tp_clear */
2217 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002218 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002219 (getiterfunc)set_iter, /* tp_iter */
2220 0, /* tp_iternext */
2221 frozenset_methods, /* tp_methods */
2222 0, /* tp_members */
2223 0, /* tp_getset */
2224 0, /* tp_base */
2225 0, /* tp_dict */
2226 0, /* tp_descr_get */
2227 0, /* tp_descr_set */
2228 0, /* tp_dictoffset */
2229 0, /* tp_init */
2230 PyType_GenericAlloc, /* tp_alloc */
2231 frozenset_new, /* tp_new */
2232 PyObject_GC_Del, /* tp_free */
Dong-hee Na1c605672020-03-19 02:30:50 +09002233 .tp_vectorcall = frozenset_vectorcall,
Raymond Hettingera690a992003-11-16 16:17:49 +00002234};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002235
2236
2237/***** C API functions *************************************************/
2238
2239PyObject *
2240PySet_New(PyObject *iterable)
2241{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002242 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002243}
2244
2245PyObject *
2246PyFrozenSet_New(PyObject *iterable)
2247{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002248 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002249}
2250
Neal Norwitz8c49c822006-03-04 18:41:19 +00002251Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002252PySet_Size(PyObject *anyset)
2253{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002254 if (!PyAnySet_Check(anyset)) {
2255 PyErr_BadInternalCall();
2256 return -1;
2257 }
2258 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002259}
2260
2261int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002262PySet_Clear(PyObject *set)
2263{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002264 if (!PySet_Check(set)) {
2265 PyErr_BadInternalCall();
2266 return -1;
2267 }
2268 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002269}
2270
2271int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002272PySet_Contains(PyObject *anyset, PyObject *key)
2273{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002274 if (!PyAnySet_Check(anyset)) {
2275 PyErr_BadInternalCall();
2276 return -1;
2277 }
2278 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002279}
2280
2281int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002282PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002283{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002284 if (!PySet_Check(set)) {
2285 PyErr_BadInternalCall();
2286 return -1;
2287 }
2288 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002289}
2290
2291int
Christian Heimesfd66e512008-01-29 12:18:50 +00002292PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002293{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002294 if (!PySet_Check(anyset) &&
2295 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2296 PyErr_BadInternalCall();
2297 return -1;
2298 }
2299 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002300}
2301
Raymond Hettinger3625af52016-03-27 01:15:07 -07002302void
Victor Stinnerbed48172019-08-27 00:12:32 +02002303_PySet_Fini(void)
Raymond Hettinger3625af52016-03-27 01:15:07 -07002304{
2305 Py_CLEAR(emptyfrozenset);
2306}
2307
2308int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002309_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002310{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002311 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002313 if (!PyAnySet_Check(set)) {
2314 PyErr_BadInternalCall();
2315 return -1;
2316 }
2317 if (set_next((PySetObject *)set, pos, &entry) == 0)
2318 return 0;
2319 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002320 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002321 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002322}
2323
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002324PyObject *
2325PySet_Pop(PyObject *set)
2326{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002327 if (!PySet_Check(set)) {
2328 PyErr_BadInternalCall();
2329 return NULL;
2330 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302331 return set_pop((PySetObject *)set, NULL);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002332}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002333
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002334int
2335_PySet_Update(PyObject *set, PyObject *iterable)
2336{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002337 if (!PySet_Check(set)) {
2338 PyErr_BadInternalCall();
2339 return -1;
2340 }
2341 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002342}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002343
Raymond Hettingere259f132013-12-15 11:56:14 -08002344/* Exported for the gdb plugin's benefit. */
2345PyObject *_PySet_Dummy = dummy;
2346
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002347#ifdef Py_DEBUG
2348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002349/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002350 Returns True and original set is restored. */
2351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002352#define assertRaises(call_return_value, exception) \
2353 do { \
2354 assert(call_return_value); \
2355 assert(PyErr_ExceptionMatches(exception)); \
2356 PyErr_Clear(); \
2357 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002358
2359static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302360test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002362 Py_ssize_t count;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +02002363 const char *s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002364 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002365 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002366 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002367 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002368 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002370 /* Verify preconditions */
2371 assert(PyAnySet_Check(ob));
2372 assert(PyAnySet_CheckExact(ob));
2373 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002375 /* so.clear(); so |= set("abc"); */
2376 str = PyUnicode_FromString("abc");
2377 if (str == NULL)
2378 return NULL;
2379 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002380 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002381 Py_DECREF(str);
2382 return NULL;
2383 }
2384 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002386 /* Exercise type/size checks */
2387 assert(PySet_Size(ob) == 3);
2388 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002390 /* Raise TypeError for non-iterable constructor arguments */
2391 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2392 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002394 /* Raise TypeError for unhashable key */
2395 dup = PySet_New(ob);
2396 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2397 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2398 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002400 /* Exercise successful pop, contains, add, and discard */
2401 elem = PySet_Pop(ob);
2402 assert(PySet_Contains(ob, elem) == 0);
2403 assert(PySet_GET_SIZE(ob) == 2);
2404 assert(PySet_Add(ob, elem) == 0);
2405 assert(PySet_Contains(ob, elem) == 1);
2406 assert(PySet_GET_SIZE(ob) == 3);
2407 assert(PySet_Discard(ob, elem) == 1);
2408 assert(PySet_GET_SIZE(ob) == 2);
2409 assert(PySet_Discard(ob, elem) == 0);
2410 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002412 /* Exercise clear */
2413 dup2 = PySet_New(dup);
2414 assert(PySet_Clear(dup2) == 0);
2415 assert(PySet_Size(dup2) == 0);
2416 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002418 /* Raise SystemError on clear or update of frozen set */
2419 f = PyFrozenSet_New(dup);
2420 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2421 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2422 assert(PySet_Add(f, elem) == 0);
2423 Py_INCREF(f);
2424 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2425 Py_DECREF(f);
2426 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002428 /* Exercise direct iteration */
2429 i = 0, count = 0;
2430 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
Serhiy Storchaka06515832016-11-20 09:13:07 +02002431 s = PyUnicode_AsUTF8(x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002432 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2433 count++;
2434 }
2435 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002437 /* Exercise updates */
2438 dup2 = PySet_New(NULL);
2439 assert(_PySet_Update(dup2, dup) == 0);
2440 assert(PySet_Size(dup2) == 3);
2441 assert(_PySet_Update(dup2, dup) == 0);
2442 assert(PySet_Size(dup2) == 3);
2443 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002444
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002445 /* Raise SystemError when self argument is not a set or frozenset. */
2446 t = PyTuple_New(0);
2447 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2448 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2449 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002450
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002451 /* Raise SystemError when self argument is not a set. */
2452 f = PyFrozenSet_New(dup);
2453 assert(PySet_Size(f) == 3);
2454 assert(PyFrozenSet_CheckExact(f));
2455 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2456 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2457 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002458
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002459 /* Raise KeyError when popping from an empty set */
2460 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2461 Py_DECREF(ob);
2462 assert(PySet_GET_SIZE(ob) == 0);
2463 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002465 /* Restore the set from the copy using the PyNumber API */
2466 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2467 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002469 /* Verify constructors accept NULL arguments */
2470 f = PySet_New(NULL);
2471 assert(f != NULL);
2472 assert(PySet_GET_SIZE(f) == 0);
2473 Py_DECREF(f);
2474 f = PyFrozenSet_New(NULL);
2475 assert(f != NULL);
2476 assert(PyFrozenSet_CheckExact(f));
2477 assert(PySet_GET_SIZE(f) == 0);
2478 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002480 Py_DECREF(elem);
2481 Py_DECREF(dup);
2482 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002483}
2484
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002485#undef assertRaises
2486
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002487#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002488
2489/***** Dummy Struct *************************************************/
2490
2491static PyObject *
2492dummy_repr(PyObject *op)
2493{
2494 return PyUnicode_FromString("<dummy key>");
2495}
2496
Victor Stinner2a4903f2020-01-30 13:09:11 +01002497static void _Py_NO_RETURN
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002498dummy_dealloc(PyObject* ignore)
2499{
2500 Py_FatalError("deallocating <dummy key>");
2501}
2502
2503static PyTypeObject _PySetDummy_Type = {
2504 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2505 "<dummy key> type",
2506 0,
2507 0,
2508 dummy_dealloc, /*tp_dealloc*/ /*never called*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002509 0, /*tp_vectorcall_offset*/
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002510 0, /*tp_getattr*/
2511 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002512 0, /*tp_as_async*/
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002513 dummy_repr, /*tp_repr*/
2514 0, /*tp_as_number*/
2515 0, /*tp_as_sequence*/
2516 0, /*tp_as_mapping*/
2517 0, /*tp_hash */
2518 0, /*tp_call */
2519 0, /*tp_str */
2520 0, /*tp_getattro */
2521 0, /*tp_setattro */
2522 0, /*tp_as_buffer */
2523 Py_TPFLAGS_DEFAULT, /*tp_flags */
2524};
2525
2526static PyObject _dummy_struct = {
2527 _PyObject_EXTRA_INIT
2528 2, &_PySetDummy_Type
2529};
2530