blob: caff85c9e38939e56ae62012b3798b4cb754095e [file] [log] [blame]
Raymond Hettingerc991db22005-08-11 07:58:45 +00001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002/* set object implementation
Raymond Hettingerae7b00e2013-09-07 15:05:00 -07003
Raymond Hettingera9d99362005-08-05 00:01:15 +00004 Written and maintained by Raymond D. Hettinger <python@rcn.com>
5 Derived from Lib/sets.py and Objects/dictobject.c.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00006
Raymond Hettingerae7b00e2013-09-07 15:05:00 -07007 The basic lookup function used by all operations.
8 This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
9
10 The initial probe index is computed as hash mod the table size.
11 Subsequent probe indices are computed as explained in Objects/dictobject.c.
12
13 To improve cache locality, each probe inspects a series of consecutive
14 nearby entries before moving on to probes elsewhere in memory. This leaves
Raymond Hettinger64263df2017-09-04 18:54:16 -070015 us with a hybrid of linear probing and randomized probing. The linear probing
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070016 reduces the cost of hash collisions because consecutive memory accesses
17 tend to be much cheaper than scattered probes. After LINEAR_PROBES steps,
Raymond Hettinger64263df2017-09-04 18:54:16 -070018 we then use more of the upper bits from the hash value and apply a simple
19 linear congruential random number genearator. This helps break-up long
20 chains of collisions.
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070021
22 All arithmetic on hash should ignore overflow.
23
Raymond Hettinger4d45c102015-01-25 16:27:40 -080024 Unlike the dictionary implementation, the lookkey function can return
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070025 NULL if the rich comparison returns an error.
Serhiy Storchaka13ad3b72017-09-14 09:38:36 +030026
Raymond Hettinger64263df2017-09-04 18:54:16 -070027 Use cases for sets differ considerably from dictionaries where looked-up
28 keys are more likely to be present. In contrast, sets are primarily
29 about membership testing where the presence of an element is not known in
30 advance. Accordingly, the set implementation needs to optimize for both
31 the found and not-found case.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000032*/
33
Raymond Hettingera690a992003-11-16 16:17:49 +000034#include "Python.h"
Victor Stinner4a21e572020-04-15 02:35:41 +020035#include "pycore_object.h" // _PyObject_GC_UNTRACK()
36#include <stddef.h> // offsetof()
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000037
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000038/* Object used as dummy key to fill deleted entries */
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -050039static PyObject _dummy_struct;
40
41#define dummy (&_dummy_struct)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000042
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000043
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -070044/* ======================================================================== */
45/* ======= Begin logic for probing the hash table ========================= */
46
Raymond Hettinger710a67e2013-09-21 20:17:31 -070047/* Set this to zero to turn-off linear probing */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070048#ifndef LINEAR_PROBES
Raymond Hettinger742d8712013-09-08 00:25:57 -070049#define LINEAR_PROBES 9
Raymond Hettinger8408dc52013-09-15 14:57:15 -070050#endif
Raymond Hettinger742d8712013-09-08 00:25:57 -070051
52/* This must be >= 1 */
53#define PERTURB_SHIFT 5
54
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000055static setentry *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020056set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000057{
Raymond Hettinger70559b52015-07-23 07:42:23 -040058 setentry *table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020059 setentry *entry;
Raymond Hettinger2cc9b842020-05-10 14:53:29 -070060 size_t perturb = hash;
Raymond Hettingerafe89092013-08-28 20:59:31 -070061 size_t mask = so->mask;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -080062 size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */
Raymond Hettinger2cc9b842020-05-10 14:53:29 -070063 int probes;
Raymond Hettinger4ef05282013-09-21 15:39:49 -070064 int cmp;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000065
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -070066 while (1) {
Raymond Hettinger2cc9b842020-05-10 14:53:29 -070067 entry = &so->table[i];
68 probes = (i + LINEAR_PROBES <= mask) ? LINEAR_PROBES: 0;
69 do {
70 if (entry->hash == 0 && entry->key == NULL)
Raymond Hettinger08e3dc02014-12-26 20:14:00 -080071 return entry;
Raymond Hettinger2cc9b842020-05-10 14:53:29 -070072 if (entry->hash == hash) {
73 PyObject *startkey = entry->key;
74 assert(startkey != dummy);
75 if (startkey == key)
Raymond Hettinger8651a502015-05-27 10:37:20 -070076 return entry;
Raymond Hettinger2cc9b842020-05-10 14:53:29 -070077 if (PyUnicode_CheckExact(startkey)
78 && PyUnicode_CheckExact(key)
79 && _PyUnicode_EQ(startkey, key))
80 return entry;
81 table = so->table;
82 Py_INCREF(startkey);
83 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
84 Py_DECREF(startkey);
85 if (cmp < 0)
86 return NULL;
87 if (table != so->table || entry->key != startkey)
88 return set_lookkey(so, key, hash);
89 if (cmp > 0)
90 return entry;
91 mask = so->mask;
Raymond Hettinger8651a502015-05-27 10:37:20 -070092 }
Raymond Hettinger2cc9b842020-05-10 14:53:29 -070093 entry++;
94 } while (probes--);
Raymond Hettinger8651a502015-05-27 10:37:20 -070095 perturb >>= PERTURB_SHIFT;
96 i = (i * 5 + 1 + perturb) & mask;
Raymond Hettinger8651a502015-05-27 10:37:20 -070097 }
98}
99
Raymond Hettinger15f08692015-07-03 17:21:17 -0700100static int set_table_resize(PySetObject *, Py_ssize_t);
101
Raymond Hettinger8651a502015-05-27 10:37:20 -0700102static int
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400103set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700104{
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400105 setentry *table;
Raymond 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;
1207 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001208 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 Py_DECREF(result);
1210 return NULL;
1211 }
1212 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001213 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001214 Py_DECREF(result);
1215 return NULL;
1216 }
1217 }
1218 }
1219 return (PyObject *)result;
1220 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001222 it = PyObject_GetIter(other);
1223 if (it == NULL) {
1224 Py_DECREF(result);
1225 return NULL;
1226 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001228 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001229 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001230 if (hash == -1)
1231 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001232 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001233 if (rv < 0)
1234 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001236 if (set_add_entry(result, key, hash))
1237 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 }
1239 Py_DECREF(key);
1240 }
1241 Py_DECREF(it);
1242 if (PyErr_Occurred()) {
1243 Py_DECREF(result);
1244 return NULL;
1245 }
1246 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001247 error:
1248 Py_DECREF(it);
1249 Py_DECREF(result);
1250 Py_DECREF(key);
1251 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001252}
1253
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001254static PyObject *
1255set_intersection_multi(PySetObject *so, PyObject *args)
1256{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 Py_ssize_t i;
1258 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301261 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 Py_INCREF(so);
1264 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1265 PyObject *other = PyTuple_GET_ITEM(args, i);
1266 PyObject *newresult = set_intersection((PySetObject *)result, other);
1267 if (newresult == NULL) {
1268 Py_DECREF(result);
1269 return NULL;
1270 }
1271 Py_DECREF(result);
1272 result = newresult;
1273 }
1274 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001275}
1276
Raymond Hettingera690a992003-11-16 16:17:49 +00001277PyDoc_STRVAR(intersection_doc,
1278"Return the intersection of two sets as a new set.\n\
1279\n\
1280(i.e. all elements that are in both sets.)");
1281
1282static PyObject *
1283set_intersection_update(PySetObject *so, PyObject *other)
1284{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001285 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 tmp = set_intersection(so, other);
1288 if (tmp == NULL)
1289 return NULL;
1290 set_swap_bodies(so, (PySetObject *)tmp);
1291 Py_DECREF(tmp);
1292 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001293}
1294
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001295static PyObject *
1296set_intersection_update_multi(PySetObject *so, PyObject *args)
1297{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001299
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 tmp = set_intersection_multi(so, args);
1301 if (tmp == NULL)
1302 return NULL;
1303 set_swap_bodies(so, (PySetObject *)tmp);
1304 Py_DECREF(tmp);
1305 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001306}
1307
Raymond Hettingera690a992003-11-16 16:17:49 +00001308PyDoc_STRVAR(intersection_update_doc,
1309"Update a set with the intersection of itself and another.");
1310
1311static PyObject *
1312set_and(PySetObject *so, PyObject *other)
1313{
Brian Curtindfc80e32011-08-10 20:28:54 -05001314 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1315 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001317}
1318
1319static PyObject *
1320set_iand(PySetObject *so, PyObject *other)
1321{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001323
Brian Curtindfc80e32011-08-10 20:28:54 -05001324 if (!PyAnySet_Check(other))
1325 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 result = set_intersection_update(so, other);
1327 if (result == NULL)
1328 return NULL;
1329 Py_DECREF(result);
1330 Py_INCREF(so);
1331 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001332}
1333
Guido van Rossum58da9312007-11-10 23:39:45 +00001334static PyObject *
1335set_isdisjoint(PySetObject *so, PyObject *other)
1336{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001338 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 if ((PyObject *)so == other) {
1341 if (PySet_GET_SIZE(so) == 0)
1342 Py_RETURN_TRUE;
1343 else
1344 Py_RETURN_FALSE;
1345 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001347 if (PyAnySet_CheckExact(other)) {
1348 Py_ssize_t pos = 0;
1349 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1352 tmp = (PyObject *)so;
1353 so = (PySetObject *)other;
1354 other = tmp;
1355 }
1356 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001357 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001358 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001359 return NULL;
1360 if (rv)
1361 Py_RETURN_FALSE;
1362 }
1363 Py_RETURN_TRUE;
1364 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 it = PyObject_GetIter(other);
1367 if (it == NULL)
1368 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001371 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 if (hash == -1) {
1374 Py_DECREF(key);
1375 Py_DECREF(it);
1376 return NULL;
1377 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001378 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001380 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 Py_DECREF(it);
1382 return NULL;
1383 }
1384 if (rv) {
1385 Py_DECREF(it);
1386 Py_RETURN_FALSE;
1387 }
1388 }
1389 Py_DECREF(it);
1390 if (PyErr_Occurred())
1391 return NULL;
1392 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001393}
1394
1395PyDoc_STRVAR(isdisjoint_doc,
1396"Return True if two sets have a null intersection.");
1397
Neal Norwitz6576bd82005-11-13 18:41:28 +00001398static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001399set_difference_update_internal(PySetObject *so, PyObject *other)
1400{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001401 if ((PyObject *)so == other)
1402 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001404 if (PyAnySet_Check(other)) {
1405 setentry *entry;
1406 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001407
Raymond Hettinger88ea1662019-08-29 09:02:58 -07001408 /* Optimization: When the other set is more than 8 times
1409 larger than the base set, replace the other set with
1410 interesection of the two sets.
1411 */
1412 if ((PySet_GET_SIZE(other) >> 3) > PySet_GET_SIZE(so)) {
1413 other = set_intersection(so, other);
1414 if (other == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 return -1;
Raymond Hettinger88ea1662019-08-29 09:02:58 -07001416 } else {
1417 Py_INCREF(other);
1418 }
1419
1420 while (set_next((PySetObject *)other, &pos, &entry))
1421 if (set_discard_entry(so, entry->key, entry->hash) < 0) {
1422 Py_DECREF(other);
1423 return -1;
1424 }
1425
1426 Py_DECREF(other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001427 } else {
1428 PyObject *key, *it;
1429 it = PyObject_GetIter(other);
1430 if (it == NULL)
1431 return -1;
1432
1433 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001434 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 Py_DECREF(it);
1436 Py_DECREF(key);
1437 return -1;
1438 }
1439 Py_DECREF(key);
1440 }
1441 Py_DECREF(it);
1442 if (PyErr_Occurred())
1443 return -1;
1444 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001445 /* If more than 1/4th are dummies, then resize them away. */
1446 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +09001448 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001449}
1450
Raymond Hettingera690a992003-11-16 16:17:49 +00001451static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001452set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001453{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001455
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001456 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1457 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001458 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 return NULL;
1460 }
1461 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001462}
1463
1464PyDoc_STRVAR(difference_update_doc,
1465"Remove all elements of another set from this set.");
1466
1467static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001468set_copy_and_difference(PySetObject *so, PyObject *other)
1469{
1470 PyObject *result;
1471
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301472 result = set_copy(so, NULL);
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001473 if (result == NULL)
1474 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001475 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001476 return result;
1477 Py_DECREF(result);
1478 return NULL;
1479}
1480
1481static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001482set_difference(PySetObject *so, PyObject *other)
1483{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001485 PyObject *key;
1486 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 setentry *entry;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001488 Py_ssize_t pos = 0, other_size;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001489 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001490
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001491 if (PyAnySet_Check(other)) {
1492 other_size = PySet_GET_SIZE(other);
1493 }
1494 else if (PyDict_CheckExact(other)) {
1495 other_size = PyDict_GET_SIZE(other);
1496 }
1497 else {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001498 return set_copy_and_difference(so, other);
1499 }
1500
1501 /* If len(so) much more than len(other), it's more efficient to simply copy
1502 * so and then iterate other looking for common elements. */
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001503 if ((PySet_GET_SIZE(so) >> 2) > other_size) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001504 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001507 result = make_new_set_basetype(Py_TYPE(so), NULL);
1508 if (result == NULL)
1509 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 if (PyDict_CheckExact(other)) {
1512 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001513 key = entry->key;
1514 hash = entry->hash;
Serhiy Storchakafb5db7e2020-10-26 08:43:39 +02001515 rv = _PyDict_Contains_KnownHash(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001516 if (rv < 0) {
1517 Py_DECREF(result);
1518 return NULL;
1519 }
1520 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001521 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001522 Py_DECREF(result);
1523 return NULL;
1524 }
1525 }
1526 }
1527 return result;
1528 }
1529
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001530 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001532 key = entry->key;
1533 hash = entry->hash;
1534 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001535 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001536 Py_DECREF(result);
1537 return NULL;
1538 }
1539 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001540 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541 Py_DECREF(result);
1542 return NULL;
1543 }
1544 }
1545 }
1546 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001547}
1548
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001549static PyObject *
1550set_difference_multi(PySetObject *so, PyObject *args)
1551{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001552 Py_ssize_t i;
1553 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001555 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301556 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 other = PyTuple_GET_ITEM(args, 0);
1559 result = set_difference(so, other);
1560 if (result == NULL)
1561 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001562
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001563 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1564 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001565 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 Py_DECREF(result);
1567 return NULL;
1568 }
1569 }
1570 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001571}
1572
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001573PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001574"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001575\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001576(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001577static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001578set_sub(PySetObject *so, PyObject *other)
1579{
Brian Curtindfc80e32011-08-10 20:28:54 -05001580 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1581 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001583}
1584
1585static PyObject *
1586set_isub(PySetObject *so, PyObject *other)
1587{
Brian Curtindfc80e32011-08-10 20:28:54 -05001588 if (!PyAnySet_Check(other))
1589 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001590 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 return NULL;
1592 Py_INCREF(so);
1593 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001594}
1595
1596static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001597set_symmetric_difference_update(PySetObject *so, PyObject *other)
1598{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001599 PySetObject *otherset;
1600 PyObject *key;
1601 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001602 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001604 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301607 return set_clear(so, NULL);
Raymond Hettingera690a992003-11-16 16:17:49 +00001608
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001609 if (PyDict_CheckExact(other)) {
1610 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001612 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001613 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001614 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001615 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001617 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001618 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001619 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001620 Py_DECREF(key);
1621 return NULL;
1622 }
1623 }
Georg Brandl2d444492010-09-03 10:52:55 +00001624 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625 }
1626 Py_RETURN_NONE;
1627 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 if (PyAnySet_Check(other)) {
1630 Py_INCREF(other);
1631 otherset = (PySetObject *)other;
1632 } else {
1633 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1634 if (otherset == NULL)
1635 return NULL;
1636 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001637
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001638 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001639 key = entry->key;
1640 hash = entry->hash;
1641 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001642 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001643 Py_DECREF(otherset);
1644 return NULL;
1645 }
1646 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001647 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001648 Py_DECREF(otherset);
1649 return NULL;
1650 }
1651 }
1652 }
1653 Py_DECREF(otherset);
1654 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001655}
1656
1657PyDoc_STRVAR(symmetric_difference_update_doc,
1658"Update a set with the symmetric difference of itself and another.");
1659
1660static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001661set_symmetric_difference(PySetObject *so, PyObject *other)
1662{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001663 PyObject *rv;
1664 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001666 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1667 if (otherset == NULL)
1668 return NULL;
1669 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
lekma491bbed2018-05-02 11:29:10 +02001670 if (rv == NULL) {
1671 Py_DECREF(otherset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001672 return NULL;
lekma491bbed2018-05-02 11:29:10 +02001673 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001674 Py_DECREF(rv);
1675 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001676}
1677
1678PyDoc_STRVAR(symmetric_difference_doc,
1679"Return the symmetric difference of two sets as a new set.\n\
1680\n\
1681(i.e. all elements that are in exactly one of the sets.)");
1682
1683static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001684set_xor(PySetObject *so, PyObject *other)
1685{
Brian Curtindfc80e32011-08-10 20:28:54 -05001686 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1687 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001688 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001689}
1690
1691static PyObject *
1692set_ixor(PySetObject *so, PyObject *other)
1693{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001694 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001695
Brian Curtindfc80e32011-08-10 20:28:54 -05001696 if (!PyAnySet_Check(other))
1697 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001698 result = set_symmetric_difference_update(so, other);
1699 if (result == NULL)
1700 return NULL;
1701 Py_DECREF(result);
1702 Py_INCREF(so);
1703 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001704}
1705
1706static PyObject *
1707set_issubset(PySetObject *so, PyObject *other)
1708{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001709 setentry *entry;
1710 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001711 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001712
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001713 if (!PyAnySet_Check(other)) {
1714 PyObject *tmp, *result;
1715 tmp = make_new_set(&PySet_Type, other);
1716 if (tmp == NULL)
1717 return NULL;
1718 result = set_issubset(so, tmp);
1719 Py_DECREF(tmp);
1720 return result;
1721 }
1722 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1723 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001724
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001725 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001726 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001727 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 return NULL;
1729 if (!rv)
1730 Py_RETURN_FALSE;
1731 }
1732 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001733}
1734
1735PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1736
1737static PyObject *
1738set_issuperset(PySetObject *so, PyObject *other)
1739{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001741
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001742 if (!PyAnySet_Check(other)) {
1743 tmp = make_new_set(&PySet_Type, other);
1744 if (tmp == NULL)
1745 return NULL;
1746 result = set_issuperset(so, tmp);
1747 Py_DECREF(tmp);
1748 return result;
1749 }
1750 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001751}
1752
1753PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1754
Raymond Hettingera690a992003-11-16 16:17:49 +00001755static PyObject *
1756set_richcompare(PySetObject *v, PyObject *w, int op)
1757{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001758 PyObject *r1;
1759 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001760
Brian Curtindfc80e32011-08-10 20:28:54 -05001761 if(!PyAnySet_Check(w))
1762 Py_RETURN_NOTIMPLEMENTED;
1763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001764 switch (op) {
1765 case Py_EQ:
1766 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1767 Py_RETURN_FALSE;
1768 if (v->hash != -1 &&
1769 ((PySetObject *)w)->hash != -1 &&
1770 v->hash != ((PySetObject *)w)->hash)
1771 Py_RETURN_FALSE;
1772 return set_issubset(v, w);
1773 case Py_NE:
1774 r1 = set_richcompare(v, w, Py_EQ);
1775 if (r1 == NULL)
1776 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001777 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001778 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001779 if (r2 < 0)
1780 return NULL;
1781 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001782 case Py_LE:
1783 return set_issubset(v, w);
1784 case Py_GE:
1785 return set_issuperset(v, w);
1786 case Py_LT:
1787 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1788 Py_RETURN_FALSE;
1789 return set_issubset(v, w);
1790 case Py_GT:
1791 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1792 Py_RETURN_FALSE;
1793 return set_issuperset(v, w);
1794 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001795 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001796}
1797
Raymond Hettingera690a992003-11-16 16:17:49 +00001798static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001799set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001800{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001801 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001802 return NULL;
1803 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001804}
1805
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001806PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001807"Add an element to a set.\n\
1808\n\
1809This has no effect if the element is already present.");
1810
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001811static int
1812set_contains(PySetObject *so, PyObject *key)
1813{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001814 PyObject *tmpkey;
1815 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001816
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001817 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001818 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001819 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1820 return -1;
1821 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001822 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001823 if (tmpkey == NULL)
1824 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001825 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001826 Py_DECREF(tmpkey);
1827 }
1828 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001829}
1830
1831static PyObject *
1832set_direct_contains(PySetObject *so, PyObject *key)
1833{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001837 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 return NULL;
1839 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001840}
1841
1842PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1843
Raymond Hettingera690a992003-11-16 16:17:49 +00001844static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001845set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001846{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 PyObject *tmpkey;
1848 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001851 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1853 return NULL;
1854 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001855 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856 if (tmpkey == NULL)
1857 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001858 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001860 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 return NULL;
1862 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001865 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 return NULL;
1867 }
1868 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001869}
1870
1871PyDoc_STRVAR(remove_doc,
1872"Remove an element from a set; it must be a member.\n\
1873\n\
1874If the element is not a member, raise a KeyError.");
1875
1876static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001877set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001878{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001879 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001882 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001883 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1885 return NULL;
1886 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001887 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 if (tmpkey == NULL)
1889 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001890 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001892 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001893 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 }
1895 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001896}
1897
1898PyDoc_STRVAR(discard_doc,
1899"Remove an element from a set if it is a member.\n\
1900\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001902
1903static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301904set_reduce(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001905{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001907 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001908
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 keys = PySequence_List((PyObject *)so);
1910 if (keys == NULL)
1911 goto done;
1912 args = PyTuple_Pack(1, keys);
1913 if (args == NULL)
1914 goto done;
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001915 if (_PyObject_LookupAttrId((PyObject *)so, &PyId___dict__, &dict) < 0) {
1916 goto done;
1917 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001918 if (dict == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 dict = Py_None;
1920 Py_INCREF(dict);
1921 }
1922 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001923done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 Py_XDECREF(args);
1925 Py_XDECREF(keys);
1926 Py_XDECREF(dict);
1927 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001928}
1929
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001930static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301931set_sizeof(PySetObject *so, PyObject *Py_UNUSED(ignored))
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001932{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001933 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001934
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02001935 res = _PyObject_SIZE(Py_TYPE(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 if (so->table != so->smalltable)
1937 res = res + (so->mask + 1) * sizeof(setentry);
1938 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001939}
1940
1941PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001942static int
1943set_init(PySetObject *self, PyObject *args, PyObject *kwds)
1944{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001945 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001946
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001947 if (!_PyArg_NoKeywords("set", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001948 return -1;
1949 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
1950 return -1;
Raymond Hettingerb72e21b2016-03-25 02:29:59 -07001951 if (self->fill)
1952 set_clear_internal(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001953 self->hash = -1;
1954 if (iterable == NULL)
1955 return 0;
1956 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001957}
1958
Dong-hee Na6ff79f652020-03-17 02:17:38 +09001959static PyObject*
1960set_vectorcall(PyObject *type, PyObject * const*args,
1961 size_t nargsf, PyObject *kwnames)
1962{
1963 assert(PyType_Check(type));
1964
1965 if (!_PyArg_NoKwnames("set", kwnames)) {
1966 return NULL;
1967 }
1968
1969 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
1970 if (!_PyArg_CheckPositional("set", nargs, 0, 1)) {
1971 return NULL;
1972 }
1973
1974 if (nargs) {
1975 return make_new_set((PyTypeObject *)type, args[0]);
1976 }
1977
1978 return make_new_set((PyTypeObject *)type, NULL);
1979}
1980
Raymond Hettingera690a992003-11-16 16:17:49 +00001981static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001982 set_len, /* sq_length */
1983 0, /* sq_concat */
1984 0, /* sq_repeat */
1985 0, /* sq_item */
1986 0, /* sq_slice */
1987 0, /* sq_ass_item */
1988 0, /* sq_ass_slice */
1989 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00001990};
1991
1992/* set object ********************************************************/
1993
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00001994#ifdef Py_DEBUG
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301995static PyObject *test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored));
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00001996
1997PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
1998All is well if assertions don't fail.");
1999#endif
2000
Raymond Hettingera690a992003-11-16 16:17:49 +00002001static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002002 {"add", (PyCFunction)set_add, METH_O,
2003 add_doc},
2004 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2005 clear_doc},
2006 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2007 contains_doc},
2008 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2009 copy_doc},
2010 {"discard", (PyCFunction)set_discard, METH_O,
2011 discard_doc},
2012 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2013 difference_doc},
2014 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2015 difference_update_doc},
2016 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2017 intersection_doc},
2018 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2019 intersection_update_doc},
2020 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2021 isdisjoint_doc},
2022 {"issubset", (PyCFunction)set_issubset, METH_O,
2023 issubset_doc},
2024 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2025 issuperset_doc},
2026 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2027 pop_doc},
2028 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2029 reduce_doc},
2030 {"remove", (PyCFunction)set_remove, METH_O,
2031 remove_doc},
2032 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2033 sizeof_doc},
2034 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2035 symmetric_difference_doc},
2036 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2037 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002038#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002039 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2040 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002041#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002042 {"union", (PyCFunction)set_union, METH_VARARGS,
2043 union_doc},
2044 {"update", (PyCFunction)set_update, METH_VARARGS,
2045 update_doc},
Guido van Rossum48b069a2020-04-07 09:50:06 -07002046 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002047 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002048};
2049
2050static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002051 0, /*nb_add*/
2052 (binaryfunc)set_sub, /*nb_subtract*/
2053 0, /*nb_multiply*/
2054 0, /*nb_remainder*/
2055 0, /*nb_divmod*/
2056 0, /*nb_power*/
2057 0, /*nb_negative*/
2058 0, /*nb_positive*/
2059 0, /*nb_absolute*/
2060 0, /*nb_bool*/
2061 0, /*nb_invert*/
2062 0, /*nb_lshift*/
2063 0, /*nb_rshift*/
2064 (binaryfunc)set_and, /*nb_and*/
2065 (binaryfunc)set_xor, /*nb_xor*/
2066 (binaryfunc)set_or, /*nb_or*/
2067 0, /*nb_int*/
2068 0, /*nb_reserved*/
2069 0, /*nb_float*/
2070 0, /*nb_inplace_add*/
2071 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2072 0, /*nb_inplace_multiply*/
2073 0, /*nb_inplace_remainder*/
2074 0, /*nb_inplace_power*/
2075 0, /*nb_inplace_lshift*/
2076 0, /*nb_inplace_rshift*/
2077 (binaryfunc)set_iand, /*nb_inplace_and*/
2078 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2079 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002080};
2081
2082PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002083"set() -> new empty set object\n\
2084set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002085\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002086Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002087
2088PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002089 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2090 "set", /* tp_name */
2091 sizeof(PySetObject), /* tp_basicsize */
2092 0, /* tp_itemsize */
2093 /* methods */
2094 (destructor)set_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002095 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002096 0, /* tp_getattr */
2097 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002098 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 (reprfunc)set_repr, /* tp_repr */
2100 &set_as_number, /* tp_as_number */
2101 &set_as_sequence, /* tp_as_sequence */
2102 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002103 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002104 0, /* tp_call */
2105 0, /* tp_str */
2106 PyObject_GenericGetAttr, /* tp_getattro */
2107 0, /* tp_setattro */
2108 0, /* tp_as_buffer */
2109 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Brandt Bucher145bf262021-02-26 14:51:55 -08002110 Py_TPFLAGS_BASETYPE |
2111 _Py_TPFLAGS_MATCH_SELF, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002112 set_doc, /* tp_doc */
2113 (traverseproc)set_traverse, /* tp_traverse */
2114 (inquiry)set_clear_internal, /* tp_clear */
2115 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002116 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2117 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002118 0, /* tp_iternext */
2119 set_methods, /* tp_methods */
2120 0, /* tp_members */
2121 0, /* tp_getset */
2122 0, /* tp_base */
2123 0, /* tp_dict */
2124 0, /* tp_descr_get */
2125 0, /* tp_descr_set */
2126 0, /* tp_dictoffset */
2127 (initproc)set_init, /* tp_init */
2128 PyType_GenericAlloc, /* tp_alloc */
2129 set_new, /* tp_new */
2130 PyObject_GC_Del, /* tp_free */
Dong-hee Na6ff79f652020-03-17 02:17:38 +09002131 .tp_vectorcall = set_vectorcall,
Raymond Hettingera690a992003-11-16 16:17:49 +00002132};
2133
2134/* frozenset object ********************************************************/
2135
2136
2137static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002138 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2139 contains_doc},
2140 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2141 copy_doc},
2142 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2143 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002144 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002145 intersection_doc},
2146 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2147 isdisjoint_doc},
2148 {"issubset", (PyCFunction)set_issubset, METH_O,
2149 issubset_doc},
2150 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2151 issuperset_doc},
2152 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2153 reduce_doc},
2154 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2155 sizeof_doc},
2156 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2157 symmetric_difference_doc},
2158 {"union", (PyCFunction)set_union, METH_VARARGS,
2159 union_doc},
Guido van Rossum48b069a2020-04-07 09:50:06 -07002160 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002162};
2163
2164static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002165 0, /*nb_add*/
2166 (binaryfunc)set_sub, /*nb_subtract*/
2167 0, /*nb_multiply*/
2168 0, /*nb_remainder*/
2169 0, /*nb_divmod*/
2170 0, /*nb_power*/
2171 0, /*nb_negative*/
2172 0, /*nb_positive*/
2173 0, /*nb_absolute*/
2174 0, /*nb_bool*/
2175 0, /*nb_invert*/
2176 0, /*nb_lshift*/
2177 0, /*nb_rshift*/
2178 (binaryfunc)set_and, /*nb_and*/
2179 (binaryfunc)set_xor, /*nb_xor*/
2180 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002181};
2182
2183PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002184"frozenset() -> empty frozenset object\n\
2185frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002186\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002187Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002188
2189PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002190 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2191 "frozenset", /* tp_name */
2192 sizeof(PySetObject), /* tp_basicsize */
2193 0, /* tp_itemsize */
2194 /* methods */
2195 (destructor)set_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002196 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002197 0, /* tp_getattr */
2198 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002199 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002200 (reprfunc)set_repr, /* tp_repr */
2201 &frozenset_as_number, /* tp_as_number */
2202 &set_as_sequence, /* tp_as_sequence */
2203 0, /* tp_as_mapping */
2204 frozenset_hash, /* tp_hash */
2205 0, /* tp_call */
2206 0, /* tp_str */
2207 PyObject_GenericGetAttr, /* tp_getattro */
2208 0, /* tp_setattro */
2209 0, /* tp_as_buffer */
2210 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Brandt Bucher145bf262021-02-26 14:51:55 -08002211 Py_TPFLAGS_BASETYPE |
2212 _Py_TPFLAGS_MATCH_SELF, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002213 frozenset_doc, /* tp_doc */
2214 (traverseproc)set_traverse, /* tp_traverse */
2215 (inquiry)set_clear_internal, /* tp_clear */
2216 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002217 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002218 (getiterfunc)set_iter, /* tp_iter */
2219 0, /* tp_iternext */
2220 frozenset_methods, /* tp_methods */
2221 0, /* tp_members */
2222 0, /* tp_getset */
2223 0, /* tp_base */
2224 0, /* tp_dict */
2225 0, /* tp_descr_get */
2226 0, /* tp_descr_set */
2227 0, /* tp_dictoffset */
2228 0, /* tp_init */
2229 PyType_GenericAlloc, /* tp_alloc */
2230 frozenset_new, /* tp_new */
2231 PyObject_GC_Del, /* tp_free */
Dong-hee Na1c605672020-03-19 02:30:50 +09002232 .tp_vectorcall = frozenset_vectorcall,
Raymond Hettingera690a992003-11-16 16:17:49 +00002233};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002234
2235
2236/***** C API functions *************************************************/
2237
2238PyObject *
2239PySet_New(PyObject *iterable)
2240{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002242}
2243
2244PyObject *
2245PyFrozenSet_New(PyObject *iterable)
2246{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002248}
2249
Neal Norwitz8c49c822006-03-04 18:41:19 +00002250Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002251PySet_Size(PyObject *anyset)
2252{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002253 if (!PyAnySet_Check(anyset)) {
2254 PyErr_BadInternalCall();
2255 return -1;
2256 }
2257 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002258}
2259
2260int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002261PySet_Clear(PyObject *set)
2262{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 if (!PySet_Check(set)) {
2264 PyErr_BadInternalCall();
2265 return -1;
2266 }
2267 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002268}
2269
2270int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002271PySet_Contains(PyObject *anyset, PyObject *key)
2272{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002273 if (!PyAnySet_Check(anyset)) {
2274 PyErr_BadInternalCall();
2275 return -1;
2276 }
2277 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002278}
2279
2280int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002281PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002282{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002283 if (!PySet_Check(set)) {
2284 PyErr_BadInternalCall();
2285 return -1;
2286 }
2287 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002288}
2289
2290int
Christian Heimesfd66e512008-01-29 12:18:50 +00002291PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002292{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002293 if (!PySet_Check(anyset) &&
2294 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2295 PyErr_BadInternalCall();
2296 return -1;
2297 }
2298 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002299}
2300
Raymond Hettinger3625af52016-03-27 01:15:07 -07002301int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002302_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002303{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002304 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002306 if (!PyAnySet_Check(set)) {
2307 PyErr_BadInternalCall();
2308 return -1;
2309 }
2310 if (set_next((PySetObject *)set, pos, &entry) == 0)
2311 return 0;
2312 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002313 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002314 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002315}
2316
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002317PyObject *
2318PySet_Pop(PyObject *set)
2319{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002320 if (!PySet_Check(set)) {
2321 PyErr_BadInternalCall();
2322 return NULL;
2323 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302324 return set_pop((PySetObject *)set, NULL);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002325}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002326
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002327int
2328_PySet_Update(PyObject *set, PyObject *iterable)
2329{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002330 if (!PySet_Check(set)) {
2331 PyErr_BadInternalCall();
2332 return -1;
2333 }
2334 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002335}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002336
Raymond Hettingere259f132013-12-15 11:56:14 -08002337/* Exported for the gdb plugin's benefit. */
2338PyObject *_PySet_Dummy = dummy;
2339
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002340#ifdef Py_DEBUG
2341
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002342/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002343 Returns True and original set is restored. */
2344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002345#define assertRaises(call_return_value, exception) \
2346 do { \
2347 assert(call_return_value); \
2348 assert(PyErr_ExceptionMatches(exception)); \
2349 PyErr_Clear(); \
2350 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002351
2352static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302353test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002354{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002355 Py_ssize_t count;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +02002356 const char *s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002357 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002358 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002359 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002360 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002361 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002363 /* Verify preconditions */
2364 assert(PyAnySet_Check(ob));
2365 assert(PyAnySet_CheckExact(ob));
2366 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002368 /* so.clear(); so |= set("abc"); */
2369 str = PyUnicode_FromString("abc");
2370 if (str == NULL)
2371 return NULL;
2372 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002373 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002374 Py_DECREF(str);
2375 return NULL;
2376 }
2377 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002379 /* Exercise type/size checks */
2380 assert(PySet_Size(ob) == 3);
2381 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002383 /* Raise TypeError for non-iterable constructor arguments */
2384 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2385 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002387 /* Raise TypeError for unhashable key */
2388 dup = PySet_New(ob);
2389 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2390 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2391 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002392
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002393 /* Exercise successful pop, contains, add, and discard */
2394 elem = PySet_Pop(ob);
2395 assert(PySet_Contains(ob, elem) == 0);
2396 assert(PySet_GET_SIZE(ob) == 2);
2397 assert(PySet_Add(ob, elem) == 0);
2398 assert(PySet_Contains(ob, elem) == 1);
2399 assert(PySet_GET_SIZE(ob) == 3);
2400 assert(PySet_Discard(ob, elem) == 1);
2401 assert(PySet_GET_SIZE(ob) == 2);
2402 assert(PySet_Discard(ob, elem) == 0);
2403 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405 /* Exercise clear */
2406 dup2 = PySet_New(dup);
2407 assert(PySet_Clear(dup2) == 0);
2408 assert(PySet_Size(dup2) == 0);
2409 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002411 /* Raise SystemError on clear or update of frozen set */
2412 f = PyFrozenSet_New(dup);
2413 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2414 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2415 assert(PySet_Add(f, elem) == 0);
2416 Py_INCREF(f);
2417 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2418 Py_DECREF(f);
2419 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 /* Exercise direct iteration */
2422 i = 0, count = 0;
2423 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
Serhiy Storchaka06515832016-11-20 09:13:07 +02002424 s = PyUnicode_AsUTF8(x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002425 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2426 count++;
2427 }
2428 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002430 /* Exercise updates */
2431 dup2 = PySet_New(NULL);
2432 assert(_PySet_Update(dup2, dup) == 0);
2433 assert(PySet_Size(dup2) == 3);
2434 assert(_PySet_Update(dup2, dup) == 0);
2435 assert(PySet_Size(dup2) == 3);
2436 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002438 /* Raise SystemError when self argument is not a set or frozenset. */
2439 t = PyTuple_New(0);
2440 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2441 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2442 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002443
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002444 /* Raise SystemError when self argument is not a set. */
2445 f = PyFrozenSet_New(dup);
2446 assert(PySet_Size(f) == 3);
2447 assert(PyFrozenSet_CheckExact(f));
2448 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2449 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2450 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002452 /* Raise KeyError when popping from an empty set */
2453 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2454 Py_DECREF(ob);
2455 assert(PySet_GET_SIZE(ob) == 0);
2456 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002458 /* Restore the set from the copy using the PyNumber API */
2459 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2460 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002462 /* Verify constructors accept NULL arguments */
2463 f = PySet_New(NULL);
2464 assert(f != NULL);
2465 assert(PySet_GET_SIZE(f) == 0);
2466 Py_DECREF(f);
2467 f = PyFrozenSet_New(NULL);
2468 assert(f != NULL);
2469 assert(PyFrozenSet_CheckExact(f));
2470 assert(PySet_GET_SIZE(f) == 0);
2471 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002472
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002473 Py_DECREF(elem);
2474 Py_DECREF(dup);
2475 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002476}
2477
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002478#undef assertRaises
2479
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002480#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002481
2482/***** Dummy Struct *************************************************/
2483
2484static PyObject *
2485dummy_repr(PyObject *op)
2486{
2487 return PyUnicode_FromString("<dummy key>");
2488}
2489
Victor Stinner2a4903f2020-01-30 13:09:11 +01002490static void _Py_NO_RETURN
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002491dummy_dealloc(PyObject* ignore)
2492{
2493 Py_FatalError("deallocating <dummy key>");
2494}
2495
2496static PyTypeObject _PySetDummy_Type = {
2497 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2498 "<dummy key> type",
2499 0,
2500 0,
2501 dummy_dealloc, /*tp_dealloc*/ /*never called*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002502 0, /*tp_vectorcall_offset*/
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002503 0, /*tp_getattr*/
2504 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002505 0, /*tp_as_async*/
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002506 dummy_repr, /*tp_repr*/
2507 0, /*tp_as_number*/
2508 0, /*tp_as_sequence*/
2509 0, /*tp_as_mapping*/
2510 0, /*tp_hash */
2511 0, /*tp_call */
2512 0, /*tp_str */
2513 0, /*tp_getattro */
2514 0, /*tp_setattro */
2515 0, /*tp_as_buffer */
2516 Py_TPFLAGS_DEFAULT, /*tp_flags */
2517};
2518
2519static PyObject _dummy_struct = {
2520 _PyObject_EXTRA_INIT
2521 2, &_PySetDummy_Type
2522};