blob: df4a0e1e9420e66f64cd6f03d5af9f4bda5efd7e [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 Hettinger38bb95e2015-06-24 01:22:19 -070060 size_t perturb;
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 Hettinger8408dc52013-09-15 14:57:15 -070063 size_t j;
Raymond Hettinger4ef05282013-09-21 15:39:49 -070064 int cmp;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000065
Raymond Hettinger70559b52015-07-23 07:42:23 -040066 entry = &so->table[i];
Raymond Hettingerafe89092013-08-28 20:59:31 -070067 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068 return entry;
Raymond Hettinger237b34b2013-08-17 02:31:53 -070069
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070070 perturb = hash;
71
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -070072 while (1) {
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080073 if (entry->hash == hash) {
Raymond Hettingerafe89092013-08-28 20:59:31 -070074 PyObject *startkey = entry->key;
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080075 /* startkey cannot be a dummy because the dummy hash field is -1 */
76 assert(startkey != dummy);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -080077 if (startkey == key)
78 return entry;
Raymond Hettinger93035c42015-01-25 16:12:49 -080079 if (PyUnicode_CheckExact(startkey)
80 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -070081 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger93035c42015-01-25 16:12:49 -080082 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -040083 table = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 Py_INCREF(startkey);
85 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
86 Py_DECREF(startkey);
Raymond Hettinger426d9952014-05-18 21:40:20 +010087 if (cmp < 0) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000088 return NULL;
Raymond Hettinger426d9952014-05-18 21:40:20 +010089 if (table != so->table || entry->key != startkey) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 return set_lookkey(so, key, hash);
Raymond Hettinger426d9952014-05-18 21:40:20 +010091 if (cmp > 0) /* likely */
Raymond Hettingerafe89092013-08-28 20:59:31 -070092 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -060093 mask = so->mask; /* help avoid a register spill */
Raymond Hettingerafe89092013-08-28 20:59:31 -070094 }
Raymond Hettingerafe89092013-08-28 20:59:31 -070095
Raymond Hettingerc658d852015-02-02 08:35:00 -080096 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -080097 for (j = 0 ; j < LINEAR_PROBES ; j++) {
Raymond Hettingerc658d852015-02-02 08:35:00 -080098 entry++;
Raymond Hettinger8651a502015-05-27 10:37:20 -070099 if (entry->hash == 0 && entry->key == NULL)
100 return entry;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800101 if (entry->hash == hash) {
102 PyObject *startkey = entry->key;
103 assert(startkey != dummy);
104 if (startkey == key)
105 return entry;
106 if (PyUnicode_CheckExact(startkey)
107 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700108 && _PyUnicode_EQ(startkey, key))
Raymond Hettingerc658d852015-02-02 08:35:00 -0800109 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400110 table = so->table;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800111 Py_INCREF(startkey);
112 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
113 Py_DECREF(startkey);
114 if (cmp < 0)
115 return NULL;
116 if (table != so->table || entry->key != startkey)
117 return set_lookkey(so, key, hash);
118 if (cmp > 0)
119 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -0600120 mask = so->mask;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800121 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700122 }
123 }
124
125 perturb >>= PERTURB_SHIFT;
126 i = (i * 5 + 1 + perturb) & mask;
127
Raymond Hettinger70559b52015-07-23 07:42:23 -0400128 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700129 if (entry->key == NULL)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700130 return entry;
131 }
132}
133
Raymond Hettinger15f08692015-07-03 17:21:17 -0700134static int set_table_resize(PySetObject *, Py_ssize_t);
135
Raymond Hettinger8651a502015-05-27 10:37:20 -0700136static int
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400137set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700138{
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400139 setentry *table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700140 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700141 size_t perturb;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400142 size_t mask;
143 size_t i; /* Unsigned for defined overflow behavior */
Raymond Hettinger8651a502015-05-27 10:37:20 -0700144 size_t j;
145 int cmp;
146
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400147 /* Pre-increment is necessary to prevent arbitrary code in the rich
148 comparison from deallocating the key just before the insertion. */
149 Py_INCREF(key);
150
151 restart:
152
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400153 mask = so->mask;
154 i = (size_t)hash & mask;
155
Raymond Hettinger70559b52015-07-23 07:42:23 -0400156 entry = &so->table[i];
Raymond Hettinger8651a502015-05-27 10:37:20 -0700157 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700158 goto found_unused;
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700159
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700160 perturb = hash;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700161
162 while (1) {
163 if (entry->hash == hash) {
164 PyObject *startkey = entry->key;
165 /* startkey cannot be a dummy because the dummy hash field is -1 */
166 assert(startkey != dummy);
167 if (startkey == key)
168 goto found_active;
169 if (PyUnicode_CheckExact(startkey)
170 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700171 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700172 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400173 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700174 Py_INCREF(startkey);
175 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
176 Py_DECREF(startkey);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700177 if (cmp > 0) /* likely */
178 goto found_active;
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700179 if (cmp < 0)
180 goto comparison_error;
181 /* Continuing the search from the current entry only makes
182 sense if the table and entry are unchanged; otherwise,
183 we have to restart from the beginning */
184 if (table != so->table || entry->key != startkey)
185 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700186 mask = so->mask; /* help avoid a register spill */
187 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700188
189 if (i + LINEAR_PROBES <= mask) {
190 for (j = 0 ; j < LINEAR_PROBES ; j++) {
191 entry++;
192 if (entry->hash == 0 && entry->key == NULL)
Raymond Hettinger3dd21572020-05-03 04:51:05 -0700193 goto found_unused;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700194 if (entry->hash == hash) {
195 PyObject *startkey = entry->key;
196 assert(startkey != dummy);
197 if (startkey == key)
198 goto found_active;
199 if (PyUnicode_CheckExact(startkey)
200 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700201 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700202 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400203 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700204 Py_INCREF(startkey);
205 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
206 Py_DECREF(startkey);
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700207 if (cmp > 0)
208 goto found_active;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700209 if (cmp < 0)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400210 goto comparison_error;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700211 if (table != so->table || entry->key != startkey)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400212 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700213 mask = so->mask;
214 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700215 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000216 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700217
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700218 perturb >>= PERTURB_SHIFT;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -0800219 i = (i * 5 + 1 + perturb) & mask;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700220
Raymond Hettinger70559b52015-07-23 07:42:23 -0400221 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700222 if (entry->key == NULL)
Raymond Hettinger3dd21572020-05-03 04:51:05 -0700223 goto found_unused;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000224 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700225
Raymond Hettinger15f08692015-07-03 17:21:17 -0700226 found_unused:
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700227 so->fill++;
228 so->used++;
229 entry->key = key;
230 entry->hash = hash;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800231 if ((size_t)so->fill*5 < mask*3)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700232 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +0900233 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700234
235 found_active:
Raymond Hettinger482c05c2015-07-20 01:23:32 -0400236 Py_DECREF(key);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700237 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000238
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400239 comparison_error:
Raymond Hettinger061091a2015-07-15 23:54:02 -0700240 Py_DECREF(key);
241 return -1;
242}
243
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000244/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000245Internal routine used by set_table_resize() to insert an item which is
246known to be absent from the set. This routine also assumes that
247the set contains no deleted entries. Besides the performance benefit,
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800248there is also safety benefit since using set_add_entry() risks making
249a callback in the middle of a set_table_resize(), see issue 1456209.
250The caller is responsible for updating the key's reference count and
251the setobject's fill and used fields.
Thomas Wouters89f507f2006-12-13 04:49:30 +0000252*/
253static void
Raymond Hettinger5088f602015-12-13 18:45:01 -0800254set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000255{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200256 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700257 size_t perturb = hash;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800258 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700259 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000260
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700261 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800262 entry = &table[i];
263 if (entry->key == NULL)
264 goto found_null;
265 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800266 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800267 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800268 if (entry->key == NULL)
269 goto found_null;
270 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700271 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700272 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800273 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000274 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700275 found_null:
Raymond Hettinger5088f602015-12-13 18:45:01 -0800276 entry->key = key;
Raymond Hettinger86d322f2015-12-13 19:27:17 -0800277 entry->hash = hash;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000278}
279
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700280/* ======== End logic for probing the hash table ========================== */
281/* ======================================================================== */
282
Thomas Wouters89f507f2006-12-13 04:49:30 +0000283/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000284Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000285keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000286actually be smaller than the old one.
287*/
288static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000289set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000290{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 setentry *oldtable, *newtable, *entry;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800292 Py_ssize_t oldmask = so->mask;
293 size_t newmask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000294 int is_oldtable_malloced;
295 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 assert(minused >= 0);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000299 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100300 /* XXX speed-up with intrinsics */
Sergey Fedoseev6c7d67c2018-09-12 04:18:01 +0500301 size_t newsize = PySet_MINSIZE;
302 while (newsize <= (size_t)minused) {
303 newsize <<= 1; // The largest possible value is PY_SSIZE_T_MAX + 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 /* Get space for a new table. */
307 oldtable = so->table;
308 assert(oldtable != NULL);
309 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 if (newsize == PySet_MINSIZE) {
312 /* A large table is shrinking, or we can't get any smaller. */
313 newtable = so->smalltable;
314 if (newtable == oldtable) {
315 if (so->fill == so->used) {
316 /* No dummies, so no point doing anything. */
317 return 0;
318 }
319 /* We're not going to resize it, but rebuild the
320 table anyway to purge old dummy entries.
321 Subtle: This is *necessary* if fill==size,
322 as set_lookkey needs at least one virgin slot to
323 terminate failing searches. If fill < size, it's
324 merely desirable, as dummies slow searches. */
325 assert(so->fill > so->used);
326 memcpy(small_copy, oldtable, sizeof(small_copy));
327 oldtable = small_copy;
328 }
329 }
330 else {
331 newtable = PyMem_NEW(setentry, newsize);
332 if (newtable == NULL) {
333 PyErr_NoMemory();
334 return -1;
335 }
336 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000338 /* Make the set empty, using the new table. */
339 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000340 memset(newtable, 0, sizeof(setentry) * newsize);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800341 so->mask = newsize - 1;
342 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000344 /* Copy the data over; this is refcount-neutral for active entries;
345 dummy entries aren't copied over, of course */
Raymond Hettinger5088f602015-12-13 18:45:01 -0800346 newmask = (size_t)so->mask;
Raymond Hettingere1af6962017-02-02 08:24:48 -0800347 if (so->fill == so->used) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800348 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800349 if (entry->key != NULL) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800350 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800351 }
352 }
353 } else {
Raymond Hettingere1af6962017-02-02 08:24:48 -0800354 so->fill = so->used;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800355 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800356 if (entry->key != NULL && entry->key != dummy) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800357 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800358 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 }
360 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 if (is_oldtable_malloced)
363 PyMem_DEL(oldtable);
364 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000365}
366
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000367static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700368set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000369{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700370 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000371
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700372 entry = set_lookkey(so, key, hash);
373 if (entry != NULL)
374 return entry->key != NULL;
375 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000376}
377
378#define DISCARD_NOTFOUND 0
379#define DISCARD_FOUND 1
380
381static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700382set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800383{
384 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000386
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700387 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 if (entry == NULL)
389 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700390 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000391 return DISCARD_NOTFOUND;
392 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000393 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800394 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000395 so->used--;
396 Py_DECREF(old_key);
397 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000398}
399
400static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700401set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000402{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200403 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000404
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700405 if (!PyUnicode_CheckExact(key) ||
406 (hash = ((PyASCIIObject *) key)->hash) == -1) {
407 hash = PyObject_Hash(key);
408 if (hash == -1)
409 return -1;
410 }
411 return set_add_entry(so, key, hash);
412}
413
414static int
415set_contains_key(PySetObject *so, PyObject *key)
416{
417 Py_hash_t hash;
418
419 if (!PyUnicode_CheckExact(key) ||
420 (hash = ((PyASCIIObject *) key)->hash) == -1) {
421 hash = PyObject_Hash(key);
422 if (hash == -1)
423 return -1;
424 }
425 return set_contains_entry(so, key, hash);
426}
427
428static int
429set_discard_key(PySetObject *so, PyObject *key)
430{
431 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000433 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200434 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000435 hash = PyObject_Hash(key);
436 if (hash == -1)
437 return -1;
438 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700439 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000440}
441
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700442static void
443set_empty_to_minsize(PySetObject *so)
444{
445 memset(so->smalltable, 0, sizeof(so->smalltable));
446 so->fill = 0;
447 so->used = 0;
448 so->mask = PySet_MINSIZE - 1;
449 so->table = so->smalltable;
450 so->hash = -1;
451}
452
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000453static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000454set_clear_internal(PySetObject *so)
455{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800456 setentry *entry;
457 setentry *table = so->table;
458 Py_ssize_t fill = so->fill;
459 Py_ssize_t used = so->used;
460 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000461 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000462
Raymond Hettinger583cd032013-09-07 22:06:35 -0700463 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000464 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 /* This is delicate. During the process of clearing the set,
467 * decrefs can cause the set to mutate. To avoid fatal confusion
468 * (voice of experience), we have to make the set empty before
469 * clearing the slots, and never refer to anything via so->ref while
470 * clearing.
471 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700473 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000474
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 else if (fill > 0) {
476 /* It's a small table with something that needs to be cleared.
477 * Afraid the only safe way is to copy the set entries into
478 * another small table first.
479 */
480 memcpy(small_copy, table, sizeof(small_copy));
481 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700482 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 }
484 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 /* Now we can finally clear things. If C had refcounts, we could
487 * assert that the refcount on table is 1 now, i.e. that this function
488 * has unique access to it, so decref side-effects can't alter it.
489 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800490 for (entry = table; used > 0; entry++) {
491 if (entry->key && entry->key != dummy) {
492 used--;
493 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 if (table_is_malloced)
498 PyMem_DEL(table);
499 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000500}
501
502/*
503 * Iterate over a set table. Use like so:
504 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000505 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000506 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000507 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000508 * while (set_next(yourset, &pos, &entry)) {
509 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000510 * }
511 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000512 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000513 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000514 */
515static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000516set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000517{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000518 Py_ssize_t i;
519 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700520 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000522 assert (PyAnySet_Check(so));
523 i = *pos_ptr;
524 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000525 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700526 entry = &so->table[i];
527 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000528 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700529 entry++;
530 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000531 *pos_ptr = i+1;
532 if (i > mask)
533 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700534 assert(entry != NULL);
535 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000537}
538
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000539static void
540set_dealloc(PySetObject *so)
541{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200542 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800543 Py_ssize_t used = so->used;
544
INADA Naokia6296d32017-08-24 14:55:17 +0900545 /* bpo-31095: UnTrack is needed before calling any callbacks */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000546 PyObject_GC_UnTrack(so);
Jeroen Demeyer351c6742019-05-10 19:21:11 +0200547 Py_TRASHCAN_BEGIN(so, set_dealloc)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 if (so->weakreflist != NULL)
549 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000550
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800551 for (entry = so->table; used > 0; entry++) {
552 if (entry->key && entry->key != dummy) {
553 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700554 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000555 }
556 }
557 if (so->table != so->smalltable)
558 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700559 Py_TYPE(so)->tp_free(so);
Jeroen Demeyer351c6742019-05-10 19:21:11 +0200560 Py_TRASHCAN_END
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000561}
562
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000563static PyObject *
564set_repr(PySetObject *so)
565{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200566 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000567 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000568
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 if (status != 0) {
570 if (status < 0)
571 return NULL;
572 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
573 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000574
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000575 /* shortcut for the empty set */
576 if (!so->used) {
577 Py_ReprLeave((PyObject*)so);
578 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
579 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 keys = PySequence_List((PyObject *)so);
582 if (keys == NULL)
583 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000584
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200585 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 listrepr = PyObject_Repr(keys);
587 Py_DECREF(keys);
588 if (listrepr == NULL)
589 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200590 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000591 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200592 if (tmp == NULL)
593 goto done;
594 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200595
Andy Lester55728702020-03-06 16:53:17 -0600596 if (!Py_IS_TYPE(so, &PySet_Type))
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200597 result = PyUnicode_FromFormat("%s({%U})",
598 Py_TYPE(so)->tp_name,
599 listrepr);
600 else
601 result = PyUnicode_FromFormat("{%U}", listrepr);
602 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000603done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604 Py_ReprLeave((PyObject*)so);
605 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000606}
607
Martin v. Löwis18e16552006-02-15 17:27:45 +0000608static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000609set_len(PyObject *so)
610{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000611 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000612}
613
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000614static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000615set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000616{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000618 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200619 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700620 setentry *so_entry;
621 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 assert (PyAnySet_Check(so));
624 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 other = (PySetObject*)otherset;
627 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700628 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 return 0;
630 /* Do one big resize at the start, rather than
631 * incrementally resizing as we insert new keys. Expect
632 * that there will be no (or few) overlapping keys.
633 */
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800634 if ((so->fill + other->used)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900635 if (set_table_resize(so, (so->used + other->used)*2) != 0)
636 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700638 so_entry = so->table;
639 other_entry = other->table;
640
641 /* If our table is empty, and both tables have the same size, and
642 there are no dummies to eliminate, then just copy the pointers. */
643 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
644 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
645 key = other_entry->key;
646 if (key != NULL) {
647 assert(so_entry->key == NULL);
648 Py_INCREF(key);
649 so_entry->key = key;
650 so_entry->hash = other_entry->hash;
651 }
652 }
653 so->fill = other->fill;
654 so->used = other->used;
655 return 0;
656 }
657
658 /* If our table is empty, we can use set_insert_clean() */
659 if (so->fill == 0) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800660 setentry *newtable = so->table;
661 size_t newmask = (size_t)so->mask;
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800662 so->fill = other->used;
663 so->used = other->used;
Raymond Hettingere4495872015-12-15 00:42:30 -0800664 for (i = other->mask + 1; i > 0 ; i--, other_entry++) {
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700665 key = other_entry->key;
666 if (key != NULL && key != dummy) {
667 Py_INCREF(key);
Raymond Hettinger5088f602015-12-13 18:45:01 -0800668 set_insert_clean(newtable, newmask, key, other_entry->hash);
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700669 }
670 }
671 return 0;
672 }
673
674 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700675 for (i = 0; i <= other->mask; i++) {
676 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700677 key = other_entry->key;
678 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700679 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681 }
682 }
683 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000684}
685
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000686static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530687set_pop(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000688{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800689 /* Make sure the search finger is in bounds */
Raymond Hettingerf9ec1b92018-11-11 14:35:47 -0800690 setentry *entry = so->table + (so->finger & so->mask);
691 setentry *limit = so->table + so->mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000692 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000693
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000694 if (so->used == 0) {
695 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
696 return NULL;
697 }
Raymond Hettingercf5863f2018-11-09 02:31:56 -0800698 while (entry->key == NULL || entry->key==dummy) {
699 entry++;
700 if (entry > limit)
701 entry = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000702 }
703 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000704 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800705 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 so->used--;
Raymond Hettingercf5863f2018-11-09 02:31:56 -0800707 so->finger = entry - so->table + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000708 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000709}
710
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000711PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
712Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000713
714static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000715set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000716{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 Py_ssize_t pos = 0;
718 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000719
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 while (set_next(so, &pos, &entry))
721 Py_VISIT(entry->key);
722 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000723}
724
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700725/* Work to increase the bit dispersion for closely spaced hash values.
726 This is important because some use cases have many combinations of a
727 small number of elements with nearby hashes so that many distinct
728 combinations collapse to only a handful of distinct hash values. */
729
730static Py_uhash_t
731_shuffle_bits(Py_uhash_t h)
732{
733 return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
734}
735
736/* Most of the constants in this hash algorithm are randomly chosen
737 large primes with "interesting bit patterns" and that passed tests
738 for good collision statistics on a variety of problematic datasets
739 including powersets and graph structures (such as David Eppstein's
740 graph recipes in Lib/test/test_set.py) */
741
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000742static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000743frozenset_hash(PyObject *self)
744{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000745 PySetObject *so = (PySetObject *)self;
Raymond Hettinger41481952015-08-07 00:43:39 -0700746 Py_uhash_t hash = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000748
Raymond Hettingerb501a272015-08-06 22:15:22 -0700749 if (so->hash != -1)
750 return so->hash;
751
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700752 /* Xor-in shuffled bits from every entry's hash field because xor is
753 commutative and a frozenset hash should be independent of order.
754
755 For speed, include null entries and dummy entries and then
756 subtract out their effect afterwards so that the final hash
757 depends only on active entries. This allows the code to be
758 vectorized by the compiler and it saves the unpredictable
759 branches that would arise when trying to exclude null and dummy
760 entries on every iteration. */
761
762 for (entry = so->table; entry <= &so->table[so->mask]; entry++)
763 hash ^= _shuffle_bits(entry->hash);
764
Raymond Hettingera286a512015-08-01 11:07:11 -0700765 /* Remove the effect of an odd number of NULL entries */
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700766 if ((so->mask + 1 - so->fill) & 1)
767 hash ^= _shuffle_bits(0);
768
769 /* Remove the effect of an odd number of dummy entries */
770 if ((so->fill - so->used) & 1)
771 hash ^= _shuffle_bits(-1);
772
Raymond Hettinger41481952015-08-07 00:43:39 -0700773 /* Factor in the number of active entries */
774 hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;
775
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700776 /* Disperse patterns arising in nested frozensets */
Raymond Hettingerfa788062018-01-18 13:23:27 -0800777 hash ^= (hash >> 11) ^ (hash >> 25);
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800778 hash = hash * 69069U + 907133923UL;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700779
Raymond Hettinger36c05002015-08-01 10:57:42 -0700780 /* -1 is reserved as an error code */
Victor Stinner12174a52014-08-15 23:17:38 +0200781 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800782 hash = 590923713UL;
Raymond Hettinger36c05002015-08-01 10:57:42 -0700783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000784 so->hash = hash;
785 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000786}
787
Raymond Hettingera9d99362005-08-05 00:01:15 +0000788/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000789
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000790typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000791 PyObject_HEAD
792 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
793 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700794 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000795 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000796} setiterobject;
797
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000798static void
799setiter_dealloc(setiterobject *si)
800{
INADA Naokia6296d32017-08-24 14:55:17 +0900801 /* bpo-31095: UnTrack is needed before calling any callbacks */
802 _PyObject_GC_UNTRACK(si);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000803 Py_XDECREF(si->si_set);
804 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000805}
806
807static int
808setiter_traverse(setiterobject *si, visitproc visit, void *arg)
809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000810 Py_VISIT(si->si_set);
811 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000812}
813
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000814static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530815setiter_len(setiterobject *si, PyObject *Py_UNUSED(ignored))
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000816{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000817 Py_ssize_t len = 0;
818 if (si->si_set != NULL && si->si_used == si->si_set->used)
819 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000820 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000821}
822
Armin Rigof5b3e362006-02-11 21:32:43 +0000823PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000824
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000825static PyObject *setiter_iternext(setiterobject *si);
826
827static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530828setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000829{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200830 _Py_IDENTIFIER(iter);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300831 /* copy the iterator state */
Sergey Fedoseev63958442018-10-20 05:43:33 +0500832 setiterobject tmp = *si;
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000833 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300834
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000835 /* iterate the temporary into a list */
Sergey Fedoseev63958442018-10-20 05:43:33 +0500836 PyObject *list = PySequence_List((PyObject*)&tmp);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000837 Py_XDECREF(tmp.si_set);
Sergey Fedoseev63958442018-10-20 05:43:33 +0500838 if (list == NULL) {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000839 return NULL;
840 }
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200841 return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000842}
843
844PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
845
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000846static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000847 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000848 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000849 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000850};
851
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000852static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000853{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700854 PyObject *key;
855 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200856 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000859 if (so == NULL)
860 return NULL;
861 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000863 if (si->si_used != so->used) {
864 PyErr_SetString(PyExc_RuntimeError,
865 "Set changed size during iteration");
866 si->si_used = -1; /* Make this state sticky */
867 return NULL;
868 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700869
870 i = si->si_pos;
871 assert(i>=0);
872 entry = so->table;
873 mask = so->mask;
874 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
875 i++;
876 si->si_pos = i+1;
877 if (i > mask)
878 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000879 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700880 key = entry[i].key;
881 Py_INCREF(key);
882 return key;
883
884fail:
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700885 si->si_set = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +0300886 Py_DECREF(so);
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700887 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000888}
889
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000890PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000891 PyVarObject_HEAD_INIT(&PyType_Type, 0)
892 "set_iterator", /* tp_name */
893 sizeof(setiterobject), /* tp_basicsize */
894 0, /* tp_itemsize */
895 /* methods */
896 (destructor)setiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200897 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000898 0, /* tp_getattr */
899 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200900 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000901 0, /* tp_repr */
902 0, /* tp_as_number */
903 0, /* tp_as_sequence */
904 0, /* tp_as_mapping */
905 0, /* tp_hash */
906 0, /* tp_call */
907 0, /* tp_str */
908 PyObject_GenericGetAttr, /* tp_getattro */
909 0, /* tp_setattro */
910 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700911 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000912 0, /* tp_doc */
913 (traverseproc)setiter_traverse, /* tp_traverse */
914 0, /* tp_clear */
915 0, /* tp_richcompare */
916 0, /* tp_weaklistoffset */
917 PyObject_SelfIter, /* tp_iter */
918 (iternextfunc)setiter_iternext, /* tp_iternext */
919 setiter_methods, /* tp_methods */
920 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000921};
922
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000923static PyObject *
924set_iter(PySetObject *so)
925{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
927 if (si == NULL)
928 return NULL;
929 Py_INCREF(so);
930 si->si_set = so;
931 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700932 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000933 si->len = so->used;
934 _PyObject_GC_TRACK(si);
935 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000936}
937
Raymond Hettingerd7946662005-08-01 21:39:29 +0000938static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000939set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000940{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000941 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000943 if (PyAnySet_Check(other))
944 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000945
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000946 if (PyDict_CheckExact(other)) {
947 PyObject *value;
948 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000949 Py_hash_t hash;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200950 Py_ssize_t dictsize = PyDict_GET_SIZE(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000952 /* Do one big resize at the start, rather than
953 * incrementally resizing as we insert new keys. Expect
954 * that there will be no (or few) overlapping keys.
955 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700956 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 return -1;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800958 if ((so->fill + dictsize)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900959 if (set_table_resize(so, (so->used + dictsize)*2) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000960 return -1;
961 }
962 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700963 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000964 return -1;
965 }
966 return 0;
967 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000968
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 it = PyObject_GetIter(other);
970 if (it == NULL)
971 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +0000972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700974 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000975 Py_DECREF(it);
976 Py_DECREF(key);
977 return -1;
978 }
979 Py_DECREF(key);
980 }
981 Py_DECREF(it);
982 if (PyErr_Occurred())
983 return -1;
984 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000985}
986
987static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000988set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +0000989{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000990 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000992 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
993 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700994 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000995 return NULL;
996 }
997 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +0000998}
999
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001000PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001001"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001002
Raymond Hettinger426d9952014-05-18 21:40:20 +01001003/* XXX Todo:
1004 If aligned memory allocations become available, make the
1005 set object 64 byte aligned so that most of the fields
1006 can be retrieved or updated in a single cache line.
1007*/
1008
Raymond Hettingera38123e2003-11-24 22:18:49 +00001009static PyObject *
1010make_new_set(PyTypeObject *type, PyObject *iterable)
1011{
Dong-hee Na1c605672020-03-19 02:30:50 +09001012 assert(PyType_Check(type));
Raymond Hettinger8421d712016-04-29 01:37:05 -07001013 PySetObject *so;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001014
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001015 so = (PySetObject *)type->tp_alloc(type, 0);
1016 if (so == NULL)
1017 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001018
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001019 so->fill = 0;
1020 so->used = 0;
1021 so->mask = PySet_MINSIZE - 1;
1022 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001023 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001024 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001025 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001026
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001028 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001029 Py_DECREF(so);
1030 return NULL;
1031 }
1032 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001033
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001035}
1036
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001037static PyObject *
1038make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1039{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001040 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1041 if (PyType_IsSubtype(type, &PySet_Type))
1042 type = &PySet_Type;
1043 else
1044 type = &PyFrozenSet_Type;
1045 }
1046 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001047}
1048
Raymond Hettingerd7946662005-08-01 21:39:29 +00001049/* The empty frozenset is a singleton */
1050static PyObject *emptyfrozenset = NULL;
1051
Raymond Hettingera690a992003-11-16 16:17:49 +00001052static PyObject *
Dong-hee Na1c605672020-03-19 02:30:50 +09001053make_new_frozenset(PyTypeObject *type, PyObject *iterable)
Raymond Hettingera690a992003-11-16 16:17:49 +00001054{
Dong-hee Na1c605672020-03-19 02:30:50 +09001055 if (type != &PyFrozenSet_Type) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001056 return make_new_set(type, iterable);
Dong-hee Na1c605672020-03-19 02:30:50 +09001057 }
Raymond Hettingerd7946662005-08-01 21:39:29 +00001058
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 if (iterable != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 if (PyFrozenSet_CheckExact(iterable)) {
Dong-hee Na1c605672020-03-19 02:30:50 +09001061 /* frozenset(f) is idempotent */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062 Py_INCREF(iterable);
1063 return iterable;
1064 }
Dong-hee Na1c605672020-03-19 02:30:50 +09001065 PyObject *res = make_new_set((PyTypeObject *)type, iterable);
1066 if (res == NULL || PySet_GET_SIZE(res) != 0) {
1067 return res;
1068 }
1069 /* If the created frozenset is empty, return the empty frozenset singleton instead */
1070 Py_DECREF(res);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 }
Dong-hee Na1c605672020-03-19 02:30:50 +09001072
1073 // The empty frozenset is a singleton
1074 if (emptyfrozenset == NULL) {
1075 emptyfrozenset = make_new_set((PyTypeObject *)type, NULL);
1076 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 Py_XINCREF(emptyfrozenset);
1078 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001079}
1080
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001081static PyObject *
Dong-hee Na1c605672020-03-19 02:30:50 +09001082frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1083{
1084 PyObject *iterable = NULL;
1085
1086 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset", kwds)) {
1087 return NULL;
1088 }
1089
1090 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable)) {
1091 return NULL;
1092 }
1093
1094 return make_new_frozenset(type, iterable);
1095}
1096
1097static PyObject *
1098frozenset_vectorcall(PyObject *type, PyObject * const*args,
1099 size_t nargsf, PyObject *kwnames)
1100{
1101 if (!_PyArg_NoKwnames("frozenset", kwnames)) {
1102 return NULL;
1103 }
1104
1105 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
1106 if (!_PyArg_CheckPositional("frozenset", nargs, 0, 1)) {
1107 return NULL;
1108 }
1109
1110 PyObject *iterable = (nargs ? args[0] : NULL);
1111 return make_new_frozenset((PyTypeObject *)type, iterable);
1112}
1113
1114static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001115set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1116{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001117 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001118}
1119
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001120/* set_swap_bodies() switches the contents of any two sets by moving their
1121 internal data pointers and, if needed, copying the internal smalltables.
1122 Semantically equivalent to:
1123
1124 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1125
1126 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001127 Useful for operations that update in-place (by allowing an intermediate
1128 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001129*/
1130
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001131static void
1132set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001133{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001134 Py_ssize_t t;
1135 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001137 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001139 t = a->fill; a->fill = b->fill; b->fill = t;
1140 t = a->used; a->used = b->used; b->used = t;
1141 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001143 u = a->table;
1144 if (a->table == a->smalltable)
1145 u = b->smalltable;
1146 a->table = b->table;
1147 if (b->table == b->smalltable)
1148 a->table = a->smalltable;
1149 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 if (a->table == a->smalltable || b->table == b->smalltable) {
1152 memcpy(tab, a->smalltable, sizeof(tab));
1153 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1154 memcpy(b->smalltable, tab, sizeof(tab));
1155 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001157 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1158 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1159 h = a->hash; a->hash = b->hash; b->hash = h;
1160 } else {
1161 a->hash = -1;
1162 b->hash = -1;
1163 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001164}
1165
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001166static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301167set_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001168{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001169 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001170}
1171
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001172static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301173frozenset_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 if (PyFrozenSet_CheckExact(so)) {
1176 Py_INCREF(so);
1177 return (PyObject *)so;
1178 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301179 return set_copy(so, NULL);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001180}
1181
Raymond Hettingera690a992003-11-16 16:17:49 +00001182PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1183
1184static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301185set_clear(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc991db22005-08-11 07:58:45 +00001186{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 set_clear_internal(so);
1188 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001189}
1190
1191PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1192
1193static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001194set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001195{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001196 PySetObject *result;
1197 PyObject *other;
1198 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001199
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301200 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001201 if (result == NULL)
1202 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001204 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1205 other = PyTuple_GET_ITEM(args, i);
1206 if ((PyObject *)so == other)
1207 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001208 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 Py_DECREF(result);
1210 return NULL;
1211 }
1212 }
1213 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001214}
1215
1216PyDoc_STRVAR(union_doc,
1217 "Return the union of sets as a new set.\n\
1218\n\
1219(i.e. all elements that are in either set.)");
1220
1221static PyObject *
1222set_or(PySetObject *so, PyObject *other)
1223{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001224 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001225
Brian Curtindfc80e32011-08-10 20:28:54 -05001226 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1227 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001228
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301229 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001230 if (result == NULL)
1231 return NULL;
1232 if ((PyObject *)so == other)
1233 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001234 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 Py_DECREF(result);
1236 return NULL;
1237 }
1238 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001239}
1240
Raymond Hettingera690a992003-11-16 16:17:49 +00001241static PyObject *
1242set_ior(PySetObject *so, PyObject *other)
1243{
Brian Curtindfc80e32011-08-10 20:28:54 -05001244 if (!PyAnySet_Check(other))
1245 Py_RETURN_NOTIMPLEMENTED;
1246
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001247 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 return NULL;
1249 Py_INCREF(so);
1250 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001251}
1252
1253static PyObject *
1254set_intersection(PySetObject *so, PyObject *other)
1255{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 PySetObject *result;
1257 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001258 Py_hash_t hash;
1259 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301262 return set_copy(so, NULL);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1265 if (result == NULL)
1266 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 if (PyAnySet_Check(other)) {
1269 Py_ssize_t pos = 0;
1270 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001272 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1273 tmp = (PyObject *)so;
1274 so = (PySetObject *)other;
1275 other = tmp;
1276 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001278 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001279 key = entry->key;
1280 hash = entry->hash;
1281 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001282 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 Py_DECREF(result);
1284 return NULL;
1285 }
1286 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001287 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 Py_DECREF(result);
1289 return NULL;
1290 }
1291 }
1292 }
1293 return (PyObject *)result;
1294 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 it = PyObject_GetIter(other);
1297 if (it == NULL) {
1298 Py_DECREF(result);
1299 return NULL;
1300 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001303 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001304 if (hash == -1)
1305 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001306 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001307 if (rv < 0)
1308 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001309 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001310 if (set_add_entry(result, key, hash))
1311 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 }
1313 Py_DECREF(key);
1314 }
1315 Py_DECREF(it);
1316 if (PyErr_Occurred()) {
1317 Py_DECREF(result);
1318 return NULL;
1319 }
1320 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001321 error:
1322 Py_DECREF(it);
1323 Py_DECREF(result);
1324 Py_DECREF(key);
1325 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001326}
1327
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001328static PyObject *
1329set_intersection_multi(PySetObject *so, PyObject *args)
1330{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001331 Py_ssize_t i;
1332 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001333
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001334 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301335 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 Py_INCREF(so);
1338 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1339 PyObject *other = PyTuple_GET_ITEM(args, i);
1340 PyObject *newresult = set_intersection((PySetObject *)result, other);
1341 if (newresult == NULL) {
1342 Py_DECREF(result);
1343 return NULL;
1344 }
1345 Py_DECREF(result);
1346 result = newresult;
1347 }
1348 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001349}
1350
Raymond Hettingera690a992003-11-16 16:17:49 +00001351PyDoc_STRVAR(intersection_doc,
1352"Return the intersection of two sets as a new set.\n\
1353\n\
1354(i.e. all elements that are in both sets.)");
1355
1356static PyObject *
1357set_intersection_update(PySetObject *so, PyObject *other)
1358{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001359 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001361 tmp = set_intersection(so, other);
1362 if (tmp == NULL)
1363 return NULL;
1364 set_swap_bodies(so, (PySetObject *)tmp);
1365 Py_DECREF(tmp);
1366 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001367}
1368
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001369static PyObject *
1370set_intersection_update_multi(PySetObject *so, PyObject *args)
1371{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 tmp = set_intersection_multi(so, args);
1375 if (tmp == NULL)
1376 return NULL;
1377 set_swap_bodies(so, (PySetObject *)tmp);
1378 Py_DECREF(tmp);
1379 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001380}
1381
Raymond Hettingera690a992003-11-16 16:17:49 +00001382PyDoc_STRVAR(intersection_update_doc,
1383"Update a set with the intersection of itself and another.");
1384
1385static PyObject *
1386set_and(PySetObject *so, PyObject *other)
1387{
Brian Curtindfc80e32011-08-10 20:28:54 -05001388 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1389 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001391}
1392
1393static PyObject *
1394set_iand(PySetObject *so, PyObject *other)
1395{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001397
Brian Curtindfc80e32011-08-10 20:28:54 -05001398 if (!PyAnySet_Check(other))
1399 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001400 result = set_intersection_update(so, other);
1401 if (result == NULL)
1402 return NULL;
1403 Py_DECREF(result);
1404 Py_INCREF(so);
1405 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001406}
1407
Guido van Rossum58da9312007-11-10 23:39:45 +00001408static PyObject *
1409set_isdisjoint(PySetObject *so, PyObject *other)
1410{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001412 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414 if ((PyObject *)so == other) {
1415 if (PySet_GET_SIZE(so) == 0)
1416 Py_RETURN_TRUE;
1417 else
1418 Py_RETURN_FALSE;
1419 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 if (PyAnySet_CheckExact(other)) {
1422 Py_ssize_t pos = 0;
1423 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1426 tmp = (PyObject *)so;
1427 so = (PySetObject *)other;
1428 other = tmp;
1429 }
1430 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001431 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001432 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 return NULL;
1434 if (rv)
1435 Py_RETURN_FALSE;
1436 }
1437 Py_RETURN_TRUE;
1438 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 it = PyObject_GetIter(other);
1441 if (it == NULL)
1442 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001443
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001444 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001445 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 if (hash == -1) {
1448 Py_DECREF(key);
1449 Py_DECREF(it);
1450 return NULL;
1451 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001452 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001453 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001454 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 Py_DECREF(it);
1456 return NULL;
1457 }
1458 if (rv) {
1459 Py_DECREF(it);
1460 Py_RETURN_FALSE;
1461 }
1462 }
1463 Py_DECREF(it);
1464 if (PyErr_Occurred())
1465 return NULL;
1466 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001467}
1468
1469PyDoc_STRVAR(isdisjoint_doc,
1470"Return True if two sets have a null intersection.");
1471
Neal Norwitz6576bd82005-11-13 18:41:28 +00001472static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001473set_difference_update_internal(PySetObject *so, PyObject *other)
1474{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 if ((PyObject *)so == other)
1476 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 if (PyAnySet_Check(other)) {
1479 setentry *entry;
1480 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001481
Raymond Hettinger88ea1662019-08-29 09:02:58 -07001482 /* Optimization: When the other set is more than 8 times
1483 larger than the base set, replace the other set with
1484 interesection of the two sets.
1485 */
1486 if ((PySet_GET_SIZE(other) >> 3) > PySet_GET_SIZE(so)) {
1487 other = set_intersection(so, other);
1488 if (other == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 return -1;
Raymond Hettinger88ea1662019-08-29 09:02:58 -07001490 } else {
1491 Py_INCREF(other);
1492 }
1493
1494 while (set_next((PySetObject *)other, &pos, &entry))
1495 if (set_discard_entry(so, entry->key, entry->hash) < 0) {
1496 Py_DECREF(other);
1497 return -1;
1498 }
1499
1500 Py_DECREF(other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 } else {
1502 PyObject *key, *it;
1503 it = PyObject_GetIter(other);
1504 if (it == NULL)
1505 return -1;
1506
1507 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001508 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 Py_DECREF(it);
1510 Py_DECREF(key);
1511 return -1;
1512 }
1513 Py_DECREF(key);
1514 }
1515 Py_DECREF(it);
1516 if (PyErr_Occurred())
1517 return -1;
1518 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001519 /* If more than 1/4th are dummies, then resize them away. */
1520 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +09001522 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001523}
1524
Raymond Hettingera690a992003-11-16 16:17:49 +00001525static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001526set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001527{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001528 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001529
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001530 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1531 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001532 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001533 return NULL;
1534 }
1535 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001536}
1537
1538PyDoc_STRVAR(difference_update_doc,
1539"Remove all elements of another set from this set.");
1540
1541static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001542set_copy_and_difference(PySetObject *so, PyObject *other)
1543{
1544 PyObject *result;
1545
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301546 result = set_copy(so, NULL);
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001547 if (result == NULL)
1548 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001549 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001550 return result;
1551 Py_DECREF(result);
1552 return NULL;
1553}
1554
1555static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001556set_difference(PySetObject *so, PyObject *other)
1557{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001559 PyObject *key;
1560 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 setentry *entry;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001562 Py_ssize_t pos = 0, other_size;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001563 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001564
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001565 if (PyAnySet_Check(other)) {
1566 other_size = PySet_GET_SIZE(other);
1567 }
1568 else if (PyDict_CheckExact(other)) {
1569 other_size = PyDict_GET_SIZE(other);
1570 }
1571 else {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001572 return set_copy_and_difference(so, other);
1573 }
1574
1575 /* If len(so) much more than len(other), it's more efficient to simply copy
1576 * so and then iterate other looking for common elements. */
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001577 if ((PySet_GET_SIZE(so) >> 2) > other_size) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001578 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001581 result = make_new_set_basetype(Py_TYPE(so), NULL);
1582 if (result == NULL)
1583 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001584
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 if (PyDict_CheckExact(other)) {
1586 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001587 key = entry->key;
1588 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001589 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001590 if (rv < 0) {
1591 Py_DECREF(result);
1592 return NULL;
1593 }
1594 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001595 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001596 Py_DECREF(result);
1597 return NULL;
1598 }
1599 }
1600 }
1601 return result;
1602 }
1603
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001604 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001605 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001606 key = entry->key;
1607 hash = entry->hash;
1608 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001609 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001610 Py_DECREF(result);
1611 return NULL;
1612 }
1613 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001614 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 Py_DECREF(result);
1616 return NULL;
1617 }
1618 }
1619 }
1620 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001621}
1622
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001623static PyObject *
1624set_difference_multi(PySetObject *so, PyObject *args)
1625{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 Py_ssize_t i;
1627 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301630 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 other = PyTuple_GET_ITEM(args, 0);
1633 result = set_difference(so, other);
1634 if (result == NULL)
1635 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001637 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1638 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001639 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001640 Py_DECREF(result);
1641 return NULL;
1642 }
1643 }
1644 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001645}
1646
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001647PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001648"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001649\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001650(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001651static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001652set_sub(PySetObject *so, PyObject *other)
1653{
Brian Curtindfc80e32011-08-10 20:28:54 -05001654 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1655 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001657}
1658
1659static PyObject *
1660set_isub(PySetObject *so, PyObject *other)
1661{
Brian Curtindfc80e32011-08-10 20:28:54 -05001662 if (!PyAnySet_Check(other))
1663 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001664 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001665 return NULL;
1666 Py_INCREF(so);
1667 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001668}
1669
1670static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001671set_symmetric_difference_update(PySetObject *so, PyObject *other)
1672{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001673 PySetObject *otherset;
1674 PyObject *key;
1675 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001676 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001677 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001678 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001679
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001680 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301681 return set_clear(so, NULL);
Raymond Hettingera690a992003-11-16 16:17:49 +00001682
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001683 if (PyDict_CheckExact(other)) {
1684 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001685 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001686 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001687 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001688 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001689 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001690 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001691 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001692 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001693 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001694 Py_DECREF(key);
1695 return NULL;
1696 }
1697 }
Georg Brandl2d444492010-09-03 10:52:55 +00001698 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001699 }
1700 Py_RETURN_NONE;
1701 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001702
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001703 if (PyAnySet_Check(other)) {
1704 Py_INCREF(other);
1705 otherset = (PySetObject *)other;
1706 } else {
1707 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1708 if (otherset == NULL)
1709 return NULL;
1710 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001711
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001712 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001713 key = entry->key;
1714 hash = entry->hash;
1715 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001716 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001717 Py_DECREF(otherset);
1718 return NULL;
1719 }
1720 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001721 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001722 Py_DECREF(otherset);
1723 return NULL;
1724 }
1725 }
1726 }
1727 Py_DECREF(otherset);
1728 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001729}
1730
1731PyDoc_STRVAR(symmetric_difference_update_doc,
1732"Update a set with the symmetric difference of itself and another.");
1733
1734static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001735set_symmetric_difference(PySetObject *so, PyObject *other)
1736{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001737 PyObject *rv;
1738 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001739
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1741 if (otherset == NULL)
1742 return NULL;
1743 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
lekma491bbed2018-05-02 11:29:10 +02001744 if (rv == NULL) {
1745 Py_DECREF(otherset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001746 return NULL;
lekma491bbed2018-05-02 11:29:10 +02001747 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001748 Py_DECREF(rv);
1749 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001750}
1751
1752PyDoc_STRVAR(symmetric_difference_doc,
1753"Return the symmetric difference of two sets as a new set.\n\
1754\n\
1755(i.e. all elements that are in exactly one of the sets.)");
1756
1757static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001758set_xor(PySetObject *so, PyObject *other)
1759{
Brian Curtindfc80e32011-08-10 20:28:54 -05001760 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1761 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001762 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001763}
1764
1765static PyObject *
1766set_ixor(PySetObject *so, PyObject *other)
1767{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001768 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001769
Brian Curtindfc80e32011-08-10 20:28:54 -05001770 if (!PyAnySet_Check(other))
1771 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001772 result = set_symmetric_difference_update(so, other);
1773 if (result == NULL)
1774 return NULL;
1775 Py_DECREF(result);
1776 Py_INCREF(so);
1777 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001778}
1779
1780static PyObject *
1781set_issubset(PySetObject *so, PyObject *other)
1782{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001783 setentry *entry;
1784 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001785 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001786
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001787 if (!PyAnySet_Check(other)) {
1788 PyObject *tmp, *result;
1789 tmp = make_new_set(&PySet_Type, other);
1790 if (tmp == NULL)
1791 return NULL;
1792 result = set_issubset(so, tmp);
1793 Py_DECREF(tmp);
1794 return result;
1795 }
1796 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1797 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001798
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001799 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001800 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001801 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001802 return NULL;
1803 if (!rv)
1804 Py_RETURN_FALSE;
1805 }
1806 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001807}
1808
1809PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1810
1811static PyObject *
1812set_issuperset(PySetObject *so, PyObject *other)
1813{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001814 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001815
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001816 if (!PyAnySet_Check(other)) {
1817 tmp = make_new_set(&PySet_Type, other);
1818 if (tmp == NULL)
1819 return NULL;
1820 result = set_issuperset(so, tmp);
1821 Py_DECREF(tmp);
1822 return result;
1823 }
1824 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001825}
1826
1827PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1828
Raymond Hettingera690a992003-11-16 16:17:49 +00001829static PyObject *
1830set_richcompare(PySetObject *v, PyObject *w, int op)
1831{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001832 PyObject *r1;
1833 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001834
Brian Curtindfc80e32011-08-10 20:28:54 -05001835 if(!PyAnySet_Check(w))
1836 Py_RETURN_NOTIMPLEMENTED;
1837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 switch (op) {
1839 case Py_EQ:
1840 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1841 Py_RETURN_FALSE;
1842 if (v->hash != -1 &&
1843 ((PySetObject *)w)->hash != -1 &&
1844 v->hash != ((PySetObject *)w)->hash)
1845 Py_RETURN_FALSE;
1846 return set_issubset(v, w);
1847 case Py_NE:
1848 r1 = set_richcompare(v, w, Py_EQ);
1849 if (r1 == NULL)
1850 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001851 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001853 if (r2 < 0)
1854 return NULL;
1855 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856 case Py_LE:
1857 return set_issubset(v, w);
1858 case Py_GE:
1859 return set_issuperset(v, w);
1860 case Py_LT:
1861 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1862 Py_RETURN_FALSE;
1863 return set_issubset(v, w);
1864 case Py_GT:
1865 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1866 Py_RETURN_FALSE;
1867 return set_issuperset(v, w);
1868 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001869 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001870}
1871
Raymond Hettingera690a992003-11-16 16:17:49 +00001872static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001873set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001874{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001875 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 return NULL;
1877 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001878}
1879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001881"Add an element to a set.\n\
1882\n\
1883This has no effect if the element is already present.");
1884
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001885static int
1886set_contains(PySetObject *so, PyObject *key)
1887{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 PyObject *tmpkey;
1889 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001892 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1894 return -1;
1895 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001896 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 if (tmpkey == NULL)
1898 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001899 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 Py_DECREF(tmpkey);
1901 }
1902 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001903}
1904
1905static PyObject *
1906set_direct_contains(PySetObject *so, PyObject *key)
1907{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001911 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001912 return NULL;
1913 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001914}
1915
1916PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1917
Raymond Hettingera690a992003-11-16 16:17:49 +00001918static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001919set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001920{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001921 PyObject *tmpkey;
1922 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001923
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001925 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1927 return NULL;
1928 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001929 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 if (tmpkey == NULL)
1931 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001932 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001933 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001934 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001935 return NULL;
1936 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001939 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001940 return NULL;
1941 }
1942 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001943}
1944
1945PyDoc_STRVAR(remove_doc,
1946"Remove an element from a set; it must be a member.\n\
1947\n\
1948If the element is not a member, raise a KeyError.");
1949
1950static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001951set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001952{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001953 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001954 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001955
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001956 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001957 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001958 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1959 return NULL;
1960 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001961 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001962 if (tmpkey == NULL)
1963 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001964 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001965 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001966 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001967 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968 }
1969 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001970}
1971
1972PyDoc_STRVAR(discard_doc,
1973"Remove an element from a set if it is a member.\n\
1974\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001975If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001976
1977static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301978set_reduce(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001979{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001981 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001983 keys = PySequence_List((PyObject *)so);
1984 if (keys == NULL)
1985 goto done;
1986 args = PyTuple_Pack(1, keys);
1987 if (args == NULL)
1988 goto done;
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001989 if (_PyObject_LookupAttrId((PyObject *)so, &PyId___dict__, &dict) < 0) {
1990 goto done;
1991 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001992 if (dict == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001993 dict = Py_None;
1994 Py_INCREF(dict);
1995 }
1996 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001997done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001998 Py_XDECREF(args);
1999 Py_XDECREF(keys);
2000 Py_XDECREF(dict);
2001 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00002002}
2003
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002004static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302005set_sizeof(PySetObject *so, PyObject *Py_UNUSED(ignored))
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002006{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002007 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002008
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02002009 res = _PyObject_SIZE(Py_TYPE(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002010 if (so->table != so->smalltable)
2011 res = res + (so->mask + 1) * sizeof(setentry);
2012 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002013}
2014
2015PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002016static int
2017set_init(PySetObject *self, PyObject *args, PyObject *kwds)
2018{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002019 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002020
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03002021 if (!_PyArg_NoKeywords("set", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002022 return -1;
2023 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
2024 return -1;
Raymond Hettingerb72e21b2016-03-25 02:29:59 -07002025 if (self->fill)
2026 set_clear_internal(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002027 self->hash = -1;
2028 if (iterable == NULL)
2029 return 0;
2030 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002031}
2032
Dong-hee Na6ff79f652020-03-17 02:17:38 +09002033static PyObject*
2034set_vectorcall(PyObject *type, PyObject * const*args,
2035 size_t nargsf, PyObject *kwnames)
2036{
2037 assert(PyType_Check(type));
2038
2039 if (!_PyArg_NoKwnames("set", kwnames)) {
2040 return NULL;
2041 }
2042
2043 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
2044 if (!_PyArg_CheckPositional("set", nargs, 0, 1)) {
2045 return NULL;
2046 }
2047
2048 if (nargs) {
2049 return make_new_set((PyTypeObject *)type, args[0]);
2050 }
2051
2052 return make_new_set((PyTypeObject *)type, NULL);
2053}
2054
Raymond Hettingera690a992003-11-16 16:17:49 +00002055static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002056 set_len, /* sq_length */
2057 0, /* sq_concat */
2058 0, /* sq_repeat */
2059 0, /* sq_item */
2060 0, /* sq_slice */
2061 0, /* sq_ass_item */
2062 0, /* sq_ass_slice */
2063 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002064};
2065
2066/* set object ********************************************************/
2067
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002068#ifdef Py_DEBUG
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302069static PyObject *test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored));
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002070
2071PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2072All is well if assertions don't fail.");
2073#endif
2074
Raymond Hettingera690a992003-11-16 16:17:49 +00002075static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002076 {"add", (PyCFunction)set_add, METH_O,
2077 add_doc},
2078 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2079 clear_doc},
2080 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2081 contains_doc},
2082 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2083 copy_doc},
2084 {"discard", (PyCFunction)set_discard, METH_O,
2085 discard_doc},
2086 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2087 difference_doc},
2088 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2089 difference_update_doc},
2090 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2091 intersection_doc},
2092 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2093 intersection_update_doc},
2094 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2095 isdisjoint_doc},
2096 {"issubset", (PyCFunction)set_issubset, METH_O,
2097 issubset_doc},
2098 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2099 issuperset_doc},
2100 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2101 pop_doc},
2102 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2103 reduce_doc},
2104 {"remove", (PyCFunction)set_remove, METH_O,
2105 remove_doc},
2106 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2107 sizeof_doc},
2108 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2109 symmetric_difference_doc},
2110 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2111 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002112#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2114 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002115#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002116 {"union", (PyCFunction)set_union, METH_VARARGS,
2117 union_doc},
2118 {"update", (PyCFunction)set_update, METH_VARARGS,
2119 update_doc},
Guido van Rossum48b069a2020-04-07 09:50:06 -07002120 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002122};
2123
2124static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002125 0, /*nb_add*/
2126 (binaryfunc)set_sub, /*nb_subtract*/
2127 0, /*nb_multiply*/
2128 0, /*nb_remainder*/
2129 0, /*nb_divmod*/
2130 0, /*nb_power*/
2131 0, /*nb_negative*/
2132 0, /*nb_positive*/
2133 0, /*nb_absolute*/
2134 0, /*nb_bool*/
2135 0, /*nb_invert*/
2136 0, /*nb_lshift*/
2137 0, /*nb_rshift*/
2138 (binaryfunc)set_and, /*nb_and*/
2139 (binaryfunc)set_xor, /*nb_xor*/
2140 (binaryfunc)set_or, /*nb_or*/
2141 0, /*nb_int*/
2142 0, /*nb_reserved*/
2143 0, /*nb_float*/
2144 0, /*nb_inplace_add*/
2145 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2146 0, /*nb_inplace_multiply*/
2147 0, /*nb_inplace_remainder*/
2148 0, /*nb_inplace_power*/
2149 0, /*nb_inplace_lshift*/
2150 0, /*nb_inplace_rshift*/
2151 (binaryfunc)set_iand, /*nb_inplace_and*/
2152 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2153 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002154};
2155
2156PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002157"set() -> new empty set object\n\
2158set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002159\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002160Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002161
2162PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002163 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2164 "set", /* tp_name */
2165 sizeof(PySetObject), /* tp_basicsize */
2166 0, /* tp_itemsize */
2167 /* methods */
2168 (destructor)set_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002169 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002170 0, /* tp_getattr */
2171 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002172 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002173 (reprfunc)set_repr, /* tp_repr */
2174 &set_as_number, /* tp_as_number */
2175 &set_as_sequence, /* tp_as_sequence */
2176 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002177 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178 0, /* tp_call */
2179 0, /* tp_str */
2180 PyObject_GenericGetAttr, /* tp_getattro */
2181 0, /* tp_setattro */
2182 0, /* tp_as_buffer */
2183 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2184 Py_TPFLAGS_BASETYPE, /* tp_flags */
2185 set_doc, /* tp_doc */
2186 (traverseproc)set_traverse, /* tp_traverse */
2187 (inquiry)set_clear_internal, /* tp_clear */
2188 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002189 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2190 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 0, /* tp_iternext */
2192 set_methods, /* tp_methods */
2193 0, /* tp_members */
2194 0, /* tp_getset */
2195 0, /* tp_base */
2196 0, /* tp_dict */
2197 0, /* tp_descr_get */
2198 0, /* tp_descr_set */
2199 0, /* tp_dictoffset */
2200 (initproc)set_init, /* tp_init */
2201 PyType_GenericAlloc, /* tp_alloc */
2202 set_new, /* tp_new */
2203 PyObject_GC_Del, /* tp_free */
Dong-hee Na6ff79f652020-03-17 02:17:38 +09002204 .tp_vectorcall = set_vectorcall,
Raymond Hettingera690a992003-11-16 16:17:49 +00002205};
2206
2207/* frozenset object ********************************************************/
2208
2209
2210static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002211 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2212 contains_doc},
2213 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2214 copy_doc},
2215 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2216 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002217 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002218 intersection_doc},
2219 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2220 isdisjoint_doc},
2221 {"issubset", (PyCFunction)set_issubset, METH_O,
2222 issubset_doc},
2223 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2224 issuperset_doc},
2225 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2226 reduce_doc},
2227 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2228 sizeof_doc},
2229 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2230 symmetric_difference_doc},
2231 {"union", (PyCFunction)set_union, METH_VARARGS,
2232 union_doc},
Guido van Rossum48b069a2020-04-07 09:50:06 -07002233 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002234 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002235};
2236
2237static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002238 0, /*nb_add*/
2239 (binaryfunc)set_sub, /*nb_subtract*/
2240 0, /*nb_multiply*/
2241 0, /*nb_remainder*/
2242 0, /*nb_divmod*/
2243 0, /*nb_power*/
2244 0, /*nb_negative*/
2245 0, /*nb_positive*/
2246 0, /*nb_absolute*/
2247 0, /*nb_bool*/
2248 0, /*nb_invert*/
2249 0, /*nb_lshift*/
2250 0, /*nb_rshift*/
2251 (binaryfunc)set_and, /*nb_and*/
2252 (binaryfunc)set_xor, /*nb_xor*/
2253 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002254};
2255
2256PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002257"frozenset() -> empty frozenset object\n\
2258frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002259\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002260Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002261
2262PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2264 "frozenset", /* tp_name */
2265 sizeof(PySetObject), /* tp_basicsize */
2266 0, /* tp_itemsize */
2267 /* methods */
2268 (destructor)set_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002269 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002270 0, /* tp_getattr */
2271 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002272 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002273 (reprfunc)set_repr, /* tp_repr */
2274 &frozenset_as_number, /* tp_as_number */
2275 &set_as_sequence, /* tp_as_sequence */
2276 0, /* tp_as_mapping */
2277 frozenset_hash, /* tp_hash */
2278 0, /* tp_call */
2279 0, /* tp_str */
2280 PyObject_GenericGetAttr, /* tp_getattro */
2281 0, /* tp_setattro */
2282 0, /* tp_as_buffer */
2283 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2284 Py_TPFLAGS_BASETYPE, /* tp_flags */
2285 frozenset_doc, /* tp_doc */
2286 (traverseproc)set_traverse, /* tp_traverse */
2287 (inquiry)set_clear_internal, /* tp_clear */
2288 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002289 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002290 (getiterfunc)set_iter, /* tp_iter */
2291 0, /* tp_iternext */
2292 frozenset_methods, /* tp_methods */
2293 0, /* tp_members */
2294 0, /* tp_getset */
2295 0, /* tp_base */
2296 0, /* tp_dict */
2297 0, /* tp_descr_get */
2298 0, /* tp_descr_set */
2299 0, /* tp_dictoffset */
2300 0, /* tp_init */
2301 PyType_GenericAlloc, /* tp_alloc */
2302 frozenset_new, /* tp_new */
2303 PyObject_GC_Del, /* tp_free */
Dong-hee Na1c605672020-03-19 02:30:50 +09002304 .tp_vectorcall = frozenset_vectorcall,
Raymond Hettingera690a992003-11-16 16:17:49 +00002305};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002306
2307
2308/***** C API functions *************************************************/
2309
2310PyObject *
2311PySet_New(PyObject *iterable)
2312{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002313 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002314}
2315
2316PyObject *
2317PyFrozenSet_New(PyObject *iterable)
2318{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002319 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002320}
2321
Neal Norwitz8c49c822006-03-04 18:41:19 +00002322Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002323PySet_Size(PyObject *anyset)
2324{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002325 if (!PyAnySet_Check(anyset)) {
2326 PyErr_BadInternalCall();
2327 return -1;
2328 }
2329 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002330}
2331
2332int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002333PySet_Clear(PyObject *set)
2334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002335 if (!PySet_Check(set)) {
2336 PyErr_BadInternalCall();
2337 return -1;
2338 }
2339 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002340}
2341
2342int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002343PySet_Contains(PyObject *anyset, PyObject *key)
2344{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002345 if (!PyAnySet_Check(anyset)) {
2346 PyErr_BadInternalCall();
2347 return -1;
2348 }
2349 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002350}
2351
2352int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002353PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002354{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002355 if (!PySet_Check(set)) {
2356 PyErr_BadInternalCall();
2357 return -1;
2358 }
2359 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002360}
2361
2362int
Christian Heimesfd66e512008-01-29 12:18:50 +00002363PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002364{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002365 if (!PySet_Check(anyset) &&
2366 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2367 PyErr_BadInternalCall();
2368 return -1;
2369 }
2370 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002371}
2372
Raymond Hettinger3625af52016-03-27 01:15:07 -07002373void
Victor Stinnerbed48172019-08-27 00:12:32 +02002374_PySet_Fini(void)
Raymond Hettinger3625af52016-03-27 01:15:07 -07002375{
2376 Py_CLEAR(emptyfrozenset);
2377}
2378
2379int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002380_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002381{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002382 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002384 if (!PyAnySet_Check(set)) {
2385 PyErr_BadInternalCall();
2386 return -1;
2387 }
2388 if (set_next((PySetObject *)set, pos, &entry) == 0)
2389 return 0;
2390 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002391 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002392 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002393}
2394
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002395PyObject *
2396PySet_Pop(PyObject *set)
2397{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002398 if (!PySet_Check(set)) {
2399 PyErr_BadInternalCall();
2400 return NULL;
2401 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302402 return set_pop((PySetObject *)set, NULL);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002403}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002404
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002405int
2406_PySet_Update(PyObject *set, PyObject *iterable)
2407{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 if (!PySet_Check(set)) {
2409 PyErr_BadInternalCall();
2410 return -1;
2411 }
2412 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002413}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002414
Raymond Hettingere259f132013-12-15 11:56:14 -08002415/* Exported for the gdb plugin's benefit. */
2416PyObject *_PySet_Dummy = dummy;
2417
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002418#ifdef Py_DEBUG
2419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002420/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002421 Returns True and original set is restored. */
2422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002423#define assertRaises(call_return_value, exception) \
2424 do { \
2425 assert(call_return_value); \
2426 assert(PyErr_ExceptionMatches(exception)); \
2427 PyErr_Clear(); \
2428 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002429
2430static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302431test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002432{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002433 Py_ssize_t count;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +02002434 const char *s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002435 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002436 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002437 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002438 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002439 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002441 /* Verify preconditions */
2442 assert(PyAnySet_Check(ob));
2443 assert(PyAnySet_CheckExact(ob));
2444 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002446 /* so.clear(); so |= set("abc"); */
2447 str = PyUnicode_FromString("abc");
2448 if (str == NULL)
2449 return NULL;
2450 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002451 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002452 Py_DECREF(str);
2453 return NULL;
2454 }
2455 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002457 /* Exercise type/size checks */
2458 assert(PySet_Size(ob) == 3);
2459 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002461 /* Raise TypeError for non-iterable constructor arguments */
2462 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2463 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002465 /* Raise TypeError for unhashable key */
2466 dup = PySet_New(ob);
2467 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2468 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2469 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002471 /* Exercise successful pop, contains, add, and discard */
2472 elem = PySet_Pop(ob);
2473 assert(PySet_Contains(ob, elem) == 0);
2474 assert(PySet_GET_SIZE(ob) == 2);
2475 assert(PySet_Add(ob, elem) == 0);
2476 assert(PySet_Contains(ob, elem) == 1);
2477 assert(PySet_GET_SIZE(ob) == 3);
2478 assert(PySet_Discard(ob, elem) == 1);
2479 assert(PySet_GET_SIZE(ob) == 2);
2480 assert(PySet_Discard(ob, elem) == 0);
2481 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002483 /* Exercise clear */
2484 dup2 = PySet_New(dup);
2485 assert(PySet_Clear(dup2) == 0);
2486 assert(PySet_Size(dup2) == 0);
2487 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002489 /* Raise SystemError on clear or update of frozen set */
2490 f = PyFrozenSet_New(dup);
2491 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2492 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2493 assert(PySet_Add(f, elem) == 0);
2494 Py_INCREF(f);
2495 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2496 Py_DECREF(f);
2497 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002499 /* Exercise direct iteration */
2500 i = 0, count = 0;
2501 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
Serhiy Storchaka06515832016-11-20 09:13:07 +02002502 s = PyUnicode_AsUTF8(x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002503 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2504 count++;
2505 }
2506 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002508 /* Exercise updates */
2509 dup2 = PySet_New(NULL);
2510 assert(_PySet_Update(dup2, dup) == 0);
2511 assert(PySet_Size(dup2) == 3);
2512 assert(_PySet_Update(dup2, dup) == 0);
2513 assert(PySet_Size(dup2) == 3);
2514 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002516 /* Raise SystemError when self argument is not a set or frozenset. */
2517 t = PyTuple_New(0);
2518 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2519 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2520 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002522 /* Raise SystemError when self argument is not a set. */
2523 f = PyFrozenSet_New(dup);
2524 assert(PySet_Size(f) == 3);
2525 assert(PyFrozenSet_CheckExact(f));
2526 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2527 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2528 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002529
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002530 /* Raise KeyError when popping from an empty set */
2531 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2532 Py_DECREF(ob);
2533 assert(PySet_GET_SIZE(ob) == 0);
2534 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002536 /* Restore the set from the copy using the PyNumber API */
2537 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2538 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002539
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002540 /* Verify constructors accept NULL arguments */
2541 f = PySet_New(NULL);
2542 assert(f != NULL);
2543 assert(PySet_GET_SIZE(f) == 0);
2544 Py_DECREF(f);
2545 f = PyFrozenSet_New(NULL);
2546 assert(f != NULL);
2547 assert(PyFrozenSet_CheckExact(f));
2548 assert(PySet_GET_SIZE(f) == 0);
2549 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002550
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002551 Py_DECREF(elem);
2552 Py_DECREF(dup);
2553 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002554}
2555
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002556#undef assertRaises
2557
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002558#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002559
2560/***** Dummy Struct *************************************************/
2561
2562static PyObject *
2563dummy_repr(PyObject *op)
2564{
2565 return PyUnicode_FromString("<dummy key>");
2566}
2567
Victor Stinner2a4903f2020-01-30 13:09:11 +01002568static void _Py_NO_RETURN
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002569dummy_dealloc(PyObject* ignore)
2570{
2571 Py_FatalError("deallocating <dummy key>");
2572}
2573
2574static PyTypeObject _PySetDummy_Type = {
2575 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2576 "<dummy key> type",
2577 0,
2578 0,
2579 dummy_dealloc, /*tp_dealloc*/ /*never called*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002580 0, /*tp_vectorcall_offset*/
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002581 0, /*tp_getattr*/
2582 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002583 0, /*tp_as_async*/
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002584 dummy_repr, /*tp_repr*/
2585 0, /*tp_as_number*/
2586 0, /*tp_as_sequence*/
2587 0, /*tp_as_mapping*/
2588 0, /*tp_hash */
2589 0, /*tp_call */
2590 0, /*tp_str */
2591 0, /*tp_getattro */
2592 0, /*tp_setattro */
2593 0, /*tp_as_buffer */
2594 Py_TPFLAGS_DEFAULT, /*tp_flags */
2595};
2596
2597static PyObject _dummy_struct = {
2598 _PyObject_EXTRA_INIT
2599 2, &_PySetDummy_Type
2600};
2601