blob: 1e4781fe11eeb99122308a78ca9a441bff9cfbe2 [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"
Eric Snow2ebc5ce2017-09-07 23:51:28 -060035#include "internal/pystate.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 */
Miss Islington (bot)66658022018-10-19 15:50:34 -0700315 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 *
701set_pop(PySetObject *so)
702{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800703 /* Make sure the search finger is in bounds */
704 Py_ssize_t i = so->finger & so->mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200705 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000707
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000708 assert (PyAnySet_Check(so));
709 if (so->used == 0) {
710 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
711 return NULL;
712 }
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000713
Raymond Hettinger1202a472015-01-18 13:12:42 -0800714 while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
715 i++;
Raymond Hettingered741d42015-01-18 21:25:15 -0800716 if (i > so->mask)
717 i = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 }
719 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800721 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000722 so->used--;
Raymond Hettinger1202a472015-01-18 13:12:42 -0800723 so->finger = i + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000725}
726
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000727PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
728Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000729
730static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000731set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000732{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000733 Py_ssize_t pos = 0;
734 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000735
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000736 while (set_next(so, &pos, &entry))
737 Py_VISIT(entry->key);
738 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000739}
740
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700741/* Work to increase the bit dispersion for closely spaced hash values.
742 This is important because some use cases have many combinations of a
743 small number of elements with nearby hashes so that many distinct
744 combinations collapse to only a handful of distinct hash values. */
745
746static Py_uhash_t
747_shuffle_bits(Py_uhash_t h)
748{
749 return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
750}
751
752/* Most of the constants in this hash algorithm are randomly chosen
753 large primes with "interesting bit patterns" and that passed tests
754 for good collision statistics on a variety of problematic datasets
755 including powersets and graph structures (such as David Eppstein's
756 graph recipes in Lib/test/test_set.py) */
757
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000758static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000759frozenset_hash(PyObject *self)
760{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000761 PySetObject *so = (PySetObject *)self;
Raymond Hettinger41481952015-08-07 00:43:39 -0700762 Py_uhash_t hash = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000763 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000764
Raymond Hettingerb501a272015-08-06 22:15:22 -0700765 if (so->hash != -1)
766 return so->hash;
767
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700768 /* Xor-in shuffled bits from every entry's hash field because xor is
769 commutative and a frozenset hash should be independent of order.
770
771 For speed, include null entries and dummy entries and then
772 subtract out their effect afterwards so that the final hash
773 depends only on active entries. This allows the code to be
774 vectorized by the compiler and it saves the unpredictable
775 branches that would arise when trying to exclude null and dummy
776 entries on every iteration. */
777
778 for (entry = so->table; entry <= &so->table[so->mask]; entry++)
779 hash ^= _shuffle_bits(entry->hash);
780
Raymond Hettingera286a512015-08-01 11:07:11 -0700781 /* Remove the effect of an odd number of NULL entries */
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700782 if ((so->mask + 1 - so->fill) & 1)
783 hash ^= _shuffle_bits(0);
784
785 /* Remove the effect of an odd number of dummy entries */
786 if ((so->fill - so->used) & 1)
787 hash ^= _shuffle_bits(-1);
788
Raymond Hettinger41481952015-08-07 00:43:39 -0700789 /* Factor in the number of active entries */
790 hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;
791
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700792 /* Disperse patterns arising in nested frozensets */
Raymond Hettingerfa788062018-01-18 13:23:27 -0800793 hash ^= (hash >> 11) ^ (hash >> 25);
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800794 hash = hash * 69069U + 907133923UL;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700795
Raymond Hettinger36c05002015-08-01 10:57:42 -0700796 /* -1 is reserved as an error code */
Victor Stinner12174a52014-08-15 23:17:38 +0200797 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800798 hash = 590923713UL;
Raymond Hettinger36c05002015-08-01 10:57:42 -0700799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 so->hash = hash;
801 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000802}
803
Raymond Hettingera9d99362005-08-05 00:01:15 +0000804/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000805
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000806typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000807 PyObject_HEAD
808 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
809 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700810 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000811 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000812} setiterobject;
813
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000814static void
815setiter_dealloc(setiterobject *si)
816{
INADA Naokia6296d32017-08-24 14:55:17 +0900817 /* bpo-31095: UnTrack is needed before calling any callbacks */
818 _PyObject_GC_UNTRACK(si);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000819 Py_XDECREF(si->si_set);
820 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000821}
822
823static int
824setiter_traverse(setiterobject *si, visitproc visit, void *arg)
825{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000826 Py_VISIT(si->si_set);
827 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000828}
829
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000830static PyObject *
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000831setiter_len(setiterobject *si)
832{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000833 Py_ssize_t len = 0;
834 if (si->si_set != NULL && si->si_used == si->si_set->used)
835 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000836 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000837}
838
Armin Rigof5b3e362006-02-11 21:32:43 +0000839PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000840
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000841static PyObject *setiter_iternext(setiterobject *si);
842
843static PyObject *
844setiter_reduce(setiterobject *si)
845{
846 PyObject *list;
847 setiterobject tmp;
848
849 list = PyList_New(0);
850 if (!list)
851 return NULL;
852
Ezio Melotti0e1af282012-09-28 16:43:40 +0300853 /* copy the iterator state */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000854 tmp = *si;
855 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300856
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000857 /* iterate the temporary into a list */
858 for(;;) {
859 PyObject *element = setiter_iternext(&tmp);
860 if (element) {
861 if (PyList_Append(list, element)) {
862 Py_DECREF(element);
863 Py_DECREF(list);
864 Py_XDECREF(tmp.si_set);
865 return NULL;
866 }
867 Py_DECREF(element);
868 } else
869 break;
870 }
871 Py_XDECREF(tmp.si_set);
872 /* check for error */
873 if (tmp.si_set != NULL) {
874 /* we have an error */
875 Py_DECREF(list);
876 return NULL;
877 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200878 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000879}
880
881PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
882
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000883static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000884 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000885 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000887};
888
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000889static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000890{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700891 PyObject *key;
892 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200893 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000894 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000896 if (so == NULL)
897 return NULL;
898 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000900 if (si->si_used != so->used) {
901 PyErr_SetString(PyExc_RuntimeError,
902 "Set changed size during iteration");
903 si->si_used = -1; /* Make this state sticky */
904 return NULL;
905 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700906
907 i = si->si_pos;
908 assert(i>=0);
909 entry = so->table;
910 mask = so->mask;
911 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
912 i++;
913 si->si_pos = i+1;
914 if (i > mask)
915 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700917 key = entry[i].key;
918 Py_INCREF(key);
919 return key;
920
921fail:
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700922 si->si_set = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +0300923 Py_DECREF(so);
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700924 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000925}
926
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000927PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000928 PyVarObject_HEAD_INIT(&PyType_Type, 0)
929 "set_iterator", /* tp_name */
930 sizeof(setiterobject), /* tp_basicsize */
931 0, /* tp_itemsize */
932 /* methods */
933 (destructor)setiter_dealloc, /* tp_dealloc */
934 0, /* tp_print */
935 0, /* tp_getattr */
936 0, /* tp_setattr */
937 0, /* tp_reserved */
938 0, /* tp_repr */
939 0, /* tp_as_number */
940 0, /* tp_as_sequence */
941 0, /* tp_as_mapping */
942 0, /* tp_hash */
943 0, /* tp_call */
944 0, /* tp_str */
945 PyObject_GenericGetAttr, /* tp_getattro */
946 0, /* tp_setattro */
947 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700948 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 0, /* tp_doc */
950 (traverseproc)setiter_traverse, /* tp_traverse */
951 0, /* tp_clear */
952 0, /* tp_richcompare */
953 0, /* tp_weaklistoffset */
954 PyObject_SelfIter, /* tp_iter */
955 (iternextfunc)setiter_iternext, /* tp_iternext */
956 setiter_methods, /* tp_methods */
957 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000958};
959
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000960static PyObject *
961set_iter(PySetObject *so)
962{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
964 if (si == NULL)
965 return NULL;
966 Py_INCREF(so);
967 si->si_set = so;
968 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700969 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000970 si->len = so->used;
971 _PyObject_GC_TRACK(si);
972 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000973}
974
Raymond Hettingerd7946662005-08-01 21:39:29 +0000975static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000976set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000977{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000980 if (PyAnySet_Check(other))
981 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 if (PyDict_CheckExact(other)) {
984 PyObject *value;
985 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000986 Py_hash_t hash;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200987 Py_ssize_t dictsize = PyDict_GET_SIZE(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000988
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 /* Do one big resize at the start, rather than
990 * incrementally resizing as we insert new keys. Expect
991 * that there will be no (or few) overlapping keys.
992 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700993 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000994 return -1;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800995 if ((so->fill + dictsize)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900996 if (set_table_resize(so, (so->used + dictsize)*2) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000997 return -1;
998 }
999 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001000 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001001 return -1;
1002 }
1003 return 0;
1004 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 it = PyObject_GetIter(other);
1007 if (it == NULL)
1008 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +00001009
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001010 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001011 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 Py_DECREF(it);
1013 Py_DECREF(key);
1014 return -1;
1015 }
1016 Py_DECREF(key);
1017 }
1018 Py_DECREF(it);
1019 if (PyErr_Occurred())
1020 return -1;
1021 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001022}
1023
1024static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001025set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001026{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001029 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1030 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001031 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 return NULL;
1033 }
1034 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001035}
1036
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001037PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001038"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001039
Raymond Hettinger426d9952014-05-18 21:40:20 +01001040/* XXX Todo:
1041 If aligned memory allocations become available, make the
1042 set object 64 byte aligned so that most of the fields
1043 can be retrieved or updated in a single cache line.
1044*/
1045
Raymond Hettingera38123e2003-11-24 22:18:49 +00001046static PyObject *
1047make_new_set(PyTypeObject *type, PyObject *iterable)
1048{
Raymond Hettinger8421d712016-04-29 01:37:05 -07001049 PySetObject *so;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001050
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001051 so = (PySetObject *)type->tp_alloc(type, 0);
1052 if (so == NULL)
1053 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001054
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001055 so->fill = 0;
1056 so->used = 0;
1057 so->mask = PySet_MINSIZE - 1;
1058 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001059 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001060 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001062
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001064 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 Py_DECREF(so);
1066 return NULL;
1067 }
1068 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001071}
1072
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001073static PyObject *
1074make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1075{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001076 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1077 if (PyType_IsSubtype(type, &PySet_Type))
1078 type = &PySet_Type;
1079 else
1080 type = &PyFrozenSet_Type;
1081 }
1082 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001083}
1084
Raymond Hettingerd7946662005-08-01 21:39:29 +00001085/* The empty frozenset is a singleton */
1086static PyObject *emptyfrozenset = NULL;
1087
Raymond Hettingera690a992003-11-16 16:17:49 +00001088static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001089frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001090{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001091 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001092
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001093 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1097 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 if (type != &PyFrozenSet_Type)
1100 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 if (iterable != NULL) {
1103 /* frozenset(f) is idempotent */
1104 if (PyFrozenSet_CheckExact(iterable)) {
1105 Py_INCREF(iterable);
1106 return iterable;
1107 }
1108 result = make_new_set(type, iterable);
1109 if (result == NULL || PySet_GET_SIZE(result))
1110 return result;
1111 Py_DECREF(result);
1112 }
1113 /* The empty frozenset is a singleton */
1114 if (emptyfrozenset == NULL)
1115 emptyfrozenset = make_new_set(type, NULL);
1116 Py_XINCREF(emptyfrozenset);
1117 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001118}
1119
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001120static PyObject *
1121set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1122{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001123 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001124}
1125
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001126/* set_swap_bodies() switches the contents of any two sets by moving their
1127 internal data pointers and, if needed, copying the internal smalltables.
1128 Semantically equivalent to:
1129
1130 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1131
1132 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001133 Useful for operations that update in-place (by allowing an intermediate
1134 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001135*/
1136
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001137static void
1138set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001139{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 Py_ssize_t t;
1141 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001143 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 t = a->fill; a->fill = b->fill; b->fill = t;
1146 t = a->used; a->used = b->used; b->used = t;
1147 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 u = a->table;
1150 if (a->table == a->smalltable)
1151 u = b->smalltable;
1152 a->table = b->table;
1153 if (b->table == b->smalltable)
1154 a->table = a->smalltable;
1155 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001157 if (a->table == a->smalltable || b->table == b->smalltable) {
1158 memcpy(tab, a->smalltable, sizeof(tab));
1159 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1160 memcpy(b->smalltable, tab, sizeof(tab));
1161 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001163 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1164 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1165 h = a->hash; a->hash = b->hash; b->hash = h;
1166 } else {
1167 a->hash = -1;
1168 b->hash = -1;
1169 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001170}
1171
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001172static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001173set_copy(PySetObject *so)
1174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001176}
1177
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001178static PyObject *
1179frozenset_copy(PySetObject *so)
1180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001181 if (PyFrozenSet_CheckExact(so)) {
1182 Py_INCREF(so);
1183 return (PyObject *)so;
1184 }
1185 return set_copy(so);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001186}
1187
Raymond Hettingera690a992003-11-16 16:17:49 +00001188PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1189
1190static PyObject *
Raymond Hettingerc991db22005-08-11 07:58:45 +00001191set_clear(PySetObject *so)
1192{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193 set_clear_internal(so);
1194 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001195}
1196
1197PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1198
1199static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001200set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001201{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001202 PySetObject *result;
1203 PyObject *other;
1204 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001206 result = (PySetObject *)set_copy(so);
1207 if (result == NULL)
1208 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001210 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1211 other = PyTuple_GET_ITEM(args, i);
1212 if ((PyObject *)so == other)
1213 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001214 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001215 Py_DECREF(result);
1216 return NULL;
1217 }
1218 }
1219 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001220}
1221
1222PyDoc_STRVAR(union_doc,
1223 "Return the union of sets as a new set.\n\
1224\n\
1225(i.e. all elements that are in either set.)");
1226
1227static PyObject *
1228set_or(PySetObject *so, PyObject *other)
1229{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001230 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001231
Brian Curtindfc80e32011-08-10 20:28:54 -05001232 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1233 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 result = (PySetObject *)set_copy(so);
1236 if (result == NULL)
1237 return NULL;
1238 if ((PyObject *)so == other)
1239 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001240 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 Py_DECREF(result);
1242 return NULL;
1243 }
1244 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001245}
1246
Raymond Hettingera690a992003-11-16 16:17:49 +00001247static PyObject *
1248set_ior(PySetObject *so, PyObject *other)
1249{
Brian Curtindfc80e32011-08-10 20:28:54 -05001250 if (!PyAnySet_Check(other))
1251 Py_RETURN_NOTIMPLEMENTED;
1252
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001253 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 return NULL;
1255 Py_INCREF(so);
1256 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001257}
1258
1259static PyObject *
1260set_intersection(PySetObject *so, PyObject *other)
1261{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 PySetObject *result;
1263 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001264 Py_hash_t hash;
1265 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 if ((PyObject *)so == other)
1268 return set_copy(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001270 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1271 if (result == NULL)
1272 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 if (PyAnySet_Check(other)) {
1275 Py_ssize_t pos = 0;
1276 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001278 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1279 tmp = (PyObject *)so;
1280 so = (PySetObject *)other;
1281 other = tmp;
1282 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001285 key = entry->key;
1286 hash = entry->hash;
1287 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001288 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 Py_DECREF(result);
1290 return NULL;
1291 }
1292 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001293 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 Py_DECREF(result);
1295 return NULL;
1296 }
1297 }
1298 }
1299 return (PyObject *)result;
1300 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 it = PyObject_GetIter(other);
1303 if (it == NULL) {
1304 Py_DECREF(result);
1305 return NULL;
1306 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001309 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001310 if (hash == -1)
1311 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001312 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001313 if (rv < 0)
1314 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001316 if (set_add_entry(result, key, hash))
1317 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 }
1319 Py_DECREF(key);
1320 }
1321 Py_DECREF(it);
1322 if (PyErr_Occurred()) {
1323 Py_DECREF(result);
1324 return NULL;
1325 }
1326 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001327 error:
1328 Py_DECREF(it);
1329 Py_DECREF(result);
1330 Py_DECREF(key);
1331 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001332}
1333
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001334static PyObject *
1335set_intersection_multi(PySetObject *so, PyObject *args)
1336{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 Py_ssize_t i;
1338 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 if (PyTuple_GET_SIZE(args) == 0)
1341 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 Py_INCREF(so);
1344 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1345 PyObject *other = PyTuple_GET_ITEM(args, i);
1346 PyObject *newresult = set_intersection((PySetObject *)result, other);
1347 if (newresult == NULL) {
1348 Py_DECREF(result);
1349 return NULL;
1350 }
1351 Py_DECREF(result);
1352 result = newresult;
1353 }
1354 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001355}
1356
Raymond Hettingera690a992003-11-16 16:17:49 +00001357PyDoc_STRVAR(intersection_doc,
1358"Return the intersection of two sets as a new set.\n\
1359\n\
1360(i.e. all elements that are in both sets.)");
1361
1362static PyObject *
1363set_intersection_update(PySetObject *so, PyObject *other)
1364{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 tmp = set_intersection(so, other);
1368 if (tmp == NULL)
1369 return NULL;
1370 set_swap_bodies(so, (PySetObject *)tmp);
1371 Py_DECREF(tmp);
1372 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001373}
1374
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001375static PyObject *
1376set_intersection_update_multi(PySetObject *so, PyObject *args)
1377{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001378 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001379
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001380 tmp = set_intersection_multi(so, args);
1381 if (tmp == NULL)
1382 return NULL;
1383 set_swap_bodies(so, (PySetObject *)tmp);
1384 Py_DECREF(tmp);
1385 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001386}
1387
Raymond Hettingera690a992003-11-16 16:17:49 +00001388PyDoc_STRVAR(intersection_update_doc,
1389"Update a set with the intersection of itself and another.");
1390
1391static PyObject *
1392set_and(PySetObject *so, PyObject *other)
1393{
Brian Curtindfc80e32011-08-10 20:28:54 -05001394 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1395 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001397}
1398
1399static PyObject *
1400set_iand(PySetObject *so, PyObject *other)
1401{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001403
Brian Curtindfc80e32011-08-10 20:28:54 -05001404 if (!PyAnySet_Check(other))
1405 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001406 result = set_intersection_update(so, other);
1407 if (result == NULL)
1408 return NULL;
1409 Py_DECREF(result);
1410 Py_INCREF(so);
1411 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001412}
1413
Guido van Rossum58da9312007-11-10 23:39:45 +00001414static PyObject *
1415set_isdisjoint(PySetObject *so, PyObject *other)
1416{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001418 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 if ((PyObject *)so == other) {
1421 if (PySet_GET_SIZE(so) == 0)
1422 Py_RETURN_TRUE;
1423 else
1424 Py_RETURN_FALSE;
1425 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001427 if (PyAnySet_CheckExact(other)) {
1428 Py_ssize_t pos = 0;
1429 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1432 tmp = (PyObject *)so;
1433 so = (PySetObject *)other;
1434 other = tmp;
1435 }
1436 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001437 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001438 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 return NULL;
1440 if (rv)
1441 Py_RETURN_FALSE;
1442 }
1443 Py_RETURN_TRUE;
1444 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 it = PyObject_GetIter(other);
1447 if (it == NULL)
1448 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001451 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001453 if (hash == -1) {
1454 Py_DECREF(key);
1455 Py_DECREF(it);
1456 return NULL;
1457 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001458 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001460 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 Py_DECREF(it);
1462 return NULL;
1463 }
1464 if (rv) {
1465 Py_DECREF(it);
1466 Py_RETURN_FALSE;
1467 }
1468 }
1469 Py_DECREF(it);
1470 if (PyErr_Occurred())
1471 return NULL;
1472 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001473}
1474
1475PyDoc_STRVAR(isdisjoint_doc,
1476"Return True if two sets have a null intersection.");
1477
Neal Norwitz6576bd82005-11-13 18:41:28 +00001478static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001479set_difference_update_internal(PySetObject *so, PyObject *other)
1480{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 if ((PyObject *)so == other)
1482 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 if (PyAnySet_Check(other)) {
1485 setentry *entry;
1486 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001489 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 return -1;
1491 } else {
1492 PyObject *key, *it;
1493 it = PyObject_GetIter(other);
1494 if (it == NULL)
1495 return -1;
1496
1497 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001498 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 Py_DECREF(it);
1500 Py_DECREF(key);
1501 return -1;
1502 }
1503 Py_DECREF(key);
1504 }
1505 Py_DECREF(it);
1506 if (PyErr_Occurred())
1507 return -1;
1508 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001509 /* If more than 1/4th are dummies, then resize them away. */
1510 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +09001512 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001513}
1514
Raymond Hettingera690a992003-11-16 16:17:49 +00001515static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001516set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001517{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1521 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001522 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001523 return NULL;
1524 }
1525 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001526}
1527
1528PyDoc_STRVAR(difference_update_doc,
1529"Remove all elements of another set from this set.");
1530
1531static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001532set_copy_and_difference(PySetObject *so, PyObject *other)
1533{
1534 PyObject *result;
1535
1536 result = set_copy(so);
1537 if (result == NULL)
1538 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001539 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001540 return result;
1541 Py_DECREF(result);
1542 return NULL;
1543}
1544
1545static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001546set_difference(PySetObject *so, PyObject *other)
1547{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001549 PyObject *key;
1550 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001551 setentry *entry;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001552 Py_ssize_t pos = 0, other_size;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001553 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001554
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001555 if (PyAnySet_Check(other)) {
1556 other_size = PySet_GET_SIZE(other);
1557 }
1558 else if (PyDict_CheckExact(other)) {
1559 other_size = PyDict_GET_SIZE(other);
1560 }
1561 else {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001562 return set_copy_and_difference(so, other);
1563 }
1564
1565 /* If len(so) much more than len(other), it's more efficient to simply copy
1566 * so and then iterate other looking for common elements. */
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001567 if ((PySet_GET_SIZE(so) >> 2) > other_size) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001568 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001569 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001571 result = make_new_set_basetype(Py_TYPE(so), NULL);
1572 if (result == NULL)
1573 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001574
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 if (PyDict_CheckExact(other)) {
1576 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001577 key = entry->key;
1578 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001579 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001580 if (rv < 0) {
1581 Py_DECREF(result);
1582 return NULL;
1583 }
1584 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001585 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 Py_DECREF(result);
1587 return NULL;
1588 }
1589 }
1590 }
1591 return result;
1592 }
1593
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001594 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001596 key = entry->key;
1597 hash = entry->hash;
1598 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001599 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 Py_DECREF(result);
1601 return NULL;
1602 }
1603 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001604 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001605 Py_DECREF(result);
1606 return NULL;
1607 }
1608 }
1609 }
1610 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001611}
1612
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001613static PyObject *
1614set_difference_multi(PySetObject *so, PyObject *args)
1615{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616 Py_ssize_t i;
1617 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001618
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001619 if (PyTuple_GET_SIZE(args) == 0)
1620 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001621
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001622 other = PyTuple_GET_ITEM(args, 0);
1623 result = set_difference(so, other);
1624 if (result == NULL)
1625 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1628 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001629 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 Py_DECREF(result);
1631 return NULL;
1632 }
1633 }
1634 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001635}
1636
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001637PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001638"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001639\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001640(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001641static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001642set_sub(PySetObject *so, PyObject *other)
1643{
Brian Curtindfc80e32011-08-10 20:28:54 -05001644 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1645 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001646 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001647}
1648
1649static PyObject *
1650set_isub(PySetObject *so, PyObject *other)
1651{
Brian Curtindfc80e32011-08-10 20:28:54 -05001652 if (!PyAnySet_Check(other))
1653 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001654 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001655 return NULL;
1656 Py_INCREF(so);
1657 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001658}
1659
1660static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001661set_symmetric_difference_update(PySetObject *so, PyObject *other)
1662{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001663 PySetObject *otherset;
1664 PyObject *key;
1665 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001666 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001667 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001668 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001669
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001670 if ((PyObject *)so == other)
1671 return set_clear(so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001672
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001673 if (PyDict_CheckExact(other)) {
1674 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001675 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001676 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001677 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001678 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001679 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001680 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001681 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001682 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001683 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001684 Py_DECREF(key);
1685 return NULL;
1686 }
1687 }
Georg Brandl2d444492010-09-03 10:52:55 +00001688 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001689 }
1690 Py_RETURN_NONE;
1691 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001692
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001693 if (PyAnySet_Check(other)) {
1694 Py_INCREF(other);
1695 otherset = (PySetObject *)other;
1696 } else {
1697 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1698 if (otherset == NULL)
1699 return NULL;
1700 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001701
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001702 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001703 key = entry->key;
1704 hash = entry->hash;
1705 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001706 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001707 Py_DECREF(otherset);
1708 return NULL;
1709 }
1710 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001711 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001712 Py_DECREF(otherset);
1713 return NULL;
1714 }
1715 }
1716 }
1717 Py_DECREF(otherset);
1718 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001719}
1720
1721PyDoc_STRVAR(symmetric_difference_update_doc,
1722"Update a set with the symmetric difference of itself and another.");
1723
1724static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001725set_symmetric_difference(PySetObject *so, PyObject *other)
1726{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001727 PyObject *rv;
1728 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001730 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1731 if (otherset == NULL)
1732 return NULL;
1733 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
Miss Islington (bot)6a567902018-05-02 02:50:48 -07001734 if (rv == NULL) {
1735 Py_DECREF(otherset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001736 return NULL;
Miss Islington (bot)6a567902018-05-02 02:50:48 -07001737 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001738 Py_DECREF(rv);
1739 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001740}
1741
1742PyDoc_STRVAR(symmetric_difference_doc,
1743"Return the symmetric difference of two sets as a new set.\n\
1744\n\
1745(i.e. all elements that are in exactly one of the sets.)");
1746
1747static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001748set_xor(PySetObject *so, PyObject *other)
1749{
Brian Curtindfc80e32011-08-10 20:28:54 -05001750 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1751 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001752 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001753}
1754
1755static PyObject *
1756set_ixor(PySetObject *so, PyObject *other)
1757{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001758 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001759
Brian Curtindfc80e32011-08-10 20:28:54 -05001760 if (!PyAnySet_Check(other))
1761 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001762 result = set_symmetric_difference_update(so, other);
1763 if (result == NULL)
1764 return NULL;
1765 Py_DECREF(result);
1766 Py_INCREF(so);
1767 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001768}
1769
1770static PyObject *
1771set_issubset(PySetObject *so, PyObject *other)
1772{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001773 setentry *entry;
1774 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001775 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 if (!PyAnySet_Check(other)) {
1778 PyObject *tmp, *result;
1779 tmp = make_new_set(&PySet_Type, other);
1780 if (tmp == NULL)
1781 return NULL;
1782 result = set_issubset(so, tmp);
1783 Py_DECREF(tmp);
1784 return result;
1785 }
1786 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1787 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001788
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001790 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001791 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001792 return NULL;
1793 if (!rv)
1794 Py_RETURN_FALSE;
1795 }
1796 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001797}
1798
1799PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1800
1801static PyObject *
1802set_issuperset(PySetObject *so, PyObject *other)
1803{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001804 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001805
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001806 if (!PyAnySet_Check(other)) {
1807 tmp = make_new_set(&PySet_Type, other);
1808 if (tmp == NULL)
1809 return NULL;
1810 result = set_issuperset(so, tmp);
1811 Py_DECREF(tmp);
1812 return result;
1813 }
1814 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001815}
1816
1817PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1818
Raymond Hettingera690a992003-11-16 16:17:49 +00001819static PyObject *
1820set_richcompare(PySetObject *v, PyObject *w, int op)
1821{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001822 PyObject *r1;
1823 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001824
Brian Curtindfc80e32011-08-10 20:28:54 -05001825 if(!PyAnySet_Check(w))
1826 Py_RETURN_NOTIMPLEMENTED;
1827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001828 switch (op) {
1829 case Py_EQ:
1830 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1831 Py_RETURN_FALSE;
1832 if (v->hash != -1 &&
1833 ((PySetObject *)w)->hash != -1 &&
1834 v->hash != ((PySetObject *)w)->hash)
1835 Py_RETURN_FALSE;
1836 return set_issubset(v, w);
1837 case Py_NE:
1838 r1 = set_richcompare(v, w, Py_EQ);
1839 if (r1 == NULL)
1840 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001841 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001842 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001843 if (r2 < 0)
1844 return NULL;
1845 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001846 case Py_LE:
1847 return set_issubset(v, w);
1848 case Py_GE:
1849 return set_issuperset(v, w);
1850 case Py_LT:
1851 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1852 Py_RETURN_FALSE;
1853 return set_issubset(v, w);
1854 case Py_GT:
1855 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1856 Py_RETURN_FALSE;
1857 return set_issuperset(v, w);
1858 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001859 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001860}
1861
Raymond Hettingera690a992003-11-16 16:17:49 +00001862static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001863set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001864{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001865 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 return NULL;
1867 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001868}
1869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001870PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001871"Add an element to a set.\n\
1872\n\
1873This has no effect if the element is already present.");
1874
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001875static int
1876set_contains(PySetObject *so, PyObject *key)
1877{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 PyObject *tmpkey;
1879 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001882 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001883 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1884 return -1;
1885 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001886 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 if (tmpkey == NULL)
1888 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001889 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 Py_DECREF(tmpkey);
1891 }
1892 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001893}
1894
1895static PyObject *
1896set_direct_contains(PySetObject *so, PyObject *key)
1897{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001898 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001901 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 return NULL;
1903 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001904}
1905
1906PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1907
Raymond Hettingera690a992003-11-16 16:17:49 +00001908static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001909set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001910{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 PyObject *tmpkey;
1912 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001913
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001915 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001916 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1917 return NULL;
1918 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001919 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001920 if (tmpkey == NULL)
1921 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001924 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 return NULL;
1926 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001928 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001929 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 return NULL;
1931 }
1932 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001933}
1934
1935PyDoc_STRVAR(remove_doc,
1936"Remove an element from a set; it must be a member.\n\
1937\n\
1938If the element is not a member, raise a KeyError.");
1939
1940static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001941set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001942{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001943 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001944 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001945
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001947 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001948 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1949 return NULL;
1950 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001951 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 if (tmpkey == NULL)
1953 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001954 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001956 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001957 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001958 }
1959 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001960}
1961
1962PyDoc_STRVAR(discard_doc,
1963"Remove an element from a set if it is a member.\n\
1964\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001965If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001966
1967static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001968set_reduce(PySetObject *so)
1969{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001970 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001971 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 keys = PySequence_List((PyObject *)so);
1974 if (keys == NULL)
1975 goto done;
1976 args = PyTuple_Pack(1, keys);
1977 if (args == NULL)
1978 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001979 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 if (dict == NULL) {
1981 PyErr_Clear();
1982 dict = Py_None;
1983 Py_INCREF(dict);
1984 }
1985 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001986done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001987 Py_XDECREF(args);
1988 Py_XDECREF(keys);
1989 Py_XDECREF(dict);
1990 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001991}
1992
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001993static PyObject *
1994set_sizeof(PySetObject *so)
1995{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001996 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001997
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02001998 res = _PyObject_SIZE(Py_TYPE(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001999 if (so->table != so->smalltable)
2000 res = res + (so->mask + 1) * sizeof(setentry);
2001 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002002}
2003
2004PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002005static int
2006set_init(PySetObject *self, PyObject *args, PyObject *kwds)
2007{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002008 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002009
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03002010 if (!_PyArg_NoKeywords("set", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002011 return -1;
2012 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
2013 return -1;
Raymond Hettingerb72e21b2016-03-25 02:29:59 -07002014 if (self->fill)
2015 set_clear_internal(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002016 self->hash = -1;
2017 if (iterable == NULL)
2018 return 0;
2019 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002020}
2021
Raymond Hettingera690a992003-11-16 16:17:49 +00002022static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002023 set_len, /* sq_length */
2024 0, /* sq_concat */
2025 0, /* sq_repeat */
2026 0, /* sq_item */
2027 0, /* sq_slice */
2028 0, /* sq_ass_item */
2029 0, /* sq_ass_slice */
2030 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002031};
2032
2033/* set object ********************************************************/
2034
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002035#ifdef Py_DEBUG
2036static PyObject *test_c_api(PySetObject *so);
2037
2038PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2039All is well if assertions don't fail.");
2040#endif
2041
Raymond Hettingera690a992003-11-16 16:17:49 +00002042static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002043 {"add", (PyCFunction)set_add, METH_O,
2044 add_doc},
2045 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2046 clear_doc},
2047 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2048 contains_doc},
2049 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2050 copy_doc},
2051 {"discard", (PyCFunction)set_discard, METH_O,
2052 discard_doc},
2053 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2054 difference_doc},
2055 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2056 difference_update_doc},
2057 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2058 intersection_doc},
2059 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2060 intersection_update_doc},
2061 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2062 isdisjoint_doc},
2063 {"issubset", (PyCFunction)set_issubset, METH_O,
2064 issubset_doc},
2065 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2066 issuperset_doc},
2067 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2068 pop_doc},
2069 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2070 reduce_doc},
2071 {"remove", (PyCFunction)set_remove, METH_O,
2072 remove_doc},
2073 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2074 sizeof_doc},
2075 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2076 symmetric_difference_doc},
2077 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2078 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002079#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002080 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2081 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002082#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002083 {"union", (PyCFunction)set_union, METH_VARARGS,
2084 union_doc},
2085 {"update", (PyCFunction)set_update, METH_VARARGS,
2086 update_doc},
2087 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002088};
2089
2090static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002091 0, /*nb_add*/
2092 (binaryfunc)set_sub, /*nb_subtract*/
2093 0, /*nb_multiply*/
2094 0, /*nb_remainder*/
2095 0, /*nb_divmod*/
2096 0, /*nb_power*/
2097 0, /*nb_negative*/
2098 0, /*nb_positive*/
2099 0, /*nb_absolute*/
2100 0, /*nb_bool*/
2101 0, /*nb_invert*/
2102 0, /*nb_lshift*/
2103 0, /*nb_rshift*/
2104 (binaryfunc)set_and, /*nb_and*/
2105 (binaryfunc)set_xor, /*nb_xor*/
2106 (binaryfunc)set_or, /*nb_or*/
2107 0, /*nb_int*/
2108 0, /*nb_reserved*/
2109 0, /*nb_float*/
2110 0, /*nb_inplace_add*/
2111 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2112 0, /*nb_inplace_multiply*/
2113 0, /*nb_inplace_remainder*/
2114 0, /*nb_inplace_power*/
2115 0, /*nb_inplace_lshift*/
2116 0, /*nb_inplace_rshift*/
2117 (binaryfunc)set_iand, /*nb_inplace_and*/
2118 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2119 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002120};
2121
2122PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002123"set() -> new empty set object\n\
2124set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002125\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002126Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002127
2128PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002129 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2130 "set", /* tp_name */
2131 sizeof(PySetObject), /* tp_basicsize */
2132 0, /* tp_itemsize */
2133 /* methods */
2134 (destructor)set_dealloc, /* tp_dealloc */
2135 0, /* tp_print */
2136 0, /* tp_getattr */
2137 0, /* tp_setattr */
2138 0, /* tp_reserved */
2139 (reprfunc)set_repr, /* tp_repr */
2140 &set_as_number, /* tp_as_number */
2141 &set_as_sequence, /* tp_as_sequence */
2142 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002143 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002144 0, /* tp_call */
2145 0, /* tp_str */
2146 PyObject_GenericGetAttr, /* tp_getattro */
2147 0, /* tp_setattro */
2148 0, /* tp_as_buffer */
2149 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2150 Py_TPFLAGS_BASETYPE, /* tp_flags */
2151 set_doc, /* tp_doc */
2152 (traverseproc)set_traverse, /* tp_traverse */
2153 (inquiry)set_clear_internal, /* tp_clear */
2154 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002155 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2156 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002157 0, /* tp_iternext */
2158 set_methods, /* tp_methods */
2159 0, /* tp_members */
2160 0, /* tp_getset */
2161 0, /* tp_base */
2162 0, /* tp_dict */
2163 0, /* tp_descr_get */
2164 0, /* tp_descr_set */
2165 0, /* tp_dictoffset */
2166 (initproc)set_init, /* tp_init */
2167 PyType_GenericAlloc, /* tp_alloc */
2168 set_new, /* tp_new */
2169 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002170};
2171
2172/* frozenset object ********************************************************/
2173
2174
2175static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002176 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2177 contains_doc},
2178 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2179 copy_doc},
2180 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2181 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002182 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002183 intersection_doc},
2184 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2185 isdisjoint_doc},
2186 {"issubset", (PyCFunction)set_issubset, METH_O,
2187 issubset_doc},
2188 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2189 issuperset_doc},
2190 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2191 reduce_doc},
2192 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2193 sizeof_doc},
2194 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2195 symmetric_difference_doc},
2196 {"union", (PyCFunction)set_union, METH_VARARGS,
2197 union_doc},
2198 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002199};
2200
2201static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002202 0, /*nb_add*/
2203 (binaryfunc)set_sub, /*nb_subtract*/
2204 0, /*nb_multiply*/
2205 0, /*nb_remainder*/
2206 0, /*nb_divmod*/
2207 0, /*nb_power*/
2208 0, /*nb_negative*/
2209 0, /*nb_positive*/
2210 0, /*nb_absolute*/
2211 0, /*nb_bool*/
2212 0, /*nb_invert*/
2213 0, /*nb_lshift*/
2214 0, /*nb_rshift*/
2215 (binaryfunc)set_and, /*nb_and*/
2216 (binaryfunc)set_xor, /*nb_xor*/
2217 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002218};
2219
2220PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002221"frozenset() -> empty frozenset object\n\
2222frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002223\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002224Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002225
2226PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002227 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2228 "frozenset", /* tp_name */
2229 sizeof(PySetObject), /* tp_basicsize */
2230 0, /* tp_itemsize */
2231 /* methods */
2232 (destructor)set_dealloc, /* tp_dealloc */
2233 0, /* tp_print */
2234 0, /* tp_getattr */
2235 0, /* tp_setattr */
2236 0, /* tp_reserved */
2237 (reprfunc)set_repr, /* tp_repr */
2238 &frozenset_as_number, /* tp_as_number */
2239 &set_as_sequence, /* tp_as_sequence */
2240 0, /* tp_as_mapping */
2241 frozenset_hash, /* tp_hash */
2242 0, /* tp_call */
2243 0, /* tp_str */
2244 PyObject_GenericGetAttr, /* tp_getattro */
2245 0, /* tp_setattro */
2246 0, /* tp_as_buffer */
2247 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2248 Py_TPFLAGS_BASETYPE, /* tp_flags */
2249 frozenset_doc, /* tp_doc */
2250 (traverseproc)set_traverse, /* tp_traverse */
2251 (inquiry)set_clear_internal, /* tp_clear */
2252 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002253 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002254 (getiterfunc)set_iter, /* tp_iter */
2255 0, /* tp_iternext */
2256 frozenset_methods, /* tp_methods */
2257 0, /* tp_members */
2258 0, /* tp_getset */
2259 0, /* tp_base */
2260 0, /* tp_dict */
2261 0, /* tp_descr_get */
2262 0, /* tp_descr_set */
2263 0, /* tp_dictoffset */
2264 0, /* tp_init */
2265 PyType_GenericAlloc, /* tp_alloc */
2266 frozenset_new, /* tp_new */
2267 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002268};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002269
2270
2271/***** C API functions *************************************************/
2272
2273PyObject *
2274PySet_New(PyObject *iterable)
2275{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002276 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002277}
2278
2279PyObject *
2280PyFrozenSet_New(PyObject *iterable)
2281{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002282 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002283}
2284
Neal Norwitz8c49c822006-03-04 18:41:19 +00002285Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002286PySet_Size(PyObject *anyset)
2287{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002288 if (!PyAnySet_Check(anyset)) {
2289 PyErr_BadInternalCall();
2290 return -1;
2291 }
2292 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002293}
2294
2295int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002296PySet_Clear(PyObject *set)
2297{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002298 if (!PySet_Check(set)) {
2299 PyErr_BadInternalCall();
2300 return -1;
2301 }
2302 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002303}
2304
2305int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002306PySet_Contains(PyObject *anyset, PyObject *key)
2307{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002308 if (!PyAnySet_Check(anyset)) {
2309 PyErr_BadInternalCall();
2310 return -1;
2311 }
2312 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002313}
2314
2315int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002316PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002317{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002318 if (!PySet_Check(set)) {
2319 PyErr_BadInternalCall();
2320 return -1;
2321 }
2322 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002323}
2324
2325int
Christian Heimesfd66e512008-01-29 12:18:50 +00002326PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002327{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002328 if (!PySet_Check(anyset) &&
2329 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2330 PyErr_BadInternalCall();
2331 return -1;
2332 }
2333 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002334}
2335
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002336int
Raymond Hettinger3625af52016-03-27 01:15:07 -07002337PySet_ClearFreeList(void)
2338{
2339 return 0;
2340}
2341
2342void
2343PySet_Fini(void)
2344{
2345 Py_CLEAR(emptyfrozenset);
2346}
2347
2348int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002349_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002350{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002351 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002353 if (!PyAnySet_Check(set)) {
2354 PyErr_BadInternalCall();
2355 return -1;
2356 }
2357 if (set_next((PySetObject *)set, pos, &entry) == 0)
2358 return 0;
2359 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002360 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002361 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002362}
2363
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002364PyObject *
2365PySet_Pop(PyObject *set)
2366{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002367 if (!PySet_Check(set)) {
2368 PyErr_BadInternalCall();
2369 return NULL;
2370 }
2371 return set_pop((PySetObject *)set);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002372}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002373
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002374int
2375_PySet_Update(PyObject *set, PyObject *iterable)
2376{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002377 if (!PySet_Check(set)) {
2378 PyErr_BadInternalCall();
2379 return -1;
2380 }
2381 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002382}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002383
Raymond Hettingere259f132013-12-15 11:56:14 -08002384/* Exported for the gdb plugin's benefit. */
2385PyObject *_PySet_Dummy = dummy;
2386
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002387#ifdef Py_DEBUG
2388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002389/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002390 Returns True and original set is restored. */
2391
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002392#define assertRaises(call_return_value, exception) \
2393 do { \
2394 assert(call_return_value); \
2395 assert(PyErr_ExceptionMatches(exception)); \
2396 PyErr_Clear(); \
2397 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002398
2399static PyObject *
2400test_c_api(PySetObject *so)
2401{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002402 Py_ssize_t count;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +02002403 const char *s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002405 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002406 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002407 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002410 /* Verify preconditions */
2411 assert(PyAnySet_Check(ob));
2412 assert(PyAnySet_CheckExact(ob));
2413 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002415 /* so.clear(); so |= set("abc"); */
2416 str = PyUnicode_FromString("abc");
2417 if (str == NULL)
2418 return NULL;
2419 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002420 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 Py_DECREF(str);
2422 return NULL;
2423 }
2424 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002426 /* Exercise type/size checks */
2427 assert(PySet_Size(ob) == 3);
2428 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002430 /* Raise TypeError for non-iterable constructor arguments */
2431 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2432 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002433
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002434 /* Raise TypeError for unhashable key */
2435 dup = PySet_New(ob);
2436 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2437 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2438 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002440 /* Exercise successful pop, contains, add, and discard */
2441 elem = PySet_Pop(ob);
2442 assert(PySet_Contains(ob, elem) == 0);
2443 assert(PySet_GET_SIZE(ob) == 2);
2444 assert(PySet_Add(ob, elem) == 0);
2445 assert(PySet_Contains(ob, elem) == 1);
2446 assert(PySet_GET_SIZE(ob) == 3);
2447 assert(PySet_Discard(ob, elem) == 1);
2448 assert(PySet_GET_SIZE(ob) == 2);
2449 assert(PySet_Discard(ob, elem) == 0);
2450 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002452 /* Exercise clear */
2453 dup2 = PySet_New(dup);
2454 assert(PySet_Clear(dup2) == 0);
2455 assert(PySet_Size(dup2) == 0);
2456 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002458 /* Raise SystemError on clear or update of frozen set */
2459 f = PyFrozenSet_New(dup);
2460 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2461 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2462 assert(PySet_Add(f, elem) == 0);
2463 Py_INCREF(f);
2464 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2465 Py_DECREF(f);
2466 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002467
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002468 /* Exercise direct iteration */
2469 i = 0, count = 0;
2470 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
Serhiy Storchaka06515832016-11-20 09:13:07 +02002471 s = PyUnicode_AsUTF8(x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002472 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2473 count++;
2474 }
2475 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002477 /* Exercise updates */
2478 dup2 = PySet_New(NULL);
2479 assert(_PySet_Update(dup2, dup) == 0);
2480 assert(PySet_Size(dup2) == 3);
2481 assert(_PySet_Update(dup2, dup) == 0);
2482 assert(PySet_Size(dup2) == 3);
2483 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002485 /* Raise SystemError when self argument is not a set or frozenset. */
2486 t = PyTuple_New(0);
2487 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2488 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2489 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002491 /* Raise SystemError when self argument is not a set. */
2492 f = PyFrozenSet_New(dup);
2493 assert(PySet_Size(f) == 3);
2494 assert(PyFrozenSet_CheckExact(f));
2495 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2496 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2497 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002499 /* Raise KeyError when popping from an empty set */
2500 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2501 Py_DECREF(ob);
2502 assert(PySet_GET_SIZE(ob) == 0);
2503 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002505 /* Restore the set from the copy using the PyNumber API */
2506 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2507 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002509 /* Verify constructors accept NULL arguments */
2510 f = PySet_New(NULL);
2511 assert(f != NULL);
2512 assert(PySet_GET_SIZE(f) == 0);
2513 Py_DECREF(f);
2514 f = PyFrozenSet_New(NULL);
2515 assert(f != NULL);
2516 assert(PyFrozenSet_CheckExact(f));
2517 assert(PySet_GET_SIZE(f) == 0);
2518 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002520 Py_DECREF(elem);
2521 Py_DECREF(dup);
2522 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002523}
2524
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002525#undef assertRaises
2526
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002527#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002528
2529/***** Dummy Struct *************************************************/
2530
2531static PyObject *
2532dummy_repr(PyObject *op)
2533{
2534 return PyUnicode_FromString("<dummy key>");
2535}
2536
2537static void
2538dummy_dealloc(PyObject* ignore)
2539{
2540 Py_FatalError("deallocating <dummy key>");
2541}
2542
2543static PyTypeObject _PySetDummy_Type = {
2544 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2545 "<dummy key> type",
2546 0,
2547 0,
2548 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2549 0, /*tp_print*/
2550 0, /*tp_getattr*/
2551 0, /*tp_setattr*/
2552 0, /*tp_reserved*/
2553 dummy_repr, /*tp_repr*/
2554 0, /*tp_as_number*/
2555 0, /*tp_as_sequence*/
2556 0, /*tp_as_mapping*/
2557 0, /*tp_hash */
2558 0, /*tp_call */
2559 0, /*tp_str */
2560 0, /*tp_getattro */
2561 0, /*tp_setattro */
2562 0, /*tp_as_buffer */
2563 Py_TPFLAGS_DEFAULT, /*tp_flags */
2564};
2565
2566static PyObject _dummy_struct = {
2567 _PyObject_EXTRA_INIT
2568 2, &_PySetDummy_Type
2569};
2570