blob: 035b1db06d8ca0f5e3b2afdda1c24bd8199d077a [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 Stinner27e2d1f2018-11-01 00:52:28 +010035#include "pycore_state.h"
Raymond Hettingera9d99362005-08-05 00:01:15 +000036#include "structmember.h"
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000037
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000038/* Object used as dummy key to fill deleted entries */
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -050039static PyObject _dummy_struct;
40
41#define dummy (&_dummy_struct)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000042
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000043
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -070044/* ======================================================================== */
45/* ======= Begin logic for probing the hash table ========================= */
46
Raymond Hettinger710a67e2013-09-21 20:17:31 -070047/* Set this to zero to turn-off linear probing */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070048#ifndef LINEAR_PROBES
Raymond Hettinger742d8712013-09-08 00:25:57 -070049#define LINEAR_PROBES 9
Raymond Hettinger8408dc52013-09-15 14:57:15 -070050#endif
Raymond Hettinger742d8712013-09-08 00:25:57 -070051
52/* This must be >= 1 */
53#define PERTURB_SHIFT 5
54
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000055static setentry *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020056set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000057{
Raymond Hettinger70559b52015-07-23 07:42:23 -040058 setentry *table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020059 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070060 size_t perturb;
Raymond Hettingerafe89092013-08-28 20:59:31 -070061 size_t mask = so->mask;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -080062 size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070063 size_t j;
Raymond Hettinger4ef05282013-09-21 15:39:49 -070064 int cmp;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000065
Raymond Hettinger70559b52015-07-23 07:42:23 -040066 entry = &so->table[i];
Raymond Hettingerafe89092013-08-28 20:59:31 -070067 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068 return entry;
Raymond Hettinger237b34b2013-08-17 02:31:53 -070069
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070070 perturb = hash;
71
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -070072 while (1) {
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080073 if (entry->hash == hash) {
Raymond Hettingerafe89092013-08-28 20:59:31 -070074 PyObject *startkey = entry->key;
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080075 /* startkey cannot be a dummy because the dummy hash field is -1 */
76 assert(startkey != dummy);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -080077 if (startkey == key)
78 return entry;
Raymond Hettinger93035c42015-01-25 16:12:49 -080079 if (PyUnicode_CheckExact(startkey)
80 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -070081 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger93035c42015-01-25 16:12:49 -080082 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -040083 table = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 Py_INCREF(startkey);
85 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
86 Py_DECREF(startkey);
Raymond Hettinger426d9952014-05-18 21:40:20 +010087 if (cmp < 0) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000088 return NULL;
Raymond Hettinger426d9952014-05-18 21:40:20 +010089 if (table != so->table || entry->key != startkey) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 return set_lookkey(so, key, hash);
Raymond Hettinger426d9952014-05-18 21:40:20 +010091 if (cmp > 0) /* likely */
Raymond Hettingerafe89092013-08-28 20:59:31 -070092 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -060093 mask = so->mask; /* help avoid a register spill */
Raymond Hettingerafe89092013-08-28 20:59:31 -070094 }
Raymond Hettingerafe89092013-08-28 20:59:31 -070095
Raymond Hettingerc658d852015-02-02 08:35:00 -080096 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -080097 for (j = 0 ; j < LINEAR_PROBES ; j++) {
Raymond Hettingerc658d852015-02-02 08:35:00 -080098 entry++;
Raymond Hettinger8651a502015-05-27 10:37:20 -070099 if (entry->hash == 0 && entry->key == NULL)
100 return entry;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800101 if (entry->hash == hash) {
102 PyObject *startkey = entry->key;
103 assert(startkey != dummy);
104 if (startkey == key)
105 return entry;
106 if (PyUnicode_CheckExact(startkey)
107 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700108 && _PyUnicode_EQ(startkey, key))
Raymond Hettingerc658d852015-02-02 08:35:00 -0800109 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400110 table = so->table;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800111 Py_INCREF(startkey);
112 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
113 Py_DECREF(startkey);
114 if (cmp < 0)
115 return NULL;
116 if (table != so->table || entry->key != startkey)
117 return set_lookkey(so, key, hash);
118 if (cmp > 0)
119 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -0600120 mask = so->mask;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800121 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700122 }
123 }
124
125 perturb >>= PERTURB_SHIFT;
126 i = (i * 5 + 1 + perturb) & mask;
127
Raymond Hettinger70559b52015-07-23 07:42:23 -0400128 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700129 if (entry->key == NULL)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700130 return entry;
131 }
132}
133
Raymond Hettinger15f08692015-07-03 17:21:17 -0700134static int set_table_resize(PySetObject *, Py_ssize_t);
135
Raymond Hettinger8651a502015-05-27 10:37:20 -0700136static int
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400137set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700138{
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400139 setentry *table;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700140 setentry *freeslot;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700141 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700142 size_t perturb;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400143 size_t mask;
144 size_t i; /* Unsigned for defined overflow behavior */
Raymond Hettinger8651a502015-05-27 10:37:20 -0700145 size_t j;
146 int cmp;
147
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400148 /* Pre-increment is necessary to prevent arbitrary code in the rich
149 comparison from deallocating the key just before the insertion. */
150 Py_INCREF(key);
151
152 restart:
153
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400154 mask = so->mask;
155 i = (size_t)hash & mask;
156
Raymond Hettinger70559b52015-07-23 07:42:23 -0400157 entry = &so->table[i];
Raymond Hettinger8651a502015-05-27 10:37:20 -0700158 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700159 goto found_unused;
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700160
161 freeslot = NULL;
162 perturb = hash;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700163
164 while (1) {
165 if (entry->hash == hash) {
166 PyObject *startkey = entry->key;
167 /* startkey cannot be a dummy because the dummy hash field is -1 */
168 assert(startkey != dummy);
169 if (startkey == key)
170 goto found_active;
171 if (PyUnicode_CheckExact(startkey)
172 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700173 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700174 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400175 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700176 Py_INCREF(startkey);
177 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
178 Py_DECREF(startkey);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700179 if (cmp > 0) /* likely */
180 goto found_active;
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700181 if (cmp < 0)
182 goto comparison_error;
183 /* Continuing the search from the current entry only makes
184 sense if the table and entry are unchanged; otherwise,
185 we have to restart from the beginning */
186 if (table != so->table || entry->key != startkey)
187 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700188 mask = so->mask; /* help avoid a register spill */
189 }
Raymond Hettinger33299922018-01-14 10:20:13 -0800190 else if (entry->hash == -1)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700191 freeslot = entry;
192
193 if (i + LINEAR_PROBES <= mask) {
194 for (j = 0 ; j < LINEAR_PROBES ; j++) {
195 entry++;
196 if (entry->hash == 0 && entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700197 goto found_unused_or_dummy;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700198 if (entry->hash == hash) {
199 PyObject *startkey = entry->key;
200 assert(startkey != dummy);
201 if (startkey == key)
202 goto found_active;
203 if (PyUnicode_CheckExact(startkey)
204 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700205 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700206 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400207 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700208 Py_INCREF(startkey);
209 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
210 Py_DECREF(startkey);
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700211 if (cmp > 0)
212 goto found_active;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700213 if (cmp < 0)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400214 goto comparison_error;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700215 if (table != so->table || entry->key != startkey)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400216 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700217 mask = so->mask;
218 }
Raymond Hettinger33299922018-01-14 10:20:13 -0800219 else if (entry->hash == -1)
Raymond Hettingerc658d852015-02-02 08:35:00 -0800220 freeslot = entry;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700221 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700223
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700224 perturb >>= PERTURB_SHIFT;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -0800225 i = (i * 5 + 1 + perturb) & mask;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700226
Raymond Hettinger70559b52015-07-23 07:42:23 -0400227 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700228 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700229 goto found_unused_or_dummy;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700231
Raymond Hettinger15f08692015-07-03 17:21:17 -0700232 found_unused_or_dummy:
233 if (freeslot == NULL)
234 goto found_unused;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700235 so->used++;
236 freeslot->key = key;
237 freeslot->hash = hash;
238 return 0;
239
240 found_unused:
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700241 so->fill++;
242 so->used++;
243 entry->key = key;
244 entry->hash = hash;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800245 if ((size_t)so->fill*5 < mask*3)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700246 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +0900247 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700248
249 found_active:
Raymond Hettinger482c05c2015-07-20 01:23:32 -0400250 Py_DECREF(key);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700251 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000252
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400253 comparison_error:
Raymond Hettinger061091a2015-07-15 23:54:02 -0700254 Py_DECREF(key);
255 return -1;
256}
257
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000258/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000259Internal routine used by set_table_resize() to insert an item which is
260known to be absent from the set. This routine also assumes that
261the set contains no deleted entries. Besides the performance benefit,
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800262there is also safety benefit since using set_add_entry() risks making
263a callback in the middle of a set_table_resize(), see issue 1456209.
264The caller is responsible for updating the key's reference count and
265the setobject's fill and used fields.
Thomas Wouters89f507f2006-12-13 04:49:30 +0000266*/
267static void
Raymond Hettinger5088f602015-12-13 18:45:01 -0800268set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000269{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200270 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700271 size_t perturb = hash;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800272 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700273 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000274
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700275 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800276 entry = &table[i];
277 if (entry->key == NULL)
278 goto found_null;
279 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800280 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800281 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800282 if (entry->key == NULL)
283 goto found_null;
284 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700285 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700286 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800287 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700289 found_null:
Raymond Hettinger5088f602015-12-13 18:45:01 -0800290 entry->key = key;
Raymond Hettinger86d322f2015-12-13 19:27:17 -0800291 entry->hash = hash;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000292}
293
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700294/* ======== End logic for probing the hash table ========================== */
295/* ======================================================================== */
296
Thomas Wouters89f507f2006-12-13 04:49:30 +0000297/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000298Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000299keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000300actually be smaller than the old one.
301*/
302static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000303set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000304{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 setentry *oldtable, *newtable, *entry;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800306 Py_ssize_t oldmask = so->mask;
307 size_t newmask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 int is_oldtable_malloced;
309 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 assert(minused >= 0);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100314 /* XXX speed-up with intrinsics */
Sergey Fedoseev6c7d67c2018-09-12 04:18:01 +0500315 size_t newsize = PySet_MINSIZE;
316 while (newsize <= (size_t)minused) {
317 newsize <<= 1; // The largest possible value is PY_SSIZE_T_MAX + 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 /* Get space for a new table. */
321 oldtable = so->table;
322 assert(oldtable != NULL);
323 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325 if (newsize == PySet_MINSIZE) {
326 /* A large table is shrinking, or we can't get any smaller. */
327 newtable = so->smalltable;
328 if (newtable == oldtable) {
329 if (so->fill == so->used) {
330 /* No dummies, so no point doing anything. */
331 return 0;
332 }
333 /* We're not going to resize it, but rebuild the
334 table anyway to purge old dummy entries.
335 Subtle: This is *necessary* if fill==size,
336 as set_lookkey needs at least one virgin slot to
337 terminate failing searches. If fill < size, it's
338 merely desirable, as dummies slow searches. */
339 assert(so->fill > so->used);
340 memcpy(small_copy, oldtable, sizeof(small_copy));
341 oldtable = small_copy;
342 }
343 }
344 else {
345 newtable = PyMem_NEW(setentry, newsize);
346 if (newtable == NULL) {
347 PyErr_NoMemory();
348 return -1;
349 }
350 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 /* Make the set empty, using the new table. */
353 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 memset(newtable, 0, sizeof(setentry) * newsize);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800355 so->mask = newsize - 1;
356 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000358 /* Copy the data over; this is refcount-neutral for active entries;
359 dummy entries aren't copied over, of course */
Raymond Hettinger5088f602015-12-13 18:45:01 -0800360 newmask = (size_t)so->mask;
Raymond Hettingere1af6962017-02-02 08:24:48 -0800361 if (so->fill == so->used) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800362 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800363 if (entry->key != NULL) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800364 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800365 }
366 }
367 } else {
Raymond Hettingere1af6962017-02-02 08:24:48 -0800368 so->fill = so->used;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800369 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800370 if (entry->key != NULL && entry->key != dummy) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800371 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800372 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 }
374 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376 if (is_oldtable_malloced)
377 PyMem_DEL(oldtable);
378 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000379}
380
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000381static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700382set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000383{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700384 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000385
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700386 entry = set_lookkey(so, key, hash);
387 if (entry != NULL)
388 return entry->key != NULL;
389 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000390}
391
392#define DISCARD_NOTFOUND 0
393#define DISCARD_FOUND 1
394
395static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700396set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800397{
398 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000400
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700401 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 if (entry == NULL)
403 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700404 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 return DISCARD_NOTFOUND;
406 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800408 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 so->used--;
410 Py_DECREF(old_key);
411 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000412}
413
414static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700415set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000416{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200417 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000418
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700419 if (!PyUnicode_CheckExact(key) ||
420 (hash = ((PyASCIIObject *) key)->hash) == -1) {
421 hash = PyObject_Hash(key);
422 if (hash == -1)
423 return -1;
424 }
425 return set_add_entry(so, key, hash);
426}
427
428static int
429set_contains_key(PySetObject *so, PyObject *key)
430{
431 Py_hash_t hash;
432
433 if (!PyUnicode_CheckExact(key) ||
434 (hash = ((PyASCIIObject *) key)->hash) == -1) {
435 hash = PyObject_Hash(key);
436 if (hash == -1)
437 return -1;
438 }
439 return set_contains_entry(so, key, hash);
440}
441
442static int
443set_discard_key(PySetObject *so, PyObject *key)
444{
445 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200448 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 hash = PyObject_Hash(key);
450 if (hash == -1)
451 return -1;
452 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700453 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000454}
455
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700456static void
457set_empty_to_minsize(PySetObject *so)
458{
459 memset(so->smalltable, 0, sizeof(so->smalltable));
460 so->fill = 0;
461 so->used = 0;
462 so->mask = PySet_MINSIZE - 1;
463 so->table = so->smalltable;
464 so->hash = -1;
465}
466
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000467static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000468set_clear_internal(PySetObject *so)
469{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800470 setentry *entry;
471 setentry *table = so->table;
472 Py_ssize_t fill = so->fill;
473 Py_ssize_t used = so->used;
474 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000476
Raymond Hettinger583cd032013-09-07 22:06:35 -0700477 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 /* This is delicate. During the process of clearing the set,
481 * decrefs can cause the set to mutate. To avoid fatal confusion
482 * (voice of experience), we have to make the set empty before
483 * clearing the slots, and never refer to anything via so->ref while
484 * clearing.
485 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700487 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 else if (fill > 0) {
490 /* It's a small table with something that needs to be cleared.
491 * Afraid the only safe way is to copy the set entries into
492 * another small table first.
493 */
494 memcpy(small_copy, table, sizeof(small_copy));
495 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700496 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 }
498 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500 /* Now we can finally clear things. If C had refcounts, we could
501 * assert that the refcount on table is 1 now, i.e. that this function
502 * has unique access to it, so decref side-effects can't alter it.
503 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800504 for (entry = table; used > 0; entry++) {
505 if (entry->key && entry->key != dummy) {
506 used--;
507 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 if (table_is_malloced)
512 PyMem_DEL(table);
513 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000514}
515
516/*
517 * Iterate over a set table. Use like so:
518 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000519 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000520 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000521 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000522 * while (set_next(yourset, &pos, &entry)) {
523 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000524 * }
525 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000526 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000528 */
529static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000530set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000531{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 Py_ssize_t i;
533 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700534 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 assert (PyAnySet_Check(so));
537 i = *pos_ptr;
538 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700540 entry = &so->table[i];
541 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700543 entry++;
544 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 *pos_ptr = i+1;
546 if (i > mask)
547 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700548 assert(entry != NULL);
549 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000551}
552
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000553static void
554set_dealloc(PySetObject *so)
555{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200556 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800557 Py_ssize_t used = so->used;
558
INADA Naokia6296d32017-08-24 14:55:17 +0900559 /* bpo-31095: UnTrack is needed before calling any callbacks */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000560 PyObject_GC_UnTrack(so);
561 Py_TRASHCAN_SAFE_BEGIN(so)
562 if (so->weakreflist != NULL)
563 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000564
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800565 for (entry = so->table; used > 0; entry++) {
566 if (entry->key && entry->key != dummy) {
567 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700568 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 }
570 }
571 if (so->table != so->smalltable)
572 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700573 Py_TYPE(so)->tp_free(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000574 Py_TRASHCAN_SAFE_END(so)
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000575}
576
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000577static PyObject *
578set_repr(PySetObject *so)
579{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200580 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583 if (status != 0) {
584 if (status < 0)
585 return NULL;
586 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
587 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000588
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000589 /* shortcut for the empty set */
590 if (!so->used) {
591 Py_ReprLeave((PyObject*)so);
592 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
593 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 keys = PySequence_List((PyObject *)so);
596 if (keys == NULL)
597 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000598
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200599 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 listrepr = PyObject_Repr(keys);
601 Py_DECREF(keys);
602 if (listrepr == NULL)
603 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200604 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200606 if (tmp == NULL)
607 goto done;
608 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200609
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200610 if (Py_TYPE(so) != &PySet_Type)
611 result = PyUnicode_FromFormat("%s({%U})",
612 Py_TYPE(so)->tp_name,
613 listrepr);
614 else
615 result = PyUnicode_FromFormat("{%U}", listrepr);
616 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000617done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618 Py_ReprLeave((PyObject*)so);
619 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000620}
621
Martin v. Löwis18e16552006-02-15 17:27:45 +0000622static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000623set_len(PyObject *so)
624{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000625 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000626}
627
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000628static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000629set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000630{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000632 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200633 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700634 setentry *so_entry;
635 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 assert (PyAnySet_Check(so));
638 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 other = (PySetObject*)otherset;
641 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700642 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 return 0;
644 /* Do one big resize at the start, rather than
645 * incrementally resizing as we insert new keys. Expect
646 * that there will be no (or few) overlapping keys.
647 */
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800648 if ((so->fill + other->used)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900649 if (set_table_resize(so, (so->used + other->used)*2) != 0)
650 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000651 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700652 so_entry = so->table;
653 other_entry = other->table;
654
655 /* If our table is empty, and both tables have the same size, and
656 there are no dummies to eliminate, then just copy the pointers. */
657 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
658 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
659 key = other_entry->key;
660 if (key != NULL) {
661 assert(so_entry->key == NULL);
662 Py_INCREF(key);
663 so_entry->key = key;
664 so_entry->hash = other_entry->hash;
665 }
666 }
667 so->fill = other->fill;
668 so->used = other->used;
669 return 0;
670 }
671
672 /* If our table is empty, we can use set_insert_clean() */
673 if (so->fill == 0) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800674 setentry *newtable = so->table;
675 size_t newmask = (size_t)so->mask;
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800676 so->fill = other->used;
677 so->used = other->used;
Raymond Hettingere4495872015-12-15 00:42:30 -0800678 for (i = other->mask + 1; i > 0 ; i--, other_entry++) {
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700679 key = other_entry->key;
680 if (key != NULL && key != dummy) {
681 Py_INCREF(key);
Raymond Hettinger5088f602015-12-13 18:45:01 -0800682 set_insert_clean(newtable, newmask, key, other_entry->hash);
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700683 }
684 }
685 return 0;
686 }
687
688 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700689 for (i = 0; i <= other->mask; i++) {
690 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700691 key = other_entry->key;
692 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700693 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000694 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 }
696 }
697 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000698}
699
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000700static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530701set_pop(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000702{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800703 /* Make sure the search finger is in bounds */
Raymond Hettingerf9ec1b92018-11-11 14:35:47 -0800704 setentry *entry = so->table + (so->finger & so->mask);
705 setentry *limit = so->table + so->mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000707
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000708 if (so->used == 0) {
709 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
710 return NULL;
711 }
Raymond Hettingercf5863f2018-11-09 02:31:56 -0800712 while (entry->key == NULL || entry->key==dummy) {
713 entry++;
714 if (entry > limit)
715 entry = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 }
717 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800719 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 so->used--;
Raymond Hettingercf5863f2018-11-09 02:31:56 -0800721 so->finger = entry - so->table + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000722 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000723}
724
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000725PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
726Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000727
728static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000729set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000730{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000731 Py_ssize_t pos = 0;
732 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000733
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 while (set_next(so, &pos, &entry))
735 Py_VISIT(entry->key);
736 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000737}
738
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700739/* Work to increase the bit dispersion for closely spaced hash values.
740 This is important because some use cases have many combinations of a
741 small number of elements with nearby hashes so that many distinct
742 combinations collapse to only a handful of distinct hash values. */
743
744static Py_uhash_t
745_shuffle_bits(Py_uhash_t h)
746{
747 return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
748}
749
750/* Most of the constants in this hash algorithm are randomly chosen
751 large primes with "interesting bit patterns" and that passed tests
752 for good collision statistics on a variety of problematic datasets
753 including powersets and graph structures (such as David Eppstein's
754 graph recipes in Lib/test/test_set.py) */
755
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000756static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000757frozenset_hash(PyObject *self)
758{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759 PySetObject *so = (PySetObject *)self;
Raymond Hettinger41481952015-08-07 00:43:39 -0700760 Py_uhash_t hash = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000761 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000762
Raymond Hettingerb501a272015-08-06 22:15:22 -0700763 if (so->hash != -1)
764 return so->hash;
765
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700766 /* Xor-in shuffled bits from every entry's hash field because xor is
767 commutative and a frozenset hash should be independent of order.
768
769 For speed, include null entries and dummy entries and then
770 subtract out their effect afterwards so that the final hash
771 depends only on active entries. This allows the code to be
772 vectorized by the compiler and it saves the unpredictable
773 branches that would arise when trying to exclude null and dummy
774 entries on every iteration. */
775
776 for (entry = so->table; entry <= &so->table[so->mask]; entry++)
777 hash ^= _shuffle_bits(entry->hash);
778
Raymond Hettingera286a512015-08-01 11:07:11 -0700779 /* Remove the effect of an odd number of NULL entries */
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700780 if ((so->mask + 1 - so->fill) & 1)
781 hash ^= _shuffle_bits(0);
782
783 /* Remove the effect of an odd number of dummy entries */
784 if ((so->fill - so->used) & 1)
785 hash ^= _shuffle_bits(-1);
786
Raymond Hettinger41481952015-08-07 00:43:39 -0700787 /* Factor in the number of active entries */
788 hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;
789
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700790 /* Disperse patterns arising in nested frozensets */
Raymond Hettingerfa788062018-01-18 13:23:27 -0800791 hash ^= (hash >> 11) ^ (hash >> 25);
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800792 hash = hash * 69069U + 907133923UL;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700793
Raymond Hettinger36c05002015-08-01 10:57:42 -0700794 /* -1 is reserved as an error code */
Victor Stinner12174a52014-08-15 23:17:38 +0200795 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800796 hash = 590923713UL;
Raymond Hettinger36c05002015-08-01 10:57:42 -0700797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 so->hash = hash;
799 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000800}
801
Raymond Hettingera9d99362005-08-05 00:01:15 +0000802/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000803
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000804typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000805 PyObject_HEAD
806 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
807 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700808 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000809 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000810} setiterobject;
811
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000812static void
813setiter_dealloc(setiterobject *si)
814{
INADA Naokia6296d32017-08-24 14:55:17 +0900815 /* bpo-31095: UnTrack is needed before calling any callbacks */
816 _PyObject_GC_UNTRACK(si);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000817 Py_XDECREF(si->si_set);
818 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000819}
820
821static int
822setiter_traverse(setiterobject *si, visitproc visit, void *arg)
823{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000824 Py_VISIT(si->si_set);
825 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000826}
827
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000828static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530829setiter_len(setiterobject *si, PyObject *Py_UNUSED(ignored))
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000830{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000831 Py_ssize_t len = 0;
832 if (si->si_set != NULL && si->si_used == si->si_set->used)
833 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000834 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000835}
836
Armin Rigof5b3e362006-02-11 21:32:43 +0000837PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000838
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000839static PyObject *setiter_iternext(setiterobject *si);
840
841static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530842setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000843{
Ezio Melotti0e1af282012-09-28 16:43:40 +0300844 /* copy the iterator state */
Sergey Fedoseev63958442018-10-20 05:43:33 +0500845 setiterobject tmp = *si;
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000846 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300847
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000848 /* iterate the temporary into a list */
Sergey Fedoseev63958442018-10-20 05:43:33 +0500849 PyObject *list = PySequence_List((PyObject*)&tmp);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000850 Py_XDECREF(tmp.si_set);
Sergey Fedoseev63958442018-10-20 05:43:33 +0500851 if (list == NULL) {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000852 return NULL;
853 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200854 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000855}
856
857PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
858
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000859static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000860 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000861 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000862 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000863};
864
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000865static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000866{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700867 PyObject *key;
868 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200869 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000870 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000872 if (so == NULL)
873 return NULL;
874 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000876 if (si->si_used != so->used) {
877 PyErr_SetString(PyExc_RuntimeError,
878 "Set changed size during iteration");
879 si->si_used = -1; /* Make this state sticky */
880 return NULL;
881 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700882
883 i = si->si_pos;
884 assert(i>=0);
885 entry = so->table;
886 mask = so->mask;
887 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
888 i++;
889 si->si_pos = i+1;
890 if (i > mask)
891 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000892 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700893 key = entry[i].key;
894 Py_INCREF(key);
895 return key;
896
897fail:
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700898 si->si_set = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +0300899 Py_DECREF(so);
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700900 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000901}
902
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000903PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000904 PyVarObject_HEAD_INIT(&PyType_Type, 0)
905 "set_iterator", /* tp_name */
906 sizeof(setiterobject), /* tp_basicsize */
907 0, /* tp_itemsize */
908 /* methods */
909 (destructor)setiter_dealloc, /* tp_dealloc */
910 0, /* tp_print */
911 0, /* tp_getattr */
912 0, /* tp_setattr */
913 0, /* tp_reserved */
914 0, /* tp_repr */
915 0, /* tp_as_number */
916 0, /* tp_as_sequence */
917 0, /* tp_as_mapping */
918 0, /* tp_hash */
919 0, /* tp_call */
920 0, /* tp_str */
921 PyObject_GenericGetAttr, /* tp_getattro */
922 0, /* tp_setattro */
923 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700924 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000925 0, /* tp_doc */
926 (traverseproc)setiter_traverse, /* tp_traverse */
927 0, /* tp_clear */
928 0, /* tp_richcompare */
929 0, /* tp_weaklistoffset */
930 PyObject_SelfIter, /* tp_iter */
931 (iternextfunc)setiter_iternext, /* tp_iternext */
932 setiter_methods, /* tp_methods */
933 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000934};
935
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000936static PyObject *
937set_iter(PySetObject *so)
938{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000939 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
940 if (si == NULL)
941 return NULL;
942 Py_INCREF(so);
943 si->si_set = so;
944 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700945 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000946 si->len = so->used;
947 _PyObject_GC_TRACK(si);
948 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000949}
950
Raymond Hettingerd7946662005-08-01 21:39:29 +0000951static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000952set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000953{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000955
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000956 if (PyAnySet_Check(other))
957 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000959 if (PyDict_CheckExact(other)) {
960 PyObject *value;
961 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000962 Py_hash_t hash;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200963 Py_ssize_t dictsize = PyDict_GET_SIZE(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000964
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000965 /* Do one big resize at the start, rather than
966 * incrementally resizing as we insert new keys. Expect
967 * that there will be no (or few) overlapping keys.
968 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700969 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000970 return -1;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800971 if ((so->fill + dictsize)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900972 if (set_table_resize(so, (so->used + dictsize)*2) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 return -1;
974 }
975 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700976 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 return -1;
978 }
979 return 0;
980 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000981
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 it = PyObject_GetIter(other);
983 if (it == NULL)
984 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +0000985
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000986 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700987 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 Py_DECREF(it);
989 Py_DECREF(key);
990 return -1;
991 }
992 Py_DECREF(key);
993 }
994 Py_DECREF(it);
995 if (PyErr_Occurred())
996 return -1;
997 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000998}
999
1000static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001001set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001002{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1006 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001007 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 return NULL;
1009 }
1010 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001011}
1012
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001013PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001014"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001015
Raymond Hettinger426d9952014-05-18 21:40:20 +01001016/* XXX Todo:
1017 If aligned memory allocations become available, make the
1018 set object 64 byte aligned so that most of the fields
1019 can be retrieved or updated in a single cache line.
1020*/
1021
Raymond Hettingera38123e2003-11-24 22:18:49 +00001022static PyObject *
1023make_new_set(PyTypeObject *type, PyObject *iterable)
1024{
Raymond Hettinger8421d712016-04-29 01:37:05 -07001025 PySetObject *so;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001026
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001027 so = (PySetObject *)type->tp_alloc(type, 0);
1028 if (so == NULL)
1029 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001030
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001031 so->fill = 0;
1032 so->used = 0;
1033 so->mask = PySet_MINSIZE - 1;
1034 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001035 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001036 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001037 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001040 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 Py_DECREF(so);
1042 return NULL;
1043 }
1044 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001045
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001047}
1048
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001049static PyObject *
1050make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1051{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001052 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1053 if (PyType_IsSubtype(type, &PySet_Type))
1054 type = &PySet_Type;
1055 else
1056 type = &PyFrozenSet_Type;
1057 }
1058 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001059}
1060
Raymond Hettingerd7946662005-08-01 21:39:29 +00001061/* The empty frozenset is a singleton */
1062static PyObject *emptyfrozenset = NULL;
1063
Raymond Hettingera690a992003-11-16 16:17:49 +00001064static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001065frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001066{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001067 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001068
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001069 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001071
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1073 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001074
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001075 if (type != &PyFrozenSet_Type)
1076 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001078 if (iterable != NULL) {
1079 /* frozenset(f) is idempotent */
1080 if (PyFrozenSet_CheckExact(iterable)) {
1081 Py_INCREF(iterable);
1082 return iterable;
1083 }
1084 result = make_new_set(type, iterable);
1085 if (result == NULL || PySet_GET_SIZE(result))
1086 return result;
1087 Py_DECREF(result);
1088 }
1089 /* The empty frozenset is a singleton */
1090 if (emptyfrozenset == NULL)
1091 emptyfrozenset = make_new_set(type, NULL);
1092 Py_XINCREF(emptyfrozenset);
1093 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001094}
1095
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001096static PyObject *
1097set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1098{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001100}
1101
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001102/* set_swap_bodies() switches the contents of any two sets by moving their
1103 internal data pointers and, if needed, copying the internal smalltables.
1104 Semantically equivalent to:
1105
1106 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1107
1108 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001109 Useful for operations that update in-place (by allowing an intermediate
1110 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001111*/
1112
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001113static void
1114set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001115{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001116 Py_ssize_t t;
1117 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001119 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001121 t = a->fill; a->fill = b->fill; b->fill = t;
1122 t = a->used; a->used = b->used; b->used = t;
1123 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001125 u = a->table;
1126 if (a->table == a->smalltable)
1127 u = b->smalltable;
1128 a->table = b->table;
1129 if (b->table == b->smalltable)
1130 a->table = a->smalltable;
1131 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001133 if (a->table == a->smalltable || b->table == b->smalltable) {
1134 memcpy(tab, a->smalltable, sizeof(tab));
1135 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1136 memcpy(b->smalltable, tab, sizeof(tab));
1137 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001139 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1140 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1141 h = a->hash; a->hash = b->hash; b->hash = h;
1142 } else {
1143 a->hash = -1;
1144 b->hash = -1;
1145 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001146}
1147
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001148static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301149set_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001150{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001152}
1153
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001154static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301155frozenset_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001156{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001157 if (PyFrozenSet_CheckExact(so)) {
1158 Py_INCREF(so);
1159 return (PyObject *)so;
1160 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301161 return set_copy(so, NULL);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001162}
1163
Raymond Hettingera690a992003-11-16 16:17:49 +00001164PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1165
1166static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301167set_clear(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc991db22005-08-11 07:58:45 +00001168{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001169 set_clear_internal(so);
1170 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001171}
1172
1173PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1174
1175static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001176set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001177{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 PySetObject *result;
1179 PyObject *other;
1180 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001181
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301182 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001183 if (result == NULL)
1184 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1187 other = PyTuple_GET_ITEM(args, i);
1188 if ((PyObject *)so == other)
1189 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001190 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001191 Py_DECREF(result);
1192 return NULL;
1193 }
1194 }
1195 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001196}
1197
1198PyDoc_STRVAR(union_doc,
1199 "Return the union of sets as a new set.\n\
1200\n\
1201(i.e. all elements that are in either set.)");
1202
1203static PyObject *
1204set_or(PySetObject *so, PyObject *other)
1205{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001206 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001207
Brian Curtindfc80e32011-08-10 20:28:54 -05001208 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1209 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001210
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301211 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 if (result == NULL)
1213 return NULL;
1214 if ((PyObject *)so == other)
1215 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001216 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 Py_DECREF(result);
1218 return NULL;
1219 }
1220 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001221}
1222
Raymond Hettingera690a992003-11-16 16:17:49 +00001223static PyObject *
1224set_ior(PySetObject *so, PyObject *other)
1225{
Brian Curtindfc80e32011-08-10 20:28:54 -05001226 if (!PyAnySet_Check(other))
1227 Py_RETURN_NOTIMPLEMENTED;
1228
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001229 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001230 return NULL;
1231 Py_INCREF(so);
1232 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001233}
1234
1235static PyObject *
1236set_intersection(PySetObject *so, PyObject *other)
1237{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 PySetObject *result;
1239 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001240 Py_hash_t hash;
1241 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001243 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301244 return set_copy(so, NULL);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1247 if (result == NULL)
1248 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 if (PyAnySet_Check(other)) {
1251 Py_ssize_t pos = 0;
1252 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1255 tmp = (PyObject *)so;
1256 so = (PySetObject *)other;
1257 other = tmp;
1258 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001261 key = entry->key;
1262 hash = entry->hash;
1263 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001264 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001265 Py_DECREF(result);
1266 return NULL;
1267 }
1268 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001269 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001270 Py_DECREF(result);
1271 return NULL;
1272 }
1273 }
1274 }
1275 return (PyObject *)result;
1276 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001278 it = PyObject_GetIter(other);
1279 if (it == NULL) {
1280 Py_DECREF(result);
1281 return NULL;
1282 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001285 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001286 if (hash == -1)
1287 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001288 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001289 if (rv < 0)
1290 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001292 if (set_add_entry(result, key, hash))
1293 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 }
1295 Py_DECREF(key);
1296 }
1297 Py_DECREF(it);
1298 if (PyErr_Occurred()) {
1299 Py_DECREF(result);
1300 return NULL;
1301 }
1302 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001303 error:
1304 Py_DECREF(it);
1305 Py_DECREF(result);
1306 Py_DECREF(key);
1307 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001308}
1309
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001310static PyObject *
1311set_intersection_multi(PySetObject *so, PyObject *args)
1312{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 Py_ssize_t i;
1314 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301317 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 Py_INCREF(so);
1320 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1321 PyObject *other = PyTuple_GET_ITEM(args, i);
1322 PyObject *newresult = set_intersection((PySetObject *)result, other);
1323 if (newresult == NULL) {
1324 Py_DECREF(result);
1325 return NULL;
1326 }
1327 Py_DECREF(result);
1328 result = newresult;
1329 }
1330 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001331}
1332
Raymond Hettingera690a992003-11-16 16:17:49 +00001333PyDoc_STRVAR(intersection_doc,
1334"Return the intersection of two sets as a new set.\n\
1335\n\
1336(i.e. all elements that are in both sets.)");
1337
1338static PyObject *
1339set_intersection_update(PySetObject *so, PyObject *other)
1340{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 tmp = set_intersection(so, other);
1344 if (tmp == NULL)
1345 return NULL;
1346 set_swap_bodies(so, (PySetObject *)tmp);
1347 Py_DECREF(tmp);
1348 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001349}
1350
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001351static PyObject *
1352set_intersection_update_multi(PySetObject *so, PyObject *args)
1353{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 tmp = set_intersection_multi(so, args);
1357 if (tmp == NULL)
1358 return NULL;
1359 set_swap_bodies(so, (PySetObject *)tmp);
1360 Py_DECREF(tmp);
1361 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001362}
1363
Raymond Hettingera690a992003-11-16 16:17:49 +00001364PyDoc_STRVAR(intersection_update_doc,
1365"Update a set with the intersection of itself and another.");
1366
1367static PyObject *
1368set_and(PySetObject *so, PyObject *other)
1369{
Brian Curtindfc80e32011-08-10 20:28:54 -05001370 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1371 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001373}
1374
1375static PyObject *
1376set_iand(PySetObject *so, PyObject *other)
1377{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001378 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001379
Brian Curtindfc80e32011-08-10 20:28:54 -05001380 if (!PyAnySet_Check(other))
1381 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382 result = set_intersection_update(so, other);
1383 if (result == NULL)
1384 return NULL;
1385 Py_DECREF(result);
1386 Py_INCREF(so);
1387 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001388}
1389
Guido van Rossum58da9312007-11-10 23:39:45 +00001390static PyObject *
1391set_isdisjoint(PySetObject *so, PyObject *other)
1392{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001394 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 if ((PyObject *)so == other) {
1397 if (PySet_GET_SIZE(so) == 0)
1398 Py_RETURN_TRUE;
1399 else
1400 Py_RETURN_FALSE;
1401 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001403 if (PyAnySet_CheckExact(other)) {
1404 Py_ssize_t pos = 0;
1405 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001406
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001407 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1408 tmp = (PyObject *)so;
1409 so = (PySetObject *)other;
1410 other = tmp;
1411 }
1412 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001413 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001414 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 return NULL;
1416 if (rv)
1417 Py_RETURN_FALSE;
1418 }
1419 Py_RETURN_TRUE;
1420 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001422 it = PyObject_GetIter(other);
1423 if (it == NULL)
1424 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001427 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 if (hash == -1) {
1430 Py_DECREF(key);
1431 Py_DECREF(it);
1432 return NULL;
1433 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001434 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001436 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001437 Py_DECREF(it);
1438 return NULL;
1439 }
1440 if (rv) {
1441 Py_DECREF(it);
1442 Py_RETURN_FALSE;
1443 }
1444 }
1445 Py_DECREF(it);
1446 if (PyErr_Occurred())
1447 return NULL;
1448 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001449}
1450
1451PyDoc_STRVAR(isdisjoint_doc,
1452"Return True if two sets have a null intersection.");
1453
Neal Norwitz6576bd82005-11-13 18:41:28 +00001454static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001455set_difference_update_internal(PySetObject *so, PyObject *other)
1456{
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001457 if (PySet_GET_SIZE(so) == 0) {
1458 return 0;
1459 }
1460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 if ((PyObject *)so == other)
1462 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 if (PyAnySet_Check(other)) {
1465 setentry *entry;
1466 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001467
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001468 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001469 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 return -1;
1471 } else {
1472 PyObject *key, *it;
1473 it = PyObject_GetIter(other);
1474 if (it == NULL)
1475 return -1;
1476
1477 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001478 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001479 Py_DECREF(it);
1480 Py_DECREF(key);
1481 return -1;
1482 }
1483 Py_DECREF(key);
1484 }
1485 Py_DECREF(it);
1486 if (PyErr_Occurred())
1487 return -1;
1488 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001489 /* If more than 1/4th are dummies, then resize them away. */
1490 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001491 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +09001492 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001493}
1494
Raymond Hettingera690a992003-11-16 16:17:49 +00001495static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001496set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001497{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1501 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001502 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 return NULL;
1504 }
1505 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001506}
1507
1508PyDoc_STRVAR(difference_update_doc,
1509"Remove all elements of another set from this set.");
1510
1511static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001512set_copy_and_difference(PySetObject *so, PyObject *other)
1513{
1514 PyObject *result;
1515
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301516 result = set_copy(so, NULL);
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001517 if (result == NULL)
1518 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001519 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001520 return result;
1521 Py_DECREF(result);
1522 return NULL;
1523}
1524
1525static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001526set_difference(PySetObject *so, PyObject *other)
1527{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001528 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001529 PyObject *key;
1530 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 setentry *entry;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001532 Py_ssize_t pos = 0, other_size;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001533 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001534
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001535 if (PySet_GET_SIZE(so) == 0) {
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301536 return set_copy(so, NULL);
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001537 }
1538
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001539 if (PyAnySet_Check(other)) {
1540 other_size = PySet_GET_SIZE(other);
1541 }
1542 else if (PyDict_CheckExact(other)) {
1543 other_size = PyDict_GET_SIZE(other);
1544 }
1545 else {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001546 return set_copy_and_difference(so, other);
1547 }
1548
1549 /* If len(so) much more than len(other), it's more efficient to simply copy
1550 * so and then iterate other looking for common elements. */
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001551 if ((PySet_GET_SIZE(so) >> 2) > other_size) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001552 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001553 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001555 result = make_new_set_basetype(Py_TYPE(so), NULL);
1556 if (result == NULL)
1557 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001558
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001559 if (PyDict_CheckExact(other)) {
1560 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001561 key = entry->key;
1562 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001563 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001564 if (rv < 0) {
1565 Py_DECREF(result);
1566 return NULL;
1567 }
1568 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001569 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001570 Py_DECREF(result);
1571 return NULL;
1572 }
1573 }
1574 }
1575 return result;
1576 }
1577
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001578 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001580 key = entry->key;
1581 hash = entry->hash;
1582 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001583 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001584 Py_DECREF(result);
1585 return NULL;
1586 }
1587 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001588 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 Py_DECREF(result);
1590 return NULL;
1591 }
1592 }
1593 }
1594 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001595}
1596
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001597static PyObject *
1598set_difference_multi(PySetObject *so, PyObject *args)
1599{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 Py_ssize_t i;
1601 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001602
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301604 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 other = PyTuple_GET_ITEM(args, 0);
1607 result = set_difference(so, other);
1608 if (result == NULL)
1609 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001610
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1612 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001613 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001614 Py_DECREF(result);
1615 return NULL;
1616 }
1617 }
1618 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001619}
1620
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001621PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001622"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001623\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001624(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001625static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001626set_sub(PySetObject *so, PyObject *other)
1627{
Brian Curtindfc80e32011-08-10 20:28:54 -05001628 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1629 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001631}
1632
1633static PyObject *
1634set_isub(PySetObject *so, PyObject *other)
1635{
Brian Curtindfc80e32011-08-10 20:28:54 -05001636 if (!PyAnySet_Check(other))
1637 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001638 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 return NULL;
1640 Py_INCREF(so);
1641 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001642}
1643
1644static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001645set_symmetric_difference_update(PySetObject *so, PyObject *other)
1646{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 PySetObject *otherset;
1648 PyObject *key;
1649 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001650 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001652 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001653
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301655 return set_clear(so, NULL);
Raymond Hettingera690a992003-11-16 16:17:49 +00001656
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001657 if (PyDict_CheckExact(other)) {
1658 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001659 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001660 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001661 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001662 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001663 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001664 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001665 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001666 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001667 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001668 Py_DECREF(key);
1669 return NULL;
1670 }
1671 }
Georg Brandl2d444492010-09-03 10:52:55 +00001672 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001673 }
1674 Py_RETURN_NONE;
1675 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001677 if (PyAnySet_Check(other)) {
1678 Py_INCREF(other);
1679 otherset = (PySetObject *)other;
1680 } else {
1681 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1682 if (otherset == NULL)
1683 return NULL;
1684 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001685
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001686 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001687 key = entry->key;
1688 hash = entry->hash;
1689 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001690 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001691 Py_DECREF(otherset);
1692 return NULL;
1693 }
1694 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001695 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001696 Py_DECREF(otherset);
1697 return NULL;
1698 }
1699 }
1700 }
1701 Py_DECREF(otherset);
1702 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001703}
1704
1705PyDoc_STRVAR(symmetric_difference_update_doc,
1706"Update a set with the symmetric difference of itself and another.");
1707
1708static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001709set_symmetric_difference(PySetObject *so, PyObject *other)
1710{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001711 PyObject *rv;
1712 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001713
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001714 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1715 if (otherset == NULL)
1716 return NULL;
1717 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
lekma491bbed2018-05-02 11:29:10 +02001718 if (rv == NULL) {
1719 Py_DECREF(otherset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001720 return NULL;
lekma491bbed2018-05-02 11:29:10 +02001721 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001722 Py_DECREF(rv);
1723 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001724}
1725
1726PyDoc_STRVAR(symmetric_difference_doc,
1727"Return the symmetric difference of two sets as a new set.\n\
1728\n\
1729(i.e. all elements that are in exactly one of the sets.)");
1730
1731static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001732set_xor(PySetObject *so, PyObject *other)
1733{
Brian Curtindfc80e32011-08-10 20:28:54 -05001734 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1735 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001736 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001737}
1738
1739static PyObject *
1740set_ixor(PySetObject *so, PyObject *other)
1741{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001742 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001743
Brian Curtindfc80e32011-08-10 20:28:54 -05001744 if (!PyAnySet_Check(other))
1745 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001746 result = set_symmetric_difference_update(so, other);
1747 if (result == NULL)
1748 return NULL;
1749 Py_DECREF(result);
1750 Py_INCREF(so);
1751 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001752}
1753
1754static PyObject *
1755set_issubset(PySetObject *so, PyObject *other)
1756{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001757 setentry *entry;
1758 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001759 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 if (!PyAnySet_Check(other)) {
1762 PyObject *tmp, *result;
1763 tmp = make_new_set(&PySet_Type, other);
1764 if (tmp == NULL)
1765 return NULL;
1766 result = set_issubset(so, tmp);
1767 Py_DECREF(tmp);
1768 return result;
1769 }
1770 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1771 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001772
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001773 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001774 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001775 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776 return NULL;
1777 if (!rv)
1778 Py_RETURN_FALSE;
1779 }
1780 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001781}
1782
1783PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1784
1785static PyObject *
1786set_issuperset(PySetObject *so, PyObject *other)
1787{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001789
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001790 if (!PyAnySet_Check(other)) {
1791 tmp = make_new_set(&PySet_Type, other);
1792 if (tmp == NULL)
1793 return NULL;
1794 result = set_issuperset(so, tmp);
1795 Py_DECREF(tmp);
1796 return result;
1797 }
1798 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001799}
1800
1801PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1802
Raymond Hettingera690a992003-11-16 16:17:49 +00001803static PyObject *
1804set_richcompare(PySetObject *v, PyObject *w, int op)
1805{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001806 PyObject *r1;
1807 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001808
Brian Curtindfc80e32011-08-10 20:28:54 -05001809 if(!PyAnySet_Check(w))
1810 Py_RETURN_NOTIMPLEMENTED;
1811
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001812 switch (op) {
1813 case Py_EQ:
1814 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1815 Py_RETURN_FALSE;
1816 if (v->hash != -1 &&
1817 ((PySetObject *)w)->hash != -1 &&
1818 v->hash != ((PySetObject *)w)->hash)
1819 Py_RETURN_FALSE;
1820 return set_issubset(v, w);
1821 case Py_NE:
1822 r1 = set_richcompare(v, w, Py_EQ);
1823 if (r1 == NULL)
1824 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001825 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001826 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001827 if (r2 < 0)
1828 return NULL;
1829 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 case Py_LE:
1831 return set_issubset(v, w);
1832 case Py_GE:
1833 return set_issuperset(v, w);
1834 case Py_LT:
1835 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1836 Py_RETURN_FALSE;
1837 return set_issubset(v, w);
1838 case Py_GT:
1839 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1840 Py_RETURN_FALSE;
1841 return set_issuperset(v, w);
1842 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001843 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001844}
1845
Raymond Hettingera690a992003-11-16 16:17:49 +00001846static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001847set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001848{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001849 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 return NULL;
1851 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001852}
1853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001854PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001855"Add an element to a set.\n\
1856\n\
1857This has no effect if the element is already present.");
1858
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001859static int
1860set_contains(PySetObject *so, PyObject *key)
1861{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001862 PyObject *tmpkey;
1863 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001866 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1868 return -1;
1869 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001870 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001871 if (tmpkey == NULL)
1872 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001873 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001874 Py_DECREF(tmpkey);
1875 }
1876 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001877}
1878
1879static PyObject *
1880set_direct_contains(PySetObject *so, PyObject *key)
1881{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001882 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001883
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001885 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 return NULL;
1887 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001888}
1889
1890PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1891
Raymond Hettingera690a992003-11-16 16:17:49 +00001892static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001893set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001894{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 PyObject *tmpkey;
1896 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001897
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001898 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001899 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1901 return NULL;
1902 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001903 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001904 if (tmpkey == NULL)
1905 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001907 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001908 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 return NULL;
1910 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001911
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001912 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001913 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 return NULL;
1915 }
1916 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001917}
1918
1919PyDoc_STRVAR(remove_doc,
1920"Remove an element from a set; it must be a member.\n\
1921\n\
1922If the element is not a member, raise a KeyError.");
1923
1924static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001925set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001926{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001927 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001928 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001931 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001932 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1933 return NULL;
1934 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001935 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 if (tmpkey == NULL)
1937 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001938 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001939 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001940 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001941 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001942 }
1943 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001944}
1945
1946PyDoc_STRVAR(discard_doc,
1947"Remove an element from a set if it is a member.\n\
1948\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001949If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001950
1951static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301952set_reduce(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001953{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001954 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001955 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001956
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001957 keys = PySequence_List((PyObject *)so);
1958 if (keys == NULL)
1959 goto done;
1960 args = PyTuple_Pack(1, keys);
1961 if (args == NULL)
1962 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001963 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001964 if (dict == NULL) {
1965 PyErr_Clear();
1966 dict = Py_None;
1967 Py_INCREF(dict);
1968 }
1969 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001970done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001971 Py_XDECREF(args);
1972 Py_XDECREF(keys);
1973 Py_XDECREF(dict);
1974 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001975}
1976
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001977static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301978set_sizeof(PySetObject *so, PyObject *Py_UNUSED(ignored))
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001979{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001981
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02001982 res = _PyObject_SIZE(Py_TYPE(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001983 if (so->table != so->smalltable)
1984 res = res + (so->mask + 1) * sizeof(setentry);
1985 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001986}
1987
1988PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001989static int
1990set_init(PySetObject *self, PyObject *args, PyObject *kwds)
1991{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001992 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001993
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001994 if (!_PyArg_NoKeywords("set", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001995 return -1;
1996 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
1997 return -1;
Raymond Hettingerb72e21b2016-03-25 02:29:59 -07001998 if (self->fill)
1999 set_clear_internal(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002000 self->hash = -1;
2001 if (iterable == NULL)
2002 return 0;
2003 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002004}
2005
Raymond Hettingera690a992003-11-16 16:17:49 +00002006static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002007 set_len, /* sq_length */
2008 0, /* sq_concat */
2009 0, /* sq_repeat */
2010 0, /* sq_item */
2011 0, /* sq_slice */
2012 0, /* sq_ass_item */
2013 0, /* sq_ass_slice */
2014 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002015};
2016
2017/* set object ********************************************************/
2018
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002019#ifdef Py_DEBUG
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302020static PyObject *test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored));
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002021
2022PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2023All is well if assertions don't fail.");
2024#endif
2025
Raymond Hettingera690a992003-11-16 16:17:49 +00002026static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002027 {"add", (PyCFunction)set_add, METH_O,
2028 add_doc},
2029 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2030 clear_doc},
2031 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2032 contains_doc},
2033 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2034 copy_doc},
2035 {"discard", (PyCFunction)set_discard, METH_O,
2036 discard_doc},
2037 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2038 difference_doc},
2039 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2040 difference_update_doc},
2041 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2042 intersection_doc},
2043 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2044 intersection_update_doc},
2045 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2046 isdisjoint_doc},
2047 {"issubset", (PyCFunction)set_issubset, METH_O,
2048 issubset_doc},
2049 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2050 issuperset_doc},
2051 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2052 pop_doc},
2053 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2054 reduce_doc},
2055 {"remove", (PyCFunction)set_remove, METH_O,
2056 remove_doc},
2057 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2058 sizeof_doc},
2059 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2060 symmetric_difference_doc},
2061 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2062 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002063#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002064 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2065 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002066#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002067 {"union", (PyCFunction)set_union, METH_VARARGS,
2068 union_doc},
2069 {"update", (PyCFunction)set_update, METH_VARARGS,
2070 update_doc},
2071 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002072};
2073
2074static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002075 0, /*nb_add*/
2076 (binaryfunc)set_sub, /*nb_subtract*/
2077 0, /*nb_multiply*/
2078 0, /*nb_remainder*/
2079 0, /*nb_divmod*/
2080 0, /*nb_power*/
2081 0, /*nb_negative*/
2082 0, /*nb_positive*/
2083 0, /*nb_absolute*/
2084 0, /*nb_bool*/
2085 0, /*nb_invert*/
2086 0, /*nb_lshift*/
2087 0, /*nb_rshift*/
2088 (binaryfunc)set_and, /*nb_and*/
2089 (binaryfunc)set_xor, /*nb_xor*/
2090 (binaryfunc)set_or, /*nb_or*/
2091 0, /*nb_int*/
2092 0, /*nb_reserved*/
2093 0, /*nb_float*/
2094 0, /*nb_inplace_add*/
2095 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2096 0, /*nb_inplace_multiply*/
2097 0, /*nb_inplace_remainder*/
2098 0, /*nb_inplace_power*/
2099 0, /*nb_inplace_lshift*/
2100 0, /*nb_inplace_rshift*/
2101 (binaryfunc)set_iand, /*nb_inplace_and*/
2102 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2103 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002104};
2105
2106PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002107"set() -> new empty set object\n\
2108set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002109\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002110Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002111
2112PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2114 "set", /* tp_name */
2115 sizeof(PySetObject), /* tp_basicsize */
2116 0, /* tp_itemsize */
2117 /* methods */
2118 (destructor)set_dealloc, /* tp_dealloc */
2119 0, /* tp_print */
2120 0, /* tp_getattr */
2121 0, /* tp_setattr */
2122 0, /* tp_reserved */
2123 (reprfunc)set_repr, /* tp_repr */
2124 &set_as_number, /* tp_as_number */
2125 &set_as_sequence, /* tp_as_sequence */
2126 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002127 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002128 0, /* tp_call */
2129 0, /* tp_str */
2130 PyObject_GenericGetAttr, /* tp_getattro */
2131 0, /* tp_setattro */
2132 0, /* tp_as_buffer */
2133 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2134 Py_TPFLAGS_BASETYPE, /* tp_flags */
2135 set_doc, /* tp_doc */
2136 (traverseproc)set_traverse, /* tp_traverse */
2137 (inquiry)set_clear_internal, /* tp_clear */
2138 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002139 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2140 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002141 0, /* tp_iternext */
2142 set_methods, /* tp_methods */
2143 0, /* tp_members */
2144 0, /* tp_getset */
2145 0, /* tp_base */
2146 0, /* tp_dict */
2147 0, /* tp_descr_get */
2148 0, /* tp_descr_set */
2149 0, /* tp_dictoffset */
2150 (initproc)set_init, /* tp_init */
2151 PyType_GenericAlloc, /* tp_alloc */
2152 set_new, /* tp_new */
2153 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002154};
2155
2156/* frozenset object ********************************************************/
2157
2158
2159static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002160 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2161 contains_doc},
2162 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2163 copy_doc},
2164 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2165 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002166 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002167 intersection_doc},
2168 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2169 isdisjoint_doc},
2170 {"issubset", (PyCFunction)set_issubset, METH_O,
2171 issubset_doc},
2172 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2173 issuperset_doc},
2174 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2175 reduce_doc},
2176 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2177 sizeof_doc},
2178 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2179 symmetric_difference_doc},
2180 {"union", (PyCFunction)set_union, METH_VARARGS,
2181 union_doc},
2182 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002183};
2184
2185static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002186 0, /*nb_add*/
2187 (binaryfunc)set_sub, /*nb_subtract*/
2188 0, /*nb_multiply*/
2189 0, /*nb_remainder*/
2190 0, /*nb_divmod*/
2191 0, /*nb_power*/
2192 0, /*nb_negative*/
2193 0, /*nb_positive*/
2194 0, /*nb_absolute*/
2195 0, /*nb_bool*/
2196 0, /*nb_invert*/
2197 0, /*nb_lshift*/
2198 0, /*nb_rshift*/
2199 (binaryfunc)set_and, /*nb_and*/
2200 (binaryfunc)set_xor, /*nb_xor*/
2201 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002202};
2203
2204PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002205"frozenset() -> empty frozenset object\n\
2206frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002207\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002208Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002209
2210PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002211 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2212 "frozenset", /* tp_name */
2213 sizeof(PySetObject), /* tp_basicsize */
2214 0, /* tp_itemsize */
2215 /* methods */
2216 (destructor)set_dealloc, /* tp_dealloc */
2217 0, /* tp_print */
2218 0, /* tp_getattr */
2219 0, /* tp_setattr */
2220 0, /* tp_reserved */
2221 (reprfunc)set_repr, /* tp_repr */
2222 &frozenset_as_number, /* tp_as_number */
2223 &set_as_sequence, /* tp_as_sequence */
2224 0, /* tp_as_mapping */
2225 frozenset_hash, /* tp_hash */
2226 0, /* tp_call */
2227 0, /* tp_str */
2228 PyObject_GenericGetAttr, /* tp_getattro */
2229 0, /* tp_setattro */
2230 0, /* tp_as_buffer */
2231 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2232 Py_TPFLAGS_BASETYPE, /* tp_flags */
2233 frozenset_doc, /* tp_doc */
2234 (traverseproc)set_traverse, /* tp_traverse */
2235 (inquiry)set_clear_internal, /* tp_clear */
2236 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002237 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002238 (getiterfunc)set_iter, /* tp_iter */
2239 0, /* tp_iternext */
2240 frozenset_methods, /* tp_methods */
2241 0, /* tp_members */
2242 0, /* tp_getset */
2243 0, /* tp_base */
2244 0, /* tp_dict */
2245 0, /* tp_descr_get */
2246 0, /* tp_descr_set */
2247 0, /* tp_dictoffset */
2248 0, /* tp_init */
2249 PyType_GenericAlloc, /* tp_alloc */
2250 frozenset_new, /* tp_new */
2251 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002252};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002253
2254
2255/***** C API functions *************************************************/
2256
2257PyObject *
2258PySet_New(PyObject *iterable)
2259{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002260 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002261}
2262
2263PyObject *
2264PyFrozenSet_New(PyObject *iterable)
2265{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002266 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002267}
2268
Neal Norwitz8c49c822006-03-04 18:41:19 +00002269Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002270PySet_Size(PyObject *anyset)
2271{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002272 if (!PyAnySet_Check(anyset)) {
2273 PyErr_BadInternalCall();
2274 return -1;
2275 }
2276 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002277}
2278
2279int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002280PySet_Clear(PyObject *set)
2281{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002282 if (!PySet_Check(set)) {
2283 PyErr_BadInternalCall();
2284 return -1;
2285 }
2286 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002287}
2288
2289int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002290PySet_Contains(PyObject *anyset, PyObject *key)
2291{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002292 if (!PyAnySet_Check(anyset)) {
2293 PyErr_BadInternalCall();
2294 return -1;
2295 }
2296 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002297}
2298
2299int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002300PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002301{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002302 if (!PySet_Check(set)) {
2303 PyErr_BadInternalCall();
2304 return -1;
2305 }
2306 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002307}
2308
2309int
Christian Heimesfd66e512008-01-29 12:18:50 +00002310PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002311{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002312 if (!PySet_Check(anyset) &&
2313 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2314 PyErr_BadInternalCall();
2315 return -1;
2316 }
2317 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002318}
2319
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002320int
Raymond Hettinger3625af52016-03-27 01:15:07 -07002321PySet_ClearFreeList(void)
2322{
2323 return 0;
2324}
2325
2326void
2327PySet_Fini(void)
2328{
2329 Py_CLEAR(emptyfrozenset);
2330}
2331
2332int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002333_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002335 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002337 if (!PyAnySet_Check(set)) {
2338 PyErr_BadInternalCall();
2339 return -1;
2340 }
2341 if (set_next((PySetObject *)set, pos, &entry) == 0)
2342 return 0;
2343 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002344 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002345 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002346}
2347
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002348PyObject *
2349PySet_Pop(PyObject *set)
2350{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002351 if (!PySet_Check(set)) {
2352 PyErr_BadInternalCall();
2353 return NULL;
2354 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302355 return set_pop((PySetObject *)set, NULL);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002356}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002357
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002358int
2359_PySet_Update(PyObject *set, PyObject *iterable)
2360{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002361 if (!PySet_Check(set)) {
2362 PyErr_BadInternalCall();
2363 return -1;
2364 }
2365 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002366}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002367
Raymond Hettingere259f132013-12-15 11:56:14 -08002368/* Exported for the gdb plugin's benefit. */
2369PyObject *_PySet_Dummy = dummy;
2370
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002371#ifdef Py_DEBUG
2372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002373/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002374 Returns True and original set is restored. */
2375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002376#define assertRaises(call_return_value, exception) \
2377 do { \
2378 assert(call_return_value); \
2379 assert(PyErr_ExceptionMatches(exception)); \
2380 PyErr_Clear(); \
2381 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002382
2383static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302384test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002385{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002386 Py_ssize_t count;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +02002387 const char *s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002388 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002389 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002390 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002391 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002392 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002394 /* Verify preconditions */
2395 assert(PyAnySet_Check(ob));
2396 assert(PyAnySet_CheckExact(ob));
2397 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002399 /* so.clear(); so |= set("abc"); */
2400 str = PyUnicode_FromString("abc");
2401 if (str == NULL)
2402 return NULL;
2403 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002404 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405 Py_DECREF(str);
2406 return NULL;
2407 }
2408 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002410 /* Exercise type/size checks */
2411 assert(PySet_Size(ob) == 3);
2412 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002414 /* Raise TypeError for non-iterable constructor arguments */
2415 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2416 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002418 /* Raise TypeError for unhashable key */
2419 dup = PySet_New(ob);
2420 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2421 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2422 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002424 /* Exercise successful pop, contains, add, and discard */
2425 elem = PySet_Pop(ob);
2426 assert(PySet_Contains(ob, elem) == 0);
2427 assert(PySet_GET_SIZE(ob) == 2);
2428 assert(PySet_Add(ob, elem) == 0);
2429 assert(PySet_Contains(ob, elem) == 1);
2430 assert(PySet_GET_SIZE(ob) == 3);
2431 assert(PySet_Discard(ob, elem) == 1);
2432 assert(PySet_GET_SIZE(ob) == 2);
2433 assert(PySet_Discard(ob, elem) == 0);
2434 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002436 /* Exercise clear */
2437 dup2 = PySet_New(dup);
2438 assert(PySet_Clear(dup2) == 0);
2439 assert(PySet_Size(dup2) == 0);
2440 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002442 /* Raise SystemError on clear or update of frozen set */
2443 f = PyFrozenSet_New(dup);
2444 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2445 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2446 assert(PySet_Add(f, elem) == 0);
2447 Py_INCREF(f);
2448 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2449 Py_DECREF(f);
2450 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002452 /* Exercise direct iteration */
2453 i = 0, count = 0;
2454 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
Serhiy Storchaka06515832016-11-20 09:13:07 +02002455 s = PyUnicode_AsUTF8(x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002456 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2457 count++;
2458 }
2459 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002461 /* Exercise updates */
2462 dup2 = PySet_New(NULL);
2463 assert(_PySet_Update(dup2, dup) == 0);
2464 assert(PySet_Size(dup2) == 3);
2465 assert(_PySet_Update(dup2, dup) == 0);
2466 assert(PySet_Size(dup2) == 3);
2467 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002469 /* Raise SystemError when self argument is not a set or frozenset. */
2470 t = PyTuple_New(0);
2471 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2472 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2473 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002474
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002475 /* Raise SystemError when self argument is not a set. */
2476 f = PyFrozenSet_New(dup);
2477 assert(PySet_Size(f) == 3);
2478 assert(PyFrozenSet_CheckExact(f));
2479 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2480 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2481 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002483 /* Raise KeyError when popping from an empty set */
2484 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2485 Py_DECREF(ob);
2486 assert(PySet_GET_SIZE(ob) == 0);
2487 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002489 /* Restore the set from the copy using the PyNumber API */
2490 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2491 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002493 /* Verify constructors accept NULL arguments */
2494 f = PySet_New(NULL);
2495 assert(f != NULL);
2496 assert(PySet_GET_SIZE(f) == 0);
2497 Py_DECREF(f);
2498 f = PyFrozenSet_New(NULL);
2499 assert(f != NULL);
2500 assert(PyFrozenSet_CheckExact(f));
2501 assert(PySet_GET_SIZE(f) == 0);
2502 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002504 Py_DECREF(elem);
2505 Py_DECREF(dup);
2506 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002507}
2508
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002509#undef assertRaises
2510
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002511#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002512
2513/***** Dummy Struct *************************************************/
2514
2515static PyObject *
2516dummy_repr(PyObject *op)
2517{
2518 return PyUnicode_FromString("<dummy key>");
2519}
2520
2521static void
2522dummy_dealloc(PyObject* ignore)
2523{
2524 Py_FatalError("deallocating <dummy key>");
2525}
2526
2527static PyTypeObject _PySetDummy_Type = {
2528 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2529 "<dummy key> type",
2530 0,
2531 0,
2532 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2533 0, /*tp_print*/
2534 0, /*tp_getattr*/
2535 0, /*tp_setattr*/
2536 0, /*tp_reserved*/
2537 dummy_repr, /*tp_repr*/
2538 0, /*tp_as_number*/
2539 0, /*tp_as_sequence*/
2540 0, /*tp_as_mapping*/
2541 0, /*tp_hash */
2542 0, /*tp_call */
2543 0, /*tp_str */
2544 0, /*tp_getattro */
2545 0, /*tp_setattro */
2546 0, /*tp_as_buffer */
2547 Py_TPFLAGS_DEFAULT, /*tp_flags */
2548};
2549
2550static PyObject _dummy_struct = {
2551 _PyObject_EXTRA_INIT
2552 2, &_PySetDummy_Type
2553};
2554