blob: ce5092195975d56c5649c8e5fcd68c82fbdc1694 [file] [log] [blame]
Raymond Hettingerc991db22005-08-11 07:58:45 +00001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002/* set object implementation
Raymond Hettingerae7b00e2013-09-07 15:05:00 -07003
Raymond Hettingera9d99362005-08-05 00:01:15 +00004 Written and maintained by Raymond D. Hettinger <python@rcn.com>
5 Derived from Lib/sets.py and Objects/dictobject.c.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00006
Raymond Hettingerae7b00e2013-09-07 15:05:00 -07007 The basic lookup function used by all operations.
8 This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
9
10 The initial probe index is computed as hash mod the table size.
11 Subsequent probe indices are computed as explained in Objects/dictobject.c.
12
13 To improve cache locality, each probe inspects a series of consecutive
14 nearby entries before moving on to probes elsewhere in memory. This leaves
Raymond Hettinger64263df2017-09-04 18:54:16 -070015 us with a hybrid of linear probing and randomized probing. The linear probing
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070016 reduces the cost of hash collisions because consecutive memory accesses
17 tend to be much cheaper than scattered probes. After LINEAR_PROBES steps,
Raymond Hettinger64263df2017-09-04 18:54:16 -070018 we then use more of the upper bits from the hash value and apply a simple
19 linear congruential random number genearator. This helps break-up long
20 chains of collisions.
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070021
22 All arithmetic on hash should ignore overflow.
23
Raymond Hettinger4d45c102015-01-25 16:27:40 -080024 Unlike the dictionary implementation, the lookkey function can return
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070025 NULL if the rich comparison returns an error.
Serhiy Storchaka13ad3b72017-09-14 09:38:36 +030026
Raymond Hettinger64263df2017-09-04 18:54:16 -070027 Use cases for sets differ considerably from dictionaries where looked-up
28 keys are more likely to be present. In contrast, sets are primarily
29 about membership testing where the presence of an element is not known in
30 advance. Accordingly, the set implementation needs to optimize for both
31 the found and not-found case.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000032*/
33
Raymond Hettingera690a992003-11-16 16:17:49 +000034#include "Python.h"
Victor Stinner27e2d1f2018-11-01 00:52:28 +010035#include "pycore_state.h"
Raymond Hettingera9d99362005-08-05 00:01:15 +000036#include "structmember.h"
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000037
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000038/* Object used as dummy key to fill deleted entries */
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -050039static PyObject _dummy_struct;
40
41#define dummy (&_dummy_struct)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000042
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000043
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -070044/* ======================================================================== */
45/* ======= Begin logic for probing the hash table ========================= */
46
Raymond Hettinger710a67e2013-09-21 20:17:31 -070047/* Set this to zero to turn-off linear probing */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070048#ifndef LINEAR_PROBES
Raymond Hettinger742d8712013-09-08 00:25:57 -070049#define LINEAR_PROBES 9
Raymond Hettinger8408dc52013-09-15 14:57:15 -070050#endif
Raymond Hettinger742d8712013-09-08 00:25:57 -070051
52/* This must be >= 1 */
53#define PERTURB_SHIFT 5
54
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000055static setentry *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020056set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000057{
Raymond Hettinger70559b52015-07-23 07:42:23 -040058 setentry *table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020059 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070060 size_t perturb;
Raymond Hettingerafe89092013-08-28 20:59:31 -070061 size_t mask = so->mask;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -080062 size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070063 size_t j;
Raymond Hettinger4ef05282013-09-21 15:39:49 -070064 int cmp;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000065
Raymond Hettinger70559b52015-07-23 07:42:23 -040066 entry = &so->table[i];
Raymond Hettingerafe89092013-08-28 20:59:31 -070067 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068 return entry;
Raymond Hettinger237b34b2013-08-17 02:31:53 -070069
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070070 perturb = hash;
71
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -070072 while (1) {
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080073 if (entry->hash == hash) {
Raymond Hettingerafe89092013-08-28 20:59:31 -070074 PyObject *startkey = entry->key;
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080075 /* startkey cannot be a dummy because the dummy hash field is -1 */
76 assert(startkey != dummy);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -080077 if (startkey == key)
78 return entry;
Raymond Hettinger93035c42015-01-25 16:12:49 -080079 if (PyUnicode_CheckExact(startkey)
80 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -070081 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger93035c42015-01-25 16:12:49 -080082 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -040083 table = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 Py_INCREF(startkey);
85 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
86 Py_DECREF(startkey);
Raymond Hettinger426d9952014-05-18 21:40:20 +010087 if (cmp < 0) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000088 return NULL;
Raymond Hettinger426d9952014-05-18 21:40:20 +010089 if (table != so->table || entry->key != startkey) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 return set_lookkey(so, key, hash);
Raymond Hettinger426d9952014-05-18 21:40:20 +010091 if (cmp > 0) /* likely */
Raymond Hettingerafe89092013-08-28 20:59:31 -070092 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -060093 mask = so->mask; /* help avoid a register spill */
Raymond Hettingerafe89092013-08-28 20:59:31 -070094 }
Raymond Hettingerafe89092013-08-28 20:59:31 -070095
Raymond Hettingerc658d852015-02-02 08:35:00 -080096 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -080097 for (j = 0 ; j < LINEAR_PROBES ; j++) {
Raymond Hettingerc658d852015-02-02 08:35:00 -080098 entry++;
Raymond Hettinger8651a502015-05-27 10:37:20 -070099 if (entry->hash == 0 && entry->key == NULL)
100 return entry;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800101 if (entry->hash == hash) {
102 PyObject *startkey = entry->key;
103 assert(startkey != dummy);
104 if (startkey == key)
105 return entry;
106 if (PyUnicode_CheckExact(startkey)
107 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700108 && _PyUnicode_EQ(startkey, key))
Raymond Hettingerc658d852015-02-02 08:35:00 -0800109 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400110 table = so->table;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800111 Py_INCREF(startkey);
112 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
113 Py_DECREF(startkey);
114 if (cmp < 0)
115 return NULL;
116 if (table != so->table || entry->key != startkey)
117 return set_lookkey(so, key, hash);
118 if (cmp > 0)
119 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -0600120 mask = so->mask;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800121 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700122 }
123 }
124
125 perturb >>= PERTURB_SHIFT;
126 i = (i * 5 + 1 + perturb) & mask;
127
Raymond Hettinger70559b52015-07-23 07:42:23 -0400128 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700129 if (entry->key == NULL)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700130 return entry;
131 }
132}
133
Raymond Hettinger15f08692015-07-03 17:21:17 -0700134static int set_table_resize(PySetObject *, Py_ssize_t);
135
Raymond Hettinger8651a502015-05-27 10:37:20 -0700136static int
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400137set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700138{
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400139 setentry *table;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700140 setentry *freeslot;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700141 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700142 size_t perturb;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400143 size_t mask;
144 size_t i; /* Unsigned for defined overflow behavior */
Raymond Hettinger8651a502015-05-27 10:37:20 -0700145 size_t j;
146 int cmp;
147
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400148 /* Pre-increment is necessary to prevent arbitrary code in the rich
149 comparison from deallocating the key just before the insertion. */
150 Py_INCREF(key);
151
152 restart:
153
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400154 mask = so->mask;
155 i = (size_t)hash & mask;
156
Raymond Hettinger70559b52015-07-23 07:42:23 -0400157 entry = &so->table[i];
Raymond Hettinger8651a502015-05-27 10:37:20 -0700158 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700159 goto found_unused;
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700160
161 freeslot = NULL;
162 perturb = hash;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700163
164 while (1) {
165 if (entry->hash == hash) {
166 PyObject *startkey = entry->key;
167 /* startkey cannot be a dummy because the dummy hash field is -1 */
168 assert(startkey != dummy);
169 if (startkey == key)
170 goto found_active;
171 if (PyUnicode_CheckExact(startkey)
172 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700173 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700174 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400175 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700176 Py_INCREF(startkey);
177 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
178 Py_DECREF(startkey);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700179 if (cmp > 0) /* likely */
180 goto found_active;
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700181 if (cmp < 0)
182 goto comparison_error;
183 /* Continuing the search from the current entry only makes
184 sense if the table and entry are unchanged; otherwise,
185 we have to restart from the beginning */
186 if (table != so->table || entry->key != startkey)
187 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700188 mask = so->mask; /* help avoid a register spill */
189 }
Raymond Hettinger33299922018-01-14 10:20:13 -0800190 else if (entry->hash == -1)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700191 freeslot = entry;
192
193 if (i + LINEAR_PROBES <= mask) {
194 for (j = 0 ; j < LINEAR_PROBES ; j++) {
195 entry++;
196 if (entry->hash == 0 && entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700197 goto found_unused_or_dummy;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700198 if (entry->hash == hash) {
199 PyObject *startkey = entry->key;
200 assert(startkey != dummy);
201 if (startkey == key)
202 goto found_active;
203 if (PyUnicode_CheckExact(startkey)
204 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700205 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700206 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400207 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700208 Py_INCREF(startkey);
209 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
210 Py_DECREF(startkey);
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700211 if (cmp > 0)
212 goto found_active;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700213 if (cmp < 0)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400214 goto comparison_error;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700215 if (table != so->table || entry->key != startkey)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400216 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700217 mask = so->mask;
218 }
Raymond Hettinger33299922018-01-14 10:20:13 -0800219 else if (entry->hash == -1)
Raymond Hettingerc658d852015-02-02 08:35:00 -0800220 freeslot = entry;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700221 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700223
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700224 perturb >>= PERTURB_SHIFT;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -0800225 i = (i * 5 + 1 + perturb) & mask;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700226
Raymond Hettinger70559b52015-07-23 07:42:23 -0400227 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700228 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700229 goto found_unused_or_dummy;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700231
Raymond Hettinger15f08692015-07-03 17:21:17 -0700232 found_unused_or_dummy:
233 if (freeslot == NULL)
234 goto found_unused;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700235 so->used++;
236 freeslot->key = key;
237 freeslot->hash = hash;
238 return 0;
239
240 found_unused:
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700241 so->fill++;
242 so->used++;
243 entry->key = key;
244 entry->hash = hash;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800245 if ((size_t)so->fill*5 < mask*3)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700246 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +0900247 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700248
249 found_active:
Raymond Hettinger482c05c2015-07-20 01:23:32 -0400250 Py_DECREF(key);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700251 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000252
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400253 comparison_error:
Raymond Hettinger061091a2015-07-15 23:54:02 -0700254 Py_DECREF(key);
255 return -1;
256}
257
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000258/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000259Internal routine used by set_table_resize() to insert an item which is
260known to be absent from the set. This routine also assumes that
261the set contains no deleted entries. Besides the performance benefit,
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800262there is also safety benefit since using set_add_entry() risks making
263a callback in the middle of a set_table_resize(), see issue 1456209.
264The caller is responsible for updating the key's reference count and
265the setobject's fill and used fields.
Thomas Wouters89f507f2006-12-13 04:49:30 +0000266*/
267static void
Raymond Hettinger5088f602015-12-13 18:45:01 -0800268set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000269{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200270 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700271 size_t perturb = hash;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800272 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700273 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000274
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700275 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800276 entry = &table[i];
277 if (entry->key == NULL)
278 goto found_null;
279 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800280 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800281 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800282 if (entry->key == NULL)
283 goto found_null;
284 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700285 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700286 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800287 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700289 found_null:
Raymond Hettinger5088f602015-12-13 18:45:01 -0800290 entry->key = key;
Raymond Hettinger86d322f2015-12-13 19:27:17 -0800291 entry->hash = hash;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000292}
293
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700294/* ======== End logic for probing the hash table ========================== */
295/* ======================================================================== */
296
Thomas Wouters89f507f2006-12-13 04:49:30 +0000297/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000298Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000299keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000300actually be smaller than the old one.
301*/
302static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000303set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000304{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 setentry *oldtable, *newtable, *entry;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800306 Py_ssize_t oldmask = so->mask;
307 size_t newmask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 int is_oldtable_malloced;
309 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 assert(minused >= 0);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100314 /* XXX speed-up with intrinsics */
Sergey Fedoseev6c7d67c2018-09-12 04:18:01 +0500315 size_t newsize = PySet_MINSIZE;
316 while (newsize <= (size_t)minused) {
317 newsize <<= 1; // The largest possible value is PY_SSIZE_T_MAX + 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 /* Get space for a new table. */
321 oldtable = so->table;
322 assert(oldtable != NULL);
323 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325 if (newsize == PySet_MINSIZE) {
326 /* A large table is shrinking, or we can't get any smaller. */
327 newtable = so->smalltable;
328 if (newtable == oldtable) {
329 if (so->fill == so->used) {
330 /* No dummies, so no point doing anything. */
331 return 0;
332 }
333 /* We're not going to resize it, but rebuild the
334 table anyway to purge old dummy entries.
335 Subtle: This is *necessary* if fill==size,
336 as set_lookkey needs at least one virgin slot to
337 terminate failing searches. If fill < size, it's
338 merely desirable, as dummies slow searches. */
339 assert(so->fill > so->used);
340 memcpy(small_copy, oldtable, sizeof(small_copy));
341 oldtable = small_copy;
342 }
343 }
344 else {
345 newtable = PyMem_NEW(setentry, newsize);
346 if (newtable == NULL) {
347 PyErr_NoMemory();
348 return -1;
349 }
350 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 /* Make the set empty, using the new table. */
353 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 memset(newtable, 0, sizeof(setentry) * newsize);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800355 so->mask = newsize - 1;
356 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000358 /* Copy the data over; this is refcount-neutral for active entries;
359 dummy entries aren't copied over, of course */
Raymond Hettinger5088f602015-12-13 18:45:01 -0800360 newmask = (size_t)so->mask;
Raymond Hettingere1af6962017-02-02 08:24:48 -0800361 if (so->fill == so->used) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800362 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800363 if (entry->key != NULL) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800364 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800365 }
366 }
367 } else {
Raymond Hettingere1af6962017-02-02 08:24:48 -0800368 so->fill = so->used;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800369 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800370 if (entry->key != NULL && entry->key != dummy) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800371 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800372 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 }
374 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376 if (is_oldtable_malloced)
377 PyMem_DEL(oldtable);
378 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000379}
380
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000381static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700382set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000383{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700384 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000385
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700386 entry = set_lookkey(so, key, hash);
387 if (entry != NULL)
388 return entry->key != NULL;
389 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000390}
391
392#define DISCARD_NOTFOUND 0
393#define DISCARD_FOUND 1
394
395static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700396set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800397{
398 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000400
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700401 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 if (entry == NULL)
403 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700404 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 return DISCARD_NOTFOUND;
406 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800408 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 so->used--;
410 Py_DECREF(old_key);
411 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000412}
413
414static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700415set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000416{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200417 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000418
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700419 if (!PyUnicode_CheckExact(key) ||
420 (hash = ((PyASCIIObject *) key)->hash) == -1) {
421 hash = PyObject_Hash(key);
422 if (hash == -1)
423 return -1;
424 }
425 return set_add_entry(so, key, hash);
426}
427
428static int
429set_contains_key(PySetObject *so, PyObject *key)
430{
431 Py_hash_t hash;
432
433 if (!PyUnicode_CheckExact(key) ||
434 (hash = ((PyASCIIObject *) key)->hash) == -1) {
435 hash = PyObject_Hash(key);
436 if (hash == -1)
437 return -1;
438 }
439 return set_contains_entry(so, key, hash);
440}
441
442static int
443set_discard_key(PySetObject *so, PyObject *key)
444{
445 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200448 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 hash = PyObject_Hash(key);
450 if (hash == -1)
451 return -1;
452 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700453 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000454}
455
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700456static void
457set_empty_to_minsize(PySetObject *so)
458{
459 memset(so->smalltable, 0, sizeof(so->smalltable));
460 so->fill = 0;
461 so->used = 0;
462 so->mask = PySet_MINSIZE - 1;
463 so->table = so->smalltable;
464 so->hash = -1;
465}
466
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000467static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000468set_clear_internal(PySetObject *so)
469{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800470 setentry *entry;
471 setentry *table = so->table;
472 Py_ssize_t fill = so->fill;
473 Py_ssize_t used = so->used;
474 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000476
Raymond Hettinger583cd032013-09-07 22:06:35 -0700477 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 /* This is delicate. During the process of clearing the set,
481 * decrefs can cause the set to mutate. To avoid fatal confusion
482 * (voice of experience), we have to make the set empty before
483 * clearing the slots, and never refer to anything via so->ref while
484 * clearing.
485 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700487 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 else if (fill > 0) {
490 /* It's a small table with something that needs to be cleared.
491 * Afraid the only safe way is to copy the set entries into
492 * another small table first.
493 */
494 memcpy(small_copy, table, sizeof(small_copy));
495 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700496 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 }
498 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500 /* Now we can finally clear things. If C had refcounts, we could
501 * assert that the refcount on table is 1 now, i.e. that this function
502 * has unique access to it, so decref side-effects can't alter it.
503 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800504 for (entry = table; used > 0; entry++) {
505 if (entry->key && entry->key != dummy) {
506 used--;
507 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 if (table_is_malloced)
512 PyMem_DEL(table);
513 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000514}
515
516/*
517 * Iterate over a set table. Use like so:
518 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000519 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000520 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000521 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000522 * while (set_next(yourset, &pos, &entry)) {
523 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000524 * }
525 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000526 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000528 */
529static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000530set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000531{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 Py_ssize_t i;
533 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700534 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 assert (PyAnySet_Check(so));
537 i = *pos_ptr;
538 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700540 entry = &so->table[i];
541 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700543 entry++;
544 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 *pos_ptr = i+1;
546 if (i > mask)
547 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700548 assert(entry != NULL);
549 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000551}
552
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000553static void
554set_dealloc(PySetObject *so)
555{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200556 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800557 Py_ssize_t used = so->used;
558
INADA Naokia6296d32017-08-24 14:55:17 +0900559 /* bpo-31095: UnTrack is needed before calling any callbacks */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000560 PyObject_GC_UnTrack(so);
561 Py_TRASHCAN_SAFE_BEGIN(so)
562 if (so->weakreflist != NULL)
563 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000564
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800565 for (entry = so->table; used > 0; entry++) {
566 if (entry->key && entry->key != dummy) {
567 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700568 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 }
570 }
571 if (so->table != so->smalltable)
572 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700573 Py_TYPE(so)->tp_free(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000574 Py_TRASHCAN_SAFE_END(so)
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000575}
576
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000577static PyObject *
578set_repr(PySetObject *so)
579{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200580 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583 if (status != 0) {
584 if (status < 0)
585 return NULL;
586 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
587 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000588
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000589 /* shortcut for the empty set */
590 if (!so->used) {
591 Py_ReprLeave((PyObject*)so);
592 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
593 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 keys = PySequence_List((PyObject *)so);
596 if (keys == NULL)
597 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000598
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200599 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 listrepr = PyObject_Repr(keys);
601 Py_DECREF(keys);
602 if (listrepr == NULL)
603 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200604 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200606 if (tmp == NULL)
607 goto done;
608 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200609
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200610 if (Py_TYPE(so) != &PySet_Type)
611 result = PyUnicode_FromFormat("%s({%U})",
612 Py_TYPE(so)->tp_name,
613 listrepr);
614 else
615 result = PyUnicode_FromFormat("{%U}", listrepr);
616 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000617done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618 Py_ReprLeave((PyObject*)so);
619 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000620}
621
Martin v. Löwis18e16552006-02-15 17:27:45 +0000622static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000623set_len(PyObject *so)
624{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000625 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000626}
627
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000628static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000629set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000630{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000632 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200633 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700634 setentry *so_entry;
635 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 assert (PyAnySet_Check(so));
638 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 other = (PySetObject*)otherset;
641 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700642 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 return 0;
644 /* Do one big resize at the start, rather than
645 * incrementally resizing as we insert new keys. Expect
646 * that there will be no (or few) overlapping keys.
647 */
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800648 if ((so->fill + other->used)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900649 if (set_table_resize(so, (so->used + other->used)*2) != 0)
650 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000651 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700652 so_entry = so->table;
653 other_entry = other->table;
654
655 /* If our table is empty, and both tables have the same size, and
656 there are no dummies to eliminate, then just copy the pointers. */
657 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
658 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
659 key = other_entry->key;
660 if (key != NULL) {
661 assert(so_entry->key == NULL);
662 Py_INCREF(key);
663 so_entry->key = key;
664 so_entry->hash = other_entry->hash;
665 }
666 }
667 so->fill = other->fill;
668 so->used = other->used;
669 return 0;
670 }
671
672 /* If our table is empty, we can use set_insert_clean() */
673 if (so->fill == 0) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800674 setentry *newtable = so->table;
675 size_t newmask = (size_t)so->mask;
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800676 so->fill = other->used;
677 so->used = other->used;
Raymond Hettingere4495872015-12-15 00:42:30 -0800678 for (i = other->mask + 1; i > 0 ; i--, other_entry++) {
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700679 key = other_entry->key;
680 if (key != NULL && key != dummy) {
681 Py_INCREF(key);
Raymond Hettinger5088f602015-12-13 18:45:01 -0800682 set_insert_clean(newtable, newmask, key, other_entry->hash);
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700683 }
684 }
685 return 0;
686 }
687
688 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700689 for (i = 0; i <= other->mask; i++) {
690 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700691 key = other_entry->key;
692 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700693 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000694 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 }
696 }
697 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000698}
699
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000700static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530701set_pop(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000702{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800703 /* Make sure the search finger is in bounds */
Raymond Hettingercf5863f2018-11-09 02:31:56 -0800704 setentry *entry, *limit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000705 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000706
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 assert (PyAnySet_Check(so));
708 if (so->used == 0) {
709 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
710 return NULL;
711 }
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000712
Raymond Hettingercf5863f2018-11-09 02:31:56 -0800713 entry = so->table + (so->finger & so->mask);
714 limit = so->table + so->mask;
715 while (entry->key == NULL || entry->key==dummy) {
716 entry++;
717 if (entry > limit)
718 entry = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 }
720 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800722 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 so->used--;
Raymond Hettingercf5863f2018-11-09 02:31:56 -0800724 so->finger = entry - so->table + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000726}
727
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000728PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
729Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000730
731static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000732set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000733{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 Py_ssize_t pos = 0;
735 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000736
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000737 while (set_next(so, &pos, &entry))
738 Py_VISIT(entry->key);
739 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000740}
741
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700742/* Work to increase the bit dispersion for closely spaced hash values.
743 This is important because some use cases have many combinations of a
744 small number of elements with nearby hashes so that many distinct
745 combinations collapse to only a handful of distinct hash values. */
746
747static Py_uhash_t
748_shuffle_bits(Py_uhash_t h)
749{
750 return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
751}
752
753/* Most of the constants in this hash algorithm are randomly chosen
754 large primes with "interesting bit patterns" and that passed tests
755 for good collision statistics on a variety of problematic datasets
756 including powersets and graph structures (such as David Eppstein's
757 graph recipes in Lib/test/test_set.py) */
758
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000759static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000760frozenset_hash(PyObject *self)
761{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 PySetObject *so = (PySetObject *)self;
Raymond Hettinger41481952015-08-07 00:43:39 -0700763 Py_uhash_t hash = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000764 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000765
Raymond Hettingerb501a272015-08-06 22:15:22 -0700766 if (so->hash != -1)
767 return so->hash;
768
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700769 /* Xor-in shuffled bits from every entry's hash field because xor is
770 commutative and a frozenset hash should be independent of order.
771
772 For speed, include null entries and dummy entries and then
773 subtract out their effect afterwards so that the final hash
774 depends only on active entries. This allows the code to be
775 vectorized by the compiler and it saves the unpredictable
776 branches that would arise when trying to exclude null and dummy
777 entries on every iteration. */
778
779 for (entry = so->table; entry <= &so->table[so->mask]; entry++)
780 hash ^= _shuffle_bits(entry->hash);
781
Raymond Hettingera286a512015-08-01 11:07:11 -0700782 /* Remove the effect of an odd number of NULL entries */
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700783 if ((so->mask + 1 - so->fill) & 1)
784 hash ^= _shuffle_bits(0);
785
786 /* Remove the effect of an odd number of dummy entries */
787 if ((so->fill - so->used) & 1)
788 hash ^= _shuffle_bits(-1);
789
Raymond Hettinger41481952015-08-07 00:43:39 -0700790 /* Factor in the number of active entries */
791 hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;
792
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700793 /* Disperse patterns arising in nested frozensets */
Raymond Hettingerfa788062018-01-18 13:23:27 -0800794 hash ^= (hash >> 11) ^ (hash >> 25);
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800795 hash = hash * 69069U + 907133923UL;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700796
Raymond Hettinger36c05002015-08-01 10:57:42 -0700797 /* -1 is reserved as an error code */
Victor Stinner12174a52014-08-15 23:17:38 +0200798 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800799 hash = 590923713UL;
Raymond Hettinger36c05002015-08-01 10:57:42 -0700800
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000801 so->hash = hash;
802 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000803}
804
Raymond Hettingera9d99362005-08-05 00:01:15 +0000805/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000806
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000807typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000808 PyObject_HEAD
809 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
810 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700811 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000812 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000813} setiterobject;
814
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000815static void
816setiter_dealloc(setiterobject *si)
817{
INADA Naokia6296d32017-08-24 14:55:17 +0900818 /* bpo-31095: UnTrack is needed before calling any callbacks */
819 _PyObject_GC_UNTRACK(si);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000820 Py_XDECREF(si->si_set);
821 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000822}
823
824static int
825setiter_traverse(setiterobject *si, visitproc visit, void *arg)
826{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000827 Py_VISIT(si->si_set);
828 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000829}
830
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000831static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530832setiter_len(setiterobject *si, PyObject *Py_UNUSED(ignored))
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000833{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000834 Py_ssize_t len = 0;
835 if (si->si_set != NULL && si->si_used == si->si_set->used)
836 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000837 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000838}
839
Armin Rigof5b3e362006-02-11 21:32:43 +0000840PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000841
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000842static PyObject *setiter_iternext(setiterobject *si);
843
844static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530845setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000846{
Ezio Melotti0e1af282012-09-28 16:43:40 +0300847 /* copy the iterator state */
Sergey Fedoseev63958442018-10-20 05:43:33 +0500848 setiterobject tmp = *si;
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000849 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300850
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000851 /* iterate the temporary into a list */
Sergey Fedoseev63958442018-10-20 05:43:33 +0500852 PyObject *list = PySequence_List((PyObject*)&tmp);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000853 Py_XDECREF(tmp.si_set);
Sergey Fedoseev63958442018-10-20 05:43:33 +0500854 if (list == NULL) {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000855 return NULL;
856 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200857 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000858}
859
860PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
861
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000862static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000863 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000864 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000865 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000866};
867
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000868static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000869{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700870 PyObject *key;
871 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200872 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000873 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000875 if (so == NULL)
876 return NULL;
877 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000878
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000879 if (si->si_used != so->used) {
880 PyErr_SetString(PyExc_RuntimeError,
881 "Set changed size during iteration");
882 si->si_used = -1; /* Make this state sticky */
883 return NULL;
884 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700885
886 i = si->si_pos;
887 assert(i>=0);
888 entry = so->table;
889 mask = so->mask;
890 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
891 i++;
892 si->si_pos = i+1;
893 if (i > mask)
894 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000895 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700896 key = entry[i].key;
897 Py_INCREF(key);
898 return key;
899
900fail:
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700901 si->si_set = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +0300902 Py_DECREF(so);
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700903 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000904}
905
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000906PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000907 PyVarObject_HEAD_INIT(&PyType_Type, 0)
908 "set_iterator", /* tp_name */
909 sizeof(setiterobject), /* tp_basicsize */
910 0, /* tp_itemsize */
911 /* methods */
912 (destructor)setiter_dealloc, /* tp_dealloc */
913 0, /* tp_print */
914 0, /* tp_getattr */
915 0, /* tp_setattr */
916 0, /* tp_reserved */
917 0, /* tp_repr */
918 0, /* tp_as_number */
919 0, /* tp_as_sequence */
920 0, /* tp_as_mapping */
921 0, /* tp_hash */
922 0, /* tp_call */
923 0, /* tp_str */
924 PyObject_GenericGetAttr, /* tp_getattro */
925 0, /* tp_setattro */
926 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700927 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000928 0, /* tp_doc */
929 (traverseproc)setiter_traverse, /* tp_traverse */
930 0, /* tp_clear */
931 0, /* tp_richcompare */
932 0, /* tp_weaklistoffset */
933 PyObject_SelfIter, /* tp_iter */
934 (iternextfunc)setiter_iternext, /* tp_iternext */
935 setiter_methods, /* tp_methods */
936 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000937};
938
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000939static PyObject *
940set_iter(PySetObject *so)
941{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000942 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
943 if (si == NULL)
944 return NULL;
945 Py_INCREF(so);
946 si->si_set = so;
947 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700948 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 si->len = so->used;
950 _PyObject_GC_TRACK(si);
951 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000952}
953
Raymond Hettingerd7946662005-08-01 21:39:29 +0000954static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000955set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000959 if (PyAnySet_Check(other))
960 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000961
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000962 if (PyDict_CheckExact(other)) {
963 PyObject *value;
964 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000965 Py_hash_t hash;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200966 Py_ssize_t dictsize = PyDict_GET_SIZE(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000967
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000968 /* Do one big resize at the start, rather than
969 * incrementally resizing as we insert new keys. Expect
970 * that there will be no (or few) overlapping keys.
971 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700972 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 return -1;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800974 if ((so->fill + dictsize)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900975 if (set_table_resize(so, (so->used + dictsize)*2) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000976 return -1;
977 }
978 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700979 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000980 return -1;
981 }
982 return 0;
983 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000984
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 it = PyObject_GetIter(other);
986 if (it == NULL)
987 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +0000988
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700990 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000991 Py_DECREF(it);
992 Py_DECREF(key);
993 return -1;
994 }
995 Py_DECREF(key);
996 }
997 Py_DECREF(it);
998 if (PyErr_Occurred())
999 return -1;
1000 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001001}
1002
1003static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001004set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001005{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1009 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001010 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001011 return NULL;
1012 }
1013 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001014}
1015
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001017"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001018
Raymond Hettinger426d9952014-05-18 21:40:20 +01001019/* XXX Todo:
1020 If aligned memory allocations become available, make the
1021 set object 64 byte aligned so that most of the fields
1022 can be retrieved or updated in a single cache line.
1023*/
1024
Raymond Hettingera38123e2003-11-24 22:18:49 +00001025static PyObject *
1026make_new_set(PyTypeObject *type, PyObject *iterable)
1027{
Raymond Hettinger8421d712016-04-29 01:37:05 -07001028 PySetObject *so;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001029
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001030 so = (PySetObject *)type->tp_alloc(type, 0);
1031 if (so == NULL)
1032 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001033
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001034 so->fill = 0;
1035 so->used = 0;
1036 so->mask = PySet_MINSIZE - 1;
1037 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001038 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001039 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001040 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001043 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001044 Py_DECREF(so);
1045 return NULL;
1046 }
1047 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001048
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001050}
1051
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001052static PyObject *
1053make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1054{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1056 if (PyType_IsSubtype(type, &PySet_Type))
1057 type = &PySet_Type;
1058 else
1059 type = &PyFrozenSet_Type;
1060 }
1061 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001062}
1063
Raymond Hettingerd7946662005-08-01 21:39:29 +00001064/* The empty frozenset is a singleton */
1065static PyObject *emptyfrozenset = NULL;
1066
Raymond Hettingera690a992003-11-16 16:17:49 +00001067static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001068frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001069{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001071
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001072 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001074
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001075 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1076 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001078 if (type != &PyFrozenSet_Type)
1079 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001080
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001081 if (iterable != NULL) {
1082 /* frozenset(f) is idempotent */
1083 if (PyFrozenSet_CheckExact(iterable)) {
1084 Py_INCREF(iterable);
1085 return iterable;
1086 }
1087 result = make_new_set(type, iterable);
1088 if (result == NULL || PySet_GET_SIZE(result))
1089 return result;
1090 Py_DECREF(result);
1091 }
1092 /* The empty frozenset is a singleton */
1093 if (emptyfrozenset == NULL)
1094 emptyfrozenset = make_new_set(type, NULL);
1095 Py_XINCREF(emptyfrozenset);
1096 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001097}
1098
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001099static PyObject *
1100set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1101{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001103}
1104
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001105/* set_swap_bodies() switches the contents of any two sets by moving their
1106 internal data pointers and, if needed, copying the internal smalltables.
1107 Semantically equivalent to:
1108
1109 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1110
1111 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001112 Useful for operations that update in-place (by allowing an intermediate
1113 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001114*/
1115
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001116static void
1117set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001118{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001119 Py_ssize_t t;
1120 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001121 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001122 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001124 t = a->fill; a->fill = b->fill; b->fill = t;
1125 t = a->used; a->used = b->used; b->used = t;
1126 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001127
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001128 u = a->table;
1129 if (a->table == a->smalltable)
1130 u = b->smalltable;
1131 a->table = b->table;
1132 if (b->table == b->smalltable)
1133 a->table = a->smalltable;
1134 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 if (a->table == a->smalltable || b->table == b->smalltable) {
1137 memcpy(tab, a->smalltable, sizeof(tab));
1138 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1139 memcpy(b->smalltable, tab, sizeof(tab));
1140 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1143 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1144 h = a->hash; a->hash = b->hash; b->hash = h;
1145 } else {
1146 a->hash = -1;
1147 b->hash = -1;
1148 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001149}
1150
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001151static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301152set_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001153{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001154 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001155}
1156
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001157static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301158frozenset_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001159{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001160 if (PyFrozenSet_CheckExact(so)) {
1161 Py_INCREF(so);
1162 return (PyObject *)so;
1163 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301164 return set_copy(so, NULL);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001165}
1166
Raymond Hettingera690a992003-11-16 16:17:49 +00001167PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1168
1169static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301170set_clear(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc991db22005-08-11 07:58:45 +00001171{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 set_clear_internal(so);
1173 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001174}
1175
1176PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1177
1178static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001179set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001181 PySetObject *result;
1182 PyObject *other;
1183 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001184
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301185 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 if (result == NULL)
1187 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1190 other = PyTuple_GET_ITEM(args, i);
1191 if ((PyObject *)so == other)
1192 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001193 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001194 Py_DECREF(result);
1195 return NULL;
1196 }
1197 }
1198 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001199}
1200
1201PyDoc_STRVAR(union_doc,
1202 "Return the union of sets as a new set.\n\
1203\n\
1204(i.e. all elements that are in either set.)");
1205
1206static PyObject *
1207set_or(PySetObject *so, PyObject *other)
1208{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001210
Brian Curtindfc80e32011-08-10 20:28:54 -05001211 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1212 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001213
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301214 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001215 if (result == NULL)
1216 return NULL;
1217 if ((PyObject *)so == other)
1218 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001219 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001220 Py_DECREF(result);
1221 return NULL;
1222 }
1223 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001224}
1225
Raymond Hettingera690a992003-11-16 16:17:49 +00001226static PyObject *
1227set_ior(PySetObject *so, PyObject *other)
1228{
Brian Curtindfc80e32011-08-10 20:28:54 -05001229 if (!PyAnySet_Check(other))
1230 Py_RETURN_NOTIMPLEMENTED;
1231
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001232 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001233 return NULL;
1234 Py_INCREF(so);
1235 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001236}
1237
1238static PyObject *
1239set_intersection(PySetObject *so, PyObject *other)
1240{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 PySetObject *result;
1242 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001243 Py_hash_t hash;
1244 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301247 return set_copy(so, NULL);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1250 if (result == NULL)
1251 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 if (PyAnySet_Check(other)) {
1254 Py_ssize_t pos = 0;
1255 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1258 tmp = (PyObject *)so;
1259 so = (PySetObject *)other;
1260 other = tmp;
1261 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001264 key = entry->key;
1265 hash = entry->hash;
1266 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001267 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 Py_DECREF(result);
1269 return NULL;
1270 }
1271 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001272 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 Py_DECREF(result);
1274 return NULL;
1275 }
1276 }
1277 }
1278 return (PyObject *)result;
1279 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 it = PyObject_GetIter(other);
1282 if (it == NULL) {
1283 Py_DECREF(result);
1284 return NULL;
1285 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001288 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001289 if (hash == -1)
1290 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001291 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001292 if (rv < 0)
1293 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001295 if (set_add_entry(result, key, hash))
1296 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 }
1298 Py_DECREF(key);
1299 }
1300 Py_DECREF(it);
1301 if (PyErr_Occurred()) {
1302 Py_DECREF(result);
1303 return NULL;
1304 }
1305 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001306 error:
1307 Py_DECREF(it);
1308 Py_DECREF(result);
1309 Py_DECREF(key);
1310 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001311}
1312
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001313static PyObject *
1314set_intersection_multi(PySetObject *so, PyObject *args)
1315{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 Py_ssize_t i;
1317 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301320 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 Py_INCREF(so);
1323 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1324 PyObject *other = PyTuple_GET_ITEM(args, i);
1325 PyObject *newresult = set_intersection((PySetObject *)result, other);
1326 if (newresult == NULL) {
1327 Py_DECREF(result);
1328 return NULL;
1329 }
1330 Py_DECREF(result);
1331 result = newresult;
1332 }
1333 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001334}
1335
Raymond Hettingera690a992003-11-16 16:17:49 +00001336PyDoc_STRVAR(intersection_doc,
1337"Return the intersection of two sets as a new set.\n\
1338\n\
1339(i.e. all elements that are in both sets.)");
1340
1341static PyObject *
1342set_intersection_update(PySetObject *so, PyObject *other)
1343{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346 tmp = set_intersection(so, other);
1347 if (tmp == NULL)
1348 return NULL;
1349 set_swap_bodies(so, (PySetObject *)tmp);
1350 Py_DECREF(tmp);
1351 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001352}
1353
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001354static PyObject *
1355set_intersection_update_multi(PySetObject *so, PyObject *args)
1356{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001357 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001359 tmp = set_intersection_multi(so, args);
1360 if (tmp == NULL)
1361 return NULL;
1362 set_swap_bodies(so, (PySetObject *)tmp);
1363 Py_DECREF(tmp);
1364 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001365}
1366
Raymond Hettingera690a992003-11-16 16:17:49 +00001367PyDoc_STRVAR(intersection_update_doc,
1368"Update a set with the intersection of itself and another.");
1369
1370static PyObject *
1371set_and(PySetObject *so, PyObject *other)
1372{
Brian Curtindfc80e32011-08-10 20:28:54 -05001373 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1374 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001376}
1377
1378static PyObject *
1379set_iand(PySetObject *so, PyObject *other)
1380{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001382
Brian Curtindfc80e32011-08-10 20:28:54 -05001383 if (!PyAnySet_Check(other))
1384 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385 result = set_intersection_update(so, other);
1386 if (result == NULL)
1387 return NULL;
1388 Py_DECREF(result);
1389 Py_INCREF(so);
1390 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001391}
1392
Guido van Rossum58da9312007-11-10 23:39:45 +00001393static PyObject *
1394set_isdisjoint(PySetObject *so, PyObject *other)
1395{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001397 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399 if ((PyObject *)so == other) {
1400 if (PySet_GET_SIZE(so) == 0)
1401 Py_RETURN_TRUE;
1402 else
1403 Py_RETURN_FALSE;
1404 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001406 if (PyAnySet_CheckExact(other)) {
1407 Py_ssize_t pos = 0;
1408 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001410 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1411 tmp = (PyObject *)so;
1412 so = (PySetObject *)other;
1413 other = tmp;
1414 }
1415 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001416 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001417 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 return NULL;
1419 if (rv)
1420 Py_RETURN_FALSE;
1421 }
1422 Py_RETURN_TRUE;
1423 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 it = PyObject_GetIter(other);
1426 if (it == NULL)
1427 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001430 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 if (hash == -1) {
1433 Py_DECREF(key);
1434 Py_DECREF(it);
1435 return NULL;
1436 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001437 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001439 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 Py_DECREF(it);
1441 return NULL;
1442 }
1443 if (rv) {
1444 Py_DECREF(it);
1445 Py_RETURN_FALSE;
1446 }
1447 }
1448 Py_DECREF(it);
1449 if (PyErr_Occurred())
1450 return NULL;
1451 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001452}
1453
1454PyDoc_STRVAR(isdisjoint_doc,
1455"Return True if two sets have a null intersection.");
1456
Neal Norwitz6576bd82005-11-13 18:41:28 +00001457static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001458set_difference_update_internal(PySetObject *so, PyObject *other)
1459{
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001460 if (PySet_GET_SIZE(so) == 0) {
1461 return 0;
1462 }
1463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 if ((PyObject *)so == other)
1465 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001467 if (PyAnySet_Check(other)) {
1468 setentry *entry;
1469 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001472 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001473 return -1;
1474 } else {
1475 PyObject *key, *it;
1476 it = PyObject_GetIter(other);
1477 if (it == NULL)
1478 return -1;
1479
1480 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001481 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001482 Py_DECREF(it);
1483 Py_DECREF(key);
1484 return -1;
1485 }
1486 Py_DECREF(key);
1487 }
1488 Py_DECREF(it);
1489 if (PyErr_Occurred())
1490 return -1;
1491 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001492 /* If more than 1/4th are dummies, then resize them away. */
1493 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +09001495 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001496}
1497
Raymond Hettingera690a992003-11-16 16:17:49 +00001498static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001499set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001500{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1504 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001505 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 return NULL;
1507 }
1508 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001509}
1510
1511PyDoc_STRVAR(difference_update_doc,
1512"Remove all elements of another set from this set.");
1513
1514static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001515set_copy_and_difference(PySetObject *so, PyObject *other)
1516{
1517 PyObject *result;
1518
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301519 result = set_copy(so, NULL);
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001520 if (result == NULL)
1521 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001522 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001523 return result;
1524 Py_DECREF(result);
1525 return NULL;
1526}
1527
1528static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001529set_difference(PySetObject *so, PyObject *other)
1530{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001532 PyObject *key;
1533 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001534 setentry *entry;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001535 Py_ssize_t pos = 0, other_size;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001536 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001537
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001538 if (PySet_GET_SIZE(so) == 0) {
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301539 return set_copy(so, NULL);
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001540 }
1541
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001542 if (PyAnySet_Check(other)) {
1543 other_size = PySet_GET_SIZE(other);
1544 }
1545 else if (PyDict_CheckExact(other)) {
1546 other_size = PyDict_GET_SIZE(other);
1547 }
1548 else {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001549 return set_copy_and_difference(so, other);
1550 }
1551
1552 /* If len(so) much more than len(other), it's more efficient to simply copy
1553 * so and then iterate other looking for common elements. */
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001554 if ((PySet_GET_SIZE(so) >> 2) > other_size) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001555 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001556 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 result = make_new_set_basetype(Py_TYPE(so), NULL);
1559 if (result == NULL)
1560 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001561
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001562 if (PyDict_CheckExact(other)) {
1563 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001564 key = entry->key;
1565 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001566 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001567 if (rv < 0) {
1568 Py_DECREF(result);
1569 return NULL;
1570 }
1571 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001572 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001573 Py_DECREF(result);
1574 return NULL;
1575 }
1576 }
1577 }
1578 return result;
1579 }
1580
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001581 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001583 key = entry->key;
1584 hash = entry->hash;
1585 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001586 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001587 Py_DECREF(result);
1588 return NULL;
1589 }
1590 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001591 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001592 Py_DECREF(result);
1593 return NULL;
1594 }
1595 }
1596 }
1597 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001598}
1599
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001600static PyObject *
1601set_difference_multi(PySetObject *so, PyObject *args)
1602{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 Py_ssize_t i;
1604 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301607 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001608
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001609 other = PyTuple_GET_ITEM(args, 0);
1610 result = set_difference(so, other);
1611 if (result == NULL)
1612 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001613
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001614 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1615 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001616 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001617 Py_DECREF(result);
1618 return NULL;
1619 }
1620 }
1621 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001622}
1623
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001624PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001625"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001626\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001627(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001628static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001629set_sub(PySetObject *so, PyObject *other)
1630{
Brian Curtindfc80e32011-08-10 20:28:54 -05001631 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1632 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001634}
1635
1636static PyObject *
1637set_isub(PySetObject *so, PyObject *other)
1638{
Brian Curtindfc80e32011-08-10 20:28:54 -05001639 if (!PyAnySet_Check(other))
1640 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001641 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 return NULL;
1643 Py_INCREF(so);
1644 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001645}
1646
1647static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001648set_symmetric_difference_update(PySetObject *so, PyObject *other)
1649{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001650 PySetObject *otherset;
1651 PyObject *key;
1652 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001653 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001655 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001656
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001657 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301658 return set_clear(so, NULL);
Raymond Hettingera690a992003-11-16 16:17:49 +00001659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 if (PyDict_CheckExact(other)) {
1661 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001662 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001663 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001664 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001665 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001666 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001667 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001669 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001670 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001671 Py_DECREF(key);
1672 return NULL;
1673 }
1674 }
Georg Brandl2d444492010-09-03 10:52:55 +00001675 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001676 }
1677 Py_RETURN_NONE;
1678 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001679
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001680 if (PyAnySet_Check(other)) {
1681 Py_INCREF(other);
1682 otherset = (PySetObject *)other;
1683 } else {
1684 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1685 if (otherset == NULL)
1686 return NULL;
1687 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001688
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001689 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001690 key = entry->key;
1691 hash = entry->hash;
1692 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001693 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001694 Py_DECREF(otherset);
1695 return NULL;
1696 }
1697 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001698 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001699 Py_DECREF(otherset);
1700 return NULL;
1701 }
1702 }
1703 }
1704 Py_DECREF(otherset);
1705 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001706}
1707
1708PyDoc_STRVAR(symmetric_difference_update_doc,
1709"Update a set with the symmetric difference of itself and another.");
1710
1711static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001712set_symmetric_difference(PySetObject *so, PyObject *other)
1713{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001714 PyObject *rv;
1715 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001716
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001717 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1718 if (otherset == NULL)
1719 return NULL;
1720 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
lekma491bbed2018-05-02 11:29:10 +02001721 if (rv == NULL) {
1722 Py_DECREF(otherset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001723 return NULL;
lekma491bbed2018-05-02 11:29:10 +02001724 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001725 Py_DECREF(rv);
1726 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001727}
1728
1729PyDoc_STRVAR(symmetric_difference_doc,
1730"Return the symmetric difference of two sets as a new set.\n\
1731\n\
1732(i.e. all elements that are in exactly one of the sets.)");
1733
1734static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001735set_xor(PySetObject *so, PyObject *other)
1736{
Brian Curtindfc80e32011-08-10 20:28:54 -05001737 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1738 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001739 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001740}
1741
1742static PyObject *
1743set_ixor(PySetObject *so, PyObject *other)
1744{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001745 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001746
Brian Curtindfc80e32011-08-10 20:28:54 -05001747 if (!PyAnySet_Check(other))
1748 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001749 result = set_symmetric_difference_update(so, other);
1750 if (result == NULL)
1751 return NULL;
1752 Py_DECREF(result);
1753 Py_INCREF(so);
1754 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001755}
1756
1757static PyObject *
1758set_issubset(PySetObject *so, PyObject *other)
1759{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001760 setentry *entry;
1761 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001762 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001764 if (!PyAnySet_Check(other)) {
1765 PyObject *tmp, *result;
1766 tmp = make_new_set(&PySet_Type, other);
1767 if (tmp == NULL)
1768 return NULL;
1769 result = set_issubset(so, tmp);
1770 Py_DECREF(tmp);
1771 return result;
1772 }
1773 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1774 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001775
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001777 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001778 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 return NULL;
1780 if (!rv)
1781 Py_RETURN_FALSE;
1782 }
1783 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001784}
1785
1786PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1787
1788static PyObject *
1789set_issuperset(PySetObject *so, PyObject *other)
1790{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001791 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001792
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001793 if (!PyAnySet_Check(other)) {
1794 tmp = make_new_set(&PySet_Type, other);
1795 if (tmp == NULL)
1796 return NULL;
1797 result = set_issuperset(so, tmp);
1798 Py_DECREF(tmp);
1799 return result;
1800 }
1801 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001802}
1803
1804PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1805
Raymond Hettingera690a992003-11-16 16:17:49 +00001806static PyObject *
1807set_richcompare(PySetObject *v, PyObject *w, int op)
1808{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001809 PyObject *r1;
1810 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001811
Brian Curtindfc80e32011-08-10 20:28:54 -05001812 if(!PyAnySet_Check(w))
1813 Py_RETURN_NOTIMPLEMENTED;
1814
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001815 switch (op) {
1816 case Py_EQ:
1817 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1818 Py_RETURN_FALSE;
1819 if (v->hash != -1 &&
1820 ((PySetObject *)w)->hash != -1 &&
1821 v->hash != ((PySetObject *)w)->hash)
1822 Py_RETURN_FALSE;
1823 return set_issubset(v, w);
1824 case Py_NE:
1825 r1 = set_richcompare(v, w, Py_EQ);
1826 if (r1 == NULL)
1827 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001828 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001829 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001830 if (r2 < 0)
1831 return NULL;
1832 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001833 case Py_LE:
1834 return set_issubset(v, w);
1835 case Py_GE:
1836 return set_issuperset(v, w);
1837 case Py_LT:
1838 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1839 Py_RETURN_FALSE;
1840 return set_issubset(v, w);
1841 case Py_GT:
1842 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1843 Py_RETURN_FALSE;
1844 return set_issuperset(v, w);
1845 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001846 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001847}
1848
Raymond Hettingera690a992003-11-16 16:17:49 +00001849static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001850set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001851{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001852 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001853 return NULL;
1854 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001855}
1856
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001857PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001858"Add an element to a set.\n\
1859\n\
1860This has no effect if the element is already present.");
1861
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001862static int
1863set_contains(PySetObject *so, PyObject *key)
1864{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 PyObject *tmpkey;
1866 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001869 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001870 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1871 return -1;
1872 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001873 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001874 if (tmpkey == NULL)
1875 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001876 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 Py_DECREF(tmpkey);
1878 }
1879 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001880}
1881
1882static PyObject *
1883set_direct_contains(PySetObject *so, PyObject *key)
1884{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001888 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001889 return NULL;
1890 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001891}
1892
1893PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1894
Raymond Hettingera690a992003-11-16 16:17:49 +00001895static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001896set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001897{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001898 PyObject *tmpkey;
1899 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001902 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001903 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1904 return NULL;
1905 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001906 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001907 if (tmpkey == NULL)
1908 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001911 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001912 return NULL;
1913 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001914
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001916 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001917 return NULL;
1918 }
1919 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001920}
1921
1922PyDoc_STRVAR(remove_doc,
1923"Remove an element from a set; it must be a member.\n\
1924\n\
1925If the element is not a member, raise a KeyError.");
1926
1927static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001928set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001929{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001930 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001933 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001934 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001935 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1936 return NULL;
1937 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001938 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001939 if (tmpkey == NULL)
1940 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001941 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001942 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001943 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001944 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001945 }
1946 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001947}
1948
1949PyDoc_STRVAR(discard_doc,
1950"Remove an element from a set if it is a member.\n\
1951\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001953
1954static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301955set_reduce(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001957 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001958 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001959
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001960 keys = PySequence_List((PyObject *)so);
1961 if (keys == NULL)
1962 goto done;
1963 args = PyTuple_Pack(1, keys);
1964 if (args == NULL)
1965 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001966 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001967 if (dict == NULL) {
1968 PyErr_Clear();
1969 dict = Py_None;
1970 Py_INCREF(dict);
1971 }
1972 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001973done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001974 Py_XDECREF(args);
1975 Py_XDECREF(keys);
1976 Py_XDECREF(dict);
1977 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001978}
1979
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001980static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301981set_sizeof(PySetObject *so, PyObject *Py_UNUSED(ignored))
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001982{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001983 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001984
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02001985 res = _PyObject_SIZE(Py_TYPE(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001986 if (so->table != so->smalltable)
1987 res = res + (so->mask + 1) * sizeof(setentry);
1988 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001989}
1990
1991PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001992static int
1993set_init(PySetObject *self, PyObject *args, PyObject *kwds)
1994{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001995 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001996
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001997 if (!_PyArg_NoKeywords("set", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001998 return -1;
1999 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
2000 return -1;
Raymond Hettingerb72e21b2016-03-25 02:29:59 -07002001 if (self->fill)
2002 set_clear_internal(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 self->hash = -1;
2004 if (iterable == NULL)
2005 return 0;
2006 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002007}
2008
Raymond Hettingera690a992003-11-16 16:17:49 +00002009static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002010 set_len, /* sq_length */
2011 0, /* sq_concat */
2012 0, /* sq_repeat */
2013 0, /* sq_item */
2014 0, /* sq_slice */
2015 0, /* sq_ass_item */
2016 0, /* sq_ass_slice */
2017 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002018};
2019
2020/* set object ********************************************************/
2021
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002022#ifdef Py_DEBUG
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302023static PyObject *test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored));
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002024
2025PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2026All is well if assertions don't fail.");
2027#endif
2028
Raymond Hettingera690a992003-11-16 16:17:49 +00002029static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002030 {"add", (PyCFunction)set_add, METH_O,
2031 add_doc},
2032 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2033 clear_doc},
2034 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2035 contains_doc},
2036 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2037 copy_doc},
2038 {"discard", (PyCFunction)set_discard, METH_O,
2039 discard_doc},
2040 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2041 difference_doc},
2042 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2043 difference_update_doc},
2044 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2045 intersection_doc},
2046 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2047 intersection_update_doc},
2048 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2049 isdisjoint_doc},
2050 {"issubset", (PyCFunction)set_issubset, METH_O,
2051 issubset_doc},
2052 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2053 issuperset_doc},
2054 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2055 pop_doc},
2056 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2057 reduce_doc},
2058 {"remove", (PyCFunction)set_remove, METH_O,
2059 remove_doc},
2060 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2061 sizeof_doc},
2062 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2063 symmetric_difference_doc},
2064 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2065 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002066#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002067 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2068 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002069#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002070 {"union", (PyCFunction)set_union, METH_VARARGS,
2071 union_doc},
2072 {"update", (PyCFunction)set_update, METH_VARARGS,
2073 update_doc},
2074 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002075};
2076
2077static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002078 0, /*nb_add*/
2079 (binaryfunc)set_sub, /*nb_subtract*/
2080 0, /*nb_multiply*/
2081 0, /*nb_remainder*/
2082 0, /*nb_divmod*/
2083 0, /*nb_power*/
2084 0, /*nb_negative*/
2085 0, /*nb_positive*/
2086 0, /*nb_absolute*/
2087 0, /*nb_bool*/
2088 0, /*nb_invert*/
2089 0, /*nb_lshift*/
2090 0, /*nb_rshift*/
2091 (binaryfunc)set_and, /*nb_and*/
2092 (binaryfunc)set_xor, /*nb_xor*/
2093 (binaryfunc)set_or, /*nb_or*/
2094 0, /*nb_int*/
2095 0, /*nb_reserved*/
2096 0, /*nb_float*/
2097 0, /*nb_inplace_add*/
2098 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2099 0, /*nb_inplace_multiply*/
2100 0, /*nb_inplace_remainder*/
2101 0, /*nb_inplace_power*/
2102 0, /*nb_inplace_lshift*/
2103 0, /*nb_inplace_rshift*/
2104 (binaryfunc)set_iand, /*nb_inplace_and*/
2105 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2106 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002107};
2108
2109PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002110"set() -> new empty set object\n\
2111set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002112\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002113Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002114
2115PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002116 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2117 "set", /* tp_name */
2118 sizeof(PySetObject), /* tp_basicsize */
2119 0, /* tp_itemsize */
2120 /* methods */
2121 (destructor)set_dealloc, /* tp_dealloc */
2122 0, /* tp_print */
2123 0, /* tp_getattr */
2124 0, /* tp_setattr */
2125 0, /* tp_reserved */
2126 (reprfunc)set_repr, /* tp_repr */
2127 &set_as_number, /* tp_as_number */
2128 &set_as_sequence, /* tp_as_sequence */
2129 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002130 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002131 0, /* tp_call */
2132 0, /* tp_str */
2133 PyObject_GenericGetAttr, /* tp_getattro */
2134 0, /* tp_setattro */
2135 0, /* tp_as_buffer */
2136 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2137 Py_TPFLAGS_BASETYPE, /* tp_flags */
2138 set_doc, /* tp_doc */
2139 (traverseproc)set_traverse, /* tp_traverse */
2140 (inquiry)set_clear_internal, /* tp_clear */
2141 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002142 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2143 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002144 0, /* tp_iternext */
2145 set_methods, /* tp_methods */
2146 0, /* tp_members */
2147 0, /* tp_getset */
2148 0, /* tp_base */
2149 0, /* tp_dict */
2150 0, /* tp_descr_get */
2151 0, /* tp_descr_set */
2152 0, /* tp_dictoffset */
2153 (initproc)set_init, /* tp_init */
2154 PyType_GenericAlloc, /* tp_alloc */
2155 set_new, /* tp_new */
2156 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002157};
2158
2159/* frozenset object ********************************************************/
2160
2161
2162static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002163 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2164 contains_doc},
2165 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2166 copy_doc},
2167 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2168 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002169 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002170 intersection_doc},
2171 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2172 isdisjoint_doc},
2173 {"issubset", (PyCFunction)set_issubset, METH_O,
2174 issubset_doc},
2175 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2176 issuperset_doc},
2177 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2178 reduce_doc},
2179 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2180 sizeof_doc},
2181 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2182 symmetric_difference_doc},
2183 {"union", (PyCFunction)set_union, METH_VARARGS,
2184 union_doc},
2185 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002186};
2187
2188static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 0, /*nb_add*/
2190 (binaryfunc)set_sub, /*nb_subtract*/
2191 0, /*nb_multiply*/
2192 0, /*nb_remainder*/
2193 0, /*nb_divmod*/
2194 0, /*nb_power*/
2195 0, /*nb_negative*/
2196 0, /*nb_positive*/
2197 0, /*nb_absolute*/
2198 0, /*nb_bool*/
2199 0, /*nb_invert*/
2200 0, /*nb_lshift*/
2201 0, /*nb_rshift*/
2202 (binaryfunc)set_and, /*nb_and*/
2203 (binaryfunc)set_xor, /*nb_xor*/
2204 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002205};
2206
2207PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002208"frozenset() -> empty frozenset object\n\
2209frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002210\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002211Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002212
2213PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002214 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2215 "frozenset", /* tp_name */
2216 sizeof(PySetObject), /* tp_basicsize */
2217 0, /* tp_itemsize */
2218 /* methods */
2219 (destructor)set_dealloc, /* tp_dealloc */
2220 0, /* tp_print */
2221 0, /* tp_getattr */
2222 0, /* tp_setattr */
2223 0, /* tp_reserved */
2224 (reprfunc)set_repr, /* tp_repr */
2225 &frozenset_as_number, /* tp_as_number */
2226 &set_as_sequence, /* tp_as_sequence */
2227 0, /* tp_as_mapping */
2228 frozenset_hash, /* tp_hash */
2229 0, /* tp_call */
2230 0, /* tp_str */
2231 PyObject_GenericGetAttr, /* tp_getattro */
2232 0, /* tp_setattro */
2233 0, /* tp_as_buffer */
2234 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2235 Py_TPFLAGS_BASETYPE, /* tp_flags */
2236 frozenset_doc, /* tp_doc */
2237 (traverseproc)set_traverse, /* tp_traverse */
2238 (inquiry)set_clear_internal, /* tp_clear */
2239 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002240 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 (getiterfunc)set_iter, /* tp_iter */
2242 0, /* tp_iternext */
2243 frozenset_methods, /* tp_methods */
2244 0, /* tp_members */
2245 0, /* tp_getset */
2246 0, /* tp_base */
2247 0, /* tp_dict */
2248 0, /* tp_descr_get */
2249 0, /* tp_descr_set */
2250 0, /* tp_dictoffset */
2251 0, /* tp_init */
2252 PyType_GenericAlloc, /* tp_alloc */
2253 frozenset_new, /* tp_new */
2254 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002255};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002256
2257
2258/***** C API functions *************************************************/
2259
2260PyObject *
2261PySet_New(PyObject *iterable)
2262{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002264}
2265
2266PyObject *
2267PyFrozenSet_New(PyObject *iterable)
2268{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002269 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002270}
2271
Neal Norwitz8c49c822006-03-04 18:41:19 +00002272Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002273PySet_Size(PyObject *anyset)
2274{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002275 if (!PyAnySet_Check(anyset)) {
2276 PyErr_BadInternalCall();
2277 return -1;
2278 }
2279 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002280}
2281
2282int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002283PySet_Clear(PyObject *set)
2284{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002285 if (!PySet_Check(set)) {
2286 PyErr_BadInternalCall();
2287 return -1;
2288 }
2289 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002290}
2291
2292int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002293PySet_Contains(PyObject *anyset, PyObject *key)
2294{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002295 if (!PyAnySet_Check(anyset)) {
2296 PyErr_BadInternalCall();
2297 return -1;
2298 }
2299 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002300}
2301
2302int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002303PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002304{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002305 if (!PySet_Check(set)) {
2306 PyErr_BadInternalCall();
2307 return -1;
2308 }
2309 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002310}
2311
2312int
Christian Heimesfd66e512008-01-29 12:18:50 +00002313PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002314{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002315 if (!PySet_Check(anyset) &&
2316 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2317 PyErr_BadInternalCall();
2318 return -1;
2319 }
2320 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002321}
2322
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002323int
Raymond Hettinger3625af52016-03-27 01:15:07 -07002324PySet_ClearFreeList(void)
2325{
2326 return 0;
2327}
2328
2329void
2330PySet_Fini(void)
2331{
2332 Py_CLEAR(emptyfrozenset);
2333}
2334
2335int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002336_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002337{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002338 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002340 if (!PyAnySet_Check(set)) {
2341 PyErr_BadInternalCall();
2342 return -1;
2343 }
2344 if (set_next((PySetObject *)set, pos, &entry) == 0)
2345 return 0;
2346 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002347 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002348 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002349}
2350
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002351PyObject *
2352PySet_Pop(PyObject *set)
2353{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002354 if (!PySet_Check(set)) {
2355 PyErr_BadInternalCall();
2356 return NULL;
2357 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302358 return set_pop((PySetObject *)set, NULL);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002359}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002360
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002361int
2362_PySet_Update(PyObject *set, PyObject *iterable)
2363{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002364 if (!PySet_Check(set)) {
2365 PyErr_BadInternalCall();
2366 return -1;
2367 }
2368 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002369}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002370
Raymond Hettingere259f132013-12-15 11:56:14 -08002371/* Exported for the gdb plugin's benefit. */
2372PyObject *_PySet_Dummy = dummy;
2373
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002374#ifdef Py_DEBUG
2375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002376/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002377 Returns True and original set is restored. */
2378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002379#define assertRaises(call_return_value, exception) \
2380 do { \
2381 assert(call_return_value); \
2382 assert(PyErr_ExceptionMatches(exception)); \
2383 PyErr_Clear(); \
2384 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002385
2386static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302387test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002388{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002389 Py_ssize_t count;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +02002390 const char *s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002391 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002392 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002393 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002394 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002395 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002397 /* Verify preconditions */
2398 assert(PyAnySet_Check(ob));
2399 assert(PyAnySet_CheckExact(ob));
2400 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002402 /* so.clear(); so |= set("abc"); */
2403 str = PyUnicode_FromString("abc");
2404 if (str == NULL)
2405 return NULL;
2406 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002407 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 Py_DECREF(str);
2409 return NULL;
2410 }
2411 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002413 /* Exercise type/size checks */
2414 assert(PySet_Size(ob) == 3);
2415 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002417 /* Raise TypeError for non-iterable constructor arguments */
2418 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2419 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 /* Raise TypeError for unhashable key */
2422 dup = PySet_New(ob);
2423 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2424 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2425 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002427 /* Exercise successful pop, contains, add, and discard */
2428 elem = PySet_Pop(ob);
2429 assert(PySet_Contains(ob, elem) == 0);
2430 assert(PySet_GET_SIZE(ob) == 2);
2431 assert(PySet_Add(ob, elem) == 0);
2432 assert(PySet_Contains(ob, elem) == 1);
2433 assert(PySet_GET_SIZE(ob) == 3);
2434 assert(PySet_Discard(ob, elem) == 1);
2435 assert(PySet_GET_SIZE(ob) == 2);
2436 assert(PySet_Discard(ob, elem) == 0);
2437 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002439 /* Exercise clear */
2440 dup2 = PySet_New(dup);
2441 assert(PySet_Clear(dup2) == 0);
2442 assert(PySet_Size(dup2) == 0);
2443 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002444
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002445 /* Raise SystemError on clear or update of frozen set */
2446 f = PyFrozenSet_New(dup);
2447 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2448 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2449 assert(PySet_Add(f, elem) == 0);
2450 Py_INCREF(f);
2451 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2452 Py_DECREF(f);
2453 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002455 /* Exercise direct iteration */
2456 i = 0, count = 0;
2457 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
Serhiy Storchaka06515832016-11-20 09:13:07 +02002458 s = PyUnicode_AsUTF8(x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002459 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2460 count++;
2461 }
2462 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002464 /* Exercise updates */
2465 dup2 = PySet_New(NULL);
2466 assert(_PySet_Update(dup2, dup) == 0);
2467 assert(PySet_Size(dup2) == 3);
2468 assert(_PySet_Update(dup2, dup) == 0);
2469 assert(PySet_Size(dup2) == 3);
2470 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002472 /* Raise SystemError when self argument is not a set or frozenset. */
2473 t = PyTuple_New(0);
2474 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2475 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2476 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002478 /* Raise SystemError when self argument is not a set. */
2479 f = PyFrozenSet_New(dup);
2480 assert(PySet_Size(f) == 3);
2481 assert(PyFrozenSet_CheckExact(f));
2482 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2483 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2484 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002486 /* Raise KeyError when popping from an empty set */
2487 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2488 Py_DECREF(ob);
2489 assert(PySet_GET_SIZE(ob) == 0);
2490 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002492 /* Restore the set from the copy using the PyNumber API */
2493 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2494 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002496 /* Verify constructors accept NULL arguments */
2497 f = PySet_New(NULL);
2498 assert(f != NULL);
2499 assert(PySet_GET_SIZE(f) == 0);
2500 Py_DECREF(f);
2501 f = PyFrozenSet_New(NULL);
2502 assert(f != NULL);
2503 assert(PyFrozenSet_CheckExact(f));
2504 assert(PySet_GET_SIZE(f) == 0);
2505 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002507 Py_DECREF(elem);
2508 Py_DECREF(dup);
2509 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002510}
2511
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002512#undef assertRaises
2513
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002514#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002515
2516/***** Dummy Struct *************************************************/
2517
2518static PyObject *
2519dummy_repr(PyObject *op)
2520{
2521 return PyUnicode_FromString("<dummy key>");
2522}
2523
2524static void
2525dummy_dealloc(PyObject* ignore)
2526{
2527 Py_FatalError("deallocating <dummy key>");
2528}
2529
2530static PyTypeObject _PySetDummy_Type = {
2531 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2532 "<dummy key> type",
2533 0,
2534 0,
2535 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2536 0, /*tp_print*/
2537 0, /*tp_getattr*/
2538 0, /*tp_setattr*/
2539 0, /*tp_reserved*/
2540 dummy_repr, /*tp_repr*/
2541 0, /*tp_as_number*/
2542 0, /*tp_as_sequence*/
2543 0, /*tp_as_mapping*/
2544 0, /*tp_hash */
2545 0, /*tp_call */
2546 0, /*tp_str */
2547 0, /*tp_getattro */
2548 0, /*tp_setattro */
2549 0, /*tp_as_buffer */
2550 Py_TPFLAGS_DEFAULT, /*tp_flags */
2551};
2552
2553static PyObject _dummy_struct = {
2554 _PyObject_EXTRA_INIT
2555 2, &_PySetDummy_Type
2556};
2557