blob: 82b58382081625cfb085801098e56048de3f74bc [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 Py_ssize_t newsize;
306 setentry *oldtable, *newtable, *entry;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800307 Py_ssize_t oldmask = so->mask;
308 size_t newmask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 int is_oldtable_malloced;
310 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 assert(minused >= 0);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000314 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100315 /* XXX speed-up with intrinsics */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000316 for (newsize = PySet_MINSIZE;
317 newsize <= minused && newsize > 0;
318 newsize <<= 1)
319 ;
320 if (newsize <= 0) {
321 PyErr_NoMemory();
322 return -1;
323 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325 /* Get space for a new table. */
326 oldtable = so->table;
327 assert(oldtable != NULL);
328 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000330 if (newsize == PySet_MINSIZE) {
331 /* A large table is shrinking, or we can't get any smaller. */
332 newtable = so->smalltable;
333 if (newtable == oldtable) {
334 if (so->fill == so->used) {
335 /* No dummies, so no point doing anything. */
336 return 0;
337 }
338 /* We're not going to resize it, but rebuild the
339 table anyway to purge old dummy entries.
340 Subtle: This is *necessary* if fill==size,
341 as set_lookkey needs at least one virgin slot to
342 terminate failing searches. If fill < size, it's
343 merely desirable, as dummies slow searches. */
344 assert(so->fill > so->used);
345 memcpy(small_copy, oldtable, sizeof(small_copy));
346 oldtable = small_copy;
347 }
348 }
349 else {
350 newtable = PyMem_NEW(setentry, newsize);
351 if (newtable == NULL) {
352 PyErr_NoMemory();
353 return -1;
354 }
355 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 /* Make the set empty, using the new table. */
358 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 memset(newtable, 0, sizeof(setentry) * newsize);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800360 so->mask = newsize - 1;
361 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 /* Copy the data over; this is refcount-neutral for active entries;
364 dummy entries aren't copied over, of course */
Raymond Hettinger5088f602015-12-13 18:45:01 -0800365 newmask = (size_t)so->mask;
Raymond Hettingere1af6962017-02-02 08:24:48 -0800366 if (so->fill == so->used) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800367 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800368 if (entry->key != NULL) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800369 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800370 }
371 }
372 } else {
Raymond Hettingere1af6962017-02-02 08:24:48 -0800373 so->fill = so->used;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800374 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800375 if (entry->key != NULL && entry->key != dummy) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800376 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800377 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 }
379 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 if (is_oldtable_malloced)
382 PyMem_DEL(oldtable);
383 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000384}
385
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000386static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700387set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000388{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700389 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000390
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700391 entry = set_lookkey(so, key, hash);
392 if (entry != NULL)
393 return entry->key != NULL;
394 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000395}
396
397#define DISCARD_NOTFOUND 0
398#define DISCARD_FOUND 1
399
400static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700401set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800402{
403 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000405
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700406 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 if (entry == NULL)
408 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700409 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000410 return DISCARD_NOTFOUND;
411 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800413 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000414 so->used--;
415 Py_DECREF(old_key);
416 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000417}
418
419static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700420set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000421{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200422 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000423
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700424 if (!PyUnicode_CheckExact(key) ||
425 (hash = ((PyASCIIObject *) key)->hash) == -1) {
426 hash = PyObject_Hash(key);
427 if (hash == -1)
428 return -1;
429 }
430 return set_add_entry(so, key, hash);
431}
432
433static int
434set_contains_key(PySetObject *so, PyObject *key)
435{
436 Py_hash_t hash;
437
438 if (!PyUnicode_CheckExact(key) ||
439 (hash = ((PyASCIIObject *) key)->hash) == -1) {
440 hash = PyObject_Hash(key);
441 if (hash == -1)
442 return -1;
443 }
444 return set_contains_entry(so, key, hash);
445}
446
447static int
448set_discard_key(PySetObject *so, PyObject *key)
449{
450 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000452 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200453 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 hash = PyObject_Hash(key);
455 if (hash == -1)
456 return -1;
457 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700458 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000459}
460
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700461static void
462set_empty_to_minsize(PySetObject *so)
463{
464 memset(so->smalltable, 0, sizeof(so->smalltable));
465 so->fill = 0;
466 so->used = 0;
467 so->mask = PySet_MINSIZE - 1;
468 so->table = so->smalltable;
469 so->hash = -1;
470}
471
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000472static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000473set_clear_internal(PySetObject *so)
474{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800475 setentry *entry;
476 setentry *table = so->table;
477 Py_ssize_t fill = so->fill;
478 Py_ssize_t used = so->used;
479 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000481
Raymond Hettinger583cd032013-09-07 22:06:35 -0700482 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 /* This is delicate. During the process of clearing the set,
486 * decrefs can cause the set to mutate. To avoid fatal confusion
487 * (voice of experience), we have to make the set empty before
488 * clearing the slots, and never refer to anything via so->ref while
489 * clearing.
490 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000491 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700492 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 else if (fill > 0) {
495 /* It's a small table with something that needs to be cleared.
496 * Afraid the only safe way is to copy the set entries into
497 * another small table first.
498 */
499 memcpy(small_copy, table, sizeof(small_copy));
500 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700501 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000502 }
503 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 /* Now we can finally clear things. If C had refcounts, we could
506 * assert that the refcount on table is 1 now, i.e. that this function
507 * has unique access to it, so decref side-effects can't alter it.
508 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800509 for (entry = table; used > 0; entry++) {
510 if (entry->key && entry->key != dummy) {
511 used--;
512 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000513 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000516 if (table_is_malloced)
517 PyMem_DEL(table);
518 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000519}
520
521/*
522 * Iterate over a set table. Use like so:
523 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000524 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000525 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000526 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000527 * while (set_next(yourset, &pos, &entry)) {
528 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000529 * }
530 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000531 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000533 */
534static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000535set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000536{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 Py_ssize_t i;
538 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700539 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000540
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 assert (PyAnySet_Check(so));
542 i = *pos_ptr;
543 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000544 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700545 entry = &so->table[i];
546 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700548 entry++;
549 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 *pos_ptr = i+1;
551 if (i > mask)
552 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700553 assert(entry != NULL);
554 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000555 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000556}
557
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000558static void
559set_dealloc(PySetObject *so)
560{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200561 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800562 Py_ssize_t used = so->used;
563
INADA Naokia6296d32017-08-24 14:55:17 +0900564 /* bpo-31095: UnTrack is needed before calling any callbacks */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000565 PyObject_GC_UnTrack(so);
566 Py_TRASHCAN_SAFE_BEGIN(so)
567 if (so->weakreflist != NULL)
568 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000569
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800570 for (entry = so->table; used > 0; entry++) {
571 if (entry->key && entry->key != dummy) {
572 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700573 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000574 }
575 }
576 if (so->table != so->smalltable)
577 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700578 Py_TYPE(so)->tp_free(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000579 Py_TRASHCAN_SAFE_END(so)
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000580}
581
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000582static PyObject *
583set_repr(PySetObject *so)
584{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200585 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 if (status != 0) {
589 if (status < 0)
590 return NULL;
591 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
592 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000594 /* shortcut for the empty set */
595 if (!so->used) {
596 Py_ReprLeave((PyObject*)so);
597 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
598 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 keys = PySequence_List((PyObject *)so);
601 if (keys == NULL)
602 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000603
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200604 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 listrepr = PyObject_Repr(keys);
606 Py_DECREF(keys);
607 if (listrepr == NULL)
608 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200609 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200611 if (tmp == NULL)
612 goto done;
613 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200614
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200615 if (Py_TYPE(so) != &PySet_Type)
616 result = PyUnicode_FromFormat("%s({%U})",
617 Py_TYPE(so)->tp_name,
618 listrepr);
619 else
620 result = PyUnicode_FromFormat("{%U}", listrepr);
621 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000622done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 Py_ReprLeave((PyObject*)so);
624 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000625}
626
Martin v. Löwis18e16552006-02-15 17:27:45 +0000627static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000628set_len(PyObject *so)
629{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000631}
632
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000633static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000634set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000635{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000636 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000637 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200638 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700639 setentry *so_entry;
640 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000641
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000642 assert (PyAnySet_Check(so));
643 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000644
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000645 other = (PySetObject*)otherset;
646 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700647 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 return 0;
649 /* Do one big resize at the start, rather than
650 * incrementally resizing as we insert new keys. Expect
651 * that there will be no (or few) overlapping keys.
652 */
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800653 if ((so->fill + other->used)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900654 if (set_table_resize(so, (so->used + other->used)*2) != 0)
655 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700657 so_entry = so->table;
658 other_entry = other->table;
659
660 /* If our table is empty, and both tables have the same size, and
661 there are no dummies to eliminate, then just copy the pointers. */
662 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
663 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
664 key = other_entry->key;
665 if (key != NULL) {
666 assert(so_entry->key == NULL);
667 Py_INCREF(key);
668 so_entry->key = key;
669 so_entry->hash = other_entry->hash;
670 }
671 }
672 so->fill = other->fill;
673 so->used = other->used;
674 return 0;
675 }
676
677 /* If our table is empty, we can use set_insert_clean() */
678 if (so->fill == 0) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800679 setentry *newtable = so->table;
680 size_t newmask = (size_t)so->mask;
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800681 so->fill = other->used;
682 so->used = other->used;
Raymond Hettingere4495872015-12-15 00:42:30 -0800683 for (i = other->mask + 1; i > 0 ; i--, other_entry++) {
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700684 key = other_entry->key;
685 if (key != NULL && key != dummy) {
686 Py_INCREF(key);
Raymond Hettinger5088f602015-12-13 18:45:01 -0800687 set_insert_clean(newtable, newmask, key, other_entry->hash);
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700688 }
689 }
690 return 0;
691 }
692
693 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700694 for (i = 0; i <= other->mask; i++) {
695 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700696 key = other_entry->key;
697 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700698 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000699 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000700 }
701 }
702 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000703}
704
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000705static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530706set_pop(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000707{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800708 /* Make sure the search finger is in bounds */
709 Py_ssize_t i = so->finger & so->mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200710 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000712
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000713 assert (PyAnySet_Check(so));
714 if (so->used == 0) {
715 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
716 return NULL;
717 }
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000718
Raymond Hettinger1202a472015-01-18 13:12:42 -0800719 while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
720 i++;
Raymond Hettingered741d42015-01-18 21:25:15 -0800721 if (i > so->mask)
722 i = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 }
724 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800726 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000727 so->used--;
Raymond Hettinger1202a472015-01-18 13:12:42 -0800728 so->finger = i + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000729 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000730}
731
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000732PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
733Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000734
735static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000736set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000737{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 Py_ssize_t pos = 0;
739 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000740
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000741 while (set_next(so, &pos, &entry))
742 Py_VISIT(entry->key);
743 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000744}
745
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700746/* Work to increase the bit dispersion for closely spaced hash values.
747 This is important because some use cases have many combinations of a
748 small number of elements with nearby hashes so that many distinct
749 combinations collapse to only a handful of distinct hash values. */
750
751static Py_uhash_t
752_shuffle_bits(Py_uhash_t h)
753{
754 return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
755}
756
757/* Most of the constants in this hash algorithm are randomly chosen
758 large primes with "interesting bit patterns" and that passed tests
759 for good collision statistics on a variety of problematic datasets
760 including powersets and graph structures (such as David Eppstein's
761 graph recipes in Lib/test/test_set.py) */
762
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000763static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000764frozenset_hash(PyObject *self)
765{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000766 PySetObject *so = (PySetObject *)self;
Raymond Hettinger41481952015-08-07 00:43:39 -0700767 Py_uhash_t hash = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000768 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000769
Raymond Hettingerb501a272015-08-06 22:15:22 -0700770 if (so->hash != -1)
771 return so->hash;
772
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700773 /* Xor-in shuffled bits from every entry's hash field because xor is
774 commutative and a frozenset hash should be independent of order.
775
776 For speed, include null entries and dummy entries and then
777 subtract out their effect afterwards so that the final hash
778 depends only on active entries. This allows the code to be
779 vectorized by the compiler and it saves the unpredictable
780 branches that would arise when trying to exclude null and dummy
781 entries on every iteration. */
782
783 for (entry = so->table; entry <= &so->table[so->mask]; entry++)
784 hash ^= _shuffle_bits(entry->hash);
785
Raymond Hettingera286a512015-08-01 11:07:11 -0700786 /* Remove the effect of an odd number of NULL entries */
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700787 if ((so->mask + 1 - so->fill) & 1)
788 hash ^= _shuffle_bits(0);
789
790 /* Remove the effect of an odd number of dummy entries */
791 if ((so->fill - so->used) & 1)
792 hash ^= _shuffle_bits(-1);
793
Raymond Hettinger41481952015-08-07 00:43:39 -0700794 /* Factor in the number of active entries */
795 hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;
796
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700797 /* Disperse patterns arising in nested frozensets */
Raymond Hettingerfa788062018-01-18 13:23:27 -0800798 hash ^= (hash >> 11) ^ (hash >> 25);
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800799 hash = hash * 69069U + 907133923UL;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700800
Raymond Hettinger36c05002015-08-01 10:57:42 -0700801 /* -1 is reserved as an error code */
Victor Stinner12174a52014-08-15 23:17:38 +0200802 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800803 hash = 590923713UL;
Raymond Hettinger36c05002015-08-01 10:57:42 -0700804
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000805 so->hash = hash;
806 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000807}
808
Raymond Hettingera9d99362005-08-05 00:01:15 +0000809/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000810
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000811typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000812 PyObject_HEAD
813 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
814 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700815 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000816 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000817} setiterobject;
818
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000819static void
820setiter_dealloc(setiterobject *si)
821{
INADA Naokia6296d32017-08-24 14:55:17 +0900822 /* bpo-31095: UnTrack is needed before calling any callbacks */
823 _PyObject_GC_UNTRACK(si);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000824 Py_XDECREF(si->si_set);
825 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000826}
827
828static int
829setiter_traverse(setiterobject *si, visitproc visit, void *arg)
830{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000831 Py_VISIT(si->si_set);
832 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000833}
834
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000835static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530836setiter_len(setiterobject *si, PyObject *Py_UNUSED(ignored))
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000837{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000838 Py_ssize_t len = 0;
839 if (si->si_set != NULL && si->si_used == si->si_set->used)
840 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000841 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000842}
843
Armin Rigof5b3e362006-02-11 21:32:43 +0000844PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000845
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000846static PyObject *setiter_iternext(setiterobject *si);
847
848static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530849setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000850{
851 PyObject *list;
852 setiterobject tmp;
853
854 list = PyList_New(0);
855 if (!list)
856 return NULL;
857
Ezio Melotti0e1af282012-09-28 16:43:40 +0300858 /* copy the iterator state */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000859 tmp = *si;
860 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300861
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000862 /* iterate the temporary into a list */
863 for(;;) {
864 PyObject *element = setiter_iternext(&tmp);
865 if (element) {
866 if (PyList_Append(list, element)) {
867 Py_DECREF(element);
868 Py_DECREF(list);
869 Py_XDECREF(tmp.si_set);
870 return NULL;
871 }
872 Py_DECREF(element);
873 } else
874 break;
875 }
876 Py_XDECREF(tmp.si_set);
877 /* check for error */
878 if (tmp.si_set != NULL) {
879 /* we have an error */
880 Py_DECREF(list);
881 return NULL;
882 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200883 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000884}
885
886PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
887
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000888static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000890 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000891 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000892};
893
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000894static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000895{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700896 PyObject *key;
897 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200898 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000899 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000901 if (so == NULL)
902 return NULL;
903 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000904
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000905 if (si->si_used != so->used) {
906 PyErr_SetString(PyExc_RuntimeError,
907 "Set changed size during iteration");
908 si->si_used = -1; /* Make this state sticky */
909 return NULL;
910 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700911
912 i = si->si_pos;
913 assert(i>=0);
914 entry = so->table;
915 mask = so->mask;
916 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
917 i++;
918 si->si_pos = i+1;
919 if (i > mask)
920 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000921 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700922 key = entry[i].key;
923 Py_INCREF(key);
924 return key;
925
926fail:
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700927 si->si_set = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +0300928 Py_DECREF(so);
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700929 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000930}
931
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000932PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000933 PyVarObject_HEAD_INIT(&PyType_Type, 0)
934 "set_iterator", /* tp_name */
935 sizeof(setiterobject), /* tp_basicsize */
936 0, /* tp_itemsize */
937 /* methods */
938 (destructor)setiter_dealloc, /* tp_dealloc */
939 0, /* tp_print */
940 0, /* tp_getattr */
941 0, /* tp_setattr */
942 0, /* tp_reserved */
943 0, /* tp_repr */
944 0, /* tp_as_number */
945 0, /* tp_as_sequence */
946 0, /* tp_as_mapping */
947 0, /* tp_hash */
948 0, /* tp_call */
949 0, /* tp_str */
950 PyObject_GenericGetAttr, /* tp_getattro */
951 0, /* tp_setattro */
952 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700953 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 0, /* tp_doc */
955 (traverseproc)setiter_traverse, /* tp_traverse */
956 0, /* tp_clear */
957 0, /* tp_richcompare */
958 0, /* tp_weaklistoffset */
959 PyObject_SelfIter, /* tp_iter */
960 (iternextfunc)setiter_iternext, /* tp_iternext */
961 setiter_methods, /* tp_methods */
962 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000963};
964
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000965static PyObject *
966set_iter(PySetObject *so)
967{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000968 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
969 if (si == NULL)
970 return NULL;
971 Py_INCREF(so);
972 si->si_set = so;
973 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700974 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000975 si->len = so->used;
976 _PyObject_GC_TRACK(si);
977 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000978}
979
Raymond Hettingerd7946662005-08-01 21:39:29 +0000980static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000981set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000982{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000984
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 if (PyAnySet_Check(other))
986 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 if (PyDict_CheckExact(other)) {
989 PyObject *value;
990 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000991 Py_hash_t hash;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200992 Py_ssize_t dictsize = PyDict_GET_SIZE(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000993
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000994 /* Do one big resize at the start, rather than
995 * incrementally resizing as we insert new keys. Expect
996 * that there will be no (or few) overlapping keys.
997 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700998 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 return -1;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -08001000 if ((so->fill + dictsize)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +09001001 if (set_table_resize(so, (so->used + dictsize)*2) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001002 return -1;
1003 }
1004 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001005 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 return -1;
1007 }
1008 return 0;
1009 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001011 it = PyObject_GetIter(other);
1012 if (it == NULL)
1013 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +00001014
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001016 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001017 Py_DECREF(it);
1018 Py_DECREF(key);
1019 return -1;
1020 }
1021 Py_DECREF(key);
1022 }
1023 Py_DECREF(it);
1024 if (PyErr_Occurred())
1025 return -1;
1026 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001027}
1028
1029static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001030set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001031{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001033
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1035 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001036 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001037 return NULL;
1038 }
1039 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001040}
1041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001043"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001044
Raymond Hettinger426d9952014-05-18 21:40:20 +01001045/* XXX Todo:
1046 If aligned memory allocations become available, make the
1047 set object 64 byte aligned so that most of the fields
1048 can be retrieved or updated in a single cache line.
1049*/
1050
Raymond Hettingera38123e2003-11-24 22:18:49 +00001051static PyObject *
1052make_new_set(PyTypeObject *type, PyObject *iterable)
1053{
Raymond Hettinger8421d712016-04-29 01:37:05 -07001054 PySetObject *so;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001055
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001056 so = (PySetObject *)type->tp_alloc(type, 0);
1057 if (so == NULL)
1058 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001059
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001060 so->fill = 0;
1061 so->used = 0;
1062 so->mask = PySet_MINSIZE - 1;
1063 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001064 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001065 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001068 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001069 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 Py_DECREF(so);
1071 return NULL;
1072 }
1073 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001074
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001075 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001076}
1077
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001078static PyObject *
1079make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001081 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1082 if (PyType_IsSubtype(type, &PySet_Type))
1083 type = &PySet_Type;
1084 else
1085 type = &PyFrozenSet_Type;
1086 }
1087 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001088}
1089
Raymond Hettingerd7946662005-08-01 21:39:29 +00001090/* The empty frozenset is a singleton */
1091static PyObject *emptyfrozenset = NULL;
1092
Raymond Hettingera690a992003-11-16 16:17:49 +00001093static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001094frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001095{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001097
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001098 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001100
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001101 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1102 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 if (type != &PyFrozenSet_Type)
1105 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001106
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001107 if (iterable != NULL) {
1108 /* frozenset(f) is idempotent */
1109 if (PyFrozenSet_CheckExact(iterable)) {
1110 Py_INCREF(iterable);
1111 return iterable;
1112 }
1113 result = make_new_set(type, iterable);
1114 if (result == NULL || PySet_GET_SIZE(result))
1115 return result;
1116 Py_DECREF(result);
1117 }
1118 /* The empty frozenset is a singleton */
1119 if (emptyfrozenset == NULL)
1120 emptyfrozenset = make_new_set(type, NULL);
1121 Py_XINCREF(emptyfrozenset);
1122 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001123}
1124
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001125static PyObject *
1126set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1127{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001128 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001129}
1130
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001131/* set_swap_bodies() switches the contents of any two sets by moving their
1132 internal data pointers and, if needed, copying the internal smalltables.
1133 Semantically equivalent to:
1134
1135 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1136
1137 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001138 Useful for operations that update in-place (by allowing an intermediate
1139 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001140*/
1141
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001142static void
1143set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001144{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 Py_ssize_t t;
1146 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001148 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 t = a->fill; a->fill = b->fill; b->fill = t;
1151 t = a->used; a->used = b->used; b->used = t;
1152 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001154 u = a->table;
1155 if (a->table == a->smalltable)
1156 u = b->smalltable;
1157 a->table = b->table;
1158 if (b->table == b->smalltable)
1159 a->table = a->smalltable;
1160 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 if (a->table == a->smalltable || b->table == b->smalltable) {
1163 memcpy(tab, a->smalltable, sizeof(tab));
1164 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1165 memcpy(b->smalltable, tab, sizeof(tab));
1166 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1169 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1170 h = a->hash; a->hash = b->hash; b->hash = h;
1171 } else {
1172 a->hash = -1;
1173 b->hash = -1;
1174 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001175}
1176
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001177static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301178set_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001179{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001180 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001181}
1182
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001183static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301184frozenset_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001185{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 if (PyFrozenSet_CheckExact(so)) {
1187 Py_INCREF(so);
1188 return (PyObject *)so;
1189 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301190 return set_copy(so, NULL);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001191}
1192
Raymond Hettingera690a992003-11-16 16:17:49 +00001193PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1194
1195static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301196set_clear(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc991db22005-08-11 07:58:45 +00001197{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001198 set_clear_internal(so);
1199 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001200}
1201
1202PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1203
1204static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001205set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001206{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 PySetObject *result;
1208 PyObject *other;
1209 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001210
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301211 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 if (result == NULL)
1213 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001215 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1216 other = PyTuple_GET_ITEM(args, i);
1217 if ((PyObject *)so == other)
1218 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001219 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001220 Py_DECREF(result);
1221 return NULL;
1222 }
1223 }
1224 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001225}
1226
1227PyDoc_STRVAR(union_doc,
1228 "Return the union of sets as a new set.\n\
1229\n\
1230(i.e. all elements that are in either set.)");
1231
1232static PyObject *
1233set_or(PySetObject *so, PyObject *other)
1234{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001236
Brian Curtindfc80e32011-08-10 20:28:54 -05001237 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1238 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001239
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301240 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 if (result == NULL)
1242 return NULL;
1243 if ((PyObject *)so == other)
1244 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001245 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 Py_DECREF(result);
1247 return NULL;
1248 }
1249 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001250}
1251
Raymond Hettingera690a992003-11-16 16:17:49 +00001252static PyObject *
1253set_ior(PySetObject *so, PyObject *other)
1254{
Brian Curtindfc80e32011-08-10 20:28:54 -05001255 if (!PyAnySet_Check(other))
1256 Py_RETURN_NOTIMPLEMENTED;
1257
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001258 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001259 return NULL;
1260 Py_INCREF(so);
1261 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001262}
1263
1264static PyObject *
1265set_intersection(PySetObject *so, PyObject *other)
1266{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 PySetObject *result;
1268 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001269 Py_hash_t hash;
1270 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001272 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301273 return set_copy(so, NULL);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1276 if (result == NULL)
1277 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 if (PyAnySet_Check(other)) {
1280 Py_ssize_t pos = 0;
1281 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1284 tmp = (PyObject *)so;
1285 so = (PySetObject *)other;
1286 other = tmp;
1287 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001290 key = entry->key;
1291 hash = entry->hash;
1292 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001293 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 Py_DECREF(result);
1295 return NULL;
1296 }
1297 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001298 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 Py_DECREF(result);
1300 return NULL;
1301 }
1302 }
1303 }
1304 return (PyObject *)result;
1305 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 it = PyObject_GetIter(other);
1308 if (it == NULL) {
1309 Py_DECREF(result);
1310 return NULL;
1311 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001314 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001315 if (hash == -1)
1316 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001317 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001318 if (rv < 0)
1319 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001321 if (set_add_entry(result, key, hash))
1322 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 }
1324 Py_DECREF(key);
1325 }
1326 Py_DECREF(it);
1327 if (PyErr_Occurred()) {
1328 Py_DECREF(result);
1329 return NULL;
1330 }
1331 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001332 error:
1333 Py_DECREF(it);
1334 Py_DECREF(result);
1335 Py_DECREF(key);
1336 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001337}
1338
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001339static PyObject *
1340set_intersection_multi(PySetObject *so, PyObject *args)
1341{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001342 Py_ssize_t i;
1343 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301346 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 Py_INCREF(so);
1349 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1350 PyObject *other = PyTuple_GET_ITEM(args, i);
1351 PyObject *newresult = set_intersection((PySetObject *)result, other);
1352 if (newresult == NULL) {
1353 Py_DECREF(result);
1354 return NULL;
1355 }
1356 Py_DECREF(result);
1357 result = newresult;
1358 }
1359 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001360}
1361
Raymond Hettingera690a992003-11-16 16:17:49 +00001362PyDoc_STRVAR(intersection_doc,
1363"Return the intersection of two sets as a new set.\n\
1364\n\
1365(i.e. all elements that are in both sets.)");
1366
1367static PyObject *
1368set_intersection_update(PySetObject *so, PyObject *other)
1369{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001371
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 tmp = set_intersection(so, other);
1373 if (tmp == NULL)
1374 return NULL;
1375 set_swap_bodies(so, (PySetObject *)tmp);
1376 Py_DECREF(tmp);
1377 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001378}
1379
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001380static PyObject *
1381set_intersection_update_multi(PySetObject *so, PyObject *args)
1382{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385 tmp = set_intersection_multi(so, args);
1386 if (tmp == NULL)
1387 return NULL;
1388 set_swap_bodies(so, (PySetObject *)tmp);
1389 Py_DECREF(tmp);
1390 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001391}
1392
Raymond Hettingera690a992003-11-16 16:17:49 +00001393PyDoc_STRVAR(intersection_update_doc,
1394"Update a set with the intersection of itself and another.");
1395
1396static PyObject *
1397set_and(PySetObject *so, PyObject *other)
1398{
Brian Curtindfc80e32011-08-10 20:28:54 -05001399 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1400 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001401 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001402}
1403
1404static PyObject *
1405set_iand(PySetObject *so, PyObject *other)
1406{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001407 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001408
Brian Curtindfc80e32011-08-10 20:28:54 -05001409 if (!PyAnySet_Check(other))
1410 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 result = set_intersection_update(so, other);
1412 if (result == NULL)
1413 return NULL;
1414 Py_DECREF(result);
1415 Py_INCREF(so);
1416 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001417}
1418
Guido van Rossum58da9312007-11-10 23:39:45 +00001419static PyObject *
1420set_isdisjoint(PySetObject *so, PyObject *other)
1421{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001422 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001423 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 if ((PyObject *)so == other) {
1426 if (PySet_GET_SIZE(so) == 0)
1427 Py_RETURN_TRUE;
1428 else
1429 Py_RETURN_FALSE;
1430 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 if (PyAnySet_CheckExact(other)) {
1433 Py_ssize_t pos = 0;
1434 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1437 tmp = (PyObject *)so;
1438 so = (PySetObject *)other;
1439 other = tmp;
1440 }
1441 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001442 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001443 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001444 return NULL;
1445 if (rv)
1446 Py_RETURN_FALSE;
1447 }
1448 Py_RETURN_TRUE;
1449 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001450
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001451 it = PyObject_GetIter(other);
1452 if (it == NULL)
1453 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001456 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001458 if (hash == -1) {
1459 Py_DECREF(key);
1460 Py_DECREF(it);
1461 return NULL;
1462 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001463 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001465 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 Py_DECREF(it);
1467 return NULL;
1468 }
1469 if (rv) {
1470 Py_DECREF(it);
1471 Py_RETURN_FALSE;
1472 }
1473 }
1474 Py_DECREF(it);
1475 if (PyErr_Occurred())
1476 return NULL;
1477 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001478}
1479
1480PyDoc_STRVAR(isdisjoint_doc,
1481"Return True if two sets have a null intersection.");
1482
Neal Norwitz6576bd82005-11-13 18:41:28 +00001483static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001484set_difference_update_internal(PySetObject *so, PyObject *other)
1485{
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001486 if (PySet_GET_SIZE(so) == 0) {
1487 return 0;
1488 }
1489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 if ((PyObject *)so == other)
1491 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001493 if (PyAnySet_Check(other)) {
1494 setentry *entry;
1495 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001497 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001498 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 return -1;
1500 } else {
1501 PyObject *key, *it;
1502 it = PyObject_GetIter(other);
1503 if (it == NULL)
1504 return -1;
1505
1506 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001507 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 Py_DECREF(it);
1509 Py_DECREF(key);
1510 return -1;
1511 }
1512 Py_DECREF(key);
1513 }
1514 Py_DECREF(it);
1515 if (PyErr_Occurred())
1516 return -1;
1517 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001518 /* If more than 1/4th are dummies, then resize them away. */
1519 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +09001521 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001522}
1523
Raymond Hettingera690a992003-11-16 16:17:49 +00001524static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001525set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001526{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001527 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1530 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001531 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001532 return NULL;
1533 }
1534 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001535}
1536
1537PyDoc_STRVAR(difference_update_doc,
1538"Remove all elements of another set from this set.");
1539
1540static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001541set_copy_and_difference(PySetObject *so, PyObject *other)
1542{
1543 PyObject *result;
1544
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301545 result = set_copy(so, NULL);
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001546 if (result == NULL)
1547 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001548 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001549 return result;
1550 Py_DECREF(result);
1551 return NULL;
1552}
1553
1554static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001555set_difference(PySetObject *so, PyObject *other)
1556{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001557 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001558 PyObject *key;
1559 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001560 setentry *entry;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001561 Py_ssize_t pos = 0, other_size;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001562 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001563
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001564 if (PySet_GET_SIZE(so) == 0) {
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301565 return set_copy(so, NULL);
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001566 }
1567
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001568 if (PyAnySet_Check(other)) {
1569 other_size = PySet_GET_SIZE(other);
1570 }
1571 else if (PyDict_CheckExact(other)) {
1572 other_size = PyDict_GET_SIZE(other);
1573 }
1574 else {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001575 return set_copy_and_difference(so, other);
1576 }
1577
1578 /* If len(so) much more than len(other), it's more efficient to simply copy
1579 * so and then iterate other looking for common elements. */
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001580 if ((PySet_GET_SIZE(so) >> 2) > other_size) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001581 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001583
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001584 result = make_new_set_basetype(Py_TYPE(so), NULL);
1585 if (result == NULL)
1586 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 if (PyDict_CheckExact(other)) {
1589 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001590 key = entry->key;
1591 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001592 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001593 if (rv < 0) {
1594 Py_DECREF(result);
1595 return NULL;
1596 }
1597 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001598 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001599 Py_DECREF(result);
1600 return NULL;
1601 }
1602 }
1603 }
1604 return result;
1605 }
1606
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001607 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001609 key = entry->key;
1610 hash = entry->hash;
1611 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001612 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 Py_DECREF(result);
1614 return NULL;
1615 }
1616 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001617 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001618 Py_DECREF(result);
1619 return NULL;
1620 }
1621 }
1622 }
1623 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001624}
1625
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001626static PyObject *
1627set_difference_multi(PySetObject *so, PyObject *args)
1628{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 Py_ssize_t i;
1630 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301633 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 other = PyTuple_GET_ITEM(args, 0);
1636 result = set_difference(so, other);
1637 if (result == NULL)
1638 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001640 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1641 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001642 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001643 Py_DECREF(result);
1644 return NULL;
1645 }
1646 }
1647 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001648}
1649
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001650PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001651"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001652\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001653(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001654static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001655set_sub(PySetObject *so, PyObject *other)
1656{
Brian Curtindfc80e32011-08-10 20:28:54 -05001657 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1658 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001659 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001660}
1661
1662static PyObject *
1663set_isub(PySetObject *so, PyObject *other)
1664{
Brian Curtindfc80e32011-08-10 20:28:54 -05001665 if (!PyAnySet_Check(other))
1666 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001667 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 return NULL;
1669 Py_INCREF(so);
1670 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001671}
1672
1673static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001674set_symmetric_difference_update(PySetObject *so, PyObject *other)
1675{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001676 PySetObject *otherset;
1677 PyObject *key;
1678 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001679 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001680 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001681 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001682
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001683 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301684 return set_clear(so, NULL);
Raymond Hettingera690a992003-11-16 16:17:49 +00001685
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001686 if (PyDict_CheckExact(other)) {
1687 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001688 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001689 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001690 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001691 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001692 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001693 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001694 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001695 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001696 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001697 Py_DECREF(key);
1698 return NULL;
1699 }
1700 }
Georg Brandl2d444492010-09-03 10:52:55 +00001701 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001702 }
1703 Py_RETURN_NONE;
1704 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001705
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001706 if (PyAnySet_Check(other)) {
1707 Py_INCREF(other);
1708 otherset = (PySetObject *)other;
1709 } else {
1710 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1711 if (otherset == NULL)
1712 return NULL;
1713 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001714
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001715 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001716 key = entry->key;
1717 hash = entry->hash;
1718 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001719 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001720 Py_DECREF(otherset);
1721 return NULL;
1722 }
1723 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001724 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001725 Py_DECREF(otherset);
1726 return NULL;
1727 }
1728 }
1729 }
1730 Py_DECREF(otherset);
1731 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001732}
1733
1734PyDoc_STRVAR(symmetric_difference_update_doc,
1735"Update a set with the symmetric difference of itself and another.");
1736
1737static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001738set_symmetric_difference(PySetObject *so, PyObject *other)
1739{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 PyObject *rv;
1741 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001742
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001743 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1744 if (otherset == NULL)
1745 return NULL;
1746 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
lekma491bbed2018-05-02 11:29:10 +02001747 if (rv == NULL) {
1748 Py_DECREF(otherset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001749 return NULL;
lekma491bbed2018-05-02 11:29:10 +02001750 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001751 Py_DECREF(rv);
1752 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001753}
1754
1755PyDoc_STRVAR(symmetric_difference_doc,
1756"Return the symmetric difference of two sets as a new set.\n\
1757\n\
1758(i.e. all elements that are in exactly one of the sets.)");
1759
1760static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001761set_xor(PySetObject *so, PyObject *other)
1762{
Brian Curtindfc80e32011-08-10 20:28:54 -05001763 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1764 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001765 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001766}
1767
1768static PyObject *
1769set_ixor(PySetObject *so, PyObject *other)
1770{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001771 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001772
Brian Curtindfc80e32011-08-10 20:28:54 -05001773 if (!PyAnySet_Check(other))
1774 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 result = set_symmetric_difference_update(so, other);
1776 if (result == NULL)
1777 return NULL;
1778 Py_DECREF(result);
1779 Py_INCREF(so);
1780 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001781}
1782
1783static PyObject *
1784set_issubset(PySetObject *so, PyObject *other)
1785{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 setentry *entry;
1787 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001788 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001789
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001790 if (!PyAnySet_Check(other)) {
1791 PyObject *tmp, *result;
1792 tmp = make_new_set(&PySet_Type, other);
1793 if (tmp == NULL)
1794 return NULL;
1795 result = set_issubset(so, tmp);
1796 Py_DECREF(tmp);
1797 return result;
1798 }
1799 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1800 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001802 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001803 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001804 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001805 return NULL;
1806 if (!rv)
1807 Py_RETURN_FALSE;
1808 }
1809 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001810}
1811
1812PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1813
1814static PyObject *
1815set_issuperset(PySetObject *so, PyObject *other)
1816{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001817 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001818
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001819 if (!PyAnySet_Check(other)) {
1820 tmp = make_new_set(&PySet_Type, other);
1821 if (tmp == NULL)
1822 return NULL;
1823 result = set_issuperset(so, tmp);
1824 Py_DECREF(tmp);
1825 return result;
1826 }
1827 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001828}
1829
1830PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1831
Raymond Hettingera690a992003-11-16 16:17:49 +00001832static PyObject *
1833set_richcompare(PySetObject *v, PyObject *w, int op)
1834{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001835 PyObject *r1;
1836 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001837
Brian Curtindfc80e32011-08-10 20:28:54 -05001838 if(!PyAnySet_Check(w))
1839 Py_RETURN_NOTIMPLEMENTED;
1840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001841 switch (op) {
1842 case Py_EQ:
1843 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1844 Py_RETURN_FALSE;
1845 if (v->hash != -1 &&
1846 ((PySetObject *)w)->hash != -1 &&
1847 v->hash != ((PySetObject *)w)->hash)
1848 Py_RETURN_FALSE;
1849 return set_issubset(v, w);
1850 case Py_NE:
1851 r1 = set_richcompare(v, w, Py_EQ);
1852 if (r1 == NULL)
1853 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001854 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001856 if (r2 < 0)
1857 return NULL;
1858 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 case Py_LE:
1860 return set_issubset(v, w);
1861 case Py_GE:
1862 return set_issuperset(v, w);
1863 case Py_LT:
1864 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1865 Py_RETURN_FALSE;
1866 return set_issubset(v, w);
1867 case Py_GT:
1868 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1869 Py_RETURN_FALSE;
1870 return set_issuperset(v, w);
1871 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001872 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001873}
1874
Raymond Hettingera690a992003-11-16 16:17:49 +00001875static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001876set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001877{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001878 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001879 return NULL;
1880 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001881}
1882
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001883PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001884"Add an element to a set.\n\
1885\n\
1886This has no effect if the element is already present.");
1887
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001888static int
1889set_contains(PySetObject *so, PyObject *key)
1890{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 PyObject *tmpkey;
1892 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001895 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1897 return -1;
1898 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001899 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 if (tmpkey == NULL)
1901 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001902 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001903 Py_DECREF(tmpkey);
1904 }
1905 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001906}
1907
1908static PyObject *
1909set_direct_contains(PySetObject *so, PyObject *key)
1910{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001913 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001914 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 return NULL;
1916 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001917}
1918
1919PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1920
Raymond Hettingera690a992003-11-16 16:17:49 +00001921static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001922set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001923{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 PyObject *tmpkey;
1925 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001928 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001929 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1930 return NULL;
1931 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001932 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001933 if (tmpkey == NULL)
1934 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001935 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001937 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 return NULL;
1939 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001940
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001941 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001942 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 return NULL;
1944 }
1945 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001946}
1947
1948PyDoc_STRVAR(remove_doc,
1949"Remove an element from a set; it must be a member.\n\
1950\n\
1951If the element is not a member, raise a KeyError.");
1952
1953static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001954set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001955{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001956 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001957 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001959 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001960 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001961 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1962 return NULL;
1963 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001964 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001965 if (tmpkey == NULL)
1966 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001967 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001969 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001970 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001971 }
1972 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001973}
1974
1975PyDoc_STRVAR(discard_doc,
1976"Remove an element from a set if it is a member.\n\
1977\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001978If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001979
1980static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301981set_reduce(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001982{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001983 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001984 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001985
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001986 keys = PySequence_List((PyObject *)so);
1987 if (keys == NULL)
1988 goto done;
1989 args = PyTuple_Pack(1, keys);
1990 if (args == NULL)
1991 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001992 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001993 if (dict == NULL) {
1994 PyErr_Clear();
1995 dict = Py_None;
1996 Py_INCREF(dict);
1997 }
1998 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001999done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002000 Py_XDECREF(args);
2001 Py_XDECREF(keys);
2002 Py_XDECREF(dict);
2003 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00002004}
2005
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002006static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302007set_sizeof(PySetObject *so, PyObject *Py_UNUSED(ignored))
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002008{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002009 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002010
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02002011 res = _PyObject_SIZE(Py_TYPE(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002012 if (so->table != so->smalltable)
2013 res = res + (so->mask + 1) * sizeof(setentry);
2014 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002015}
2016
2017PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002018static int
2019set_init(PySetObject *self, PyObject *args, PyObject *kwds)
2020{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002021 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002022
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03002023 if (!_PyArg_NoKeywords("set", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002024 return -1;
2025 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
2026 return -1;
Raymond Hettingerb72e21b2016-03-25 02:29:59 -07002027 if (self->fill)
2028 set_clear_internal(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002029 self->hash = -1;
2030 if (iterable == NULL)
2031 return 0;
2032 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002033}
2034
Raymond Hettingera690a992003-11-16 16:17:49 +00002035static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002036 set_len, /* sq_length */
2037 0, /* sq_concat */
2038 0, /* sq_repeat */
2039 0, /* sq_item */
2040 0, /* sq_slice */
2041 0, /* sq_ass_item */
2042 0, /* sq_ass_slice */
2043 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002044};
2045
2046/* set object ********************************************************/
2047
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002048#ifdef Py_DEBUG
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302049static PyObject *test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored));
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002050
2051PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2052All is well if assertions don't fail.");
2053#endif
2054
Raymond Hettingera690a992003-11-16 16:17:49 +00002055static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002056 {"add", (PyCFunction)set_add, METH_O,
2057 add_doc},
2058 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2059 clear_doc},
2060 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2061 contains_doc},
2062 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2063 copy_doc},
2064 {"discard", (PyCFunction)set_discard, METH_O,
2065 discard_doc},
2066 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2067 difference_doc},
2068 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2069 difference_update_doc},
2070 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2071 intersection_doc},
2072 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2073 intersection_update_doc},
2074 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2075 isdisjoint_doc},
2076 {"issubset", (PyCFunction)set_issubset, METH_O,
2077 issubset_doc},
2078 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2079 issuperset_doc},
2080 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2081 pop_doc},
2082 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2083 reduce_doc},
2084 {"remove", (PyCFunction)set_remove, METH_O,
2085 remove_doc},
2086 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2087 sizeof_doc},
2088 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2089 symmetric_difference_doc},
2090 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2091 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002092#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002093 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2094 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002095#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002096 {"union", (PyCFunction)set_union, METH_VARARGS,
2097 union_doc},
2098 {"update", (PyCFunction)set_update, METH_VARARGS,
2099 update_doc},
2100 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002101};
2102
2103static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002104 0, /*nb_add*/
2105 (binaryfunc)set_sub, /*nb_subtract*/
2106 0, /*nb_multiply*/
2107 0, /*nb_remainder*/
2108 0, /*nb_divmod*/
2109 0, /*nb_power*/
2110 0, /*nb_negative*/
2111 0, /*nb_positive*/
2112 0, /*nb_absolute*/
2113 0, /*nb_bool*/
2114 0, /*nb_invert*/
2115 0, /*nb_lshift*/
2116 0, /*nb_rshift*/
2117 (binaryfunc)set_and, /*nb_and*/
2118 (binaryfunc)set_xor, /*nb_xor*/
2119 (binaryfunc)set_or, /*nb_or*/
2120 0, /*nb_int*/
2121 0, /*nb_reserved*/
2122 0, /*nb_float*/
2123 0, /*nb_inplace_add*/
2124 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2125 0, /*nb_inplace_multiply*/
2126 0, /*nb_inplace_remainder*/
2127 0, /*nb_inplace_power*/
2128 0, /*nb_inplace_lshift*/
2129 0, /*nb_inplace_rshift*/
2130 (binaryfunc)set_iand, /*nb_inplace_and*/
2131 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2132 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002133};
2134
2135PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002136"set() -> new empty set object\n\
2137set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002138\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002139Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002140
2141PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002142 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2143 "set", /* tp_name */
2144 sizeof(PySetObject), /* tp_basicsize */
2145 0, /* tp_itemsize */
2146 /* methods */
2147 (destructor)set_dealloc, /* tp_dealloc */
2148 0, /* tp_print */
2149 0, /* tp_getattr */
2150 0, /* tp_setattr */
2151 0, /* tp_reserved */
2152 (reprfunc)set_repr, /* tp_repr */
2153 &set_as_number, /* tp_as_number */
2154 &set_as_sequence, /* tp_as_sequence */
2155 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002156 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002157 0, /* tp_call */
2158 0, /* tp_str */
2159 PyObject_GenericGetAttr, /* tp_getattro */
2160 0, /* tp_setattro */
2161 0, /* tp_as_buffer */
2162 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2163 Py_TPFLAGS_BASETYPE, /* tp_flags */
2164 set_doc, /* tp_doc */
2165 (traverseproc)set_traverse, /* tp_traverse */
2166 (inquiry)set_clear_internal, /* tp_clear */
2167 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002168 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2169 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002170 0, /* tp_iternext */
2171 set_methods, /* tp_methods */
2172 0, /* tp_members */
2173 0, /* tp_getset */
2174 0, /* tp_base */
2175 0, /* tp_dict */
2176 0, /* tp_descr_get */
2177 0, /* tp_descr_set */
2178 0, /* tp_dictoffset */
2179 (initproc)set_init, /* tp_init */
2180 PyType_GenericAlloc, /* tp_alloc */
2181 set_new, /* tp_new */
2182 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002183};
2184
2185/* frozenset object ********************************************************/
2186
2187
2188static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2190 contains_doc},
2191 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2192 copy_doc},
2193 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2194 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002195 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 intersection_doc},
2197 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2198 isdisjoint_doc},
2199 {"issubset", (PyCFunction)set_issubset, METH_O,
2200 issubset_doc},
2201 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2202 issuperset_doc},
2203 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2204 reduce_doc},
2205 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2206 sizeof_doc},
2207 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2208 symmetric_difference_doc},
2209 {"union", (PyCFunction)set_union, METH_VARARGS,
2210 union_doc},
2211 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002212};
2213
2214static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002215 0, /*nb_add*/
2216 (binaryfunc)set_sub, /*nb_subtract*/
2217 0, /*nb_multiply*/
2218 0, /*nb_remainder*/
2219 0, /*nb_divmod*/
2220 0, /*nb_power*/
2221 0, /*nb_negative*/
2222 0, /*nb_positive*/
2223 0, /*nb_absolute*/
2224 0, /*nb_bool*/
2225 0, /*nb_invert*/
2226 0, /*nb_lshift*/
2227 0, /*nb_rshift*/
2228 (binaryfunc)set_and, /*nb_and*/
2229 (binaryfunc)set_xor, /*nb_xor*/
2230 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002231};
2232
2233PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002234"frozenset() -> empty frozenset object\n\
2235frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002236\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002237Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002238
2239PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002240 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2241 "frozenset", /* tp_name */
2242 sizeof(PySetObject), /* tp_basicsize */
2243 0, /* tp_itemsize */
2244 /* methods */
2245 (destructor)set_dealloc, /* tp_dealloc */
2246 0, /* tp_print */
2247 0, /* tp_getattr */
2248 0, /* tp_setattr */
2249 0, /* tp_reserved */
2250 (reprfunc)set_repr, /* tp_repr */
2251 &frozenset_as_number, /* tp_as_number */
2252 &set_as_sequence, /* tp_as_sequence */
2253 0, /* tp_as_mapping */
2254 frozenset_hash, /* tp_hash */
2255 0, /* tp_call */
2256 0, /* tp_str */
2257 PyObject_GenericGetAttr, /* tp_getattro */
2258 0, /* tp_setattro */
2259 0, /* tp_as_buffer */
2260 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2261 Py_TPFLAGS_BASETYPE, /* tp_flags */
2262 frozenset_doc, /* tp_doc */
2263 (traverseproc)set_traverse, /* tp_traverse */
2264 (inquiry)set_clear_internal, /* tp_clear */
2265 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002266 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002267 (getiterfunc)set_iter, /* tp_iter */
2268 0, /* tp_iternext */
2269 frozenset_methods, /* tp_methods */
2270 0, /* tp_members */
2271 0, /* tp_getset */
2272 0, /* tp_base */
2273 0, /* tp_dict */
2274 0, /* tp_descr_get */
2275 0, /* tp_descr_set */
2276 0, /* tp_dictoffset */
2277 0, /* tp_init */
2278 PyType_GenericAlloc, /* tp_alloc */
2279 frozenset_new, /* tp_new */
2280 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002281};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002282
2283
2284/***** C API functions *************************************************/
2285
2286PyObject *
2287PySet_New(PyObject *iterable)
2288{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002289 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002290}
2291
2292PyObject *
2293PyFrozenSet_New(PyObject *iterable)
2294{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002295 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002296}
2297
Neal Norwitz8c49c822006-03-04 18:41:19 +00002298Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002299PySet_Size(PyObject *anyset)
2300{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002301 if (!PyAnySet_Check(anyset)) {
2302 PyErr_BadInternalCall();
2303 return -1;
2304 }
2305 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002306}
2307
2308int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002309PySet_Clear(PyObject *set)
2310{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002311 if (!PySet_Check(set)) {
2312 PyErr_BadInternalCall();
2313 return -1;
2314 }
2315 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002316}
2317
2318int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002319PySet_Contains(PyObject *anyset, PyObject *key)
2320{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002321 if (!PyAnySet_Check(anyset)) {
2322 PyErr_BadInternalCall();
2323 return -1;
2324 }
2325 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002326}
2327
2328int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002329PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002330{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002331 if (!PySet_Check(set)) {
2332 PyErr_BadInternalCall();
2333 return -1;
2334 }
2335 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002336}
2337
2338int
Christian Heimesfd66e512008-01-29 12:18:50 +00002339PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002340{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002341 if (!PySet_Check(anyset) &&
2342 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2343 PyErr_BadInternalCall();
2344 return -1;
2345 }
2346 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002347}
2348
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002349int
Raymond Hettinger3625af52016-03-27 01:15:07 -07002350PySet_ClearFreeList(void)
2351{
2352 return 0;
2353}
2354
2355void
2356PySet_Fini(void)
2357{
2358 Py_CLEAR(emptyfrozenset);
2359}
2360
2361int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002362_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002363{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002364 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002366 if (!PyAnySet_Check(set)) {
2367 PyErr_BadInternalCall();
2368 return -1;
2369 }
2370 if (set_next((PySetObject *)set, pos, &entry) == 0)
2371 return 0;
2372 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002373 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002374 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002375}
2376
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002377PyObject *
2378PySet_Pop(PyObject *set)
2379{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002380 if (!PySet_Check(set)) {
2381 PyErr_BadInternalCall();
2382 return NULL;
2383 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302384 return set_pop((PySetObject *)set, NULL);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002385}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002386
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002387int
2388_PySet_Update(PyObject *set, PyObject *iterable)
2389{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002390 if (!PySet_Check(set)) {
2391 PyErr_BadInternalCall();
2392 return -1;
2393 }
2394 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002395}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002396
Raymond Hettingere259f132013-12-15 11:56:14 -08002397/* Exported for the gdb plugin's benefit. */
2398PyObject *_PySet_Dummy = dummy;
2399
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002400#ifdef Py_DEBUG
2401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002402/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002403 Returns True and original set is restored. */
2404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405#define assertRaises(call_return_value, exception) \
2406 do { \
2407 assert(call_return_value); \
2408 assert(PyErr_ExceptionMatches(exception)); \
2409 PyErr_Clear(); \
2410 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002411
2412static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302413test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002414{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002415 Py_ssize_t count;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +02002416 const char *s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002417 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002418 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002419 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002420 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002423 /* Verify preconditions */
2424 assert(PyAnySet_Check(ob));
2425 assert(PyAnySet_CheckExact(ob));
2426 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002428 /* so.clear(); so |= set("abc"); */
2429 str = PyUnicode_FromString("abc");
2430 if (str == NULL)
2431 return NULL;
2432 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002433 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002434 Py_DECREF(str);
2435 return NULL;
2436 }
2437 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002439 /* Exercise type/size checks */
2440 assert(PySet_Size(ob) == 3);
2441 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002443 /* Raise TypeError for non-iterable constructor arguments */
2444 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2445 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002447 /* Raise TypeError for unhashable key */
2448 dup = PySet_New(ob);
2449 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2450 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2451 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002453 /* Exercise successful pop, contains, add, and discard */
2454 elem = PySet_Pop(ob);
2455 assert(PySet_Contains(ob, elem) == 0);
2456 assert(PySet_GET_SIZE(ob) == 2);
2457 assert(PySet_Add(ob, elem) == 0);
2458 assert(PySet_Contains(ob, elem) == 1);
2459 assert(PySet_GET_SIZE(ob) == 3);
2460 assert(PySet_Discard(ob, elem) == 1);
2461 assert(PySet_GET_SIZE(ob) == 2);
2462 assert(PySet_Discard(ob, elem) == 0);
2463 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002465 /* Exercise clear */
2466 dup2 = PySet_New(dup);
2467 assert(PySet_Clear(dup2) == 0);
2468 assert(PySet_Size(dup2) == 0);
2469 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002471 /* Raise SystemError on clear or update of frozen set */
2472 f = PyFrozenSet_New(dup);
2473 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2474 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2475 assert(PySet_Add(f, elem) == 0);
2476 Py_INCREF(f);
2477 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2478 Py_DECREF(f);
2479 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002481 /* Exercise direct iteration */
2482 i = 0, count = 0;
2483 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
Serhiy Storchaka06515832016-11-20 09:13:07 +02002484 s = PyUnicode_AsUTF8(x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002485 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2486 count++;
2487 }
2488 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002490 /* Exercise updates */
2491 dup2 = PySet_New(NULL);
2492 assert(_PySet_Update(dup2, dup) == 0);
2493 assert(PySet_Size(dup2) == 3);
2494 assert(_PySet_Update(dup2, dup) == 0);
2495 assert(PySet_Size(dup2) == 3);
2496 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002498 /* Raise SystemError when self argument is not a set or frozenset. */
2499 t = PyTuple_New(0);
2500 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2501 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2502 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002504 /* Raise SystemError when self argument is not a set. */
2505 f = PyFrozenSet_New(dup);
2506 assert(PySet_Size(f) == 3);
2507 assert(PyFrozenSet_CheckExact(f));
2508 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2509 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2510 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002512 /* Raise KeyError when popping from an empty set */
2513 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2514 Py_DECREF(ob);
2515 assert(PySet_GET_SIZE(ob) == 0);
2516 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002517
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002518 /* Restore the set from the copy using the PyNumber API */
2519 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2520 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002522 /* Verify constructors accept NULL arguments */
2523 f = PySet_New(NULL);
2524 assert(f != NULL);
2525 assert(PySet_GET_SIZE(f) == 0);
2526 Py_DECREF(f);
2527 f = PyFrozenSet_New(NULL);
2528 assert(f != NULL);
2529 assert(PyFrozenSet_CheckExact(f));
2530 assert(PySet_GET_SIZE(f) == 0);
2531 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002532
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002533 Py_DECREF(elem);
2534 Py_DECREF(dup);
2535 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002536}
2537
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002538#undef assertRaises
2539
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002540#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002541
2542/***** Dummy Struct *************************************************/
2543
2544static PyObject *
2545dummy_repr(PyObject *op)
2546{
2547 return PyUnicode_FromString("<dummy key>");
2548}
2549
2550static void
2551dummy_dealloc(PyObject* ignore)
2552{
2553 Py_FatalError("deallocating <dummy key>");
2554}
2555
2556static PyTypeObject _PySetDummy_Type = {
2557 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2558 "<dummy key> type",
2559 0,
2560 0,
2561 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2562 0, /*tp_print*/
2563 0, /*tp_getattr*/
2564 0, /*tp_setattr*/
2565 0, /*tp_reserved*/
2566 dummy_repr, /*tp_repr*/
2567 0, /*tp_as_number*/
2568 0, /*tp_as_sequence*/
2569 0, /*tp_as_mapping*/
2570 0, /*tp_hash */
2571 0, /*tp_call */
2572 0, /*tp_str */
2573 0, /*tp_getattro */
2574 0, /*tp_setattro */
2575 0, /*tp_as_buffer */
2576 Py_TPFLAGS_DEFAULT, /*tp_flags */
2577};
2578
2579static PyObject _dummy_struct = {
2580 _PyObject_EXTRA_INIT
2581 2, &_PySetDummy_Type
2582};
2583