blob: e8ba32e5781a8667ff8f4ba269cb7bc124682c5f [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
Miss Islington (bot)5ba61f42021-10-02 12:33:49 -070019 linear congruential random number generator. This helps break-up long
Raymond Hettinger64263df2017-09-04 18:54:16 -070020 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 Hettinger72789592021-03-24 15:33:27 -0700106 setentry *freeslot;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700107 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700108 size_t perturb;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400109 size_t mask;
110 size_t i; /* Unsigned for defined overflow behavior */
Raymond Hettinger2cc9b842020-05-10 14:53:29 -0700111 int probes;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700112 int cmp;
113
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400114 /* Pre-increment is necessary to prevent arbitrary code in the rich
115 comparison from deallocating the key just before the insertion. */
116 Py_INCREF(key);
117
118 restart:
119
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400120 mask = so->mask;
121 i = (size_t)hash & mask;
Raymond Hettinger72789592021-03-24 15:33:27 -0700122 freeslot = NULL;
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700123 perturb = hash;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700124
125 while (1) {
Raymond Hettinger2cc9b842020-05-10 14:53:29 -0700126 entry = &so->table[i];
127 probes = (i + LINEAR_PROBES <= mask) ? LINEAR_PROBES: 0;
128 do {
129 if (entry->hash == 0 && entry->key == NULL)
Raymond Hettinger72789592021-03-24 15:33:27 -0700130 goto found_unused_or_dummy;
Raymond Hettinger2cc9b842020-05-10 14:53:29 -0700131 if (entry->hash == hash) {
132 PyObject *startkey = entry->key;
133 assert(startkey != dummy);
134 if (startkey == key)
135 goto found_active;
136 if (PyUnicode_CheckExact(startkey)
137 && PyUnicode_CheckExact(key)
138 && _PyUnicode_EQ(startkey, key))
139 goto found_active;
140 table = so->table;
141 Py_INCREF(startkey);
142 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
143 Py_DECREF(startkey);
144 if (cmp > 0)
145 goto found_active;
146 if (cmp < 0)
147 goto comparison_error;
148 if (table != so->table || entry->key != startkey)
149 goto restart;
150 mask = so->mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700151 }
Raymond Hettinger72789592021-03-24 15:33:27 -0700152 else if (entry->hash == -1) {
153 assert (entry->key == dummy);
154 freeslot = entry;
155 }
Raymond Hettinger2cc9b842020-05-10 14:53:29 -0700156 entry++;
157 } while (probes--);
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700158 perturb >>= PERTURB_SHIFT;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -0800159 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000160 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700161
Raymond Hettinger72789592021-03-24 15:33:27 -0700162 found_unused_or_dummy:
163 if (freeslot == NULL)
164 goto found_unused;
165 so->used++;
166 freeslot->key = key;
167 freeslot->hash = hash;
168 return 0;
169
Raymond Hettinger15f08692015-07-03 17:21:17 -0700170 found_unused:
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700171 so->fill++;
172 so->used++;
173 entry->key = key;
174 entry->hash = hash;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800175 if ((size_t)so->fill*5 < mask*3)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700176 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +0900177 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700178
179 found_active:
Raymond Hettinger482c05c2015-07-20 01:23:32 -0400180 Py_DECREF(key);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700181 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000182
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400183 comparison_error:
Raymond Hettinger061091a2015-07-15 23:54:02 -0700184 Py_DECREF(key);
185 return -1;
186}
187
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000188/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000189Internal routine used by set_table_resize() to insert an item which is
Raymond Hettingerd699d5e2020-05-03 11:25:46 -0700190known to be absent from the set. Besides the performance benefit,
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800191there is also safety benefit since using set_add_entry() risks making
192a callback in the middle of a set_table_resize(), see issue 1456209.
193The caller is responsible for updating the key's reference count and
194the setobject's fill and used fields.
Thomas Wouters89f507f2006-12-13 04:49:30 +0000195*/
196static void
Raymond Hettinger5088f602015-12-13 18:45:01 -0800197set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000198{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200199 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700200 size_t perturb = hash;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800201 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700202 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000203
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700204 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800205 entry = &table[i];
206 if (entry->key == NULL)
207 goto found_null;
208 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800209 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800210 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800211 if (entry->key == NULL)
212 goto found_null;
213 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700214 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700215 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800216 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000217 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700218 found_null:
Raymond Hettinger5088f602015-12-13 18:45:01 -0800219 entry->key = key;
Raymond Hettinger86d322f2015-12-13 19:27:17 -0800220 entry->hash = hash;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000221}
222
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700223/* ======== End logic for probing the hash table ========================== */
224/* ======================================================================== */
225
Thomas Wouters89f507f2006-12-13 04:49:30 +0000226/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000227Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000228keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000229actually be smaller than the old one.
230*/
231static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000232set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000233{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 setentry *oldtable, *newtable, *entry;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800235 Py_ssize_t oldmask = so->mask;
236 size_t newmask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237 int is_oldtable_malloced;
238 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000240 assert(minused >= 0);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100243 /* XXX speed-up with intrinsics */
Sergey Fedoseev6c7d67c2018-09-12 04:18:01 +0500244 size_t newsize = PySet_MINSIZE;
245 while (newsize <= (size_t)minused) {
246 newsize <<= 1; // The largest possible value is PY_SSIZE_T_MAX + 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000247 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000249 /* Get space for a new table. */
250 oldtable = so->table;
251 assert(oldtable != NULL);
252 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000254 if (newsize == PySet_MINSIZE) {
255 /* A large table is shrinking, or we can't get any smaller. */
256 newtable = so->smalltable;
257 if (newtable == oldtable) {
258 if (so->fill == so->used) {
259 /* No dummies, so no point doing anything. */
260 return 0;
261 }
262 /* We're not going to resize it, but rebuild the
263 table anyway to purge old dummy entries.
264 Subtle: This is *necessary* if fill==size,
265 as set_lookkey needs at least one virgin slot to
266 terminate failing searches. If fill < size, it's
267 merely desirable, as dummies slow searches. */
268 assert(so->fill > so->used);
269 memcpy(small_copy, oldtable, sizeof(small_copy));
270 oldtable = small_copy;
271 }
272 }
273 else {
274 newtable = PyMem_NEW(setentry, newsize);
275 if (newtable == NULL) {
276 PyErr_NoMemory();
277 return -1;
278 }
279 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 /* Make the set empty, using the new table. */
282 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 memset(newtable, 0, sizeof(setentry) * newsize);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800284 so->mask = newsize - 1;
285 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 /* Copy the data over; this is refcount-neutral for active entries;
288 dummy entries aren't copied over, of course */
Raymond Hettinger5088f602015-12-13 18:45:01 -0800289 newmask = (size_t)so->mask;
Raymond Hettingere1af6962017-02-02 08:24:48 -0800290 if (so->fill == so->used) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800291 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800292 if (entry->key != NULL) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800293 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800294 }
295 }
296 } else {
Raymond Hettingere1af6962017-02-02 08:24:48 -0800297 so->fill = so->used;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800298 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800299 if (entry->key != NULL && entry->key != dummy) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800300 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800301 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302 }
303 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 if (is_oldtable_malloced)
Victor Stinner00d7abd2020-12-01 09:56:42 +0100306 PyMem_Free(oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000308}
309
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000310static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700311set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000312{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700313 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000314
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700315 entry = set_lookkey(so, key, hash);
316 if (entry != NULL)
317 return entry->key != NULL;
318 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000319}
320
321#define DISCARD_NOTFOUND 0
322#define DISCARD_FOUND 1
323
324static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700325set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800326{
327 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000328 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000329
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700330 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331 if (entry == NULL)
332 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700333 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 return DISCARD_NOTFOUND;
335 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800337 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000338 so->used--;
339 Py_DECREF(old_key);
340 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000341}
342
343static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700344set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000345{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200346 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000347
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700348 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_add_entry(so, key, hash);
355}
356
357static int
358set_contains_key(PySetObject *so, PyObject *key)
359{
360 Py_hash_t hash;
361
362 if (!PyUnicode_CheckExact(key) ||
363 (hash = ((PyASCIIObject *) key)->hash) == -1) {
364 hash = PyObject_Hash(key);
365 if (hash == -1)
366 return -1;
367 }
368 return set_contains_entry(so, key, hash);
369}
370
371static int
372set_discard_key(PySetObject *so, PyObject *key)
373{
374 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200377 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 hash = PyObject_Hash(key);
379 if (hash == -1)
380 return -1;
381 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700382 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000383}
384
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700385static void
386set_empty_to_minsize(PySetObject *so)
387{
388 memset(so->smalltable, 0, sizeof(so->smalltable));
389 so->fill = 0;
390 so->used = 0;
391 so->mask = PySet_MINSIZE - 1;
392 so->table = so->smalltable;
393 so->hash = -1;
394}
395
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000396static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000397set_clear_internal(PySetObject *so)
398{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800399 setentry *entry;
400 setentry *table = so->table;
401 Py_ssize_t fill = so->fill;
402 Py_ssize_t used = so->used;
403 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000405
Raymond Hettinger583cd032013-09-07 22:06:35 -0700406 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 /* This is delicate. During the process of clearing the set,
410 * decrefs can cause the set to mutate. To avoid fatal confusion
411 * (voice of experience), we have to make the set empty before
412 * clearing the slots, and never refer to anything via so->ref while
413 * clearing.
414 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000415 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700416 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000418 else if (fill > 0) {
419 /* It's a small table with something that needs to be cleared.
420 * Afraid the only safe way is to copy the set entries into
421 * another small table first.
422 */
423 memcpy(small_copy, table, sizeof(small_copy));
424 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700425 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 }
427 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 /* Now we can finally clear things. If C had refcounts, we could
430 * assert that the refcount on table is 1 now, i.e. that this function
431 * has unique access to it, so decref side-effects can't alter it.
432 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800433 for (entry = table; used > 0; entry++) {
434 if (entry->key && entry->key != dummy) {
435 used--;
436 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000437 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000438 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000440 if (table_is_malloced)
Victor Stinner00d7abd2020-12-01 09:56:42 +0100441 PyMem_Free(table);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000443}
444
445/*
446 * Iterate over a set table. Use like so:
447 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000448 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000449 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000450 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000451 * while (set_next(yourset, &pos, &entry)) {
452 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000453 * }
454 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000455 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000457 */
458static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000459set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000460{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000461 Py_ssize_t i;
462 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700463 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000465 assert (PyAnySet_Check(so));
466 i = *pos_ptr;
467 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000468 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700469 entry = &so->table[i];
470 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700472 entry++;
473 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 *pos_ptr = i+1;
475 if (i > mask)
476 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700477 assert(entry != NULL);
478 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000480}
481
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000482static void
483set_dealloc(PySetObject *so)
484{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200485 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800486 Py_ssize_t used = so->used;
487
INADA Naokia6296d32017-08-24 14:55:17 +0900488 /* bpo-31095: UnTrack is needed before calling any callbacks */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 PyObject_GC_UnTrack(so);
Jeroen Demeyer351c6742019-05-10 19:21:11 +0200490 Py_TRASHCAN_BEGIN(so, set_dealloc)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000491 if (so->weakreflist != NULL)
492 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000493
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800494 for (entry = so->table; used > 0; entry++) {
495 if (entry->key && entry->key != dummy) {
496 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700497 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 }
499 }
500 if (so->table != so->smalltable)
Victor Stinner00d7abd2020-12-01 09:56:42 +0100501 PyMem_Free(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700502 Py_TYPE(so)->tp_free(so);
Jeroen Demeyer351c6742019-05-10 19:21:11 +0200503 Py_TRASHCAN_END
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000504}
505
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000506static PyObject *
507set_repr(PySetObject *so)
508{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200509 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 if (status != 0) {
513 if (status < 0)
514 return NULL;
515 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
516 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000517
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000518 /* shortcut for the empty set */
519 if (!so->used) {
520 Py_ReprLeave((PyObject*)so);
521 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
522 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 keys = PySequence_List((PyObject *)so);
525 if (keys == NULL)
526 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000527
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200528 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000529 listrepr = PyObject_Repr(keys);
530 Py_DECREF(keys);
531 if (listrepr == NULL)
532 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200533 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200535 if (tmp == NULL)
536 goto done;
537 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200538
Pablo Galindod439fb32021-02-20 18:03:08 +0000539 if (!PySet_CheckExact(so))
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200540 result = PyUnicode_FromFormat("%s({%U})",
541 Py_TYPE(so)->tp_name,
542 listrepr);
543 else
544 result = PyUnicode_FromFormat("{%U}", listrepr);
545 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000546done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 Py_ReprLeave((PyObject*)so);
548 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000549}
550
Martin v. Löwis18e16552006-02-15 17:27:45 +0000551static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000552set_len(PyObject *so)
553{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000554 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000555}
556
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000557static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000558set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000559{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000560 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000561 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200562 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700563 setentry *so_entry;
564 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 assert (PyAnySet_Check(so));
567 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000568
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 other = (PySetObject*)otherset;
570 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700571 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000572 return 0;
573 /* Do one big resize at the start, rather than
574 * incrementally resizing as we insert new keys. Expect
575 * that there will be no (or few) overlapping keys.
576 */
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800577 if ((so->fill + other->used)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900578 if (set_table_resize(so, (so->used + other->used)*2) != 0)
579 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000580 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700581 so_entry = so->table;
582 other_entry = other->table;
583
584 /* If our table is empty, and both tables have the same size, and
585 there are no dummies to eliminate, then just copy the pointers. */
586 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
587 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
588 key = other_entry->key;
589 if (key != NULL) {
590 assert(so_entry->key == NULL);
591 Py_INCREF(key);
592 so_entry->key = key;
593 so_entry->hash = other_entry->hash;
594 }
595 }
596 so->fill = other->fill;
597 so->used = other->used;
598 return 0;
599 }
600
601 /* If our table is empty, we can use set_insert_clean() */
602 if (so->fill == 0) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800603 setentry *newtable = so->table;
604 size_t newmask = (size_t)so->mask;
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800605 so->fill = other->used;
606 so->used = other->used;
Raymond Hettingere4495872015-12-15 00:42:30 -0800607 for (i = other->mask + 1; i > 0 ; i--, other_entry++) {
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700608 key = other_entry->key;
609 if (key != NULL && key != dummy) {
610 Py_INCREF(key);
Raymond Hettinger5088f602015-12-13 18:45:01 -0800611 set_insert_clean(newtable, newmask, key, other_entry->hash);
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700612 }
613 }
614 return 0;
615 }
616
617 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700618 for (i = 0; i <= other->mask; i++) {
619 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700620 key = other_entry->key;
621 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700622 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 }
625 }
626 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000627}
628
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000629static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530630set_pop(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000631{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800632 /* Make sure the search finger is in bounds */
Raymond Hettingerf9ec1b92018-11-11 14:35:47 -0800633 setentry *entry = so->table + (so->finger & so->mask);
634 setentry *limit = so->table + so->mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 if (so->used == 0) {
638 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
639 return NULL;
640 }
Raymond Hettingercf5863f2018-11-09 02:31:56 -0800641 while (entry->key == NULL || entry->key==dummy) {
642 entry++;
643 if (entry > limit)
644 entry = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000645 }
646 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000647 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800648 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000649 so->used--;
Raymond Hettingercf5863f2018-11-09 02:31:56 -0800650 so->finger = entry - so->table + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000651 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000652}
653
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000654PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
655Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000656
657static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000658set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000659{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 Py_ssize_t pos = 0;
661 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000662
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000663 while (set_next(so, &pos, &entry))
664 Py_VISIT(entry->key);
665 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000666}
667
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700668/* Work to increase the bit dispersion for closely spaced hash values.
669 This is important because some use cases have many combinations of a
670 small number of elements with nearby hashes so that many distinct
671 combinations collapse to only a handful of distinct hash values. */
672
673static Py_uhash_t
674_shuffle_bits(Py_uhash_t h)
675{
676 return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
677}
678
679/* Most of the constants in this hash algorithm are randomly chosen
680 large primes with "interesting bit patterns" and that passed tests
681 for good collision statistics on a variety of problematic datasets
682 including powersets and graph structures (such as David Eppstein's
683 graph recipes in Lib/test/test_set.py) */
684
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000685static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000686frozenset_hash(PyObject *self)
687{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000688 PySetObject *so = (PySetObject *)self;
Raymond Hettinger41481952015-08-07 00:43:39 -0700689 Py_uhash_t hash = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000690 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000691
Raymond Hettingerb501a272015-08-06 22:15:22 -0700692 if (so->hash != -1)
693 return so->hash;
694
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700695 /* Xor-in shuffled bits from every entry's hash field because xor is
696 commutative and a frozenset hash should be independent of order.
697
698 For speed, include null entries and dummy entries and then
699 subtract out their effect afterwards so that the final hash
700 depends only on active entries. This allows the code to be
701 vectorized by the compiler and it saves the unpredictable
702 branches that would arise when trying to exclude null and dummy
703 entries on every iteration. */
704
705 for (entry = so->table; entry <= &so->table[so->mask]; entry++)
706 hash ^= _shuffle_bits(entry->hash);
707
Raymond Hettingera286a512015-08-01 11:07:11 -0700708 /* Remove the effect of an odd number of NULL entries */
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700709 if ((so->mask + 1 - so->fill) & 1)
710 hash ^= _shuffle_bits(0);
711
712 /* Remove the effect of an odd number of dummy entries */
713 if ((so->fill - so->used) & 1)
714 hash ^= _shuffle_bits(-1);
715
Raymond Hettinger41481952015-08-07 00:43:39 -0700716 /* Factor in the number of active entries */
717 hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;
718
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700719 /* Disperse patterns arising in nested frozensets */
Raymond Hettingerfa788062018-01-18 13:23:27 -0800720 hash ^= (hash >> 11) ^ (hash >> 25);
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800721 hash = hash * 69069U + 907133923UL;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700722
Raymond Hettinger36c05002015-08-01 10:57:42 -0700723 /* -1 is reserved as an error code */
Victor Stinner12174a52014-08-15 23:17:38 +0200724 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800725 hash = 590923713UL;
Raymond Hettinger36c05002015-08-01 10:57:42 -0700726
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000727 so->hash = hash;
728 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000729}
730
Raymond Hettingera9d99362005-08-05 00:01:15 +0000731/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000732
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000733typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 PyObject_HEAD
735 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
736 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700737 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000739} setiterobject;
740
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000741static void
742setiter_dealloc(setiterobject *si)
743{
INADA Naokia6296d32017-08-24 14:55:17 +0900744 /* bpo-31095: UnTrack is needed before calling any callbacks */
745 _PyObject_GC_UNTRACK(si);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 Py_XDECREF(si->si_set);
747 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000748}
749
750static int
751setiter_traverse(setiterobject *si, visitproc visit, void *arg)
752{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000753 Py_VISIT(si->si_set);
754 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000755}
756
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000757static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530758setiter_len(setiterobject *si, PyObject *Py_UNUSED(ignored))
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000759{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000760 Py_ssize_t len = 0;
761 if (si->si_set != NULL && si->si_used == si->si_set->used)
762 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000763 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000764}
765
Armin Rigof5b3e362006-02-11 21:32:43 +0000766PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000767
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000768static PyObject *setiter_iternext(setiterobject *si);
769
770static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530771setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000772{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200773 _Py_IDENTIFIER(iter);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300774 /* copy the iterator state */
Sergey Fedoseev63958442018-10-20 05:43:33 +0500775 setiterobject tmp = *si;
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000776 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300777
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000778 /* iterate the temporary into a list */
Sergey Fedoseev63958442018-10-20 05:43:33 +0500779 PyObject *list = PySequence_List((PyObject*)&tmp);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000780 Py_XDECREF(tmp.si_set);
Sergey Fedoseev63958442018-10-20 05:43:33 +0500781 if (list == NULL) {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000782 return NULL;
783 }
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200784 return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000785}
786
787PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
788
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000789static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000790 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000791 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000792 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000793};
794
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000795static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000796{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700797 PyObject *key;
798 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200799 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000802 if (so == NULL)
803 return NULL;
804 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000805
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000806 if (si->si_used != so->used) {
807 PyErr_SetString(PyExc_RuntimeError,
808 "Set changed size during iteration");
809 si->si_used = -1; /* Make this state sticky */
810 return NULL;
811 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700812
813 i = si->si_pos;
814 assert(i>=0);
815 entry = so->table;
816 mask = so->mask;
817 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
818 i++;
819 si->si_pos = i+1;
820 if (i > mask)
821 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000822 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700823 key = entry[i].key;
824 Py_INCREF(key);
825 return key;
826
827fail:
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700828 si->si_set = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +0300829 Py_DECREF(so);
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700830 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000831}
832
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000833PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000834 PyVarObject_HEAD_INIT(&PyType_Type, 0)
835 "set_iterator", /* tp_name */
836 sizeof(setiterobject), /* tp_basicsize */
837 0, /* tp_itemsize */
838 /* methods */
839 (destructor)setiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200840 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 0, /* tp_getattr */
842 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200843 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000844 0, /* tp_repr */
845 0, /* tp_as_number */
846 0, /* tp_as_sequence */
847 0, /* tp_as_mapping */
848 0, /* tp_hash */
849 0, /* tp_call */
850 0, /* tp_str */
851 PyObject_GenericGetAttr, /* tp_getattro */
852 0, /* tp_setattro */
853 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700854 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000855 0, /* tp_doc */
856 (traverseproc)setiter_traverse, /* tp_traverse */
857 0, /* tp_clear */
858 0, /* tp_richcompare */
859 0, /* tp_weaklistoffset */
860 PyObject_SelfIter, /* tp_iter */
861 (iternextfunc)setiter_iternext, /* tp_iternext */
862 setiter_methods, /* tp_methods */
863 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000864};
865
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000866static PyObject *
867set_iter(PySetObject *so)
868{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000869 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
870 if (si == NULL)
871 return NULL;
872 Py_INCREF(so);
873 si->si_set = so;
874 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700875 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000876 si->len = so->used;
877 _PyObject_GC_TRACK(si);
878 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000879}
880
Raymond Hettingerd7946662005-08-01 21:39:29 +0000881static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000882set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000883{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000884 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 if (PyAnySet_Check(other))
887 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 if (PyDict_CheckExact(other)) {
890 PyObject *value;
891 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000892 Py_hash_t hash;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200893 Py_ssize_t dictsize = PyDict_GET_SIZE(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000895 /* Do one big resize at the start, rather than
896 * incrementally resizing as we insert new keys. Expect
897 * that there will be no (or few) overlapping keys.
898 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700899 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000900 return -1;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800901 if ((so->fill + dictsize)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900902 if (set_table_resize(so, (so->used + dictsize)*2) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000903 return -1;
904 }
905 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700906 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000907 return -1;
908 }
909 return 0;
910 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000911
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000912 it = PyObject_GetIter(other);
913 if (it == NULL)
914 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +0000915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700917 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000918 Py_DECREF(it);
919 Py_DECREF(key);
920 return -1;
921 }
922 Py_DECREF(key);
923 }
924 Py_DECREF(it);
925 if (PyErr_Occurred())
926 return -1;
927 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000928}
929
930static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000931set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +0000932{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000933 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000934
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000935 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
936 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700937 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000938 return NULL;
939 }
940 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +0000941}
942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000943PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000944"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +0000945
Raymond Hettinger426d9952014-05-18 21:40:20 +0100946/* XXX Todo:
947 If aligned memory allocations become available, make the
948 set object 64 byte aligned so that most of the fields
949 can be retrieved or updated in a single cache line.
950*/
951
Raymond Hettingera38123e2003-11-24 22:18:49 +0000952static PyObject *
953make_new_set(PyTypeObject *type, PyObject *iterable)
954{
Dong-hee Na1c605672020-03-19 02:30:50 +0900955 assert(PyType_Check(type));
Raymond Hettinger8421d712016-04-29 01:37:05 -0700956 PySetObject *so;
Raymond Hettingera38123e2003-11-24 22:18:49 +0000957
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700958 so = (PySetObject *)type->tp_alloc(type, 0);
959 if (so == NULL)
960 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000961
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700962 so->fill = 0;
963 so->used = 0;
964 so->mask = PySet_MINSIZE - 1;
965 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700966 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -0800967 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000968 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +0000969
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000970 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700971 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000972 Py_DECREF(so);
973 return NULL;
974 }
975 }
Raymond Hettingera38123e2003-11-24 22:18:49 +0000976
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +0000978}
979
Raymond Hettinger7d99f092008-11-16 11:44:54 +0000980static PyObject *
981make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
982{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
984 if (PyType_IsSubtype(type, &PySet_Type))
985 type = &PySet_Type;
986 else
987 type = &PyFrozenSet_Type;
988 }
989 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +0000990}
991
Raymond Hettingera690a992003-11-16 16:17:49 +0000992static PyObject *
Dong-hee Na1c605672020-03-19 02:30:50 +0900993make_new_frozenset(PyTypeObject *type, PyObject *iterable)
Raymond Hettingera690a992003-11-16 16:17:49 +0000994{
Dong-hee Na1c605672020-03-19 02:30:50 +0900995 if (type != &PyFrozenSet_Type) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000996 return make_new_set(type, iterable);
Dong-hee Na1c605672020-03-19 02:30:50 +0900997 }
Raymond Hettingerd7946662005-08-01 21:39:29 +0000998
Raymond Hettingerf9bd05e2020-06-23 08:42:55 -0700999 if (iterable != NULL && PyFrozenSet_CheckExact(iterable)) {
1000 /* frozenset(f) is idempotent */
1001 Py_INCREF(iterable);
1002 return iterable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 }
Raymond Hettingerf9bd05e2020-06-23 08:42:55 -07001004 return make_new_set((PyTypeObject *)type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001005}
1006
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001007static PyObject *
Dong-hee Na1c605672020-03-19 02:30:50 +09001008frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1009{
1010 PyObject *iterable = NULL;
1011
1012 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset", kwds)) {
1013 return NULL;
1014 }
1015
1016 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable)) {
1017 return NULL;
1018 }
1019
1020 return make_new_frozenset(type, iterable);
1021}
1022
1023static PyObject *
1024frozenset_vectorcall(PyObject *type, PyObject * const*args,
1025 size_t nargsf, PyObject *kwnames)
1026{
1027 if (!_PyArg_NoKwnames("frozenset", kwnames)) {
1028 return NULL;
1029 }
1030
1031 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
1032 if (!_PyArg_CheckPositional("frozenset", nargs, 0, 1)) {
1033 return NULL;
1034 }
1035
1036 PyObject *iterable = (nargs ? args[0] : NULL);
1037 return make_new_frozenset((PyTypeObject *)type, iterable);
1038}
1039
1040static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001041set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1042{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001043 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001044}
1045
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001046/* set_swap_bodies() switches the contents of any two sets by moving their
1047 internal data pointers and, if needed, copying the internal smalltables.
1048 Semantically equivalent to:
1049
1050 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1051
1052 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001053 Useful for operations that update in-place (by allowing an intermediate
1054 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001055*/
1056
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001057static void
1058set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001059{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 Py_ssize_t t;
1061 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001063 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001064
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 t = a->fill; a->fill = b->fill; b->fill = t;
1066 t = a->used; a->used = b->used; b->used = t;
1067 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 u = a->table;
1070 if (a->table == a->smalltable)
1071 u = b->smalltable;
1072 a->table = b->table;
1073 if (b->table == b->smalltable)
1074 a->table = a->smalltable;
1075 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001076
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 if (a->table == a->smalltable || b->table == b->smalltable) {
1078 memcpy(tab, a->smalltable, sizeof(tab));
1079 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1080 memcpy(b->smalltable, tab, sizeof(tab));
1081 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001083 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1084 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1085 h = a->hash; a->hash = b->hash; b->hash = h;
1086 } else {
1087 a->hash = -1;
1088 b->hash = -1;
1089 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001090}
1091
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001092static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301093set_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001094{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001096}
1097
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001098static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301099frozenset_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001100{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001101 if (PyFrozenSet_CheckExact(so)) {
1102 Py_INCREF(so);
1103 return (PyObject *)so;
1104 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301105 return set_copy(so, NULL);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001106}
1107
Raymond Hettingera690a992003-11-16 16:17:49 +00001108PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1109
1110static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301111set_clear(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc991db22005-08-11 07:58:45 +00001112{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001113 set_clear_internal(so);
1114 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001115}
1116
1117PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1118
1119static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001120set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001121{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122 PySetObject *result;
1123 PyObject *other;
1124 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001125
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301126 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001127 if (result == NULL)
1128 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001130 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1131 other = PyTuple_GET_ITEM(args, i);
1132 if ((PyObject *)so == other)
1133 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001134 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 Py_DECREF(result);
1136 return NULL;
1137 }
1138 }
1139 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001140}
1141
1142PyDoc_STRVAR(union_doc,
1143 "Return the union of sets as a new set.\n\
1144\n\
1145(i.e. all elements that are in either set.)");
1146
1147static PyObject *
1148set_or(PySetObject *so, PyObject *other)
1149{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001151
Brian Curtindfc80e32011-08-10 20:28:54 -05001152 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1153 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001154
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301155 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 if (result == NULL)
1157 return NULL;
1158 if ((PyObject *)so == other)
1159 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001160 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 Py_DECREF(result);
1162 return NULL;
1163 }
1164 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001165}
1166
Raymond Hettingera690a992003-11-16 16:17:49 +00001167static PyObject *
1168set_ior(PySetObject *so, PyObject *other)
1169{
Brian Curtindfc80e32011-08-10 20:28:54 -05001170 if (!PyAnySet_Check(other))
1171 Py_RETURN_NOTIMPLEMENTED;
1172
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001173 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001174 return NULL;
1175 Py_INCREF(so);
1176 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001177}
1178
1179static PyObject *
1180set_intersection(PySetObject *so, PyObject *other)
1181{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001182 PySetObject *result;
1183 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001184 Py_hash_t hash;
1185 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301188 return set_copy(so, NULL);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1191 if (result == NULL)
1192 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001194 if (PyAnySet_Check(other)) {
1195 Py_ssize_t pos = 0;
1196 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001197
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001198 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1199 tmp = (PyObject *)so;
1200 so = (PySetObject *)other;
1201 other = tmp;
1202 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001204 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001205 key = entry->key;
1206 hash = entry->hash;
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001207 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001208 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001209 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001210 Py_DECREF(result);
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001211 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 return NULL;
1213 }
1214 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001215 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 Py_DECREF(result);
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001217 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001218 return NULL;
1219 }
1220 }
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001221 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001222 }
1223 return (PyObject *)result;
1224 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001226 it = PyObject_GetIter(other);
1227 if (it == NULL) {
1228 Py_DECREF(result);
1229 return NULL;
1230 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001233 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001234 if (hash == -1)
1235 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001236 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001237 if (rv < 0)
1238 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001239 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001240 if (set_add_entry(result, key, hash))
1241 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 }
1243 Py_DECREF(key);
1244 }
1245 Py_DECREF(it);
1246 if (PyErr_Occurred()) {
1247 Py_DECREF(result);
1248 return NULL;
1249 }
1250 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001251 error:
1252 Py_DECREF(it);
1253 Py_DECREF(result);
1254 Py_DECREF(key);
1255 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001256}
1257
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001258static PyObject *
1259set_intersection_multi(PySetObject *so, PyObject *args)
1260{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 Py_ssize_t i;
1262 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301265 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 Py_INCREF(so);
1268 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1269 PyObject *other = PyTuple_GET_ITEM(args, i);
1270 PyObject *newresult = set_intersection((PySetObject *)result, other);
1271 if (newresult == NULL) {
1272 Py_DECREF(result);
1273 return NULL;
1274 }
1275 Py_DECREF(result);
1276 result = newresult;
1277 }
1278 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001279}
1280
Raymond Hettingera690a992003-11-16 16:17:49 +00001281PyDoc_STRVAR(intersection_doc,
1282"Return the intersection of two sets as a new set.\n\
1283\n\
1284(i.e. all elements that are in both sets.)");
1285
1286static PyObject *
1287set_intersection_update(PySetObject *so, PyObject *other)
1288{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 tmp = set_intersection(so, other);
1292 if (tmp == NULL)
1293 return NULL;
1294 set_swap_bodies(so, (PySetObject *)tmp);
1295 Py_DECREF(tmp);
1296 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001297}
1298
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001299static PyObject *
1300set_intersection_update_multi(PySetObject *so, PyObject *args)
1301{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 tmp = set_intersection_multi(so, args);
1305 if (tmp == NULL)
1306 return NULL;
1307 set_swap_bodies(so, (PySetObject *)tmp);
1308 Py_DECREF(tmp);
1309 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001310}
1311
Raymond Hettingera690a992003-11-16 16:17:49 +00001312PyDoc_STRVAR(intersection_update_doc,
1313"Update a set with the intersection of itself and another.");
1314
1315static PyObject *
1316set_and(PySetObject *so, PyObject *other)
1317{
Brian Curtindfc80e32011-08-10 20:28:54 -05001318 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1319 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001321}
1322
1323static PyObject *
1324set_iand(PySetObject *so, PyObject *other)
1325{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001327
Brian Curtindfc80e32011-08-10 20:28:54 -05001328 if (!PyAnySet_Check(other))
1329 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 result = set_intersection_update(so, other);
1331 if (result == NULL)
1332 return NULL;
1333 Py_DECREF(result);
1334 Py_INCREF(so);
1335 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001336}
1337
Guido van Rossum58da9312007-11-10 23:39:45 +00001338static PyObject *
1339set_isdisjoint(PySetObject *so, PyObject *other)
1340{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001342 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 if ((PyObject *)so == other) {
1345 if (PySet_GET_SIZE(so) == 0)
1346 Py_RETURN_TRUE;
1347 else
1348 Py_RETURN_FALSE;
1349 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 if (PyAnySet_CheckExact(other)) {
1352 Py_ssize_t pos = 0;
1353 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1356 tmp = (PyObject *)so;
1357 so = (PySetObject *)other;
1358 other = tmp;
1359 }
1360 while (set_next((PySetObject *)other, &pos, &entry)) {
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001361 PyObject *key = entry->key;
1362 Py_INCREF(key);
1363 rv = set_contains_entry(so, key, entry->hash);
1364 Py_DECREF(key);
1365 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 return NULL;
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001367 }
1368 if (rv) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 Py_RETURN_FALSE;
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001370 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 }
1372 Py_RETURN_TRUE;
1373 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 it = PyObject_GetIter(other);
1376 if (it == NULL)
1377 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001380 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382 if (hash == -1) {
1383 Py_DECREF(key);
1384 Py_DECREF(it);
1385 return NULL;
1386 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001387 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001389 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390 Py_DECREF(it);
1391 return NULL;
1392 }
1393 if (rv) {
1394 Py_DECREF(it);
1395 Py_RETURN_FALSE;
1396 }
1397 }
1398 Py_DECREF(it);
1399 if (PyErr_Occurred())
1400 return NULL;
1401 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001402}
1403
1404PyDoc_STRVAR(isdisjoint_doc,
1405"Return True if two sets have a null intersection.");
1406
Neal Norwitz6576bd82005-11-13 18:41:28 +00001407static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001408set_difference_update_internal(PySetObject *so, PyObject *other)
1409{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001410 if ((PyObject *)so == other)
1411 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 if (PyAnySet_Check(other)) {
1414 setentry *entry;
1415 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001416
Raymond Hettinger88ea1662019-08-29 09:02:58 -07001417 /* Optimization: When the other set is more than 8 times
1418 larger than the base set, replace the other set with
Christian Claussdcfbe4f2021-10-07 16:31:33 +02001419 intersection of the two sets.
Raymond Hettinger88ea1662019-08-29 09:02:58 -07001420 */
1421 if ((PySet_GET_SIZE(other) >> 3) > PySet_GET_SIZE(so)) {
1422 other = set_intersection(so, other);
1423 if (other == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424 return -1;
Raymond Hettinger88ea1662019-08-29 09:02:58 -07001425 } else {
1426 Py_INCREF(other);
1427 }
1428
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001429 while (set_next((PySetObject *)other, &pos, &entry)) {
1430 PyObject *key = entry->key;
1431 Py_INCREF(key);
1432 if (set_discard_entry(so, key, entry->hash) < 0) {
Raymond Hettinger88ea1662019-08-29 09:02:58 -07001433 Py_DECREF(other);
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001434 Py_DECREF(key);
Raymond Hettinger88ea1662019-08-29 09:02:58 -07001435 return -1;
1436 }
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001437 Py_DECREF(key);
1438 }
Raymond Hettinger88ea1662019-08-29 09:02:58 -07001439
1440 Py_DECREF(other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 } else {
1442 PyObject *key, *it;
1443 it = PyObject_GetIter(other);
1444 if (it == NULL)
1445 return -1;
1446
1447 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001448 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001449 Py_DECREF(it);
1450 Py_DECREF(key);
1451 return -1;
1452 }
1453 Py_DECREF(key);
1454 }
1455 Py_DECREF(it);
1456 if (PyErr_Occurred())
1457 return -1;
1458 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001459 /* If more than 1/4th are dummies, then resize them away. */
1460 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +09001462 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001463}
1464
Raymond Hettingera690a992003-11-16 16:17:49 +00001465static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001466set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001467{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001468 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1471 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001472 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001473 return NULL;
1474 }
1475 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001476}
1477
1478PyDoc_STRVAR(difference_update_doc,
1479"Remove all elements of another set from this set.");
1480
1481static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001482set_copy_and_difference(PySetObject *so, PyObject *other)
1483{
1484 PyObject *result;
1485
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301486 result = set_copy(so, NULL);
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001487 if (result == NULL)
1488 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001489 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001490 return result;
1491 Py_DECREF(result);
1492 return NULL;
1493}
1494
1495static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001496set_difference(PySetObject *so, PyObject *other)
1497{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001499 PyObject *key;
1500 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 setentry *entry;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001502 Py_ssize_t pos = 0, other_size;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001503 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001504
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001505 if (PyAnySet_Check(other)) {
1506 other_size = PySet_GET_SIZE(other);
1507 }
1508 else if (PyDict_CheckExact(other)) {
1509 other_size = PyDict_GET_SIZE(other);
1510 }
1511 else {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001512 return set_copy_and_difference(so, other);
1513 }
1514
1515 /* If len(so) much more than len(other), it's more efficient to simply copy
1516 * so and then iterate other looking for common elements. */
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001517 if ((PySet_GET_SIZE(so) >> 2) > other_size) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001518 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 result = make_new_set_basetype(Py_TYPE(so), NULL);
1522 if (result == NULL)
1523 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001525 if (PyDict_CheckExact(other)) {
1526 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001527 key = entry->key;
1528 hash = entry->hash;
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001529 Py_INCREF(key);
Serhiy Storchakafb5db7e2020-10-26 08:43:39 +02001530 rv = _PyDict_Contains_KnownHash(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001531 if (rv < 0) {
1532 Py_DECREF(result);
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001533 Py_DECREF(key);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001534 return NULL;
1535 }
1536 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001537 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 Py_DECREF(result);
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001539 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001540 return NULL;
1541 }
1542 }
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001543 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001544 }
1545 return result;
1546 }
1547
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001548 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001550 key = entry->key;
1551 hash = entry->hash;
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001552 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001553 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001554 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001555 Py_DECREF(result);
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001556 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001557 return NULL;
1558 }
1559 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001560 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 Py_DECREF(result);
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001562 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001563 return NULL;
1564 }
1565 }
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001566 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001567 }
1568 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001569}
1570
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001571static PyObject *
1572set_difference_multi(PySetObject *so, PyObject *args)
1573{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001574 Py_ssize_t i;
1575 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001576
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301578 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 other = PyTuple_GET_ITEM(args, 0);
1581 result = set_difference(so, other);
1582 if (result == NULL)
1583 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001584
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1586 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001587 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 Py_DECREF(result);
1589 return NULL;
1590 }
1591 }
1592 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001593}
1594
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001595PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001596"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001597\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001598(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001599static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001600set_sub(PySetObject *so, PyObject *other)
1601{
Brian Curtindfc80e32011-08-10 20:28:54 -05001602 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1603 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001605}
1606
1607static PyObject *
1608set_isub(PySetObject *so, PyObject *other)
1609{
Brian Curtindfc80e32011-08-10 20:28:54 -05001610 if (!PyAnySet_Check(other))
1611 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001612 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 return NULL;
1614 Py_INCREF(so);
1615 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001616}
1617
1618static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001619set_symmetric_difference_update(PySetObject *so, PyObject *other)
1620{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 PySetObject *otherset;
1622 PyObject *key;
1623 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001624 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001626 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301629 return set_clear(so, NULL);
Raymond Hettingera690a992003-11-16 16:17:49 +00001630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 if (PyDict_CheckExact(other)) {
1632 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001634 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001635 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001636 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001637 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001638 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001640 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001641 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001642 Py_DECREF(key);
1643 return NULL;
1644 }
1645 }
Georg Brandl2d444492010-09-03 10:52:55 +00001646 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 }
1648 Py_RETURN_NONE;
1649 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001650
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 if (PyAnySet_Check(other)) {
1652 Py_INCREF(other);
1653 otherset = (PySetObject *)other;
1654 } else {
1655 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1656 if (otherset == NULL)
1657 return NULL;
1658 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001661 key = entry->key;
1662 hash = entry->hash;
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001663 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001664 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001665 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001666 Py_DECREF(otherset);
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001667 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 return NULL;
1669 }
1670 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001671 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001672 Py_DECREF(otherset);
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001673 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001674 return NULL;
1675 }
1676 }
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001677 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001678 }
1679 Py_DECREF(otherset);
1680 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001681}
1682
1683PyDoc_STRVAR(symmetric_difference_update_doc,
1684"Update a set with the symmetric difference of itself and another.");
1685
1686static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001687set_symmetric_difference(PySetObject *so, PyObject *other)
1688{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001689 PyObject *rv;
1690 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001692 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1693 if (otherset == NULL)
1694 return NULL;
1695 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
lekma491bbed2018-05-02 11:29:10 +02001696 if (rv == NULL) {
1697 Py_DECREF(otherset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001698 return NULL;
lekma491bbed2018-05-02 11:29:10 +02001699 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001700 Py_DECREF(rv);
1701 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001702}
1703
1704PyDoc_STRVAR(symmetric_difference_doc,
1705"Return the symmetric difference of two sets as a new set.\n\
1706\n\
1707(i.e. all elements that are in exactly one of the sets.)");
1708
1709static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001710set_xor(PySetObject *so, PyObject *other)
1711{
Brian Curtindfc80e32011-08-10 20:28:54 -05001712 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1713 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001714 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001715}
1716
1717static PyObject *
1718set_ixor(PySetObject *so, PyObject *other)
1719{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001720 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001721
Brian Curtindfc80e32011-08-10 20:28:54 -05001722 if (!PyAnySet_Check(other))
1723 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001724 result = set_symmetric_difference_update(so, other);
1725 if (result == NULL)
1726 return NULL;
1727 Py_DECREF(result);
1728 Py_INCREF(so);
1729 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001730}
1731
1732static PyObject *
1733set_issubset(PySetObject *so, PyObject *other)
1734{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001735 setentry *entry;
1736 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001737 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001738
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001739 if (!PyAnySet_Check(other)) {
1740 PyObject *tmp, *result;
1741 tmp = make_new_set(&PySet_Type, other);
1742 if (tmp == NULL)
1743 return NULL;
1744 result = set_issubset(so, tmp);
1745 Py_DECREF(tmp);
1746 return result;
1747 }
1748 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1749 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001750
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001751 while (set_next(so, &pos, &entry)) {
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001752 PyObject *key = entry->key;
1753 Py_INCREF(key);
1754 rv = set_contains_entry((PySetObject *)other, key, entry->hash);
1755 Py_DECREF(key);
1756 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001757 return NULL;
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001758 }
1759 if (!rv) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001760 Py_RETURN_FALSE;
Miss Islington (bot)1f5fe992022-02-11 12:44:17 -08001761 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001762 }
1763 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001764}
1765
1766PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1767
1768static PyObject *
1769set_issuperset(PySetObject *so, PyObject *other)
1770{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001771 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001772
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001773 if (!PyAnySet_Check(other)) {
1774 tmp = make_new_set(&PySet_Type, other);
1775 if (tmp == NULL)
1776 return NULL;
1777 result = set_issuperset(so, tmp);
1778 Py_DECREF(tmp);
1779 return result;
1780 }
1781 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001782}
1783
1784PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1785
Raymond Hettingera690a992003-11-16 16:17:49 +00001786static PyObject *
1787set_richcompare(PySetObject *v, PyObject *w, int op)
1788{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001789 PyObject *r1;
1790 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001791
Brian Curtindfc80e32011-08-10 20:28:54 -05001792 if(!PyAnySet_Check(w))
1793 Py_RETURN_NOTIMPLEMENTED;
1794
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001795 switch (op) {
1796 case Py_EQ:
1797 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1798 Py_RETURN_FALSE;
1799 if (v->hash != -1 &&
1800 ((PySetObject *)w)->hash != -1 &&
1801 v->hash != ((PySetObject *)w)->hash)
1802 Py_RETURN_FALSE;
1803 return set_issubset(v, w);
1804 case Py_NE:
1805 r1 = set_richcompare(v, w, Py_EQ);
1806 if (r1 == NULL)
1807 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001808 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001809 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001810 if (r2 < 0)
1811 return NULL;
1812 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001813 case Py_LE:
1814 return set_issubset(v, w);
1815 case Py_GE:
1816 return set_issuperset(v, w);
1817 case Py_LT:
1818 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1819 Py_RETURN_FALSE;
1820 return set_issubset(v, w);
1821 case Py_GT:
1822 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1823 Py_RETURN_FALSE;
1824 return set_issuperset(v, w);
1825 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001826 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001827}
1828
Raymond Hettingera690a992003-11-16 16:17:49 +00001829static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001830set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001831{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001832 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001833 return NULL;
1834 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001835}
1836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001837PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001838"Add an element to a set.\n\
1839\n\
1840This has no effect if the element is already present.");
1841
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001842static int
1843set_contains(PySetObject *so, PyObject *key)
1844{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 PyObject *tmpkey;
1846 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001849 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1851 return -1;
1852 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001853 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001854 if (tmpkey == NULL)
1855 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001856 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001857 Py_DECREF(tmpkey);
1858 }
1859 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001860}
1861
1862static PyObject *
1863set_direct_contains(PySetObject *so, PyObject *key)
1864{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001868 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001869 return NULL;
1870 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001871}
1872
1873PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1874
Raymond Hettingera690a992003-11-16 16:17:49 +00001875static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001876set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001877{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 PyObject *tmpkey;
1879 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001882 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001883 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1884 return NULL;
1885 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001886 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 if (tmpkey == NULL)
1888 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001889 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001891 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 return NULL;
1893 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001896 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 return NULL;
1898 }
1899 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001900}
1901
1902PyDoc_STRVAR(remove_doc,
1903"Remove an element from a set; it must be a member.\n\
1904\n\
1905If the element is not a member, raise a KeyError.");
1906
1907static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001908set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001909{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001910 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001913 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001914 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1916 return NULL;
1917 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001918 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 if (tmpkey == NULL)
1920 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001921 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001923 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001924 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 }
1926 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001927}
1928
1929PyDoc_STRVAR(discard_doc,
1930"Remove an element from a set if it is a member.\n\
1931\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001932If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001933
1934static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301935set_reduce(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001936{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001938 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001940 keys = PySequence_List((PyObject *)so);
1941 if (keys == NULL)
1942 goto done;
1943 args = PyTuple_Pack(1, keys);
1944 if (args == NULL)
1945 goto done;
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001946 if (_PyObject_LookupAttrId((PyObject *)so, &PyId___dict__, &dict) < 0) {
1947 goto done;
1948 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001949 if (dict == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001950 dict = Py_None;
1951 Py_INCREF(dict);
1952 }
1953 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001954done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 Py_XDECREF(args);
1956 Py_XDECREF(keys);
1957 Py_XDECREF(dict);
1958 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001959}
1960
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001961static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301962set_sizeof(PySetObject *so, PyObject *Py_UNUSED(ignored))
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001963{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001964 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001965
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02001966 res = _PyObject_SIZE(Py_TYPE(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001967 if (so->table != so->smalltable)
1968 res = res + (so->mask + 1) * sizeof(setentry);
1969 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001970}
1971
1972PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001973static int
1974set_init(PySetObject *self, PyObject *args, PyObject *kwds)
1975{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001976 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001977
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001978 if (!_PyArg_NoKeywords("set", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001979 return -1;
1980 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
1981 return -1;
Raymond Hettingerb72e21b2016-03-25 02:29:59 -07001982 if (self->fill)
1983 set_clear_internal(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001984 self->hash = -1;
1985 if (iterable == NULL)
1986 return 0;
1987 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001988}
1989
Dong-hee Na6ff79f652020-03-17 02:17:38 +09001990static PyObject*
1991set_vectorcall(PyObject *type, PyObject * const*args,
1992 size_t nargsf, PyObject *kwnames)
1993{
1994 assert(PyType_Check(type));
1995
1996 if (!_PyArg_NoKwnames("set", kwnames)) {
1997 return NULL;
1998 }
1999
2000 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
2001 if (!_PyArg_CheckPositional("set", nargs, 0, 1)) {
2002 return NULL;
2003 }
2004
2005 if (nargs) {
2006 return make_new_set((PyTypeObject *)type, args[0]);
2007 }
2008
2009 return make_new_set((PyTypeObject *)type, NULL);
2010}
2011
Raymond Hettingera690a992003-11-16 16:17:49 +00002012static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002013 set_len, /* sq_length */
2014 0, /* sq_concat */
2015 0, /* sq_repeat */
2016 0, /* sq_item */
2017 0, /* sq_slice */
2018 0, /* sq_ass_item */
2019 0, /* sq_ass_slice */
2020 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002021};
2022
2023/* set object ********************************************************/
2024
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002025#ifdef Py_DEBUG
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302026static PyObject *test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored));
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002027
2028PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2029All is well if assertions don't fail.");
2030#endif
2031
Raymond Hettingera690a992003-11-16 16:17:49 +00002032static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002033 {"add", (PyCFunction)set_add, METH_O,
2034 add_doc},
2035 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2036 clear_doc},
2037 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2038 contains_doc},
2039 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2040 copy_doc},
2041 {"discard", (PyCFunction)set_discard, METH_O,
2042 discard_doc},
2043 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2044 difference_doc},
2045 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2046 difference_update_doc},
2047 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2048 intersection_doc},
2049 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2050 intersection_update_doc},
2051 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2052 isdisjoint_doc},
2053 {"issubset", (PyCFunction)set_issubset, METH_O,
2054 issubset_doc},
2055 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2056 issuperset_doc},
2057 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2058 pop_doc},
2059 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2060 reduce_doc},
2061 {"remove", (PyCFunction)set_remove, METH_O,
2062 remove_doc},
2063 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2064 sizeof_doc},
2065 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2066 symmetric_difference_doc},
2067 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2068 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002069#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002070 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2071 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002072#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002073 {"union", (PyCFunction)set_union, METH_VARARGS,
2074 union_doc},
2075 {"update", (PyCFunction)set_update, METH_VARARGS,
2076 update_doc},
Guido van Rossum48b069a2020-04-07 09:50:06 -07002077 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002078 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002079};
2080
2081static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002082 0, /*nb_add*/
2083 (binaryfunc)set_sub, /*nb_subtract*/
2084 0, /*nb_multiply*/
2085 0, /*nb_remainder*/
2086 0, /*nb_divmod*/
2087 0, /*nb_power*/
2088 0, /*nb_negative*/
2089 0, /*nb_positive*/
2090 0, /*nb_absolute*/
2091 0, /*nb_bool*/
2092 0, /*nb_invert*/
2093 0, /*nb_lshift*/
2094 0, /*nb_rshift*/
2095 (binaryfunc)set_and, /*nb_and*/
2096 (binaryfunc)set_xor, /*nb_xor*/
2097 (binaryfunc)set_or, /*nb_or*/
2098 0, /*nb_int*/
2099 0, /*nb_reserved*/
2100 0, /*nb_float*/
2101 0, /*nb_inplace_add*/
2102 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2103 0, /*nb_inplace_multiply*/
2104 0, /*nb_inplace_remainder*/
2105 0, /*nb_inplace_power*/
2106 0, /*nb_inplace_lshift*/
2107 0, /*nb_inplace_rshift*/
2108 (binaryfunc)set_iand, /*nb_inplace_and*/
2109 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2110 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002111};
2112
2113PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002114"set() -> new empty set object\n\
2115set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002116\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002117Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002118
2119PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002120 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2121 "set", /* tp_name */
2122 sizeof(PySetObject), /* tp_basicsize */
2123 0, /* tp_itemsize */
2124 /* methods */
2125 (destructor)set_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002126 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002127 0, /* tp_getattr */
2128 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002129 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002130 (reprfunc)set_repr, /* tp_repr */
2131 &set_as_number, /* tp_as_number */
2132 &set_as_sequence, /* tp_as_sequence */
2133 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002134 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002135 0, /* tp_call */
2136 0, /* tp_str */
2137 PyObject_GenericGetAttr, /* tp_getattro */
2138 0, /* tp_setattro */
2139 0, /* tp_as_buffer */
2140 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Brandt Bucher145bf262021-02-26 14:51:55 -08002141 Py_TPFLAGS_BASETYPE |
2142 _Py_TPFLAGS_MATCH_SELF, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002143 set_doc, /* tp_doc */
2144 (traverseproc)set_traverse, /* tp_traverse */
2145 (inquiry)set_clear_internal, /* tp_clear */
2146 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002147 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2148 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002149 0, /* tp_iternext */
2150 set_methods, /* tp_methods */
2151 0, /* tp_members */
2152 0, /* tp_getset */
2153 0, /* tp_base */
2154 0, /* tp_dict */
2155 0, /* tp_descr_get */
2156 0, /* tp_descr_set */
2157 0, /* tp_dictoffset */
2158 (initproc)set_init, /* tp_init */
2159 PyType_GenericAlloc, /* tp_alloc */
2160 set_new, /* tp_new */
2161 PyObject_GC_Del, /* tp_free */
Dong-hee Na6ff79f652020-03-17 02:17:38 +09002162 .tp_vectorcall = set_vectorcall,
Raymond Hettingera690a992003-11-16 16:17:49 +00002163};
2164
2165/* frozenset object ********************************************************/
2166
2167
2168static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002169 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2170 contains_doc},
2171 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2172 copy_doc},
2173 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2174 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002175 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002176 intersection_doc},
2177 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2178 isdisjoint_doc},
2179 {"issubset", (PyCFunction)set_issubset, METH_O,
2180 issubset_doc},
2181 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2182 issuperset_doc},
2183 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2184 reduce_doc},
2185 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2186 sizeof_doc},
2187 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2188 symmetric_difference_doc},
2189 {"union", (PyCFunction)set_union, METH_VARARGS,
2190 union_doc},
Guido van Rossum48b069a2020-04-07 09:50:06 -07002191 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002192 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002193};
2194
2195static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 0, /*nb_add*/
2197 (binaryfunc)set_sub, /*nb_subtract*/
2198 0, /*nb_multiply*/
2199 0, /*nb_remainder*/
2200 0, /*nb_divmod*/
2201 0, /*nb_power*/
2202 0, /*nb_negative*/
2203 0, /*nb_positive*/
2204 0, /*nb_absolute*/
2205 0, /*nb_bool*/
2206 0, /*nb_invert*/
2207 0, /*nb_lshift*/
2208 0, /*nb_rshift*/
2209 (binaryfunc)set_and, /*nb_and*/
2210 (binaryfunc)set_xor, /*nb_xor*/
2211 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002212};
2213
2214PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002215"frozenset() -> empty frozenset object\n\
2216frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002217\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002218Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002219
2220PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002221 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2222 "frozenset", /* tp_name */
2223 sizeof(PySetObject), /* tp_basicsize */
2224 0, /* tp_itemsize */
2225 /* methods */
2226 (destructor)set_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002227 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002228 0, /* tp_getattr */
2229 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002230 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002231 (reprfunc)set_repr, /* tp_repr */
2232 &frozenset_as_number, /* tp_as_number */
2233 &set_as_sequence, /* tp_as_sequence */
2234 0, /* tp_as_mapping */
2235 frozenset_hash, /* tp_hash */
2236 0, /* tp_call */
2237 0, /* tp_str */
2238 PyObject_GenericGetAttr, /* tp_getattro */
2239 0, /* tp_setattro */
2240 0, /* tp_as_buffer */
2241 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Brandt Bucher145bf262021-02-26 14:51:55 -08002242 Py_TPFLAGS_BASETYPE |
2243 _Py_TPFLAGS_MATCH_SELF, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002244 frozenset_doc, /* tp_doc */
2245 (traverseproc)set_traverse, /* tp_traverse */
2246 (inquiry)set_clear_internal, /* tp_clear */
2247 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002248 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002249 (getiterfunc)set_iter, /* tp_iter */
2250 0, /* tp_iternext */
2251 frozenset_methods, /* tp_methods */
2252 0, /* tp_members */
2253 0, /* tp_getset */
2254 0, /* tp_base */
2255 0, /* tp_dict */
2256 0, /* tp_descr_get */
2257 0, /* tp_descr_set */
2258 0, /* tp_dictoffset */
2259 0, /* tp_init */
2260 PyType_GenericAlloc, /* tp_alloc */
2261 frozenset_new, /* tp_new */
2262 PyObject_GC_Del, /* tp_free */
Dong-hee Na1c605672020-03-19 02:30:50 +09002263 .tp_vectorcall = frozenset_vectorcall,
Raymond Hettingera690a992003-11-16 16:17:49 +00002264};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002265
2266
2267/***** C API functions *************************************************/
2268
2269PyObject *
2270PySet_New(PyObject *iterable)
2271{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002272 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002273}
2274
2275PyObject *
2276PyFrozenSet_New(PyObject *iterable)
2277{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002278 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002279}
2280
Neal Norwitz8c49c822006-03-04 18:41:19 +00002281Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002282PySet_Size(PyObject *anyset)
2283{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002284 if (!PyAnySet_Check(anyset)) {
2285 PyErr_BadInternalCall();
2286 return -1;
2287 }
2288 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002289}
2290
2291int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002292PySet_Clear(PyObject *set)
2293{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002294 if (!PySet_Check(set)) {
2295 PyErr_BadInternalCall();
2296 return -1;
2297 }
2298 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002299}
2300
2301int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002302PySet_Contains(PyObject *anyset, PyObject *key)
2303{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002304 if (!PyAnySet_Check(anyset)) {
2305 PyErr_BadInternalCall();
2306 return -1;
2307 }
2308 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002309}
2310
2311int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002312PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002313{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002314 if (!PySet_Check(set)) {
2315 PyErr_BadInternalCall();
2316 return -1;
2317 }
2318 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002319}
2320
2321int
Christian Heimesfd66e512008-01-29 12:18:50 +00002322PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002323{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002324 if (!PySet_Check(anyset) &&
2325 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2326 PyErr_BadInternalCall();
2327 return -1;
2328 }
2329 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002330}
2331
Raymond Hettinger3625af52016-03-27 01:15:07 -07002332int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002333_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002335 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002337 if (!PyAnySet_Check(set)) {
2338 PyErr_BadInternalCall();
2339 return -1;
2340 }
2341 if (set_next((PySetObject *)set, pos, &entry) == 0)
2342 return 0;
2343 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002344 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002345 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002346}
2347
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002348PyObject *
2349PySet_Pop(PyObject *set)
2350{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002351 if (!PySet_Check(set)) {
2352 PyErr_BadInternalCall();
2353 return NULL;
2354 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302355 return set_pop((PySetObject *)set, NULL);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002356}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002357
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002358int
2359_PySet_Update(PyObject *set, PyObject *iterable)
2360{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002361 if (!PySet_Check(set)) {
2362 PyErr_BadInternalCall();
2363 return -1;
2364 }
2365 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002366}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002367
Raymond Hettingere259f132013-12-15 11:56:14 -08002368/* Exported for the gdb plugin's benefit. */
2369PyObject *_PySet_Dummy = dummy;
2370
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002371#ifdef Py_DEBUG
2372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002373/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002374 Returns True and original set is restored. */
2375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002376#define assertRaises(call_return_value, exception) \
2377 do { \
2378 assert(call_return_value); \
2379 assert(PyErr_ExceptionMatches(exception)); \
2380 PyErr_Clear(); \
2381 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002382
2383static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302384test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002385{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002386 Py_ssize_t count;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +02002387 const char *s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002388 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002389 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002390 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002391 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002392 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002394 /* Verify preconditions */
2395 assert(PyAnySet_Check(ob));
2396 assert(PyAnySet_CheckExact(ob));
2397 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002399 /* so.clear(); so |= set("abc"); */
2400 str = PyUnicode_FromString("abc");
2401 if (str == NULL)
2402 return NULL;
2403 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002404 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405 Py_DECREF(str);
2406 return NULL;
2407 }
2408 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002410 /* Exercise type/size checks */
2411 assert(PySet_Size(ob) == 3);
2412 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002414 /* Raise TypeError for non-iterable constructor arguments */
2415 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2416 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002418 /* Raise TypeError for unhashable key */
2419 dup = PySet_New(ob);
2420 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2421 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2422 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002424 /* Exercise successful pop, contains, add, and discard */
2425 elem = PySet_Pop(ob);
2426 assert(PySet_Contains(ob, elem) == 0);
2427 assert(PySet_GET_SIZE(ob) == 2);
2428 assert(PySet_Add(ob, elem) == 0);
2429 assert(PySet_Contains(ob, elem) == 1);
2430 assert(PySet_GET_SIZE(ob) == 3);
2431 assert(PySet_Discard(ob, elem) == 1);
2432 assert(PySet_GET_SIZE(ob) == 2);
2433 assert(PySet_Discard(ob, elem) == 0);
2434 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002436 /* Exercise clear */
2437 dup2 = PySet_New(dup);
2438 assert(PySet_Clear(dup2) == 0);
2439 assert(PySet_Size(dup2) == 0);
2440 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002442 /* Raise SystemError on clear or update of frozen set */
2443 f = PyFrozenSet_New(dup);
2444 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2445 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2446 assert(PySet_Add(f, elem) == 0);
2447 Py_INCREF(f);
2448 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2449 Py_DECREF(f);
2450 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002452 /* Exercise direct iteration */
2453 i = 0, count = 0;
2454 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
Serhiy Storchaka06515832016-11-20 09:13:07 +02002455 s = PyUnicode_AsUTF8(x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002456 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2457 count++;
2458 }
2459 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002461 /* Exercise updates */
2462 dup2 = PySet_New(NULL);
2463 assert(_PySet_Update(dup2, dup) == 0);
2464 assert(PySet_Size(dup2) == 3);
2465 assert(_PySet_Update(dup2, dup) == 0);
2466 assert(PySet_Size(dup2) == 3);
2467 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002469 /* Raise SystemError when self argument is not a set or frozenset. */
2470 t = PyTuple_New(0);
2471 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2472 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2473 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002474
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002475 /* Raise SystemError when self argument is not a set. */
2476 f = PyFrozenSet_New(dup);
2477 assert(PySet_Size(f) == 3);
2478 assert(PyFrozenSet_CheckExact(f));
2479 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2480 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2481 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002483 /* Raise KeyError when popping from an empty set */
2484 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2485 Py_DECREF(ob);
2486 assert(PySet_GET_SIZE(ob) == 0);
2487 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002489 /* Restore the set from the copy using the PyNumber API */
2490 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2491 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002493 /* Verify constructors accept NULL arguments */
2494 f = PySet_New(NULL);
2495 assert(f != NULL);
2496 assert(PySet_GET_SIZE(f) == 0);
2497 Py_DECREF(f);
2498 f = PyFrozenSet_New(NULL);
2499 assert(f != NULL);
2500 assert(PyFrozenSet_CheckExact(f));
2501 assert(PySet_GET_SIZE(f) == 0);
2502 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002504 Py_DECREF(elem);
2505 Py_DECREF(dup);
2506 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002507}
2508
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002509#undef assertRaises
2510
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002511#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002512
2513/***** Dummy Struct *************************************************/
2514
2515static PyObject *
2516dummy_repr(PyObject *op)
2517{
2518 return PyUnicode_FromString("<dummy key>");
2519}
2520
Victor Stinner2a4903f2020-01-30 13:09:11 +01002521static void _Py_NO_RETURN
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002522dummy_dealloc(PyObject* ignore)
2523{
2524 Py_FatalError("deallocating <dummy key>");
2525}
2526
2527static PyTypeObject _PySetDummy_Type = {
2528 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2529 "<dummy key> type",
2530 0,
2531 0,
2532 dummy_dealloc, /*tp_dealloc*/ /*never called*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002533 0, /*tp_vectorcall_offset*/
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002534 0, /*tp_getattr*/
2535 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002536 0, /*tp_as_async*/
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002537 dummy_repr, /*tp_repr*/
2538 0, /*tp_as_number*/
2539 0, /*tp_as_sequence*/
2540 0, /*tp_as_mapping*/
2541 0, /*tp_hash */
2542 0, /*tp_call */
2543 0, /*tp_str */
2544 0, /*tp_getattro */
2545 0, /*tp_setattro */
2546 0, /*tp_as_buffer */
2547 Py_TPFLAGS_DEFAULT, /*tp_flags */
2548};
2549
2550static PyObject _dummy_struct = {
2551 _PyObject_EXTRA_INIT
2552 2, &_PySetDummy_Type
2553};