blob: c2a1467ba61a8b44ebaad612216fd177553260f2 [file] [log] [blame]
Raymond Hettingerc991db22005-08-11 07:58:45 +00001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002/* set object implementation
Raymond Hettingerae7b00e2013-09-07 15:05:00 -07003
Raymond Hettingera9d99362005-08-05 00:01:15 +00004 Written and maintained by Raymond D. Hettinger <python@rcn.com>
5 Derived from Lib/sets.py and Objects/dictobject.c.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00006
Raymond Hettingerae7b00e2013-09-07 15:05:00 -07007 The basic lookup function used by all operations.
8 This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
9
10 The initial probe index is computed as hash mod the table size.
11 Subsequent probe indices are computed as explained in Objects/dictobject.c.
12
13 To improve cache locality, each probe inspects a series of consecutive
14 nearby entries before moving on to probes elsewhere in memory. This leaves
Raymond Hettinger64263df2017-09-04 18:54:16 -070015 us with a hybrid of linear probing and randomized probing. The linear probing
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070016 reduces the cost of hash collisions because consecutive memory accesses
17 tend to be much cheaper than scattered probes. After LINEAR_PROBES steps,
Raymond Hettinger64263df2017-09-04 18:54:16 -070018 we then use more of the upper bits from the hash value and apply a simple
19 linear congruential random number genearator. This helps break-up long
20 chains of collisions.
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070021
22 All arithmetic on hash should ignore overflow.
23
Raymond Hettinger4d45c102015-01-25 16:27:40 -080024 Unlike the dictionary implementation, the lookkey function can return
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070025 NULL if the rich comparison returns an error.
Serhiy Storchaka13ad3b72017-09-14 09:38:36 +030026
Raymond Hettinger64263df2017-09-04 18:54:16 -070027 Use cases for sets differ considerably from dictionaries where looked-up
28 keys are more likely to be present. In contrast, sets are primarily
29 about membership testing where the presence of an element is not known in
30 advance. Accordingly, the set implementation needs to optimize for both
31 the found and not-found case.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000032*/
33
Raymond Hettingera690a992003-11-16 16:17:49 +000034#include "Python.h"
Victor Stinnerbcda8f12018-11-21 22:27:47 +010035#include "pycore_object.h"
Victor Stinner621cebe2018-11-12 16:53:38 +010036#include "pycore_pystate.h"
Raymond Hettingera9d99362005-08-05 00:01:15 +000037#include "structmember.h"
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000038
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000039/* Object used as dummy key to fill deleted entries */
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -050040static PyObject _dummy_struct;
41
42#define dummy (&_dummy_struct)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000043
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000044
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -070045/* ======================================================================== */
46/* ======= Begin logic for probing the hash table ========================= */
47
Raymond Hettinger710a67e2013-09-21 20:17:31 -070048/* Set this to zero to turn-off linear probing */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070049#ifndef LINEAR_PROBES
Raymond Hettinger742d8712013-09-08 00:25:57 -070050#define LINEAR_PROBES 9
Raymond Hettinger8408dc52013-09-15 14:57:15 -070051#endif
Raymond Hettinger742d8712013-09-08 00:25:57 -070052
53/* This must be >= 1 */
54#define PERTURB_SHIFT 5
55
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000056static setentry *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020057set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000058{
Raymond Hettinger70559b52015-07-23 07:42:23 -040059 setentry *table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020060 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070061 size_t perturb;
Raymond Hettingerafe89092013-08-28 20:59:31 -070062 size_t mask = so->mask;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -080063 size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070064 size_t j;
Raymond Hettinger4ef05282013-09-21 15:39:49 -070065 int cmp;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000066
Raymond Hettinger70559b52015-07-23 07:42:23 -040067 entry = &so->table[i];
Raymond Hettingerafe89092013-08-28 20:59:31 -070068 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000069 return entry;
Raymond Hettinger237b34b2013-08-17 02:31:53 -070070
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070071 perturb = hash;
72
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -070073 while (1) {
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080074 if (entry->hash == hash) {
Raymond Hettingerafe89092013-08-28 20:59:31 -070075 PyObject *startkey = entry->key;
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080076 /* startkey cannot be a dummy because the dummy hash field is -1 */
77 assert(startkey != dummy);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -080078 if (startkey == key)
79 return entry;
Raymond Hettinger93035c42015-01-25 16:12:49 -080080 if (PyUnicode_CheckExact(startkey)
81 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -070082 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger93035c42015-01-25 16:12:49 -080083 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -040084 table = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000085 Py_INCREF(startkey);
86 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
87 Py_DECREF(startkey);
Raymond Hettinger426d9952014-05-18 21:40:20 +010088 if (cmp < 0) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000089 return NULL;
Raymond Hettinger426d9952014-05-18 21:40:20 +010090 if (table != so->table || entry->key != startkey) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091 return set_lookkey(so, key, hash);
Raymond Hettinger426d9952014-05-18 21:40:20 +010092 if (cmp > 0) /* likely */
Raymond Hettingerafe89092013-08-28 20:59:31 -070093 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -060094 mask = so->mask; /* help avoid a register spill */
Raymond Hettingerafe89092013-08-28 20:59:31 -070095 }
Raymond Hettingerafe89092013-08-28 20:59:31 -070096
Raymond Hettingerc658d852015-02-02 08:35:00 -080097 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -080098 for (j = 0 ; j < LINEAR_PROBES ; j++) {
Raymond Hettingerc658d852015-02-02 08:35:00 -080099 entry++;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700100 if (entry->hash == 0 && entry->key == NULL)
101 return entry;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800102 if (entry->hash == hash) {
103 PyObject *startkey = entry->key;
104 assert(startkey != dummy);
105 if (startkey == key)
106 return entry;
107 if (PyUnicode_CheckExact(startkey)
108 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700109 && _PyUnicode_EQ(startkey, key))
Raymond Hettingerc658d852015-02-02 08:35:00 -0800110 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400111 table = so->table;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800112 Py_INCREF(startkey);
113 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
114 Py_DECREF(startkey);
115 if (cmp < 0)
116 return NULL;
117 if (table != so->table || entry->key != startkey)
118 return set_lookkey(so, key, hash);
119 if (cmp > 0)
120 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -0600121 mask = so->mask;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800122 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700123 }
124 }
125
126 perturb >>= PERTURB_SHIFT;
127 i = (i * 5 + 1 + perturb) & mask;
128
Raymond Hettinger70559b52015-07-23 07:42:23 -0400129 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700130 if (entry->key == NULL)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700131 return entry;
132 }
133}
134
Raymond Hettinger15f08692015-07-03 17:21:17 -0700135static int set_table_resize(PySetObject *, Py_ssize_t);
136
Raymond Hettinger8651a502015-05-27 10:37:20 -0700137static int
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400138set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700139{
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400140 setentry *table;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700141 setentry *freeslot;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700142 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700143 size_t perturb;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400144 size_t mask;
145 size_t i; /* Unsigned for defined overflow behavior */
Raymond Hettinger8651a502015-05-27 10:37:20 -0700146 size_t j;
147 int cmp;
148
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400149 /* Pre-increment is necessary to prevent arbitrary code in the rich
150 comparison from deallocating the key just before the insertion. */
151 Py_INCREF(key);
152
153 restart:
154
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400155 mask = so->mask;
156 i = (size_t)hash & mask;
157
Raymond Hettinger70559b52015-07-23 07:42:23 -0400158 entry = &so->table[i];
Raymond Hettinger8651a502015-05-27 10:37:20 -0700159 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700160 goto found_unused;
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700161
162 freeslot = NULL;
163 perturb = hash;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700164
165 while (1) {
166 if (entry->hash == hash) {
167 PyObject *startkey = entry->key;
168 /* startkey cannot be a dummy because the dummy hash field is -1 */
169 assert(startkey != dummy);
170 if (startkey == key)
171 goto found_active;
172 if (PyUnicode_CheckExact(startkey)
173 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700174 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700175 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400176 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700177 Py_INCREF(startkey);
178 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
179 Py_DECREF(startkey);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700180 if (cmp > 0) /* likely */
181 goto found_active;
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700182 if (cmp < 0)
183 goto comparison_error;
184 /* Continuing the search from the current entry only makes
185 sense if the table and entry are unchanged; otherwise,
186 we have to restart from the beginning */
187 if (table != so->table || entry->key != startkey)
188 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700189 mask = so->mask; /* help avoid a register spill */
190 }
Raymond Hettinger33299922018-01-14 10:20:13 -0800191 else if (entry->hash == -1)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700192 freeslot = entry;
193
194 if (i + LINEAR_PROBES <= mask) {
195 for (j = 0 ; j < LINEAR_PROBES ; j++) {
196 entry++;
197 if (entry->hash == 0 && entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700198 goto found_unused_or_dummy;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700199 if (entry->hash == hash) {
200 PyObject *startkey = entry->key;
201 assert(startkey != dummy);
202 if (startkey == key)
203 goto found_active;
204 if (PyUnicode_CheckExact(startkey)
205 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700206 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700207 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400208 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700209 Py_INCREF(startkey);
210 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
211 Py_DECREF(startkey);
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700212 if (cmp > 0)
213 goto found_active;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700214 if (cmp < 0)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400215 goto comparison_error;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700216 if (table != so->table || entry->key != startkey)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400217 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700218 mask = so->mask;
219 }
Raymond Hettinger33299922018-01-14 10:20:13 -0800220 else if (entry->hash == -1)
Raymond Hettingerc658d852015-02-02 08:35:00 -0800221 freeslot = entry;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700222 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000223 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700224
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700225 perturb >>= PERTURB_SHIFT;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -0800226 i = (i * 5 + 1 + perturb) & mask;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700227
Raymond Hettinger70559b52015-07-23 07:42:23 -0400228 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700229 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700230 goto found_unused_or_dummy;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000231 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700232
Raymond Hettinger15f08692015-07-03 17:21:17 -0700233 found_unused_or_dummy:
234 if (freeslot == NULL)
235 goto found_unused;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700236 so->used++;
237 freeslot->key = key;
238 freeslot->hash = hash;
239 return 0;
240
241 found_unused:
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700242 so->fill++;
243 so->used++;
244 entry->key = key;
245 entry->hash = hash;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800246 if ((size_t)so->fill*5 < mask*3)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700247 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +0900248 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700249
250 found_active:
Raymond Hettinger482c05c2015-07-20 01:23:32 -0400251 Py_DECREF(key);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700252 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000253
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400254 comparison_error:
Raymond Hettinger061091a2015-07-15 23:54:02 -0700255 Py_DECREF(key);
256 return -1;
257}
258
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000259/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000260Internal routine used by set_table_resize() to insert an item which is
261known to be absent from the set. This routine also assumes that
262the set contains no deleted entries. Besides the performance benefit,
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800263there is also safety benefit since using set_add_entry() risks making
264a callback in the middle of a set_table_resize(), see issue 1456209.
265The caller is responsible for updating the key's reference count and
266the setobject's fill and used fields.
Thomas Wouters89f507f2006-12-13 04:49:30 +0000267*/
268static void
Raymond Hettinger5088f602015-12-13 18:45:01 -0800269set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000270{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200271 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700272 size_t perturb = hash;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800273 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700274 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000275
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700276 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800277 entry = &table[i];
278 if (entry->key == NULL)
279 goto found_null;
280 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800281 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800282 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800283 if (entry->key == NULL)
284 goto found_null;
285 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700286 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700287 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800288 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700290 found_null:
Raymond Hettinger5088f602015-12-13 18:45:01 -0800291 entry->key = key;
Raymond Hettinger86d322f2015-12-13 19:27:17 -0800292 entry->hash = hash;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000293}
294
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700295/* ======== End logic for probing the hash table ========================== */
296/* ======================================================================== */
297
Thomas Wouters89f507f2006-12-13 04:49:30 +0000298/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000299Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000300keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000301actually be smaller than the old one.
302*/
303static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000304set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000305{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 setentry *oldtable, *newtable, *entry;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800307 Py_ssize_t oldmask = so->mask;
308 size_t newmask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 int is_oldtable_malloced;
310 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 assert(minused >= 0);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000314 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100315 /* XXX speed-up with intrinsics */
Sergey Fedoseev6c7d67c2018-09-12 04:18:01 +0500316 size_t newsize = PySet_MINSIZE;
317 while (newsize <= (size_t)minused) {
318 newsize <<= 1; // The largest possible value is PY_SSIZE_T_MAX + 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000319 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000321 /* Get space for a new table. */
322 oldtable = so->table;
323 assert(oldtable != NULL);
324 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 if (newsize == PySet_MINSIZE) {
327 /* A large table is shrinking, or we can't get any smaller. */
328 newtable = so->smalltable;
329 if (newtable == oldtable) {
330 if (so->fill == so->used) {
331 /* No dummies, so no point doing anything. */
332 return 0;
333 }
334 /* We're not going to resize it, but rebuild the
335 table anyway to purge old dummy entries.
336 Subtle: This is *necessary* if fill==size,
337 as set_lookkey needs at least one virgin slot to
338 terminate failing searches. If fill < size, it's
339 merely desirable, as dummies slow searches. */
340 assert(so->fill > so->used);
341 memcpy(small_copy, oldtable, sizeof(small_copy));
342 oldtable = small_copy;
343 }
344 }
345 else {
346 newtable = PyMem_NEW(setentry, newsize);
347 if (newtable == NULL) {
348 PyErr_NoMemory();
349 return -1;
350 }
351 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 /* Make the set empty, using the new table. */
354 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 memset(newtable, 0, sizeof(setentry) * newsize);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800356 so->mask = newsize - 1;
357 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 /* Copy the data over; this is refcount-neutral for active entries;
360 dummy entries aren't copied over, of course */
Raymond Hettinger5088f602015-12-13 18:45:01 -0800361 newmask = (size_t)so->mask;
Raymond Hettingere1af6962017-02-02 08:24:48 -0800362 if (so->fill == so->used) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800363 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800364 if (entry->key != NULL) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800365 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800366 }
367 }
368 } else {
Raymond Hettingere1af6962017-02-02 08:24:48 -0800369 so->fill = so->used;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800370 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800371 if (entry->key != NULL && entry->key != dummy) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800372 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800373 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 }
375 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 if (is_oldtable_malloced)
378 PyMem_DEL(oldtable);
379 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000380}
381
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000382static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700383set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000384{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700385 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000386
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700387 entry = set_lookkey(so, key, hash);
388 if (entry != NULL)
389 return entry->key != NULL;
390 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000391}
392
393#define DISCARD_NOTFOUND 0
394#define DISCARD_FOUND 1
395
396static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700397set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800398{
399 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000401
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700402 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 if (entry == NULL)
404 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700405 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 return DISCARD_NOTFOUND;
407 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800409 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000410 so->used--;
411 Py_DECREF(old_key);
412 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000413}
414
415static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700416set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000417{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200418 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000419
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700420 if (!PyUnicode_CheckExact(key) ||
421 (hash = ((PyASCIIObject *) key)->hash) == -1) {
422 hash = PyObject_Hash(key);
423 if (hash == -1)
424 return -1;
425 }
426 return set_add_entry(so, key, hash);
427}
428
429static int
430set_contains_key(PySetObject *so, PyObject *key)
431{
432 Py_hash_t hash;
433
434 if (!PyUnicode_CheckExact(key) ||
435 (hash = ((PyASCIIObject *) key)->hash) == -1) {
436 hash = PyObject_Hash(key);
437 if (hash == -1)
438 return -1;
439 }
440 return set_contains_entry(so, key, hash);
441}
442
443static int
444set_discard_key(PySetObject *so, PyObject *key)
445{
446 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000448 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200449 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450 hash = PyObject_Hash(key);
451 if (hash == -1)
452 return -1;
453 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700454 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000455}
456
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700457static void
458set_empty_to_minsize(PySetObject *so)
459{
460 memset(so->smalltable, 0, sizeof(so->smalltable));
461 so->fill = 0;
462 so->used = 0;
463 so->mask = PySet_MINSIZE - 1;
464 so->table = so->smalltable;
465 so->hash = -1;
466}
467
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000468static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000469set_clear_internal(PySetObject *so)
470{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800471 setentry *entry;
472 setentry *table = so->table;
473 Py_ssize_t fill = so->fill;
474 Py_ssize_t used = so->used;
475 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000477
Raymond Hettinger583cd032013-09-07 22:06:35 -0700478 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 /* This is delicate. During the process of clearing the set,
482 * decrefs can cause the set to mutate. To avoid fatal confusion
483 * (voice of experience), we have to make the set empty before
484 * clearing the slots, and never refer to anything via so->ref while
485 * clearing.
486 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700488 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490 else if (fill > 0) {
491 /* It's a small table with something that needs to be cleared.
492 * Afraid the only safe way is to copy the set entries into
493 * another small table first.
494 */
495 memcpy(small_copy, table, sizeof(small_copy));
496 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700497 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 }
499 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 /* Now we can finally clear things. If C had refcounts, we could
502 * assert that the refcount on table is 1 now, i.e. that this function
503 * has unique access to it, so decref side-effects can't alter it.
504 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800505 for (entry = table; used > 0; entry++) {
506 if (entry->key && entry->key != dummy) {
507 used--;
508 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 if (table_is_malloced)
513 PyMem_DEL(table);
514 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000515}
516
517/*
518 * Iterate over a set table. Use like so:
519 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000520 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000521 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000522 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000523 * while (set_next(yourset, &pos, &entry)) {
524 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000525 * }
526 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000527 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000528 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000529 */
530static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000531set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000532{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 Py_ssize_t i;
534 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700535 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 assert (PyAnySet_Check(so));
538 i = *pos_ptr;
539 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700541 entry = &so->table[i];
542 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700544 entry++;
545 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000546 *pos_ptr = i+1;
547 if (i > mask)
548 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700549 assert(entry != NULL);
550 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000552}
553
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000554static void
555set_dealloc(PySetObject *so)
556{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200557 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800558 Py_ssize_t used = so->used;
559
INADA Naokia6296d32017-08-24 14:55:17 +0900560 /* bpo-31095: UnTrack is needed before calling any callbacks */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000561 PyObject_GC_UnTrack(so);
562 Py_TRASHCAN_SAFE_BEGIN(so)
563 if (so->weakreflist != NULL)
564 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000565
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800566 for (entry = so->table; used > 0; entry++) {
567 if (entry->key && entry->key != dummy) {
568 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700569 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 }
571 }
572 if (so->table != so->smalltable)
573 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700574 Py_TYPE(so)->tp_free(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000575 Py_TRASHCAN_SAFE_END(so)
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000576}
577
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000578static PyObject *
579set_repr(PySetObject *so)
580{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200581 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000582 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000583
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000584 if (status != 0) {
585 if (status < 0)
586 return NULL;
587 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
588 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000589
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000590 /* shortcut for the empty set */
591 if (!so->used) {
592 Py_ReprLeave((PyObject*)so);
593 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
594 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000595
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000596 keys = PySequence_List((PyObject *)so);
597 if (keys == NULL)
598 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000599
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200600 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000601 listrepr = PyObject_Repr(keys);
602 Py_DECREF(keys);
603 if (listrepr == NULL)
604 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200605 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200607 if (tmp == NULL)
608 goto done;
609 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200610
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200611 if (Py_TYPE(so) != &PySet_Type)
612 result = PyUnicode_FromFormat("%s({%U})",
613 Py_TYPE(so)->tp_name,
614 listrepr);
615 else
616 result = PyUnicode_FromFormat("{%U}", listrepr);
617 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000618done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 Py_ReprLeave((PyObject*)so);
620 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000621}
622
Martin v. Löwis18e16552006-02-15 17:27:45 +0000623static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000624set_len(PyObject *so)
625{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000627}
628
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000629static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000630set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000631{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000632 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000633 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200634 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700635 setentry *so_entry;
636 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000637
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 assert (PyAnySet_Check(so));
639 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 other = (PySetObject*)otherset;
642 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700643 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000644 return 0;
645 /* Do one big resize at the start, rather than
646 * incrementally resizing as we insert new keys. Expect
647 * that there will be no (or few) overlapping keys.
648 */
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800649 if ((so->fill + other->used)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900650 if (set_table_resize(so, (so->used + other->used)*2) != 0)
651 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000652 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700653 so_entry = so->table;
654 other_entry = other->table;
655
656 /* If our table is empty, and both tables have the same size, and
657 there are no dummies to eliminate, then just copy the pointers. */
658 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
659 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
660 key = other_entry->key;
661 if (key != NULL) {
662 assert(so_entry->key == NULL);
663 Py_INCREF(key);
664 so_entry->key = key;
665 so_entry->hash = other_entry->hash;
666 }
667 }
668 so->fill = other->fill;
669 so->used = other->used;
670 return 0;
671 }
672
673 /* If our table is empty, we can use set_insert_clean() */
674 if (so->fill == 0) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800675 setentry *newtable = so->table;
676 size_t newmask = (size_t)so->mask;
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800677 so->fill = other->used;
678 so->used = other->used;
Raymond Hettingere4495872015-12-15 00:42:30 -0800679 for (i = other->mask + 1; i > 0 ; i--, other_entry++) {
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700680 key = other_entry->key;
681 if (key != NULL && key != dummy) {
682 Py_INCREF(key);
Raymond Hettinger5088f602015-12-13 18:45:01 -0800683 set_insert_clean(newtable, newmask, key, other_entry->hash);
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700684 }
685 }
686 return 0;
687 }
688
689 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700690 for (i = 0; i <= other->mask; i++) {
691 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700692 key = other_entry->key;
693 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700694 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000696 }
697 }
698 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000699}
700
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000701static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530702set_pop(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000703{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800704 /* Make sure the search finger is in bounds */
Raymond Hettingerf9ec1b92018-11-11 14:35:47 -0800705 setentry *entry = so->table + (so->finger & so->mask);
706 setentry *limit = so->table + so->mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000708
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000709 if (so->used == 0) {
710 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
711 return NULL;
712 }
Raymond Hettingercf5863f2018-11-09 02:31:56 -0800713 while (entry->key == NULL || entry->key==dummy) {
714 entry++;
715 if (entry > limit)
716 entry = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 }
718 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800720 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 so->used--;
Raymond Hettingercf5863f2018-11-09 02:31:56 -0800722 so->finger = entry - so->table + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000724}
725
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000726PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
727Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000728
729static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000730set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000731{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000732 Py_ssize_t pos = 0;
733 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 while (set_next(so, &pos, &entry))
736 Py_VISIT(entry->key);
737 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000738}
739
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700740/* Work to increase the bit dispersion for closely spaced hash values.
741 This is important because some use cases have many combinations of a
742 small number of elements with nearby hashes so that many distinct
743 combinations collapse to only a handful of distinct hash values. */
744
745static Py_uhash_t
746_shuffle_bits(Py_uhash_t h)
747{
748 return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
749}
750
751/* Most of the constants in this hash algorithm are randomly chosen
752 large primes with "interesting bit patterns" and that passed tests
753 for good collision statistics on a variety of problematic datasets
754 including powersets and graph structures (such as David Eppstein's
755 graph recipes in Lib/test/test_set.py) */
756
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000757static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000758frozenset_hash(PyObject *self)
759{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000760 PySetObject *so = (PySetObject *)self;
Raymond Hettinger41481952015-08-07 00:43:39 -0700761 Py_uhash_t hash = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000763
Raymond Hettingerb501a272015-08-06 22:15:22 -0700764 if (so->hash != -1)
765 return so->hash;
766
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700767 /* Xor-in shuffled bits from every entry's hash field because xor is
768 commutative and a frozenset hash should be independent of order.
769
770 For speed, include null entries and dummy entries and then
771 subtract out their effect afterwards so that the final hash
772 depends only on active entries. This allows the code to be
773 vectorized by the compiler and it saves the unpredictable
774 branches that would arise when trying to exclude null and dummy
775 entries on every iteration. */
776
777 for (entry = so->table; entry <= &so->table[so->mask]; entry++)
778 hash ^= _shuffle_bits(entry->hash);
779
Raymond Hettingera286a512015-08-01 11:07:11 -0700780 /* Remove the effect of an odd number of NULL entries */
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700781 if ((so->mask + 1 - so->fill) & 1)
782 hash ^= _shuffle_bits(0);
783
784 /* Remove the effect of an odd number of dummy entries */
785 if ((so->fill - so->used) & 1)
786 hash ^= _shuffle_bits(-1);
787
Raymond Hettinger41481952015-08-07 00:43:39 -0700788 /* Factor in the number of active entries */
789 hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;
790
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700791 /* Disperse patterns arising in nested frozensets */
Raymond Hettingerfa788062018-01-18 13:23:27 -0800792 hash ^= (hash >> 11) ^ (hash >> 25);
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800793 hash = hash * 69069U + 907133923UL;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700794
Raymond Hettinger36c05002015-08-01 10:57:42 -0700795 /* -1 is reserved as an error code */
Victor Stinner12174a52014-08-15 23:17:38 +0200796 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800797 hash = 590923713UL;
Raymond Hettinger36c05002015-08-01 10:57:42 -0700798
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000799 so->hash = hash;
800 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000801}
802
Raymond Hettingera9d99362005-08-05 00:01:15 +0000803/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000804
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000805typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000806 PyObject_HEAD
807 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
808 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700809 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000810 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000811} setiterobject;
812
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000813static void
814setiter_dealloc(setiterobject *si)
815{
INADA Naokia6296d32017-08-24 14:55:17 +0900816 /* bpo-31095: UnTrack is needed before calling any callbacks */
817 _PyObject_GC_UNTRACK(si);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000818 Py_XDECREF(si->si_set);
819 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000820}
821
822static int
823setiter_traverse(setiterobject *si, visitproc visit, void *arg)
824{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000825 Py_VISIT(si->si_set);
826 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000827}
828
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000829static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530830setiter_len(setiterobject *si, PyObject *Py_UNUSED(ignored))
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000831{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000832 Py_ssize_t len = 0;
833 if (si->si_set != NULL && si->si_used == si->si_set->used)
834 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000835 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000836}
837
Armin Rigof5b3e362006-02-11 21:32:43 +0000838PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000839
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000840static PyObject *setiter_iternext(setiterobject *si);
841
842static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530843setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000844{
Ezio Melotti0e1af282012-09-28 16:43:40 +0300845 /* copy the iterator state */
Sergey Fedoseev63958442018-10-20 05:43:33 +0500846 setiterobject tmp = *si;
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000847 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300848
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000849 /* iterate the temporary into a list */
Sergey Fedoseev63958442018-10-20 05:43:33 +0500850 PyObject *list = PySequence_List((PyObject*)&tmp);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000851 Py_XDECREF(tmp.si_set);
Sergey Fedoseev63958442018-10-20 05:43:33 +0500852 if (list == NULL) {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000853 return NULL;
854 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200855 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000856}
857
858PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
859
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000860static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000861 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000862 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000863 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000864};
865
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000866static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000867{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700868 PyObject *key;
869 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200870 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000871 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000873 if (so == NULL)
874 return NULL;
875 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000877 if (si->si_used != so->used) {
878 PyErr_SetString(PyExc_RuntimeError,
879 "Set changed size during iteration");
880 si->si_used = -1; /* Make this state sticky */
881 return NULL;
882 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700883
884 i = si->si_pos;
885 assert(i>=0);
886 entry = so->table;
887 mask = so->mask;
888 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
889 i++;
890 si->si_pos = i+1;
891 if (i > mask)
892 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000893 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700894 key = entry[i].key;
895 Py_INCREF(key);
896 return key;
897
898fail:
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700899 si->si_set = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +0300900 Py_DECREF(so);
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700901 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000902}
903
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000904PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000905 PyVarObject_HEAD_INIT(&PyType_Type, 0)
906 "set_iterator", /* tp_name */
907 sizeof(setiterobject), /* tp_basicsize */
908 0, /* tp_itemsize */
909 /* methods */
910 (destructor)setiter_dealloc, /* tp_dealloc */
911 0, /* tp_print */
912 0, /* tp_getattr */
913 0, /* tp_setattr */
914 0, /* tp_reserved */
915 0, /* tp_repr */
916 0, /* tp_as_number */
917 0, /* tp_as_sequence */
918 0, /* tp_as_mapping */
919 0, /* tp_hash */
920 0, /* tp_call */
921 0, /* tp_str */
922 PyObject_GenericGetAttr, /* tp_getattro */
923 0, /* tp_setattro */
924 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700925 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 0, /* tp_doc */
927 (traverseproc)setiter_traverse, /* tp_traverse */
928 0, /* tp_clear */
929 0, /* tp_richcompare */
930 0, /* tp_weaklistoffset */
931 PyObject_SelfIter, /* tp_iter */
932 (iternextfunc)setiter_iternext, /* tp_iternext */
933 setiter_methods, /* tp_methods */
934 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000935};
936
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000937static PyObject *
938set_iter(PySetObject *so)
939{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000940 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
941 if (si == NULL)
942 return NULL;
943 Py_INCREF(so);
944 si->si_set = so;
945 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700946 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000947 si->len = so->used;
948 _PyObject_GC_TRACK(si);
949 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000950}
951
Raymond Hettingerd7946662005-08-01 21:39:29 +0000952static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000953set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000954{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000955 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000956
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 if (PyAnySet_Check(other))
958 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000959
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000960 if (PyDict_CheckExact(other)) {
961 PyObject *value;
962 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000963 Py_hash_t hash;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200964 Py_ssize_t dictsize = PyDict_GET_SIZE(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 /* Do one big resize at the start, rather than
967 * incrementally resizing as we insert new keys. Expect
968 * that there will be no (or few) overlapping keys.
969 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700970 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 return -1;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800972 if ((so->fill + dictsize)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900973 if (set_table_resize(so, (so->used + dictsize)*2) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 return -1;
975 }
976 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700977 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 return -1;
979 }
980 return 0;
981 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 it = PyObject_GetIter(other);
984 if (it == NULL)
985 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +0000986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000987 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700988 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 Py_DECREF(it);
990 Py_DECREF(key);
991 return -1;
992 }
993 Py_DECREF(key);
994 }
995 Py_DECREF(it);
996 if (PyErr_Occurred())
997 return -1;
998 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000999}
1000
1001static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001002set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1007 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001008 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001009 return NULL;
1010 }
1011 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001012}
1013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001015"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001016
Raymond Hettinger426d9952014-05-18 21:40:20 +01001017/* XXX Todo:
1018 If aligned memory allocations become available, make the
1019 set object 64 byte aligned so that most of the fields
1020 can be retrieved or updated in a single cache line.
1021*/
1022
Raymond Hettingera38123e2003-11-24 22:18:49 +00001023static PyObject *
1024make_new_set(PyTypeObject *type, PyObject *iterable)
1025{
Raymond Hettinger8421d712016-04-29 01:37:05 -07001026 PySetObject *so;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001027
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001028 so = (PySetObject *)type->tp_alloc(type, 0);
1029 if (so == NULL)
1030 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001031
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001032 so->fill = 0;
1033 so->used = 0;
1034 so->mask = PySet_MINSIZE - 1;
1035 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001036 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001037 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001038 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001039
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001040 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001041 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 Py_DECREF(so);
1043 return NULL;
1044 }
1045 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001046
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001047 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001048}
1049
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001050static PyObject *
1051make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1052{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001053 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1054 if (PyType_IsSubtype(type, &PySet_Type))
1055 type = &PySet_Type;
1056 else
1057 type = &PyFrozenSet_Type;
1058 }
1059 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001060}
1061
Raymond Hettingerd7946662005-08-01 21:39:29 +00001062/* The empty frozenset is a singleton */
1063static PyObject *emptyfrozenset = NULL;
1064
Raymond Hettingera690a992003-11-16 16:17:49 +00001065static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001066frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001067{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001068 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001069
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001070 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1074 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001076 if (type != &PyFrozenSet_Type)
1077 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001078
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001079 if (iterable != NULL) {
1080 /* frozenset(f) is idempotent */
1081 if (PyFrozenSet_CheckExact(iterable)) {
1082 Py_INCREF(iterable);
1083 return iterable;
1084 }
1085 result = make_new_set(type, iterable);
1086 if (result == NULL || PySet_GET_SIZE(result))
1087 return result;
1088 Py_DECREF(result);
1089 }
1090 /* The empty frozenset is a singleton */
1091 if (emptyfrozenset == NULL)
1092 emptyfrozenset = make_new_set(type, NULL);
1093 Py_XINCREF(emptyfrozenset);
1094 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001095}
1096
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001097static PyObject *
1098set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1099{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001101}
1102
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001103/* set_swap_bodies() switches the contents of any two sets by moving their
1104 internal data pointers and, if needed, copying the internal smalltables.
1105 Semantically equivalent to:
1106
1107 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1108
1109 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001110 Useful for operations that update in-place (by allowing an intermediate
1111 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001112*/
1113
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001114static void
1115set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001116{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001117 Py_ssize_t t;
1118 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001119 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001120 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122 t = a->fill; a->fill = b->fill; b->fill = t;
1123 t = a->used; a->used = b->used; b->used = t;
1124 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001125
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001126 u = a->table;
1127 if (a->table == a->smalltable)
1128 u = b->smalltable;
1129 a->table = b->table;
1130 if (b->table == b->smalltable)
1131 a->table = a->smalltable;
1132 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001133
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001134 if (a->table == a->smalltable || b->table == b->smalltable) {
1135 memcpy(tab, a->smalltable, sizeof(tab));
1136 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1137 memcpy(b->smalltable, tab, sizeof(tab));
1138 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001139
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1141 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1142 h = a->hash; a->hash = b->hash; b->hash = h;
1143 } else {
1144 a->hash = -1;
1145 b->hash = -1;
1146 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001147}
1148
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001149static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301150set_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001151{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001153}
1154
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001155static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301156frozenset_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001157{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001158 if (PyFrozenSet_CheckExact(so)) {
1159 Py_INCREF(so);
1160 return (PyObject *)so;
1161 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301162 return set_copy(so, NULL);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001163}
1164
Raymond Hettingera690a992003-11-16 16:17:49 +00001165PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1166
1167static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301168set_clear(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc991db22005-08-11 07:58:45 +00001169{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 set_clear_internal(so);
1171 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001172}
1173
1174PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1175
1176static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001177set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001178{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001179 PySetObject *result;
1180 PyObject *other;
1181 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001182
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301183 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001184 if (result == NULL)
1185 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1188 other = PyTuple_GET_ITEM(args, i);
1189 if ((PyObject *)so == other)
1190 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001191 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001192 Py_DECREF(result);
1193 return NULL;
1194 }
1195 }
1196 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001197}
1198
1199PyDoc_STRVAR(union_doc,
1200 "Return the union of sets as a new set.\n\
1201\n\
1202(i.e. all elements that are in either set.)");
1203
1204static PyObject *
1205set_or(PySetObject *so, PyObject *other)
1206{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001208
Brian Curtindfc80e32011-08-10 20:28:54 -05001209 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1210 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001211
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301212 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001213 if (result == NULL)
1214 return NULL;
1215 if ((PyObject *)so == other)
1216 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001217 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001218 Py_DECREF(result);
1219 return NULL;
1220 }
1221 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001222}
1223
Raymond Hettingera690a992003-11-16 16:17:49 +00001224static PyObject *
1225set_ior(PySetObject *so, PyObject *other)
1226{
Brian Curtindfc80e32011-08-10 20:28:54 -05001227 if (!PyAnySet_Check(other))
1228 Py_RETURN_NOTIMPLEMENTED;
1229
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001230 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001231 return NULL;
1232 Py_INCREF(so);
1233 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001234}
1235
1236static PyObject *
1237set_intersection(PySetObject *so, PyObject *other)
1238{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001239 PySetObject *result;
1240 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001241 Py_hash_t hash;
1242 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301245 return set_copy(so, NULL);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1248 if (result == NULL)
1249 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001250
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 if (PyAnySet_Check(other)) {
1252 Py_ssize_t pos = 0;
1253 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1256 tmp = (PyObject *)so;
1257 so = (PySetObject *)other;
1258 other = tmp;
1259 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001262 key = entry->key;
1263 hash = entry->hash;
1264 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001265 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 Py_DECREF(result);
1267 return NULL;
1268 }
1269 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001270 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 Py_DECREF(result);
1272 return NULL;
1273 }
1274 }
1275 }
1276 return (PyObject *)result;
1277 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 it = PyObject_GetIter(other);
1280 if (it == NULL) {
1281 Py_DECREF(result);
1282 return NULL;
1283 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001285 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001286 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001287 if (hash == -1)
1288 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001289 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001290 if (rv < 0)
1291 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001293 if (set_add_entry(result, key, hash))
1294 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 }
1296 Py_DECREF(key);
1297 }
1298 Py_DECREF(it);
1299 if (PyErr_Occurred()) {
1300 Py_DECREF(result);
1301 return NULL;
1302 }
1303 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001304 error:
1305 Py_DECREF(it);
1306 Py_DECREF(result);
1307 Py_DECREF(key);
1308 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001309}
1310
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001311static PyObject *
1312set_intersection_multi(PySetObject *so, PyObject *args)
1313{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 Py_ssize_t i;
1315 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301318 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 Py_INCREF(so);
1321 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1322 PyObject *other = PyTuple_GET_ITEM(args, i);
1323 PyObject *newresult = set_intersection((PySetObject *)result, other);
1324 if (newresult == NULL) {
1325 Py_DECREF(result);
1326 return NULL;
1327 }
1328 Py_DECREF(result);
1329 result = newresult;
1330 }
1331 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001332}
1333
Raymond Hettingera690a992003-11-16 16:17:49 +00001334PyDoc_STRVAR(intersection_doc,
1335"Return the intersection of two sets as a new set.\n\
1336\n\
1337(i.e. all elements that are in both sets.)");
1338
1339static PyObject *
1340set_intersection_update(PySetObject *so, PyObject *other)
1341{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001342 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 tmp = set_intersection(so, other);
1345 if (tmp == NULL)
1346 return NULL;
1347 set_swap_bodies(so, (PySetObject *)tmp);
1348 Py_DECREF(tmp);
1349 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001350}
1351
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001352static PyObject *
1353set_intersection_update_multi(PySetObject *so, PyObject *args)
1354{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001357 tmp = set_intersection_multi(so, args);
1358 if (tmp == NULL)
1359 return NULL;
1360 set_swap_bodies(so, (PySetObject *)tmp);
1361 Py_DECREF(tmp);
1362 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001363}
1364
Raymond Hettingera690a992003-11-16 16:17:49 +00001365PyDoc_STRVAR(intersection_update_doc,
1366"Update a set with the intersection of itself and another.");
1367
1368static PyObject *
1369set_and(PySetObject *so, PyObject *other)
1370{
Brian Curtindfc80e32011-08-10 20:28:54 -05001371 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1372 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001374}
1375
1376static PyObject *
1377set_iand(PySetObject *so, PyObject *other)
1378{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001380
Brian Curtindfc80e32011-08-10 20:28:54 -05001381 if (!PyAnySet_Check(other))
1382 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 result = set_intersection_update(so, other);
1384 if (result == NULL)
1385 return NULL;
1386 Py_DECREF(result);
1387 Py_INCREF(so);
1388 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001389}
1390
Guido van Rossum58da9312007-11-10 23:39:45 +00001391static PyObject *
1392set_isdisjoint(PySetObject *so, PyObject *other)
1393{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001395 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001397 if ((PyObject *)so == other) {
1398 if (PySet_GET_SIZE(so) == 0)
1399 Py_RETURN_TRUE;
1400 else
1401 Py_RETURN_FALSE;
1402 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001404 if (PyAnySet_CheckExact(other)) {
1405 Py_ssize_t pos = 0;
1406 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1409 tmp = (PyObject *)so;
1410 so = (PySetObject *)other;
1411 other = tmp;
1412 }
1413 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001414 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001415 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416 return NULL;
1417 if (rv)
1418 Py_RETURN_FALSE;
1419 }
1420 Py_RETURN_TRUE;
1421 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001423 it = PyObject_GetIter(other);
1424 if (it == NULL)
1425 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001427 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001428 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 if (hash == -1) {
1431 Py_DECREF(key);
1432 Py_DECREF(it);
1433 return NULL;
1434 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001435 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001437 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 Py_DECREF(it);
1439 return NULL;
1440 }
1441 if (rv) {
1442 Py_DECREF(it);
1443 Py_RETURN_FALSE;
1444 }
1445 }
1446 Py_DECREF(it);
1447 if (PyErr_Occurred())
1448 return NULL;
1449 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001450}
1451
1452PyDoc_STRVAR(isdisjoint_doc,
1453"Return True if two sets have a null intersection.");
1454
Neal Norwitz6576bd82005-11-13 18:41:28 +00001455static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001456set_difference_update_internal(PySetObject *so, PyObject *other)
1457{
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001458 if (PySet_GET_SIZE(so) == 0) {
1459 return 0;
1460 }
1461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462 if ((PyObject *)so == other)
1463 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 if (PyAnySet_Check(other)) {
1466 setentry *entry;
1467 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001469 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001470 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 return -1;
1472 } else {
1473 PyObject *key, *it;
1474 it = PyObject_GetIter(other);
1475 if (it == NULL)
1476 return -1;
1477
1478 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001479 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 Py_DECREF(it);
1481 Py_DECREF(key);
1482 return -1;
1483 }
1484 Py_DECREF(key);
1485 }
1486 Py_DECREF(it);
1487 if (PyErr_Occurred())
1488 return -1;
1489 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001490 /* If more than 1/4th are dummies, then resize them away. */
1491 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +09001493 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001494}
1495
Raymond Hettingera690a992003-11-16 16:17:49 +00001496static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001497set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001498{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1502 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001503 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 return NULL;
1505 }
1506 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001507}
1508
1509PyDoc_STRVAR(difference_update_doc,
1510"Remove all elements of another set from this set.");
1511
1512static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001513set_copy_and_difference(PySetObject *so, PyObject *other)
1514{
1515 PyObject *result;
1516
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301517 result = set_copy(so, NULL);
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001518 if (result == NULL)
1519 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001520 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001521 return result;
1522 Py_DECREF(result);
1523 return NULL;
1524}
1525
1526static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001527set_difference(PySetObject *so, PyObject *other)
1528{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001530 PyObject *key;
1531 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001532 setentry *entry;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001533 Py_ssize_t pos = 0, other_size;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001534 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001535
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001536 if (PySet_GET_SIZE(so) == 0) {
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301537 return set_copy(so, NULL);
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001538 }
1539
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001540 if (PyAnySet_Check(other)) {
1541 other_size = PySet_GET_SIZE(other);
1542 }
1543 else if (PyDict_CheckExact(other)) {
1544 other_size = PyDict_GET_SIZE(other);
1545 }
1546 else {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001547 return set_copy_and_difference(so, other);
1548 }
1549
1550 /* If len(so) much more than len(other), it's more efficient to simply copy
1551 * so and then iterate other looking for common elements. */
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001552 if ((PySet_GET_SIZE(so) >> 2) > other_size) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001553 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001554 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001555
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001556 result = make_new_set_basetype(Py_TYPE(so), NULL);
1557 if (result == NULL)
1558 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001560 if (PyDict_CheckExact(other)) {
1561 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001562 key = entry->key;
1563 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001564 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001565 if (rv < 0) {
1566 Py_DECREF(result);
1567 return NULL;
1568 }
1569 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001570 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001571 Py_DECREF(result);
1572 return NULL;
1573 }
1574 }
1575 }
1576 return result;
1577 }
1578
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001579 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001581 key = entry->key;
1582 hash = entry->hash;
1583 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001584 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 Py_DECREF(result);
1586 return NULL;
1587 }
1588 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001589 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001590 Py_DECREF(result);
1591 return NULL;
1592 }
1593 }
1594 }
1595 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001596}
1597
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001598static PyObject *
1599set_difference_multi(PySetObject *so, PyObject *args)
1600{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 Py_ssize_t i;
1602 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301605 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001607 other = PyTuple_GET_ITEM(args, 0);
1608 result = set_difference(so, other);
1609 if (result == NULL)
1610 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001611
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001612 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1613 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001614 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 Py_DECREF(result);
1616 return NULL;
1617 }
1618 }
1619 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001620}
1621
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001622PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001623"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001624\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001625(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001626static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001627set_sub(PySetObject *so, PyObject *other)
1628{
Brian Curtindfc80e32011-08-10 20:28:54 -05001629 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1630 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001632}
1633
1634static PyObject *
1635set_isub(PySetObject *so, PyObject *other)
1636{
Brian Curtindfc80e32011-08-10 20:28:54 -05001637 if (!PyAnySet_Check(other))
1638 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001639 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001640 return NULL;
1641 Py_INCREF(so);
1642 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001643}
1644
1645static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001646set_symmetric_difference_update(PySetObject *so, PyObject *other)
1647{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001648 PySetObject *otherset;
1649 PyObject *key;
1650 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001651 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001653 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001654
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001655 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301656 return set_clear(so, NULL);
Raymond Hettingera690a992003-11-16 16:17:49 +00001657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001658 if (PyDict_CheckExact(other)) {
1659 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001661 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001662 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001663 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001664 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001665 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001666 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001667 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001668 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001669 Py_DECREF(key);
1670 return NULL;
1671 }
1672 }
Georg Brandl2d444492010-09-03 10:52:55 +00001673 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001674 }
1675 Py_RETURN_NONE;
1676 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001677
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001678 if (PyAnySet_Check(other)) {
1679 Py_INCREF(other);
1680 otherset = (PySetObject *)other;
1681 } else {
1682 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1683 if (otherset == NULL)
1684 return NULL;
1685 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001687 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001688 key = entry->key;
1689 hash = entry->hash;
1690 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001691 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001692 Py_DECREF(otherset);
1693 return NULL;
1694 }
1695 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001696 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001697 Py_DECREF(otherset);
1698 return NULL;
1699 }
1700 }
1701 }
1702 Py_DECREF(otherset);
1703 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001704}
1705
1706PyDoc_STRVAR(symmetric_difference_update_doc,
1707"Update a set with the symmetric difference of itself and another.");
1708
1709static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001710set_symmetric_difference(PySetObject *so, PyObject *other)
1711{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001712 PyObject *rv;
1713 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001714
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001715 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1716 if (otherset == NULL)
1717 return NULL;
1718 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
lekma491bbed2018-05-02 11:29:10 +02001719 if (rv == NULL) {
1720 Py_DECREF(otherset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001721 return NULL;
lekma491bbed2018-05-02 11:29:10 +02001722 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001723 Py_DECREF(rv);
1724 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001725}
1726
1727PyDoc_STRVAR(symmetric_difference_doc,
1728"Return the symmetric difference of two sets as a new set.\n\
1729\n\
1730(i.e. all elements that are in exactly one of the sets.)");
1731
1732static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001733set_xor(PySetObject *so, PyObject *other)
1734{
Brian Curtindfc80e32011-08-10 20:28:54 -05001735 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1736 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001737 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001738}
1739
1740static PyObject *
1741set_ixor(PySetObject *so, PyObject *other)
1742{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001743 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001744
Brian Curtindfc80e32011-08-10 20:28:54 -05001745 if (!PyAnySet_Check(other))
1746 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001747 result = set_symmetric_difference_update(so, other);
1748 if (result == NULL)
1749 return NULL;
1750 Py_DECREF(result);
1751 Py_INCREF(so);
1752 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001753}
1754
1755static PyObject *
1756set_issubset(PySetObject *so, PyObject *other)
1757{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001758 setentry *entry;
1759 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001760 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001761
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001762 if (!PyAnySet_Check(other)) {
1763 PyObject *tmp, *result;
1764 tmp = make_new_set(&PySet_Type, other);
1765 if (tmp == NULL)
1766 return NULL;
1767 result = set_issubset(so, tmp);
1768 Py_DECREF(tmp);
1769 return result;
1770 }
1771 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1772 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001773
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001774 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001775 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001776 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 return NULL;
1778 if (!rv)
1779 Py_RETURN_FALSE;
1780 }
1781 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001782}
1783
1784PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1785
1786static PyObject *
1787set_issuperset(PySetObject *so, PyObject *other)
1788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001790
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001791 if (!PyAnySet_Check(other)) {
1792 tmp = make_new_set(&PySet_Type, other);
1793 if (tmp == NULL)
1794 return NULL;
1795 result = set_issuperset(so, tmp);
1796 Py_DECREF(tmp);
1797 return result;
1798 }
1799 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001800}
1801
1802PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1803
Raymond Hettingera690a992003-11-16 16:17:49 +00001804static PyObject *
1805set_richcompare(PySetObject *v, PyObject *w, int op)
1806{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001807 PyObject *r1;
1808 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001809
Brian Curtindfc80e32011-08-10 20:28:54 -05001810 if(!PyAnySet_Check(w))
1811 Py_RETURN_NOTIMPLEMENTED;
1812
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001813 switch (op) {
1814 case Py_EQ:
1815 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1816 Py_RETURN_FALSE;
1817 if (v->hash != -1 &&
1818 ((PySetObject *)w)->hash != -1 &&
1819 v->hash != ((PySetObject *)w)->hash)
1820 Py_RETURN_FALSE;
1821 return set_issubset(v, w);
1822 case Py_NE:
1823 r1 = set_richcompare(v, w, Py_EQ);
1824 if (r1 == NULL)
1825 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001826 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001827 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001828 if (r2 < 0)
1829 return NULL;
1830 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001831 case Py_LE:
1832 return set_issubset(v, w);
1833 case Py_GE:
1834 return set_issuperset(v, w);
1835 case Py_LT:
1836 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1837 Py_RETURN_FALSE;
1838 return set_issubset(v, w);
1839 case Py_GT:
1840 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1841 Py_RETURN_FALSE;
1842 return set_issuperset(v, w);
1843 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001844 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001845}
1846
Raymond Hettingera690a992003-11-16 16:17:49 +00001847static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001848set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001849{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001850 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001851 return NULL;
1852 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001853}
1854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001856"Add an element to a set.\n\
1857\n\
1858This has no effect if the element is already present.");
1859
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001860static int
1861set_contains(PySetObject *so, PyObject *key)
1862{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 PyObject *tmpkey;
1864 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001867 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1869 return -1;
1870 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001871 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 if (tmpkey == NULL)
1873 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001874 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 Py_DECREF(tmpkey);
1876 }
1877 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001878}
1879
1880static PyObject *
1881set_direct_contains(PySetObject *so, PyObject *key)
1882{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001883 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001886 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 return NULL;
1888 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001889}
1890
1891PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1892
Raymond Hettingera690a992003-11-16 16:17:49 +00001893static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001894set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001895{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 PyObject *tmpkey;
1897 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001899 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001900 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1902 return NULL;
1903 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001904 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 if (tmpkey == NULL)
1906 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001907 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001909 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 return NULL;
1911 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001913 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001914 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 return NULL;
1916 }
1917 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001918}
1919
1920PyDoc_STRVAR(remove_doc,
1921"Remove an element from a set; it must be a member.\n\
1922\n\
1923If the element is not a member, raise a KeyError.");
1924
1925static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001926set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001927{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001928 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001929 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001932 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001933 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1934 return NULL;
1935 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001936 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 if (tmpkey == NULL)
1938 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001939 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001940 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001941 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001942 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 }
1944 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001945}
1946
1947PyDoc_STRVAR(discard_doc,
1948"Remove an element from a set if it is a member.\n\
1949\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001950If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001951
1952static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301953set_reduce(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001954{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001956 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001957
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001958 keys = PySequence_List((PyObject *)so);
1959 if (keys == NULL)
1960 goto done;
1961 args = PyTuple_Pack(1, keys);
1962 if (args == NULL)
1963 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001964 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001965 if (dict == NULL) {
1966 PyErr_Clear();
1967 dict = Py_None;
1968 Py_INCREF(dict);
1969 }
1970 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001971done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001972 Py_XDECREF(args);
1973 Py_XDECREF(keys);
1974 Py_XDECREF(dict);
1975 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001976}
1977
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001978static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301979set_sizeof(PySetObject *so, PyObject *Py_UNUSED(ignored))
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001980{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001981 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001982
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02001983 res = _PyObject_SIZE(Py_TYPE(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001984 if (so->table != so->smalltable)
1985 res = res + (so->mask + 1) * sizeof(setentry);
1986 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001987}
1988
1989PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001990static int
1991set_init(PySetObject *self, PyObject *args, PyObject *kwds)
1992{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001993 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001994
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001995 if (!_PyArg_NoKeywords("set", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001996 return -1;
1997 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
1998 return -1;
Raymond Hettingerb72e21b2016-03-25 02:29:59 -07001999 if (self->fill)
2000 set_clear_internal(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002001 self->hash = -1;
2002 if (iterable == NULL)
2003 return 0;
2004 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002005}
2006
Raymond Hettingera690a992003-11-16 16:17:49 +00002007static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002008 set_len, /* sq_length */
2009 0, /* sq_concat */
2010 0, /* sq_repeat */
2011 0, /* sq_item */
2012 0, /* sq_slice */
2013 0, /* sq_ass_item */
2014 0, /* sq_ass_slice */
2015 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002016};
2017
2018/* set object ********************************************************/
2019
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002020#ifdef Py_DEBUG
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302021static PyObject *test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored));
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002022
2023PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2024All is well if assertions don't fail.");
2025#endif
2026
Raymond Hettingera690a992003-11-16 16:17:49 +00002027static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002028 {"add", (PyCFunction)set_add, METH_O,
2029 add_doc},
2030 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2031 clear_doc},
2032 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2033 contains_doc},
2034 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2035 copy_doc},
2036 {"discard", (PyCFunction)set_discard, METH_O,
2037 discard_doc},
2038 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2039 difference_doc},
2040 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2041 difference_update_doc},
2042 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2043 intersection_doc},
2044 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2045 intersection_update_doc},
2046 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2047 isdisjoint_doc},
2048 {"issubset", (PyCFunction)set_issubset, METH_O,
2049 issubset_doc},
2050 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2051 issuperset_doc},
2052 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2053 pop_doc},
2054 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2055 reduce_doc},
2056 {"remove", (PyCFunction)set_remove, METH_O,
2057 remove_doc},
2058 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2059 sizeof_doc},
2060 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2061 symmetric_difference_doc},
2062 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2063 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002064#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002065 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2066 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002067#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002068 {"union", (PyCFunction)set_union, METH_VARARGS,
2069 union_doc},
2070 {"update", (PyCFunction)set_update, METH_VARARGS,
2071 update_doc},
2072 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002073};
2074
2075static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002076 0, /*nb_add*/
2077 (binaryfunc)set_sub, /*nb_subtract*/
2078 0, /*nb_multiply*/
2079 0, /*nb_remainder*/
2080 0, /*nb_divmod*/
2081 0, /*nb_power*/
2082 0, /*nb_negative*/
2083 0, /*nb_positive*/
2084 0, /*nb_absolute*/
2085 0, /*nb_bool*/
2086 0, /*nb_invert*/
2087 0, /*nb_lshift*/
2088 0, /*nb_rshift*/
2089 (binaryfunc)set_and, /*nb_and*/
2090 (binaryfunc)set_xor, /*nb_xor*/
2091 (binaryfunc)set_or, /*nb_or*/
2092 0, /*nb_int*/
2093 0, /*nb_reserved*/
2094 0, /*nb_float*/
2095 0, /*nb_inplace_add*/
2096 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2097 0, /*nb_inplace_multiply*/
2098 0, /*nb_inplace_remainder*/
2099 0, /*nb_inplace_power*/
2100 0, /*nb_inplace_lshift*/
2101 0, /*nb_inplace_rshift*/
2102 (binaryfunc)set_iand, /*nb_inplace_and*/
2103 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2104 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002105};
2106
2107PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002108"set() -> new empty set object\n\
2109set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002110\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002111Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002112
2113PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002114 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2115 "set", /* tp_name */
2116 sizeof(PySetObject), /* tp_basicsize */
2117 0, /* tp_itemsize */
2118 /* methods */
2119 (destructor)set_dealloc, /* tp_dealloc */
2120 0, /* tp_print */
2121 0, /* tp_getattr */
2122 0, /* tp_setattr */
2123 0, /* tp_reserved */
2124 (reprfunc)set_repr, /* tp_repr */
2125 &set_as_number, /* tp_as_number */
2126 &set_as_sequence, /* tp_as_sequence */
2127 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002128 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002129 0, /* tp_call */
2130 0, /* tp_str */
2131 PyObject_GenericGetAttr, /* tp_getattro */
2132 0, /* tp_setattro */
2133 0, /* tp_as_buffer */
2134 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2135 Py_TPFLAGS_BASETYPE, /* tp_flags */
2136 set_doc, /* tp_doc */
2137 (traverseproc)set_traverse, /* tp_traverse */
2138 (inquiry)set_clear_internal, /* tp_clear */
2139 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002140 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2141 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002142 0, /* tp_iternext */
2143 set_methods, /* tp_methods */
2144 0, /* tp_members */
2145 0, /* tp_getset */
2146 0, /* tp_base */
2147 0, /* tp_dict */
2148 0, /* tp_descr_get */
2149 0, /* tp_descr_set */
2150 0, /* tp_dictoffset */
2151 (initproc)set_init, /* tp_init */
2152 PyType_GenericAlloc, /* tp_alloc */
2153 set_new, /* tp_new */
2154 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002155};
2156
2157/* frozenset object ********************************************************/
2158
2159
2160static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2162 contains_doc},
2163 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2164 copy_doc},
2165 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2166 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002167 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002168 intersection_doc},
2169 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2170 isdisjoint_doc},
2171 {"issubset", (PyCFunction)set_issubset, METH_O,
2172 issubset_doc},
2173 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2174 issuperset_doc},
2175 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2176 reduce_doc},
2177 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2178 sizeof_doc},
2179 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2180 symmetric_difference_doc},
2181 {"union", (PyCFunction)set_union, METH_VARARGS,
2182 union_doc},
2183 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002184};
2185
2186static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002187 0, /*nb_add*/
2188 (binaryfunc)set_sub, /*nb_subtract*/
2189 0, /*nb_multiply*/
2190 0, /*nb_remainder*/
2191 0, /*nb_divmod*/
2192 0, /*nb_power*/
2193 0, /*nb_negative*/
2194 0, /*nb_positive*/
2195 0, /*nb_absolute*/
2196 0, /*nb_bool*/
2197 0, /*nb_invert*/
2198 0, /*nb_lshift*/
2199 0, /*nb_rshift*/
2200 (binaryfunc)set_and, /*nb_and*/
2201 (binaryfunc)set_xor, /*nb_xor*/
2202 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002203};
2204
2205PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002206"frozenset() -> empty frozenset object\n\
2207frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002208\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002209Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002210
2211PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002212 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2213 "frozenset", /* tp_name */
2214 sizeof(PySetObject), /* tp_basicsize */
2215 0, /* tp_itemsize */
2216 /* methods */
2217 (destructor)set_dealloc, /* tp_dealloc */
2218 0, /* tp_print */
2219 0, /* tp_getattr */
2220 0, /* tp_setattr */
2221 0, /* tp_reserved */
2222 (reprfunc)set_repr, /* tp_repr */
2223 &frozenset_as_number, /* tp_as_number */
2224 &set_as_sequence, /* tp_as_sequence */
2225 0, /* tp_as_mapping */
2226 frozenset_hash, /* tp_hash */
2227 0, /* tp_call */
2228 0, /* tp_str */
2229 PyObject_GenericGetAttr, /* tp_getattro */
2230 0, /* tp_setattro */
2231 0, /* tp_as_buffer */
2232 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2233 Py_TPFLAGS_BASETYPE, /* tp_flags */
2234 frozenset_doc, /* tp_doc */
2235 (traverseproc)set_traverse, /* tp_traverse */
2236 (inquiry)set_clear_internal, /* tp_clear */
2237 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002238 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002239 (getiterfunc)set_iter, /* tp_iter */
2240 0, /* tp_iternext */
2241 frozenset_methods, /* tp_methods */
2242 0, /* tp_members */
2243 0, /* tp_getset */
2244 0, /* tp_base */
2245 0, /* tp_dict */
2246 0, /* tp_descr_get */
2247 0, /* tp_descr_set */
2248 0, /* tp_dictoffset */
2249 0, /* tp_init */
2250 PyType_GenericAlloc, /* tp_alloc */
2251 frozenset_new, /* tp_new */
2252 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002253};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002254
2255
2256/***** C API functions *************************************************/
2257
2258PyObject *
2259PySet_New(PyObject *iterable)
2260{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002261 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002262}
2263
2264PyObject *
2265PyFrozenSet_New(PyObject *iterable)
2266{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002267 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002268}
2269
Neal Norwitz8c49c822006-03-04 18:41:19 +00002270Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002271PySet_Size(PyObject *anyset)
2272{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002273 if (!PyAnySet_Check(anyset)) {
2274 PyErr_BadInternalCall();
2275 return -1;
2276 }
2277 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002278}
2279
2280int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002281PySet_Clear(PyObject *set)
2282{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002283 if (!PySet_Check(set)) {
2284 PyErr_BadInternalCall();
2285 return -1;
2286 }
2287 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002288}
2289
2290int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002291PySet_Contains(PyObject *anyset, PyObject *key)
2292{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002293 if (!PyAnySet_Check(anyset)) {
2294 PyErr_BadInternalCall();
2295 return -1;
2296 }
2297 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002298}
2299
2300int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002301PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002302{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002303 if (!PySet_Check(set)) {
2304 PyErr_BadInternalCall();
2305 return -1;
2306 }
2307 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002308}
2309
2310int
Christian Heimesfd66e512008-01-29 12:18:50 +00002311PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002312{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002313 if (!PySet_Check(anyset) &&
2314 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2315 PyErr_BadInternalCall();
2316 return -1;
2317 }
2318 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002319}
2320
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002321int
Raymond Hettinger3625af52016-03-27 01:15:07 -07002322PySet_ClearFreeList(void)
2323{
2324 return 0;
2325}
2326
2327void
2328PySet_Fini(void)
2329{
2330 Py_CLEAR(emptyfrozenset);
2331}
2332
2333int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002334_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002335{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002336 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002338 if (!PyAnySet_Check(set)) {
2339 PyErr_BadInternalCall();
2340 return -1;
2341 }
2342 if (set_next((PySetObject *)set, pos, &entry) == 0)
2343 return 0;
2344 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002345 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002346 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002347}
2348
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002349PyObject *
2350PySet_Pop(PyObject *set)
2351{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002352 if (!PySet_Check(set)) {
2353 PyErr_BadInternalCall();
2354 return NULL;
2355 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302356 return set_pop((PySetObject *)set, NULL);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002357}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002358
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002359int
2360_PySet_Update(PyObject *set, PyObject *iterable)
2361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002362 if (!PySet_Check(set)) {
2363 PyErr_BadInternalCall();
2364 return -1;
2365 }
2366 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002367}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002368
Raymond Hettingere259f132013-12-15 11:56:14 -08002369/* Exported for the gdb plugin's benefit. */
2370PyObject *_PySet_Dummy = dummy;
2371
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002372#ifdef Py_DEBUG
2373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002374/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002375 Returns True and original set is restored. */
2376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002377#define assertRaises(call_return_value, exception) \
2378 do { \
2379 assert(call_return_value); \
2380 assert(PyErr_ExceptionMatches(exception)); \
2381 PyErr_Clear(); \
2382 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002383
2384static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302385test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002386{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002387 Py_ssize_t count;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +02002388 const char *s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002389 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002390 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002391 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002392 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002393 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002395 /* Verify preconditions */
2396 assert(PyAnySet_Check(ob));
2397 assert(PyAnySet_CheckExact(ob));
2398 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002400 /* so.clear(); so |= set("abc"); */
2401 str = PyUnicode_FromString("abc");
2402 if (str == NULL)
2403 return NULL;
2404 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002405 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002406 Py_DECREF(str);
2407 return NULL;
2408 }
2409 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002411 /* Exercise type/size checks */
2412 assert(PySet_Size(ob) == 3);
2413 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002415 /* Raise TypeError for non-iterable constructor arguments */
2416 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2417 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002418
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002419 /* Raise TypeError for unhashable key */
2420 dup = PySet_New(ob);
2421 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2422 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2423 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002425 /* Exercise successful pop, contains, add, and discard */
2426 elem = PySet_Pop(ob);
2427 assert(PySet_Contains(ob, elem) == 0);
2428 assert(PySet_GET_SIZE(ob) == 2);
2429 assert(PySet_Add(ob, elem) == 0);
2430 assert(PySet_Contains(ob, elem) == 1);
2431 assert(PySet_GET_SIZE(ob) == 3);
2432 assert(PySet_Discard(ob, elem) == 1);
2433 assert(PySet_GET_SIZE(ob) == 2);
2434 assert(PySet_Discard(ob, elem) == 0);
2435 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002437 /* Exercise clear */
2438 dup2 = PySet_New(dup);
2439 assert(PySet_Clear(dup2) == 0);
2440 assert(PySet_Size(dup2) == 0);
2441 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002443 /* Raise SystemError on clear or update of frozen set */
2444 f = PyFrozenSet_New(dup);
2445 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2446 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2447 assert(PySet_Add(f, elem) == 0);
2448 Py_INCREF(f);
2449 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2450 Py_DECREF(f);
2451 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002453 /* Exercise direct iteration */
2454 i = 0, count = 0;
2455 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
Serhiy Storchaka06515832016-11-20 09:13:07 +02002456 s = PyUnicode_AsUTF8(x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002457 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2458 count++;
2459 }
2460 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002462 /* Exercise updates */
2463 dup2 = PySet_New(NULL);
2464 assert(_PySet_Update(dup2, dup) == 0);
2465 assert(PySet_Size(dup2) == 3);
2466 assert(_PySet_Update(dup2, dup) == 0);
2467 assert(PySet_Size(dup2) == 3);
2468 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002470 /* Raise SystemError when self argument is not a set or frozenset. */
2471 t = PyTuple_New(0);
2472 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2473 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2474 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002476 /* Raise SystemError when self argument is not a set. */
2477 f = PyFrozenSet_New(dup);
2478 assert(PySet_Size(f) == 3);
2479 assert(PyFrozenSet_CheckExact(f));
2480 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2481 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2482 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002484 /* Raise KeyError when popping from an empty set */
2485 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2486 Py_DECREF(ob);
2487 assert(PySet_GET_SIZE(ob) == 0);
2488 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002490 /* Restore the set from the copy using the PyNumber API */
2491 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2492 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002494 /* Verify constructors accept NULL arguments */
2495 f = PySet_New(NULL);
2496 assert(f != NULL);
2497 assert(PySet_GET_SIZE(f) == 0);
2498 Py_DECREF(f);
2499 f = PyFrozenSet_New(NULL);
2500 assert(f != NULL);
2501 assert(PyFrozenSet_CheckExact(f));
2502 assert(PySet_GET_SIZE(f) == 0);
2503 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002505 Py_DECREF(elem);
2506 Py_DECREF(dup);
2507 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002508}
2509
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002510#undef assertRaises
2511
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002512#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002513
2514/***** Dummy Struct *************************************************/
2515
2516static PyObject *
2517dummy_repr(PyObject *op)
2518{
2519 return PyUnicode_FromString("<dummy key>");
2520}
2521
2522static void
2523dummy_dealloc(PyObject* ignore)
2524{
2525 Py_FatalError("deallocating <dummy key>");
2526}
2527
2528static PyTypeObject _PySetDummy_Type = {
2529 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2530 "<dummy key> type",
2531 0,
2532 0,
2533 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2534 0, /*tp_print*/
2535 0, /*tp_getattr*/
2536 0, /*tp_setattr*/
2537 0, /*tp_reserved*/
2538 dummy_repr, /*tp_repr*/
2539 0, /*tp_as_number*/
2540 0, /*tp_as_sequence*/
2541 0, /*tp_as_mapping*/
2542 0, /*tp_hash */
2543 0, /*tp_call */
2544 0, /*tp_str */
2545 0, /*tp_getattro */
2546 0, /*tp_setattro */
2547 0, /*tp_as_buffer */
2548 Py_TPFLAGS_DEFAULT, /*tp_flags */
2549};
2550
2551static PyObject _dummy_struct = {
2552 _PyObject_EXTRA_INIT
2553 2, &_PySetDummy_Type
2554};
2555