blob: 232ba6d97a07011ae63172c50e9d73b31c996893 [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 Stinnerbcda8f12018-11-21 22:27:47 +010035#include "pycore_object.h"
Victor Stinner621cebe2018-11-12 16:53:38 +010036#include "pycore_pystate.h"
Raymond Hettingera9d99362005-08-05 00:01:15 +000037#include "structmember.h"
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000038
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000039/* Object used as dummy key to fill deleted entries */
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -050040static PyObject _dummy_struct;
41
42#define dummy (&_dummy_struct)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000043
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000044
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -070045/* ======================================================================== */
46/* ======= Begin logic for probing the hash table ========================= */
47
Raymond Hettinger710a67e2013-09-21 20:17:31 -070048/* Set this to zero to turn-off linear probing */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070049#ifndef LINEAR_PROBES
Raymond Hettinger742d8712013-09-08 00:25:57 -070050#define LINEAR_PROBES 9
Raymond Hettinger8408dc52013-09-15 14:57:15 -070051#endif
Raymond Hettinger742d8712013-09-08 00:25:57 -070052
53/* This must be >= 1 */
54#define PERTURB_SHIFT 5
55
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000056static setentry *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020057set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000058{
Raymond Hettinger70559b52015-07-23 07:42:23 -040059 setentry *table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020060 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070061 size_t perturb;
Raymond Hettingerafe89092013-08-28 20:59:31 -070062 size_t mask = so->mask;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -080063 size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070064 size_t j;
Raymond Hettinger4ef05282013-09-21 15:39:49 -070065 int cmp;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000066
Raymond Hettinger70559b52015-07-23 07:42:23 -040067 entry = &so->table[i];
Raymond Hettingerafe89092013-08-28 20:59:31 -070068 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000069 return entry;
Raymond Hettinger237b34b2013-08-17 02:31:53 -070070
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070071 perturb = hash;
72
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -070073 while (1) {
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080074 if (entry->hash == hash) {
Raymond Hettingerafe89092013-08-28 20:59:31 -070075 PyObject *startkey = entry->key;
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080076 /* startkey cannot be a dummy because the dummy hash field is -1 */
77 assert(startkey != dummy);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -080078 if (startkey == key)
79 return entry;
Raymond Hettinger93035c42015-01-25 16:12:49 -080080 if (PyUnicode_CheckExact(startkey)
81 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -070082 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger93035c42015-01-25 16:12:49 -080083 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -040084 table = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000085 Py_INCREF(startkey);
86 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
87 Py_DECREF(startkey);
Raymond Hettinger426d9952014-05-18 21:40:20 +010088 if (cmp < 0) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000089 return NULL;
Raymond Hettinger426d9952014-05-18 21:40:20 +010090 if (table != so->table || entry->key != startkey) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091 return set_lookkey(so, key, hash);
Raymond Hettinger426d9952014-05-18 21:40:20 +010092 if (cmp > 0) /* likely */
Raymond Hettingerafe89092013-08-28 20:59:31 -070093 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -060094 mask = so->mask; /* help avoid a register spill */
Raymond Hettingerafe89092013-08-28 20:59:31 -070095 }
Raymond Hettingerafe89092013-08-28 20:59:31 -070096
Raymond Hettingerc658d852015-02-02 08:35:00 -080097 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -080098 for (j = 0 ; j < LINEAR_PROBES ; j++) {
Raymond Hettingerc658d852015-02-02 08:35:00 -080099 entry++;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700100 if (entry->hash == 0 && entry->key == NULL)
101 return entry;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800102 if (entry->hash == hash) {
103 PyObject *startkey = entry->key;
104 assert(startkey != dummy);
105 if (startkey == key)
106 return entry;
107 if (PyUnicode_CheckExact(startkey)
108 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700109 && _PyUnicode_EQ(startkey, key))
Raymond Hettingerc658d852015-02-02 08:35:00 -0800110 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400111 table = so->table;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800112 Py_INCREF(startkey);
113 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
114 Py_DECREF(startkey);
115 if (cmp < 0)
116 return NULL;
117 if (table != so->table || entry->key != startkey)
118 return set_lookkey(so, key, hash);
119 if (cmp > 0)
120 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -0600121 mask = so->mask;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800122 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700123 }
124 }
125
126 perturb >>= PERTURB_SHIFT;
127 i = (i * 5 + 1 + perturb) & mask;
128
Raymond Hettinger70559b52015-07-23 07:42:23 -0400129 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700130 if (entry->key == NULL)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700131 return entry;
132 }
133}
134
Raymond Hettinger15f08692015-07-03 17:21:17 -0700135static int set_table_resize(PySetObject *, Py_ssize_t);
136
Raymond Hettinger8651a502015-05-27 10:37:20 -0700137static int
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400138set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700139{
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400140 setentry *table;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700141 setentry *freeslot;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700142 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700143 size_t perturb;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400144 size_t mask;
145 size_t i; /* Unsigned for defined overflow behavior */
Raymond Hettinger8651a502015-05-27 10:37:20 -0700146 size_t j;
147 int cmp;
148
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400149 /* Pre-increment is necessary to prevent arbitrary code in the rich
150 comparison from deallocating the key just before the insertion. */
151 Py_INCREF(key);
152
153 restart:
154
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400155 mask = so->mask;
156 i = (size_t)hash & mask;
157
Raymond Hettinger70559b52015-07-23 07:42:23 -0400158 entry = &so->table[i];
Raymond Hettinger8651a502015-05-27 10:37:20 -0700159 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700160 goto found_unused;
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700161
162 freeslot = NULL;
163 perturb = hash;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700164
165 while (1) {
166 if (entry->hash == hash) {
167 PyObject *startkey = entry->key;
168 /* startkey cannot be a dummy because the dummy hash field is -1 */
169 assert(startkey != dummy);
170 if (startkey == key)
171 goto found_active;
172 if (PyUnicode_CheckExact(startkey)
173 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700174 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700175 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400176 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700177 Py_INCREF(startkey);
178 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
179 Py_DECREF(startkey);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700180 if (cmp > 0) /* likely */
181 goto found_active;
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700182 if (cmp < 0)
183 goto comparison_error;
184 /* Continuing the search from the current entry only makes
185 sense if the table and entry are unchanged; otherwise,
186 we have to restart from the beginning */
187 if (table != so->table || entry->key != startkey)
188 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700189 mask = so->mask; /* help avoid a register spill */
190 }
Raymond Hettinger33299922018-01-14 10:20:13 -0800191 else if (entry->hash == -1)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700192 freeslot = entry;
193
194 if (i + LINEAR_PROBES <= mask) {
195 for (j = 0 ; j < LINEAR_PROBES ; j++) {
196 entry++;
197 if (entry->hash == 0 && entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700198 goto found_unused_or_dummy;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700199 if (entry->hash == hash) {
200 PyObject *startkey = entry->key;
201 assert(startkey != dummy);
202 if (startkey == key)
203 goto found_active;
204 if (PyUnicode_CheckExact(startkey)
205 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700206 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700207 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400208 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700209 Py_INCREF(startkey);
210 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
211 Py_DECREF(startkey);
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700212 if (cmp > 0)
213 goto found_active;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700214 if (cmp < 0)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400215 goto comparison_error;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700216 if (table != so->table || entry->key != startkey)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400217 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700218 mask = so->mask;
219 }
Raymond Hettinger33299922018-01-14 10:20:13 -0800220 else if (entry->hash == -1)
Raymond Hettingerc658d852015-02-02 08:35:00 -0800221 freeslot = entry;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700222 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000223 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700224
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700225 perturb >>= PERTURB_SHIFT;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -0800226 i = (i * 5 + 1 + perturb) & mask;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700227
Raymond Hettinger70559b52015-07-23 07:42:23 -0400228 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700229 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700230 goto found_unused_or_dummy;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000231 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700232
Raymond Hettinger15f08692015-07-03 17:21:17 -0700233 found_unused_or_dummy:
234 if (freeslot == NULL)
235 goto found_unused;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700236 so->used++;
237 freeslot->key = key;
238 freeslot->hash = hash;
239 return 0;
240
241 found_unused:
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700242 so->fill++;
243 so->used++;
244 entry->key = key;
245 entry->hash = hash;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800246 if ((size_t)so->fill*5 < mask*3)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700247 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +0900248 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700249
250 found_active:
Raymond Hettinger482c05c2015-07-20 01:23:32 -0400251 Py_DECREF(key);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700252 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000253
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400254 comparison_error:
Raymond Hettinger061091a2015-07-15 23:54:02 -0700255 Py_DECREF(key);
256 return -1;
257}
258
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000259/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000260Internal routine used by set_table_resize() to insert an item which is
261known to be absent from the set. This routine also assumes that
262the set contains no deleted entries. Besides the performance benefit,
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800263there is also safety benefit since using set_add_entry() risks making
264a callback in the middle of a set_table_resize(), see issue 1456209.
265The caller is responsible for updating the key's reference count and
266the setobject's fill and used fields.
Thomas Wouters89f507f2006-12-13 04:49:30 +0000267*/
268static void
Raymond Hettinger5088f602015-12-13 18:45:01 -0800269set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000270{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200271 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700272 size_t perturb = hash;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800273 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700274 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000275
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700276 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800277 entry = &table[i];
278 if (entry->key == NULL)
279 goto found_null;
280 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800281 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800282 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800283 if (entry->key == NULL)
284 goto found_null;
285 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700286 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700287 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800288 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700290 found_null:
Raymond Hettinger5088f602015-12-13 18:45:01 -0800291 entry->key = key;
Raymond Hettinger86d322f2015-12-13 19:27:17 -0800292 entry->hash = hash;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000293}
294
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700295/* ======== End logic for probing the hash table ========================== */
296/* ======================================================================== */
297
Thomas Wouters89f507f2006-12-13 04:49:30 +0000298/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000299Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000300keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000301actually be smaller than the old one.
302*/
303static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000304set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000305{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 setentry *oldtable, *newtable, *entry;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800307 Py_ssize_t oldmask = so->mask;
308 size_t newmask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 int is_oldtable_malloced;
310 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 assert(minused >= 0);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000314 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100315 /* XXX speed-up with intrinsics */
Sergey Fedoseev6c7d67c2018-09-12 04:18:01 +0500316 size_t newsize = PySet_MINSIZE;
317 while (newsize <= (size_t)minused) {
318 newsize <<= 1; // The largest possible value is PY_SSIZE_T_MAX + 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000319 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000321 /* Get space for a new table. */
322 oldtable = so->table;
323 assert(oldtable != NULL);
324 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 if (newsize == PySet_MINSIZE) {
327 /* A large table is shrinking, or we can't get any smaller. */
328 newtable = so->smalltable;
329 if (newtable == oldtable) {
330 if (so->fill == so->used) {
331 /* No dummies, so no point doing anything. */
332 return 0;
333 }
334 /* We're not going to resize it, but rebuild the
335 table anyway to purge old dummy entries.
336 Subtle: This is *necessary* if fill==size,
337 as set_lookkey needs at least one virgin slot to
338 terminate failing searches. If fill < size, it's
339 merely desirable, as dummies slow searches. */
340 assert(so->fill > so->used);
341 memcpy(small_copy, oldtable, sizeof(small_copy));
342 oldtable = small_copy;
343 }
344 }
345 else {
346 newtable = PyMem_NEW(setentry, newsize);
347 if (newtable == NULL) {
348 PyErr_NoMemory();
349 return -1;
350 }
351 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 /* Make the set empty, using the new table. */
354 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 memset(newtable, 0, sizeof(setentry) * newsize);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800356 so->mask = newsize - 1;
357 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 /* Copy the data over; this is refcount-neutral for active entries;
360 dummy entries aren't copied over, of course */
Raymond Hettinger5088f602015-12-13 18:45:01 -0800361 newmask = (size_t)so->mask;
Raymond Hettingere1af6962017-02-02 08:24:48 -0800362 if (so->fill == so->used) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800363 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800364 if (entry->key != NULL) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800365 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800366 }
367 }
368 } else {
Raymond Hettingere1af6962017-02-02 08:24:48 -0800369 so->fill = so->used;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800370 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800371 if (entry->key != NULL && entry->key != dummy) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800372 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800373 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 }
375 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 if (is_oldtable_malloced)
378 PyMem_DEL(oldtable);
379 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000380}
381
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000382static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700383set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000384{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700385 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000386
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700387 entry = set_lookkey(so, key, hash);
388 if (entry != NULL)
389 return entry->key != NULL;
390 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000391}
392
393#define DISCARD_NOTFOUND 0
394#define DISCARD_FOUND 1
395
396static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700397set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800398{
399 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000401
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700402 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 if (entry == NULL)
404 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700405 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 return DISCARD_NOTFOUND;
407 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800409 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000410 so->used--;
411 Py_DECREF(old_key);
412 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000413}
414
415static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700416set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000417{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200418 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000419
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700420 if (!PyUnicode_CheckExact(key) ||
421 (hash = ((PyASCIIObject *) key)->hash) == -1) {
422 hash = PyObject_Hash(key);
423 if (hash == -1)
424 return -1;
425 }
426 return set_add_entry(so, key, hash);
427}
428
429static int
430set_contains_key(PySetObject *so, PyObject *key)
431{
432 Py_hash_t hash;
433
434 if (!PyUnicode_CheckExact(key) ||
435 (hash = ((PyASCIIObject *) key)->hash) == -1) {
436 hash = PyObject_Hash(key);
437 if (hash == -1)
438 return -1;
439 }
440 return set_contains_entry(so, key, hash);
441}
442
443static int
444set_discard_key(PySetObject *so, PyObject *key)
445{
446 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000448 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200449 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450 hash = PyObject_Hash(key);
451 if (hash == -1)
452 return -1;
453 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700454 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000455}
456
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700457static void
458set_empty_to_minsize(PySetObject *so)
459{
460 memset(so->smalltable, 0, sizeof(so->smalltable));
461 so->fill = 0;
462 so->used = 0;
463 so->mask = PySet_MINSIZE - 1;
464 so->table = so->smalltable;
465 so->hash = -1;
466}
467
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000468static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000469set_clear_internal(PySetObject *so)
470{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800471 setentry *entry;
472 setentry *table = so->table;
473 Py_ssize_t fill = so->fill;
474 Py_ssize_t used = so->used;
475 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000477
Raymond Hettinger583cd032013-09-07 22:06:35 -0700478 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 /* This is delicate. During the process of clearing the set,
482 * decrefs can cause the set to mutate. To avoid fatal confusion
483 * (voice of experience), we have to make the set empty before
484 * clearing the slots, and never refer to anything via so->ref while
485 * clearing.
486 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700488 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490 else if (fill > 0) {
491 /* It's a small table with something that needs to be cleared.
492 * Afraid the only safe way is to copy the set entries into
493 * another small table first.
494 */
495 memcpy(small_copy, table, sizeof(small_copy));
496 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700497 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 }
499 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 /* Now we can finally clear things. If C had refcounts, we could
502 * assert that the refcount on table is 1 now, i.e. that this function
503 * has unique access to it, so decref side-effects can't alter it.
504 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800505 for (entry = table; used > 0; entry++) {
506 if (entry->key && entry->key != dummy) {
507 used--;
508 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 if (table_is_malloced)
513 PyMem_DEL(table);
514 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000515}
516
517/*
518 * Iterate over a set table. Use like so:
519 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000520 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000521 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000522 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000523 * while (set_next(yourset, &pos, &entry)) {
524 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000525 * }
526 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000527 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000528 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000529 */
530static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000531set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000532{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 Py_ssize_t i;
534 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700535 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 assert (PyAnySet_Check(so));
538 i = *pos_ptr;
539 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700541 entry = &so->table[i];
542 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700544 entry++;
545 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000546 *pos_ptr = i+1;
547 if (i > mask)
548 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700549 assert(entry != NULL);
550 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000552}
553
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000554static void
555set_dealloc(PySetObject *so)
556{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200557 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800558 Py_ssize_t used = so->used;
559
INADA Naokia6296d32017-08-24 14:55:17 +0900560 /* bpo-31095: UnTrack is needed before calling any callbacks */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000561 PyObject_GC_UnTrack(so);
Jeroen Demeyer351c6742019-05-10 19:21:11 +0200562 Py_TRASHCAN_BEGIN(so, set_dealloc)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000563 if (so->weakreflist != NULL)
564 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000565
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800566 for (entry = so->table; used > 0; entry++) {
567 if (entry->key && entry->key != dummy) {
568 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700569 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 }
571 }
572 if (so->table != so->smalltable)
573 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700574 Py_TYPE(so)->tp_free(so);
Jeroen Demeyer351c6742019-05-10 19:21:11 +0200575 Py_TRASHCAN_END
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000576}
577
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000578static PyObject *
579set_repr(PySetObject *so)
580{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200581 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000582 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000583
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000584 if (status != 0) {
585 if (status < 0)
586 return NULL;
587 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
588 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000589
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000590 /* shortcut for the empty set */
591 if (!so->used) {
592 Py_ReprLeave((PyObject*)so);
593 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
594 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000595
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000596 keys = PySequence_List((PyObject *)so);
597 if (keys == NULL)
598 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000599
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200600 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000601 listrepr = PyObject_Repr(keys);
602 Py_DECREF(keys);
603 if (listrepr == NULL)
604 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200605 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200607 if (tmp == NULL)
608 goto done;
609 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200610
Andy Lester55728702020-03-06 16:53:17 -0600611 if (!Py_IS_TYPE(so, &PySet_Type))
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200612 result = PyUnicode_FromFormat("%s({%U})",
613 Py_TYPE(so)->tp_name,
614 listrepr);
615 else
616 result = PyUnicode_FromFormat("{%U}", listrepr);
617 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000618done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 Py_ReprLeave((PyObject*)so);
620 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000621}
622
Martin v. Löwis18e16552006-02-15 17:27:45 +0000623static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000624set_len(PyObject *so)
625{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000627}
628
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000629static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000630set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000631{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000632 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000633 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200634 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700635 setentry *so_entry;
636 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000637
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 assert (PyAnySet_Check(so));
639 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 other = (PySetObject*)otherset;
642 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700643 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000644 return 0;
645 /* Do one big resize at the start, rather than
646 * incrementally resizing as we insert new keys. Expect
647 * that there will be no (or few) overlapping keys.
648 */
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800649 if ((so->fill + other->used)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900650 if (set_table_resize(so, (so->used + other->used)*2) != 0)
651 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000652 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700653 so_entry = so->table;
654 other_entry = other->table;
655
656 /* If our table is empty, and both tables have the same size, and
657 there are no dummies to eliminate, then just copy the pointers. */
658 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
659 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
660 key = other_entry->key;
661 if (key != NULL) {
662 assert(so_entry->key == NULL);
663 Py_INCREF(key);
664 so_entry->key = key;
665 so_entry->hash = other_entry->hash;
666 }
667 }
668 so->fill = other->fill;
669 so->used = other->used;
670 return 0;
671 }
672
673 /* If our table is empty, we can use set_insert_clean() */
674 if (so->fill == 0) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800675 setentry *newtable = so->table;
676 size_t newmask = (size_t)so->mask;
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800677 so->fill = other->used;
678 so->used = other->used;
Raymond Hettingere4495872015-12-15 00:42:30 -0800679 for (i = other->mask + 1; i > 0 ; i--, other_entry++) {
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700680 key = other_entry->key;
681 if (key != NULL && key != dummy) {
682 Py_INCREF(key);
Raymond Hettinger5088f602015-12-13 18:45:01 -0800683 set_insert_clean(newtable, newmask, key, other_entry->hash);
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700684 }
685 }
686 return 0;
687 }
688
689 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700690 for (i = 0; i <= other->mask; i++) {
691 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700692 key = other_entry->key;
693 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700694 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000696 }
697 }
698 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000699}
700
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000701static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530702set_pop(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000703{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800704 /* Make sure the search finger is in bounds */
Raymond Hettingerf9ec1b92018-11-11 14:35:47 -0800705 setentry *entry = so->table + (so->finger & so->mask);
706 setentry *limit = so->table + so->mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000708
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000709 if (so->used == 0) {
710 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
711 return NULL;
712 }
Raymond Hettingercf5863f2018-11-09 02:31:56 -0800713 while (entry->key == NULL || entry->key==dummy) {
714 entry++;
715 if (entry > limit)
716 entry = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 }
718 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800720 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 so->used--;
Raymond Hettingercf5863f2018-11-09 02:31:56 -0800722 so->finger = entry - so->table + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000724}
725
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000726PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
727Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000728
729static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000730set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000731{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000732 Py_ssize_t pos = 0;
733 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 while (set_next(so, &pos, &entry))
736 Py_VISIT(entry->key);
737 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000738}
739
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700740/* Work to increase the bit dispersion for closely spaced hash values.
741 This is important because some use cases have many combinations of a
742 small number of elements with nearby hashes so that many distinct
743 combinations collapse to only a handful of distinct hash values. */
744
745static Py_uhash_t
746_shuffle_bits(Py_uhash_t h)
747{
748 return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
749}
750
751/* Most of the constants in this hash algorithm are randomly chosen
752 large primes with "interesting bit patterns" and that passed tests
753 for good collision statistics on a variety of problematic datasets
754 including powersets and graph structures (such as David Eppstein's
755 graph recipes in Lib/test/test_set.py) */
756
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000757static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000758frozenset_hash(PyObject *self)
759{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000760 PySetObject *so = (PySetObject *)self;
Raymond Hettinger41481952015-08-07 00:43:39 -0700761 Py_uhash_t hash = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000763
Raymond Hettingerb501a272015-08-06 22:15:22 -0700764 if (so->hash != -1)
765 return so->hash;
766
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700767 /* Xor-in shuffled bits from every entry's hash field because xor is
768 commutative and a frozenset hash should be independent of order.
769
770 For speed, include null entries and dummy entries and then
771 subtract out their effect afterwards so that the final hash
772 depends only on active entries. This allows the code to be
773 vectorized by the compiler and it saves the unpredictable
774 branches that would arise when trying to exclude null and dummy
775 entries on every iteration. */
776
777 for (entry = so->table; entry <= &so->table[so->mask]; entry++)
778 hash ^= _shuffle_bits(entry->hash);
779
Raymond Hettingera286a512015-08-01 11:07:11 -0700780 /* Remove the effect of an odd number of NULL entries */
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700781 if ((so->mask + 1 - so->fill) & 1)
782 hash ^= _shuffle_bits(0);
783
784 /* Remove the effect of an odd number of dummy entries */
785 if ((so->fill - so->used) & 1)
786 hash ^= _shuffle_bits(-1);
787
Raymond Hettinger41481952015-08-07 00:43:39 -0700788 /* Factor in the number of active entries */
789 hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;
790
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700791 /* Disperse patterns arising in nested frozensets */
Raymond Hettingerfa788062018-01-18 13:23:27 -0800792 hash ^= (hash >> 11) ^ (hash >> 25);
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800793 hash = hash * 69069U + 907133923UL;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700794
Raymond Hettinger36c05002015-08-01 10:57:42 -0700795 /* -1 is reserved as an error code */
Victor Stinner12174a52014-08-15 23:17:38 +0200796 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800797 hash = 590923713UL;
Raymond Hettinger36c05002015-08-01 10:57:42 -0700798
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000799 so->hash = hash;
800 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000801}
802
Raymond Hettingera9d99362005-08-05 00:01:15 +0000803/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000804
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000805typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000806 PyObject_HEAD
807 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
808 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700809 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000810 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000811} setiterobject;
812
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000813static void
814setiter_dealloc(setiterobject *si)
815{
INADA Naokia6296d32017-08-24 14:55:17 +0900816 /* bpo-31095: UnTrack is needed before calling any callbacks */
817 _PyObject_GC_UNTRACK(si);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000818 Py_XDECREF(si->si_set);
819 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000820}
821
822static int
823setiter_traverse(setiterobject *si, visitproc visit, void *arg)
824{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000825 Py_VISIT(si->si_set);
826 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000827}
828
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000829static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530830setiter_len(setiterobject *si, PyObject *Py_UNUSED(ignored))
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000831{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000832 Py_ssize_t len = 0;
833 if (si->si_set != NULL && si->si_used == si->si_set->used)
834 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000835 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000836}
837
Armin Rigof5b3e362006-02-11 21:32:43 +0000838PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000839
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000840static PyObject *setiter_iternext(setiterobject *si);
841
842static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530843setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000844{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200845 _Py_IDENTIFIER(iter);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300846 /* copy the iterator state */
Sergey Fedoseev63958442018-10-20 05:43:33 +0500847 setiterobject tmp = *si;
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000848 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300849
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000850 /* iterate the temporary into a list */
Sergey Fedoseev63958442018-10-20 05:43:33 +0500851 PyObject *list = PySequence_List((PyObject*)&tmp);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000852 Py_XDECREF(tmp.si_set);
Sergey Fedoseev63958442018-10-20 05:43:33 +0500853 if (list == NULL) {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000854 return NULL;
855 }
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200856 return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000857}
858
859PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
860
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000861static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000862 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000863 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000864 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000865};
866
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000867static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000868{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700869 PyObject *key;
870 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200871 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000872 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000873
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000874 if (so == NULL)
875 return NULL;
876 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000878 if (si->si_used != so->used) {
879 PyErr_SetString(PyExc_RuntimeError,
880 "Set changed size during iteration");
881 si->si_used = -1; /* Make this state sticky */
882 return NULL;
883 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700884
885 i = si->si_pos;
886 assert(i>=0);
887 entry = so->table;
888 mask = so->mask;
889 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
890 i++;
891 si->si_pos = i+1;
892 if (i > mask)
893 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000894 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700895 key = entry[i].key;
896 Py_INCREF(key);
897 return key;
898
899fail:
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700900 si->si_set = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +0300901 Py_DECREF(so);
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700902 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000903}
904
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000905PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000906 PyVarObject_HEAD_INIT(&PyType_Type, 0)
907 "set_iterator", /* tp_name */
908 sizeof(setiterobject), /* tp_basicsize */
909 0, /* tp_itemsize */
910 /* methods */
911 (destructor)setiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200912 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000913 0, /* tp_getattr */
914 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200915 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916 0, /* tp_repr */
917 0, /* tp_as_number */
918 0, /* tp_as_sequence */
919 0, /* tp_as_mapping */
920 0, /* tp_hash */
921 0, /* tp_call */
922 0, /* tp_str */
923 PyObject_GenericGetAttr, /* tp_getattro */
924 0, /* tp_setattro */
925 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700926 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000927 0, /* tp_doc */
928 (traverseproc)setiter_traverse, /* tp_traverse */
929 0, /* tp_clear */
930 0, /* tp_richcompare */
931 0, /* tp_weaklistoffset */
932 PyObject_SelfIter, /* tp_iter */
933 (iternextfunc)setiter_iternext, /* tp_iternext */
934 setiter_methods, /* tp_methods */
935 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000936};
937
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000938static PyObject *
939set_iter(PySetObject *so)
940{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000941 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
942 if (si == NULL)
943 return NULL;
944 Py_INCREF(so);
945 si->si_set = so;
946 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700947 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000948 si->len = so->used;
949 _PyObject_GC_TRACK(si);
950 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000951}
952
Raymond Hettingerd7946662005-08-01 21:39:29 +0000953static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000954set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000955{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000956 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000957
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000958 if (PyAnySet_Check(other))
959 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 if (PyDict_CheckExact(other)) {
962 PyObject *value;
963 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000964 Py_hash_t hash;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200965 Py_ssize_t dictsize = PyDict_GET_SIZE(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 /* Do one big resize at the start, rather than
968 * incrementally resizing as we insert new keys. Expect
969 * that there will be no (or few) overlapping keys.
970 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700971 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000972 return -1;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800973 if ((so->fill + dictsize)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900974 if (set_table_resize(so, (so->used + dictsize)*2) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000975 return -1;
976 }
977 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700978 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000979 return -1;
980 }
981 return 0;
982 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 it = PyObject_GetIter(other);
985 if (it == NULL)
986 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +0000987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700989 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000990 Py_DECREF(it);
991 Py_DECREF(key);
992 return -1;
993 }
994 Py_DECREF(key);
995 }
996 Py_DECREF(it);
997 if (PyErr_Occurred())
998 return -1;
999 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001000}
1001
1002static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001003set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001004{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1008 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001009 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001010 return NULL;
1011 }
1012 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001013}
1014
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001016"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001017
Raymond Hettinger426d9952014-05-18 21:40:20 +01001018/* XXX Todo:
1019 If aligned memory allocations become available, make the
1020 set object 64 byte aligned so that most of the fields
1021 can be retrieved or updated in a single cache line.
1022*/
1023
Raymond Hettingera38123e2003-11-24 22:18:49 +00001024static PyObject *
1025make_new_set(PyTypeObject *type, PyObject *iterable)
1026{
Dong-hee Na1c605672020-03-19 02:30:50 +09001027 assert(PyType_Check(type));
Raymond Hettinger8421d712016-04-29 01:37:05 -07001028 PySetObject *so;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001029
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001030 so = (PySetObject *)type->tp_alloc(type, 0);
1031 if (so == NULL)
1032 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001033
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001034 so->fill = 0;
1035 so->used = 0;
1036 so->mask = PySet_MINSIZE - 1;
1037 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001038 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001039 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001040 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001043 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001044 Py_DECREF(so);
1045 return NULL;
1046 }
1047 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001048
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001050}
1051
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001052static PyObject *
1053make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1054{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1056 if (PyType_IsSubtype(type, &PySet_Type))
1057 type = &PySet_Type;
1058 else
1059 type = &PyFrozenSet_Type;
1060 }
1061 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001062}
1063
Raymond Hettingerd7946662005-08-01 21:39:29 +00001064/* The empty frozenset is a singleton */
1065static PyObject *emptyfrozenset = NULL;
1066
Raymond Hettingera690a992003-11-16 16:17:49 +00001067static PyObject *
Dong-hee Na1c605672020-03-19 02:30:50 +09001068make_new_frozenset(PyTypeObject *type, PyObject *iterable)
Raymond Hettingera690a992003-11-16 16:17:49 +00001069{
Dong-hee Na1c605672020-03-19 02:30:50 +09001070 if (type != &PyFrozenSet_Type) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 return make_new_set(type, iterable);
Dong-hee Na1c605672020-03-19 02:30:50 +09001072 }
Raymond Hettingerd7946662005-08-01 21:39:29 +00001073
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 if (iterable != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001075 if (PyFrozenSet_CheckExact(iterable)) {
Dong-hee Na1c605672020-03-19 02:30:50 +09001076 /* frozenset(f) is idempotent */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 Py_INCREF(iterable);
1078 return iterable;
1079 }
Dong-hee Na1c605672020-03-19 02:30:50 +09001080 PyObject *res = make_new_set((PyTypeObject *)type, iterable);
1081 if (res == NULL || PySet_GET_SIZE(res) != 0) {
1082 return res;
1083 }
1084 /* If the created frozenset is empty, return the empty frozenset singleton instead */
1085 Py_DECREF(res);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001086 }
Dong-hee Na1c605672020-03-19 02:30:50 +09001087
1088 // The empty frozenset is a singleton
1089 if (emptyfrozenset == NULL) {
1090 emptyfrozenset = make_new_set((PyTypeObject *)type, NULL);
1091 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 Py_XINCREF(emptyfrozenset);
1093 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001094}
1095
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001096static PyObject *
Dong-hee Na1c605672020-03-19 02:30:50 +09001097frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1098{
1099 PyObject *iterable = NULL;
1100
1101 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset", kwds)) {
1102 return NULL;
1103 }
1104
1105 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable)) {
1106 return NULL;
1107 }
1108
1109 return make_new_frozenset(type, iterable);
1110}
1111
1112static PyObject *
1113frozenset_vectorcall(PyObject *type, PyObject * const*args,
1114 size_t nargsf, PyObject *kwnames)
1115{
1116 if (!_PyArg_NoKwnames("frozenset", kwnames)) {
1117 return NULL;
1118 }
1119
1120 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
1121 if (!_PyArg_CheckPositional("frozenset", nargs, 0, 1)) {
1122 return NULL;
1123 }
1124
1125 PyObject *iterable = (nargs ? args[0] : NULL);
1126 return make_new_frozenset((PyTypeObject *)type, iterable);
1127}
1128
1129static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001130set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1131{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001132 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001133}
1134
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001135/* set_swap_bodies() switches the contents of any two sets by moving their
1136 internal data pointers and, if needed, copying the internal smalltables.
1137 Semantically equivalent to:
1138
1139 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1140
1141 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001142 Useful for operations that update in-place (by allowing an intermediate
1143 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001144*/
1145
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001146static void
1147set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001148{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 Py_ssize_t t;
1150 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001152 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001154 t = a->fill; a->fill = b->fill; b->fill = t;
1155 t = a->used; a->used = b->used; b->used = t;
1156 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001158 u = a->table;
1159 if (a->table == a->smalltable)
1160 u = b->smalltable;
1161 a->table = b->table;
1162 if (b->table == b->smalltable)
1163 a->table = a->smalltable;
1164 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001166 if (a->table == a->smalltable || b->table == b->smalltable) {
1167 memcpy(tab, a->smalltable, sizeof(tab));
1168 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1169 memcpy(b->smalltable, tab, sizeof(tab));
1170 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1173 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1174 h = a->hash; a->hash = b->hash; b->hash = h;
1175 } else {
1176 a->hash = -1;
1177 b->hash = -1;
1178 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001179}
1180
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001181static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301182set_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001183{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001184 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001185}
1186
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001187static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301188frozenset_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001189{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 if (PyFrozenSet_CheckExact(so)) {
1191 Py_INCREF(so);
1192 return (PyObject *)so;
1193 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301194 return set_copy(so, NULL);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001195}
1196
Raymond Hettingera690a992003-11-16 16:17:49 +00001197PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1198
1199static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301200set_clear(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc991db22005-08-11 07:58:45 +00001201{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001202 set_clear_internal(so);
1203 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001204}
1205
1206PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1207
1208static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001209set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001210{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001211 PySetObject *result;
1212 PyObject *other;
1213 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001214
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301215 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 if (result == NULL)
1217 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001219 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1220 other = PyTuple_GET_ITEM(args, i);
1221 if ((PyObject *)so == other)
1222 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001223 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001224 Py_DECREF(result);
1225 return NULL;
1226 }
1227 }
1228 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001229}
1230
1231PyDoc_STRVAR(union_doc,
1232 "Return the union of sets as a new set.\n\
1233\n\
1234(i.e. all elements that are in either set.)");
1235
1236static PyObject *
1237set_or(PySetObject *so, PyObject *other)
1238{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001239 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001240
Brian Curtindfc80e32011-08-10 20:28:54 -05001241 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1242 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001243
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301244 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 if (result == NULL)
1246 return NULL;
1247 if ((PyObject *)so == other)
1248 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001249 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 Py_DECREF(result);
1251 return NULL;
1252 }
1253 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001254}
1255
Raymond Hettingera690a992003-11-16 16:17:49 +00001256static PyObject *
1257set_ior(PySetObject *so, PyObject *other)
1258{
Brian Curtindfc80e32011-08-10 20:28:54 -05001259 if (!PyAnySet_Check(other))
1260 Py_RETURN_NOTIMPLEMENTED;
1261
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001262 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 return NULL;
1264 Py_INCREF(so);
1265 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001266}
1267
1268static PyObject *
1269set_intersection(PySetObject *so, PyObject *other)
1270{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 PySetObject *result;
1272 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001273 Py_hash_t hash;
1274 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001276 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301277 return set_copy(so, NULL);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1280 if (result == NULL)
1281 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 if (PyAnySet_Check(other)) {
1284 Py_ssize_t pos = 0;
1285 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1288 tmp = (PyObject *)so;
1289 so = (PySetObject *)other;
1290 other = tmp;
1291 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001292
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001293 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001294 key = entry->key;
1295 hash = entry->hash;
1296 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001297 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 Py_DECREF(result);
1299 return NULL;
1300 }
1301 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001302 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 Py_DECREF(result);
1304 return NULL;
1305 }
1306 }
1307 }
1308 return (PyObject *)result;
1309 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 it = PyObject_GetIter(other);
1312 if (it == NULL) {
1313 Py_DECREF(result);
1314 return NULL;
1315 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001318 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001319 if (hash == -1)
1320 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001321 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001322 if (rv < 0)
1323 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001325 if (set_add_entry(result, key, hash))
1326 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 }
1328 Py_DECREF(key);
1329 }
1330 Py_DECREF(it);
1331 if (PyErr_Occurred()) {
1332 Py_DECREF(result);
1333 return NULL;
1334 }
1335 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001336 error:
1337 Py_DECREF(it);
1338 Py_DECREF(result);
1339 Py_DECREF(key);
1340 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001341}
1342
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001343static PyObject *
1344set_intersection_multi(PySetObject *so, PyObject *args)
1345{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346 Py_ssize_t i;
1347 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301350 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001352 Py_INCREF(so);
1353 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1354 PyObject *other = PyTuple_GET_ITEM(args, i);
1355 PyObject *newresult = set_intersection((PySetObject *)result, other);
1356 if (newresult == NULL) {
1357 Py_DECREF(result);
1358 return NULL;
1359 }
1360 Py_DECREF(result);
1361 result = newresult;
1362 }
1363 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001364}
1365
Raymond Hettingera690a992003-11-16 16:17:49 +00001366PyDoc_STRVAR(intersection_doc,
1367"Return the intersection of two sets as a new set.\n\
1368\n\
1369(i.e. all elements that are in both sets.)");
1370
1371static PyObject *
1372set_intersection_update(PySetObject *so, PyObject *other)
1373{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 tmp = set_intersection(so, other);
1377 if (tmp == NULL)
1378 return NULL;
1379 set_swap_bodies(so, (PySetObject *)tmp);
1380 Py_DECREF(tmp);
1381 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001382}
1383
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001384static PyObject *
1385set_intersection_update_multi(PySetObject *so, PyObject *args)
1386{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 tmp = set_intersection_multi(so, args);
1390 if (tmp == NULL)
1391 return NULL;
1392 set_swap_bodies(so, (PySetObject *)tmp);
1393 Py_DECREF(tmp);
1394 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001395}
1396
Raymond Hettingera690a992003-11-16 16:17:49 +00001397PyDoc_STRVAR(intersection_update_doc,
1398"Update a set with the intersection of itself and another.");
1399
1400static PyObject *
1401set_and(PySetObject *so, PyObject *other)
1402{
Brian Curtindfc80e32011-08-10 20:28:54 -05001403 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1404 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001405 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001406}
1407
1408static PyObject *
1409set_iand(PySetObject *so, PyObject *other)
1410{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001412
Brian Curtindfc80e32011-08-10 20:28:54 -05001413 if (!PyAnySet_Check(other))
1414 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 result = set_intersection_update(so, other);
1416 if (result == NULL)
1417 return NULL;
1418 Py_DECREF(result);
1419 Py_INCREF(so);
1420 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001421}
1422
Guido van Rossum58da9312007-11-10 23:39:45 +00001423static PyObject *
1424set_isdisjoint(PySetObject *so, PyObject *other)
1425{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001427 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 if ((PyObject *)so == other) {
1430 if (PySet_GET_SIZE(so) == 0)
1431 Py_RETURN_TRUE;
1432 else
1433 Py_RETURN_FALSE;
1434 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 if (PyAnySet_CheckExact(other)) {
1437 Py_ssize_t pos = 0;
1438 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1441 tmp = (PyObject *)so;
1442 so = (PySetObject *)other;
1443 other = tmp;
1444 }
1445 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001446 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001447 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 return NULL;
1449 if (rv)
1450 Py_RETURN_FALSE;
1451 }
1452 Py_RETURN_TRUE;
1453 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 it = PyObject_GetIter(other);
1456 if (it == NULL)
1457 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001458
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001460 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462 if (hash == -1) {
1463 Py_DECREF(key);
1464 Py_DECREF(it);
1465 return NULL;
1466 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001467 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001468 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001469 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 Py_DECREF(it);
1471 return NULL;
1472 }
1473 if (rv) {
1474 Py_DECREF(it);
1475 Py_RETURN_FALSE;
1476 }
1477 }
1478 Py_DECREF(it);
1479 if (PyErr_Occurred())
1480 return NULL;
1481 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001482}
1483
1484PyDoc_STRVAR(isdisjoint_doc,
1485"Return True if two sets have a null intersection.");
1486
Neal Norwitz6576bd82005-11-13 18:41:28 +00001487static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001488set_difference_update_internal(PySetObject *so, PyObject *other)
1489{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 if ((PyObject *)so == other)
1491 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001493 if (PyAnySet_Check(other)) {
1494 setentry *entry;
1495 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001496
Raymond Hettinger88ea1662019-08-29 09:02:58 -07001497 /* Optimization: When the other set is more than 8 times
1498 larger than the base set, replace the other set with
1499 interesection of the two sets.
1500 */
1501 if ((PySet_GET_SIZE(other) >> 3) > PySet_GET_SIZE(so)) {
1502 other = set_intersection(so, other);
1503 if (other == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 return -1;
Raymond Hettinger88ea1662019-08-29 09:02:58 -07001505 } else {
1506 Py_INCREF(other);
1507 }
1508
1509 while (set_next((PySetObject *)other, &pos, &entry))
1510 if (set_discard_entry(so, entry->key, entry->hash) < 0) {
1511 Py_DECREF(other);
1512 return -1;
1513 }
1514
1515 Py_DECREF(other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 } else {
1517 PyObject *key, *it;
1518 it = PyObject_GetIter(other);
1519 if (it == NULL)
1520 return -1;
1521
1522 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001523 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 Py_DECREF(it);
1525 Py_DECREF(key);
1526 return -1;
1527 }
1528 Py_DECREF(key);
1529 }
1530 Py_DECREF(it);
1531 if (PyErr_Occurred())
1532 return -1;
1533 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001534 /* If more than 1/4th are dummies, then resize them away. */
1535 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001536 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +09001537 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001538}
1539
Raymond Hettingera690a992003-11-16 16:17:49 +00001540static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001541set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001542{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1546 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001547 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 return NULL;
1549 }
1550 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001551}
1552
1553PyDoc_STRVAR(difference_update_doc,
1554"Remove all elements of another set from this set.");
1555
1556static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001557set_copy_and_difference(PySetObject *so, PyObject *other)
1558{
1559 PyObject *result;
1560
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301561 result = set_copy(so, NULL);
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001562 if (result == NULL)
1563 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001564 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001565 return result;
1566 Py_DECREF(result);
1567 return NULL;
1568}
1569
1570static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001571set_difference(PySetObject *so, PyObject *other)
1572{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001573 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001574 PyObject *key;
1575 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 setentry *entry;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001577 Py_ssize_t pos = 0, other_size;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001578 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001579
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001580 if (PyAnySet_Check(other)) {
1581 other_size = PySet_GET_SIZE(other);
1582 }
1583 else if (PyDict_CheckExact(other)) {
1584 other_size = PyDict_GET_SIZE(other);
1585 }
1586 else {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001587 return set_copy_and_difference(so, other);
1588 }
1589
1590 /* If len(so) much more than len(other), it's more efficient to simply copy
1591 * so and then iterate other looking for common elements. */
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001592 if ((PySet_GET_SIZE(so) >> 2) > other_size) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001593 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001595
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001596 result = make_new_set_basetype(Py_TYPE(so), NULL);
1597 if (result == NULL)
1598 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 if (PyDict_CheckExact(other)) {
1601 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001602 key = entry->key;
1603 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001604 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001605 if (rv < 0) {
1606 Py_DECREF(result);
1607 return NULL;
1608 }
1609 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001610 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 Py_DECREF(result);
1612 return NULL;
1613 }
1614 }
1615 }
1616 return result;
1617 }
1618
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001619 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001621 key = entry->key;
1622 hash = entry->hash;
1623 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001624 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625 Py_DECREF(result);
1626 return NULL;
1627 }
1628 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001629 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 Py_DECREF(result);
1631 return NULL;
1632 }
1633 }
1634 }
1635 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001636}
1637
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001638static PyObject *
1639set_difference_multi(PySetObject *so, PyObject *args)
1640{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001641 Py_ssize_t i;
1642 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001643
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001644 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301645 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001646
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 other = PyTuple_GET_ITEM(args, 0);
1648 result = set_difference(so, other);
1649 if (result == NULL)
1650 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001651
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1653 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001654 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001655 Py_DECREF(result);
1656 return NULL;
1657 }
1658 }
1659 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001660}
1661
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001662PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001663"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001664\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001665(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001666static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001667set_sub(PySetObject *so, PyObject *other)
1668{
Brian Curtindfc80e32011-08-10 20:28:54 -05001669 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1670 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001671 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001672}
1673
1674static PyObject *
1675set_isub(PySetObject *so, PyObject *other)
1676{
Brian Curtindfc80e32011-08-10 20:28:54 -05001677 if (!PyAnySet_Check(other))
1678 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001679 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001680 return NULL;
1681 Py_INCREF(so);
1682 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001683}
1684
1685static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001686set_symmetric_difference_update(PySetObject *so, PyObject *other)
1687{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001688 PySetObject *otherset;
1689 PyObject *key;
1690 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001691 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001692 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001693 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001694
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001695 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301696 return set_clear(so, NULL);
Raymond Hettingera690a992003-11-16 16:17:49 +00001697
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001698 if (PyDict_CheckExact(other)) {
1699 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001700 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001701 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001702 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001703 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001704 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001705 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001706 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001707 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001708 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001709 Py_DECREF(key);
1710 return NULL;
1711 }
1712 }
Georg Brandl2d444492010-09-03 10:52:55 +00001713 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001714 }
1715 Py_RETURN_NONE;
1716 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001717
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001718 if (PyAnySet_Check(other)) {
1719 Py_INCREF(other);
1720 otherset = (PySetObject *)other;
1721 } else {
1722 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1723 if (otherset == NULL)
1724 return NULL;
1725 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001726
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001727 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001728 key = entry->key;
1729 hash = entry->hash;
1730 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001731 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001732 Py_DECREF(otherset);
1733 return NULL;
1734 }
1735 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001736 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001737 Py_DECREF(otherset);
1738 return NULL;
1739 }
1740 }
1741 }
1742 Py_DECREF(otherset);
1743 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001744}
1745
1746PyDoc_STRVAR(symmetric_difference_update_doc,
1747"Update a set with the symmetric difference of itself and another.");
1748
1749static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001750set_symmetric_difference(PySetObject *so, PyObject *other)
1751{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001752 PyObject *rv;
1753 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001754
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001755 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1756 if (otherset == NULL)
1757 return NULL;
1758 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
lekma491bbed2018-05-02 11:29:10 +02001759 if (rv == NULL) {
1760 Py_DECREF(otherset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 return NULL;
lekma491bbed2018-05-02 11:29:10 +02001762 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 Py_DECREF(rv);
1764 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001765}
1766
1767PyDoc_STRVAR(symmetric_difference_doc,
1768"Return the symmetric difference of two sets as a new set.\n\
1769\n\
1770(i.e. all elements that are in exactly one of the sets.)");
1771
1772static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001773set_xor(PySetObject *so, PyObject *other)
1774{
Brian Curtindfc80e32011-08-10 20:28:54 -05001775 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1776 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001778}
1779
1780static PyObject *
1781set_ixor(PySetObject *so, PyObject *other)
1782{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001783 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001784
Brian Curtindfc80e32011-08-10 20:28:54 -05001785 if (!PyAnySet_Check(other))
1786 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001787 result = set_symmetric_difference_update(so, other);
1788 if (result == NULL)
1789 return NULL;
1790 Py_DECREF(result);
1791 Py_INCREF(so);
1792 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001793}
1794
1795static PyObject *
1796set_issubset(PySetObject *so, PyObject *other)
1797{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001798 setentry *entry;
1799 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001800 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001802 if (!PyAnySet_Check(other)) {
1803 PyObject *tmp, *result;
1804 tmp = make_new_set(&PySet_Type, other);
1805 if (tmp == NULL)
1806 return NULL;
1807 result = set_issubset(so, tmp);
1808 Py_DECREF(tmp);
1809 return result;
1810 }
1811 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1812 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001813
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001814 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001815 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001816 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001817 return NULL;
1818 if (!rv)
1819 Py_RETURN_FALSE;
1820 }
1821 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001822}
1823
1824PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1825
1826static PyObject *
1827set_issuperset(PySetObject *so, PyObject *other)
1828{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001829 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001831 if (!PyAnySet_Check(other)) {
1832 tmp = make_new_set(&PySet_Type, other);
1833 if (tmp == NULL)
1834 return NULL;
1835 result = set_issuperset(so, tmp);
1836 Py_DECREF(tmp);
1837 return result;
1838 }
1839 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001840}
1841
1842PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1843
Raymond Hettingera690a992003-11-16 16:17:49 +00001844static PyObject *
1845set_richcompare(PySetObject *v, PyObject *w, int op)
1846{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001847 PyObject *r1;
1848 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001849
Brian Curtindfc80e32011-08-10 20:28:54 -05001850 if(!PyAnySet_Check(w))
1851 Py_RETURN_NOTIMPLEMENTED;
1852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001853 switch (op) {
1854 case Py_EQ:
1855 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1856 Py_RETURN_FALSE;
1857 if (v->hash != -1 &&
1858 ((PySetObject *)w)->hash != -1 &&
1859 v->hash != ((PySetObject *)w)->hash)
1860 Py_RETURN_FALSE;
1861 return set_issubset(v, w);
1862 case Py_NE:
1863 r1 = set_richcompare(v, w, Py_EQ);
1864 if (r1 == NULL)
1865 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001866 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001868 if (r2 < 0)
1869 return NULL;
1870 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001871 case Py_LE:
1872 return set_issubset(v, w);
1873 case Py_GE:
1874 return set_issuperset(v, w);
1875 case Py_LT:
1876 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1877 Py_RETURN_FALSE;
1878 return set_issubset(v, w);
1879 case Py_GT:
1880 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1881 Py_RETURN_FALSE;
1882 return set_issuperset(v, w);
1883 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001884 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001885}
1886
Raymond Hettingera690a992003-11-16 16:17:49 +00001887static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001888set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001889{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001890 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 return NULL;
1892 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001893}
1894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001896"Add an element to a set.\n\
1897\n\
1898This has no effect if the element is already present.");
1899
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001900static int
1901set_contains(PySetObject *so, PyObject *key)
1902{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001903 PyObject *tmpkey;
1904 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001905
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001907 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1909 return -1;
1910 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001911 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001912 if (tmpkey == NULL)
1913 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001914 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 Py_DECREF(tmpkey);
1916 }
1917 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001918}
1919
1920static PyObject *
1921set_direct_contains(PySetObject *so, PyObject *key)
1922{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001926 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927 return NULL;
1928 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001929}
1930
1931PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1932
Raymond Hettingera690a992003-11-16 16:17:49 +00001933static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001934set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001935{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 PyObject *tmpkey;
1937 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001938
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001939 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001940 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001941 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1942 return NULL;
1943 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001944 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001945 if (tmpkey == NULL)
1946 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001948 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001949 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001950 return NULL;
1951 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001952
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001953 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001954 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 return NULL;
1956 }
1957 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001958}
1959
1960PyDoc_STRVAR(remove_doc,
1961"Remove an element from a set; it must be a member.\n\
1962\n\
1963If the element is not a member, raise a KeyError.");
1964
1965static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001966set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001967{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001968 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001969 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001970
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001971 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001972 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1974 return NULL;
1975 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001976 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001977 if (tmpkey == NULL)
1978 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001979 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001981 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001982 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001983 }
1984 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001985}
1986
1987PyDoc_STRVAR(discard_doc,
1988"Remove an element from a set if it is a member.\n\
1989\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001990If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001991
1992static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301993set_reduce(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001994{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001995 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001996 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001997
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001998 keys = PySequence_List((PyObject *)so);
1999 if (keys == NULL)
2000 goto done;
2001 args = PyTuple_Pack(1, keys);
2002 if (args == NULL)
2003 goto done;
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03002004 if (_PyObject_LookupAttrId((PyObject *)so, &PyId___dict__, &dict) < 0) {
2005 goto done;
2006 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002007 if (dict == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002008 dict = Py_None;
2009 Py_INCREF(dict);
2010 }
2011 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00002012done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002013 Py_XDECREF(args);
2014 Py_XDECREF(keys);
2015 Py_XDECREF(dict);
2016 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00002017}
2018
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002019static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302020set_sizeof(PySetObject *so, PyObject *Py_UNUSED(ignored))
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002021{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002022 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002023
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02002024 res = _PyObject_SIZE(Py_TYPE(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 if (so->table != so->smalltable)
2026 res = res + (so->mask + 1) * sizeof(setentry);
2027 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002028}
2029
2030PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002031static int
2032set_init(PySetObject *self, PyObject *args, PyObject *kwds)
2033{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002034 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002035
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03002036 if (!_PyArg_NoKeywords("set", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002037 return -1;
2038 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
2039 return -1;
Raymond Hettingerb72e21b2016-03-25 02:29:59 -07002040 if (self->fill)
2041 set_clear_internal(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002042 self->hash = -1;
2043 if (iterable == NULL)
2044 return 0;
2045 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002046}
2047
Dong-hee Na6ff79f652020-03-17 02:17:38 +09002048static PyObject*
2049set_vectorcall(PyObject *type, PyObject * const*args,
2050 size_t nargsf, PyObject *kwnames)
2051{
2052 assert(PyType_Check(type));
2053
2054 if (!_PyArg_NoKwnames("set", kwnames)) {
2055 return NULL;
2056 }
2057
2058 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
2059 if (!_PyArg_CheckPositional("set", nargs, 0, 1)) {
2060 return NULL;
2061 }
2062
2063 if (nargs) {
2064 return make_new_set((PyTypeObject *)type, args[0]);
2065 }
2066
2067 return make_new_set((PyTypeObject *)type, NULL);
2068}
2069
Raymond Hettingera690a992003-11-16 16:17:49 +00002070static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002071 set_len, /* sq_length */
2072 0, /* sq_concat */
2073 0, /* sq_repeat */
2074 0, /* sq_item */
2075 0, /* sq_slice */
2076 0, /* sq_ass_item */
2077 0, /* sq_ass_slice */
2078 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002079};
2080
2081/* set object ********************************************************/
2082
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002083#ifdef Py_DEBUG
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302084static PyObject *test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored));
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002085
2086PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2087All is well if assertions don't fail.");
2088#endif
2089
Raymond Hettingera690a992003-11-16 16:17:49 +00002090static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002091 {"add", (PyCFunction)set_add, METH_O,
2092 add_doc},
2093 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2094 clear_doc},
2095 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2096 contains_doc},
2097 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2098 copy_doc},
2099 {"discard", (PyCFunction)set_discard, METH_O,
2100 discard_doc},
2101 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2102 difference_doc},
2103 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2104 difference_update_doc},
2105 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2106 intersection_doc},
2107 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2108 intersection_update_doc},
2109 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2110 isdisjoint_doc},
2111 {"issubset", (PyCFunction)set_issubset, METH_O,
2112 issubset_doc},
2113 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2114 issuperset_doc},
2115 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2116 pop_doc},
2117 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2118 reduce_doc},
2119 {"remove", (PyCFunction)set_remove, METH_O,
2120 remove_doc},
2121 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2122 sizeof_doc},
2123 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2124 symmetric_difference_doc},
2125 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2126 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002127#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002128 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2129 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002130#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002131 {"union", (PyCFunction)set_union, METH_VARARGS,
2132 union_doc},
2133 {"update", (PyCFunction)set_update, METH_VARARGS,
2134 update_doc},
Guido van Rossum48b069a2020-04-07 09:50:06 -07002135 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002136 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002137};
2138
2139static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002140 0, /*nb_add*/
2141 (binaryfunc)set_sub, /*nb_subtract*/
2142 0, /*nb_multiply*/
2143 0, /*nb_remainder*/
2144 0, /*nb_divmod*/
2145 0, /*nb_power*/
2146 0, /*nb_negative*/
2147 0, /*nb_positive*/
2148 0, /*nb_absolute*/
2149 0, /*nb_bool*/
2150 0, /*nb_invert*/
2151 0, /*nb_lshift*/
2152 0, /*nb_rshift*/
2153 (binaryfunc)set_and, /*nb_and*/
2154 (binaryfunc)set_xor, /*nb_xor*/
2155 (binaryfunc)set_or, /*nb_or*/
2156 0, /*nb_int*/
2157 0, /*nb_reserved*/
2158 0, /*nb_float*/
2159 0, /*nb_inplace_add*/
2160 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2161 0, /*nb_inplace_multiply*/
2162 0, /*nb_inplace_remainder*/
2163 0, /*nb_inplace_power*/
2164 0, /*nb_inplace_lshift*/
2165 0, /*nb_inplace_rshift*/
2166 (binaryfunc)set_iand, /*nb_inplace_and*/
2167 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2168 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002169};
2170
2171PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002172"set() -> new empty set object\n\
2173set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002174\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002175Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002176
2177PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2179 "set", /* tp_name */
2180 sizeof(PySetObject), /* tp_basicsize */
2181 0, /* tp_itemsize */
2182 /* methods */
2183 (destructor)set_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002184 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002185 0, /* tp_getattr */
2186 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002187 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002188 (reprfunc)set_repr, /* tp_repr */
2189 &set_as_number, /* tp_as_number */
2190 &set_as_sequence, /* tp_as_sequence */
2191 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002192 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002193 0, /* tp_call */
2194 0, /* tp_str */
2195 PyObject_GenericGetAttr, /* tp_getattro */
2196 0, /* tp_setattro */
2197 0, /* tp_as_buffer */
2198 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2199 Py_TPFLAGS_BASETYPE, /* tp_flags */
2200 set_doc, /* tp_doc */
2201 (traverseproc)set_traverse, /* tp_traverse */
2202 (inquiry)set_clear_internal, /* tp_clear */
2203 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002204 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2205 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002206 0, /* tp_iternext */
2207 set_methods, /* tp_methods */
2208 0, /* tp_members */
2209 0, /* tp_getset */
2210 0, /* tp_base */
2211 0, /* tp_dict */
2212 0, /* tp_descr_get */
2213 0, /* tp_descr_set */
2214 0, /* tp_dictoffset */
2215 (initproc)set_init, /* tp_init */
2216 PyType_GenericAlloc, /* tp_alloc */
2217 set_new, /* tp_new */
2218 PyObject_GC_Del, /* tp_free */
Dong-hee Na6ff79f652020-03-17 02:17:38 +09002219 .tp_vectorcall = set_vectorcall,
Raymond Hettingera690a992003-11-16 16:17:49 +00002220};
2221
2222/* frozenset object ********************************************************/
2223
2224
2225static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002226 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2227 contains_doc},
2228 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2229 copy_doc},
2230 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2231 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002232 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002233 intersection_doc},
2234 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2235 isdisjoint_doc},
2236 {"issubset", (PyCFunction)set_issubset, METH_O,
2237 issubset_doc},
2238 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2239 issuperset_doc},
2240 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2241 reduce_doc},
2242 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2243 sizeof_doc},
2244 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2245 symmetric_difference_doc},
2246 {"union", (PyCFunction)set_union, METH_VARARGS,
2247 union_doc},
Guido van Rossum48b069a2020-04-07 09:50:06 -07002248 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002249 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002250};
2251
2252static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002253 0, /*nb_add*/
2254 (binaryfunc)set_sub, /*nb_subtract*/
2255 0, /*nb_multiply*/
2256 0, /*nb_remainder*/
2257 0, /*nb_divmod*/
2258 0, /*nb_power*/
2259 0, /*nb_negative*/
2260 0, /*nb_positive*/
2261 0, /*nb_absolute*/
2262 0, /*nb_bool*/
2263 0, /*nb_invert*/
2264 0, /*nb_lshift*/
2265 0, /*nb_rshift*/
2266 (binaryfunc)set_and, /*nb_and*/
2267 (binaryfunc)set_xor, /*nb_xor*/
2268 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002269};
2270
2271PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002272"frozenset() -> empty frozenset object\n\
2273frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002274\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002275Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002276
2277PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002278 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2279 "frozenset", /* tp_name */
2280 sizeof(PySetObject), /* tp_basicsize */
2281 0, /* tp_itemsize */
2282 /* methods */
2283 (destructor)set_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002284 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002285 0, /* tp_getattr */
2286 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002287 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002288 (reprfunc)set_repr, /* tp_repr */
2289 &frozenset_as_number, /* tp_as_number */
2290 &set_as_sequence, /* tp_as_sequence */
2291 0, /* tp_as_mapping */
2292 frozenset_hash, /* tp_hash */
2293 0, /* tp_call */
2294 0, /* tp_str */
2295 PyObject_GenericGetAttr, /* tp_getattro */
2296 0, /* tp_setattro */
2297 0, /* tp_as_buffer */
2298 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2299 Py_TPFLAGS_BASETYPE, /* tp_flags */
2300 frozenset_doc, /* tp_doc */
2301 (traverseproc)set_traverse, /* tp_traverse */
2302 (inquiry)set_clear_internal, /* tp_clear */
2303 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002304 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002305 (getiterfunc)set_iter, /* tp_iter */
2306 0, /* tp_iternext */
2307 frozenset_methods, /* tp_methods */
2308 0, /* tp_members */
2309 0, /* tp_getset */
2310 0, /* tp_base */
2311 0, /* tp_dict */
2312 0, /* tp_descr_get */
2313 0, /* tp_descr_set */
2314 0, /* tp_dictoffset */
2315 0, /* tp_init */
2316 PyType_GenericAlloc, /* tp_alloc */
2317 frozenset_new, /* tp_new */
2318 PyObject_GC_Del, /* tp_free */
Dong-hee Na1c605672020-03-19 02:30:50 +09002319 .tp_vectorcall = frozenset_vectorcall,
Raymond Hettingera690a992003-11-16 16:17:49 +00002320};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002321
2322
2323/***** C API functions *************************************************/
2324
2325PyObject *
2326PySet_New(PyObject *iterable)
2327{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002328 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002329}
2330
2331PyObject *
2332PyFrozenSet_New(PyObject *iterable)
2333{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002334 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002335}
2336
Neal Norwitz8c49c822006-03-04 18:41:19 +00002337Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002338PySet_Size(PyObject *anyset)
2339{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002340 if (!PyAnySet_Check(anyset)) {
2341 PyErr_BadInternalCall();
2342 return -1;
2343 }
2344 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002345}
2346
2347int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002348PySet_Clear(PyObject *set)
2349{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002350 if (!PySet_Check(set)) {
2351 PyErr_BadInternalCall();
2352 return -1;
2353 }
2354 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002355}
2356
2357int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002358PySet_Contains(PyObject *anyset, PyObject *key)
2359{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002360 if (!PyAnySet_Check(anyset)) {
2361 PyErr_BadInternalCall();
2362 return -1;
2363 }
2364 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002365}
2366
2367int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002368PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002369{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002370 if (!PySet_Check(set)) {
2371 PyErr_BadInternalCall();
2372 return -1;
2373 }
2374 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002375}
2376
2377int
Christian Heimesfd66e512008-01-29 12:18:50 +00002378PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002379{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002380 if (!PySet_Check(anyset) &&
2381 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2382 PyErr_BadInternalCall();
2383 return -1;
2384 }
2385 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002386}
2387
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002388int
Raymond Hettinger3625af52016-03-27 01:15:07 -07002389PySet_ClearFreeList(void)
2390{
2391 return 0;
2392}
2393
2394void
Victor Stinnerbed48172019-08-27 00:12:32 +02002395_PySet_Fini(void)
Raymond Hettinger3625af52016-03-27 01:15:07 -07002396{
2397 Py_CLEAR(emptyfrozenset);
2398}
2399
2400int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002401_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002402{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002403 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405 if (!PyAnySet_Check(set)) {
2406 PyErr_BadInternalCall();
2407 return -1;
2408 }
2409 if (set_next((PySetObject *)set, pos, &entry) == 0)
2410 return 0;
2411 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002412 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002413 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002414}
2415
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002416PyObject *
2417PySet_Pop(PyObject *set)
2418{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002419 if (!PySet_Check(set)) {
2420 PyErr_BadInternalCall();
2421 return NULL;
2422 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302423 return set_pop((PySetObject *)set, NULL);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002424}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002425
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002426int
2427_PySet_Update(PyObject *set, PyObject *iterable)
2428{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002429 if (!PySet_Check(set)) {
2430 PyErr_BadInternalCall();
2431 return -1;
2432 }
2433 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002434}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002435
Raymond Hettingere259f132013-12-15 11:56:14 -08002436/* Exported for the gdb plugin's benefit. */
2437PyObject *_PySet_Dummy = dummy;
2438
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002439#ifdef Py_DEBUG
2440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002441/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002442 Returns True and original set is restored. */
2443
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002444#define assertRaises(call_return_value, exception) \
2445 do { \
2446 assert(call_return_value); \
2447 assert(PyErr_ExceptionMatches(exception)); \
2448 PyErr_Clear(); \
2449 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002450
2451static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302452test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002453{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002454 Py_ssize_t count;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +02002455 const char *s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002456 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002457 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002458 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002459 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002460 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002462 /* Verify preconditions */
2463 assert(PyAnySet_Check(ob));
2464 assert(PyAnySet_CheckExact(ob));
2465 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002467 /* so.clear(); so |= set("abc"); */
2468 str = PyUnicode_FromString("abc");
2469 if (str == NULL)
2470 return NULL;
2471 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002472 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002473 Py_DECREF(str);
2474 return NULL;
2475 }
2476 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002478 /* Exercise type/size checks */
2479 assert(PySet_Size(ob) == 3);
2480 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002482 /* Raise TypeError for non-iterable constructor arguments */
2483 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2484 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002486 /* Raise TypeError for unhashable key */
2487 dup = PySet_New(ob);
2488 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2489 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2490 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002492 /* Exercise successful pop, contains, add, and discard */
2493 elem = PySet_Pop(ob);
2494 assert(PySet_Contains(ob, elem) == 0);
2495 assert(PySet_GET_SIZE(ob) == 2);
2496 assert(PySet_Add(ob, elem) == 0);
2497 assert(PySet_Contains(ob, elem) == 1);
2498 assert(PySet_GET_SIZE(ob) == 3);
2499 assert(PySet_Discard(ob, elem) == 1);
2500 assert(PySet_GET_SIZE(ob) == 2);
2501 assert(PySet_Discard(ob, elem) == 0);
2502 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002504 /* Exercise clear */
2505 dup2 = PySet_New(dup);
2506 assert(PySet_Clear(dup2) == 0);
2507 assert(PySet_Size(dup2) == 0);
2508 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002510 /* Raise SystemError on clear or update of frozen set */
2511 f = PyFrozenSet_New(dup);
2512 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2513 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2514 assert(PySet_Add(f, elem) == 0);
2515 Py_INCREF(f);
2516 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2517 Py_DECREF(f);
2518 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002520 /* Exercise direct iteration */
2521 i = 0, count = 0;
2522 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
Serhiy Storchaka06515832016-11-20 09:13:07 +02002523 s = PyUnicode_AsUTF8(x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002524 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2525 count++;
2526 }
2527 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002529 /* Exercise updates */
2530 dup2 = PySet_New(NULL);
2531 assert(_PySet_Update(dup2, dup) == 0);
2532 assert(PySet_Size(dup2) == 3);
2533 assert(_PySet_Update(dup2, dup) == 0);
2534 assert(PySet_Size(dup2) == 3);
2535 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002537 /* Raise SystemError when self argument is not a set or frozenset. */
2538 t = PyTuple_New(0);
2539 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2540 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2541 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002542
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002543 /* Raise SystemError when self argument is not a set. */
2544 f = PyFrozenSet_New(dup);
2545 assert(PySet_Size(f) == 3);
2546 assert(PyFrozenSet_CheckExact(f));
2547 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2548 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2549 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002550
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002551 /* Raise KeyError when popping from an empty set */
2552 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2553 Py_DECREF(ob);
2554 assert(PySet_GET_SIZE(ob) == 0);
2555 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002557 /* Restore the set from the copy using the PyNumber API */
2558 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2559 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002561 /* Verify constructors accept NULL arguments */
2562 f = PySet_New(NULL);
2563 assert(f != NULL);
2564 assert(PySet_GET_SIZE(f) == 0);
2565 Py_DECREF(f);
2566 f = PyFrozenSet_New(NULL);
2567 assert(f != NULL);
2568 assert(PyFrozenSet_CheckExact(f));
2569 assert(PySet_GET_SIZE(f) == 0);
2570 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002571
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002572 Py_DECREF(elem);
2573 Py_DECREF(dup);
2574 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002575}
2576
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002577#undef assertRaises
2578
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002579#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002580
2581/***** Dummy Struct *************************************************/
2582
2583static PyObject *
2584dummy_repr(PyObject *op)
2585{
2586 return PyUnicode_FromString("<dummy key>");
2587}
2588
Victor Stinner2a4903f2020-01-30 13:09:11 +01002589static void _Py_NO_RETURN
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002590dummy_dealloc(PyObject* ignore)
2591{
2592 Py_FatalError("deallocating <dummy key>");
2593}
2594
2595static PyTypeObject _PySetDummy_Type = {
2596 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2597 "<dummy key> type",
2598 0,
2599 0,
2600 dummy_dealloc, /*tp_dealloc*/ /*never called*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002601 0, /*tp_vectorcall_offset*/
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002602 0, /*tp_getattr*/
2603 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002604 0, /*tp_as_async*/
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002605 dummy_repr, /*tp_repr*/
2606 0, /*tp_as_number*/
2607 0, /*tp_as_sequence*/
2608 0, /*tp_as_mapping*/
2609 0, /*tp_hash */
2610 0, /*tp_call */
2611 0, /*tp_str */
2612 0, /*tp_getattro */
2613 0, /*tp_setattro */
2614 0, /*tp_as_buffer */
2615 Py_TPFLAGS_DEFAULT, /*tp_flags */
2616};
2617
2618static PyObject _dummy_struct = {
2619 _PyObject_EXTRA_INIT
2620 2, &_PySetDummy_Type
2621};
2622